Mitch Rosenburg
Mitch Rosenburg

Reputation: 223

Adding multiple Prefixes to DefaultModelBinder MVC2

I've looked at most of the ModelBinding examples but can't seem to glean what I'm looking for.

I'd like:

<%= Html.TextBox("User.FirstName") %>
<%= Html.TextBox("User.LastName") %>

to bind to this method on post

public ActionResult Index(UserInputModel input) {}

where UserInputModel is

public class UserInputModel {
    public string FirstName {get; set;}
    public string LastName {get; set;}
}

The convention is to use the class name sans "InputModel", but I'd like to not have to specify this each time with the BindAttribute, ie:

public ActionResult Index([Bind(Prefix="User")]UserInputModel input) {}

I've tried overriding the DefaultModelBinder but can't seem to find the proper place to inject this tiny bit of functionality.

Upvotes: 1

Views: 1912

Answers (2)

Nathan Anderson
Nathan Anderson

Reputation: 6878

The ModelName property in the ModelBindingContext object passed to the BindModel function is what you want to set. Here's a model binder that does this:

 public class PrefixedModelBinder : DefaultModelBinder
 {
     public string ModelPrefix
     {
         get;
         set;
     }

     public PrefixedModelBinder(string modelPrefix)
     {
         ModelPrefix = modelPrefix;
     }

     public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
     {
         bindingContext.ModelName = ModelPrefix;
         return base.BindModel(controllerContext, bindingContext);
     }
 }

Register it in your Application_Start like so:

ModelBinders.Binders.Add(typeof(MyType), new PrefixedModelBinder("Content"));

Now you will no longer to need to add the Bind attribute for types you specify use this model binder!

Upvotes: 2

Derek Greer
Derek Greer

Reputation: 16252

The BindAttribute can be used at the class level to avoid duplicating it for each instance of the UserInputModel parameter.

======EDIT======

Just dropping the prefix from your form or using the BindAttribute on the view model would be the easiest option, but an alternative would be to register a custom model binder for the UserInputModel type and explicitly looking for the prefix you want.

Upvotes: 1

Related Questions