Sunday, January 15, 2012

Implementing ASP.NET MVC like NameValueCollection translation to method parameters

If you've programmed with ASP.NET MVC, you know about a neat feature where the form post data or the query string, which is string data, is automagically converted to strongly typed objects when it is passed to its Controller Action.

For instance, consider the following code:

public class HomeController : Controller
{
     public ActionResult ProductQuery(string Name, int Code)
     {
     ...
     }
}

The web request to http://<server<:port>></AppRoot>/Home/ProductQuery?Name=123&Code=456 will be properly handled and Name will be treated as a string while Code will be treated as an integer value.

Also consider the following code:

// UserRegFormData.cs
public class UserRegFormData
{
     public string Name{get;set;}
     public DateTime Dob{get;set;}
}

// HomeController.cs
public ActionResult Register(UserRegFormData urfd)
{
...
}

You could now setup an html form with action=/Home/Register, method=post, a text field with name="urfd.Name" and another one with name="urfd.Dob". When this form is submitted with data in the two text fields, ASP.NET MVC will automatically create the strongly typed UserRegFormData object with correct values for its properties. This wasn't the case before ASP.NET MVC. You would receive all the values as strings and you were responsible for doing the conversions in your ASP.NET server side code.
Well I've been thinking about how this could be done without using ASP.NET MVC.

Why reinvent the wheel, you might ask. The answer is two fold. Firstly, there might be situations where ASP.NET MVC might just not be a suitable solution, a non web application, perhaps. This type of routing and smart parameter translation would also be useful in scenarios where input contains both the parameters as well as the operation the perform on them. Secondly, I have been facinated by this very approach ever since I discovered it in ASP.NET MVC. When I recently came across Managed Extensibility Framework (MEF) as it is packaged with .Net 4, I wondered if it could be used to create an MVC framework from scratch. It would be a good learning opportunity and I wanted to cease it.

While I made some progress with routing URLs to methods in controller objects, I got faced with the issue of handling the input. The input data would not translate itself to strongly typed objects. Few searches on the Internet revealed that there was nothing readily available for this and I really didn't want to dig through the ASP.NET MVC code to see how it was implemented there.

I did an Internet search on how to convert string objects to other object types. This StackOverflow article provided the solution:

Another search on how to assign property values using reflection yeilded this post on DotNetSpider:

I found how to create strongly typed arrays from this article on Byte.com:

I had most of what I needed to get started.

I have uploaded the initial code to my github repository. The code is still crude and it has not yet undergone a refactoring exercise. https://github.com/jimmy00784/MEFExample/tree/master/StringToArgumentsTest.

1 comment:

  1. wonderful issues altogether, you just received brand new|a new} reader. What may you recommend in regards to your publish that you made a few days in the past? Any certain?
    All-Clad Stainless Mesh Splatter Screen

    ReplyDelete