Posts
208
Comments
1144
Trackbacks
51
MVC Control Extensions - Automatically Set Control Names

To set a normal text box in the MVC framework, the most typical code would look like this:

   1:  <%=Html.TextBox("FirstName", ViewData.Model.Contact.FirstName)%>

The key here is that you should set the name of the textbox to be the exact same name of the property name.  If you do this, then it enables you to use extension methods such as the UpdateFrom() method to automatically populate your object from Request.Form parameters when you post to your controller action.  This is all well and good but it is very easy to make a typo when typing the "FirstName" string for example.  Wouldn't it be nice if this all just happened automatically? 

Well, I found a very elegant solution to this last week when I was browsing the latest code of the Validation Framework on CodePlex.  In the MVC quick start code for the Validation Framework, they provide extension methods for creating a "ValidatedTextbox", for example, that works with that validation framework which looks like this:

   1:  <%=Html.TextBoxValidated(() => ViewData.Model.Product.ProductName)%>

Not only is this solution elegant but I quickly realized that this could be easily generalized to so many other scenarios.  Not just in the context of this validation framework but also for creating the most "normal" textbox scenario.  By using this method, I can now re-write the first example like this:

   1:  <%=Html.TextBox(() => ViewData.Model.Contact.FirstName)%>

The resulting HTML that is produced will populate the textbox with the value from the FirstName property and it will also name the textbox "FirstName".  So the HTML the gets rendered in the browser is:

   1:  <input type="text" name="FirstName" id="FirstName" value="Bill" />

It turns out that there is not many lines of code required to pull this off.  The lambda expression is specified in the mark up and a Linq Expression is used for the method parameter.  The complete code for the Textbox extension methods is as follows:

   1:  public static class ControlExtensions
   2:  {
   3:      public static string TextBox<T>(this HtmlHelper htmlHelper, Expression<Func<T>> expression)
   4:      {
   5:          return TextBox<T>(htmlHelper, expression, null);
   6:      }
   7:   
   8:      public static string TextBox<T>(this HtmlHelper htmlHelper, Expression<Func<T>> expression, object htmlAttributes)
   9:      {
  10:          MemberExpression memberExpression = expression.Body as MemberExpression;
  11:          if (memberExpression == null)
  12:          {
  13:              throw new ArgumentException("The specified expression is not a valid MemberExpression.", "expression");
  14:          }
  15:   
  16:          Func<T> compile = expression.Compile();
  17:          T value = compile.Invoke();
  18:   
  19:          return htmlHelper.TextBox(memberExpression.Member.Name, Convert.ToString(value), htmlAttributes);
  20:      }
  21:  }

Notice that since this is a MemberExpression where we're just getting a value from a property, we can simply use the Member.Name to get at the "FirstName" string.  And then we can use the Compile() method of the Expression<TDelegate> class to get executable code in the form of a delegate that represents the lambda.  Now that we have the Func<T> we can simply call Invoke() to get at the value of the FirstName property.  Now that we have the name and value, we can pass it to the already existing TextBox extension methods.

This technique can really be generalized to any MVC control.  It can also be generalized to create composite controls as they have done in the Validation Framework above.  In my opinion, Microsoft should consider including this type of thing in the base MVC library.  But if not, it's easy enough to add to your own MVC helper libraries.

posted on Sunday, June 22, 2008 11:03 PM Print
Comments
Gravatar
# re: MVC Control Extensions - Automatically Set Control Names
Oskar Austegard
2/6/2009 10:30 AM
Brilliant.

I love the elegant terseness of MVC + Extension Methods + Lamdas...
Gravatar
# re: MVC Control Extensions - Automatically Set Control Names
Kannan
2/26/2010 2:45 AM
Hi,
Can you post some working example for the above?

Thanks,
Kannan
Gravatar
# re: MVC Control Extensions - Automatically Set Control Names
Steve
2/26/2010 4:09 AM
@Kannan - I complete code is in the blog post above. But regardless, this post is a little out dated now. See this post for more up-to-date information: http://geekswithblogs.net/michelotti/archive/2010/01/17/encapsulate-multiple-html-helpers-to-make-views-more-dry.aspx

Post Comment

Title *
Name *
Email
Comment *  
Verification

View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers




Google My Blog

Tag Cloud