In the process of rewriting this blog’s framework, I ran across an issue with binding my MVC views to custom view models.  Specifically, when I tried updating my model on post back like so:
   1:  [AcceptVerbs(HttpVerbs.Post)]
   2:  public ActionResult Contact()
   3:  {
   4:      ContactScreen screen = new ContactScreen();
   5:      TryUpdateModel(screen);

Or when I tried to get the view model object directly in as a parameter for the method like so:
   1:  [AcceptVerbs(HttpVerbs.Post)]
   2:  public ActionResult Contact(ContactScreen screen)
   3:  {

I was consistently getting this error:
No parameterless constructor defined for this object.
Unfortunately the stack trace didn’t really give me much information.  What it did tell me was that the issue was coming from the DefaultModelBinder.  After commenting out different properties of my ContactScreen object (the view model my view was bound to) I discovered that the culprit was this right here:
public SelectList AuthorSelectList { get; set; }
Basically, the default data binder in MVC 2.0 doesn’t understand how to instantiate a select list when you’re not passing data over.  Since my SelectList is normally instantiated in a method that loads different data to the screen, I only ran into the error when it was trying to do the data binding behind the scenes.  Fortunately, there is a way around this that doesn’t involve us having to alter the default binder.  We can tell the class to exclude certain elements when it’s binding.  This is done very easily by putting a Bind attribute on the class and telling it to exclude our property like so:
   1:  [Bind(Exclude="AuthorSelectList")]
   2:  public class ContactScreen : ScreenBase
   3:  {
   4:       public SelectList AuthorSelectList { get; set; }
Unfortunately, we do have to handle custom binding of the value selected for the select list, but we only have to do it for our one value instead of everything in our class.

Chris Risner

Leave a Comment