Noah Blumenthal's Blog

January 14, 2009

MVC ModelBinders, complex types, Enumerables, and partial binding

Filed under: ASP.NET MVC — noahblu @ 5:15 pm

If you’ve got an object that’s got some sort of enumerable, you’re going to have to write your own ModelBinder.

For example, suppose you have a Person object with a List<string> containing friends’ names.  Now suppose you have an HTML page that has 10 textboxes and the user can add 10 friends at a time (better yet, give them a JS widget that adds textboxes as necessary).  You could post back 10 or 20 friends at a time, right?

Now the Person object might just have a FirstName & LastName (which are strings) and maybe a phone number (also a string), and, aside from this list of friends, be nicely updated using the default ModelBinder included in MVC.  However, you really want these friends to be updated with the Person object, right?  Well here’s an easy way to do it.

I’m going to call this partial binding even though that’s NOT what it is.  I mean it’s partial binding relative to my programming effort — I’m only going to bind part of my Person object and someone else (ie the MVC framework’s built in binders) will bind the rest.

Here goes:

internal class PersonModelBinder : IModelBinder
{
public ModelBinderResult BindModel(ModelBindingContext bindingContext)
{
ModelBinderResult result = ModelBinders.DefaultBinder.BindModel(bindingContext);
Person p = result.Value as Person;

// What we just did was bind the Person’s non-complex types: e.g. the string of FirstName, LastName, and PhoneNumber
// all the stuff MVC would do anyway without any intervention on our part.


// Now all you have to do is add logic to populate the list here

return result;
}
}

Ok, so that’s easy.  How about populating the list?  Well one way of doing it would be this:

Suppose your textboxes were named like “txtFriend_1”, “txtFriend_2”, “txtFriend_3”, etc, then you could easily loop through the form variables:

foreach (System.String key in bindingContext.HttpContext.Request.Form.AllKeys)
{
if (System.Text.RegularExpressions.Regex.IsMatch(key, @”^txtFriend_\d+$”, System.Text.RegularExpressions.RegexOptions.IgnoreCase))
{
p.Friends.Add(bindingContext.HttpContext.Request.Form[key]);
}
}

You don’t have to use regular expressions of course.  Pretty easy, huh?

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: