1

I am beginning out using the .NET MVC 4 Framework and am trying to figure out how to customize the data binding that Razor uses for forms. For example, I have been taught in class to use something like @Html.TextBoxFor(be => be.Title) to bind an input text box to a Model.Title property. But what if I want to send a custom control across the same binding Model?

For example, I am creating a blogging CMS and have a custom "tagging" control for tagging blog posts. I want to bind a string array of tags to a List<String>() object in my backend. How can I go about making this work correctly?

1 Answer 1

1

For binding to a List you don't need a custom model binder, simply use the syntax in your razor view:

 @for (int i = 0; i < Model.SomeCollectionProperty.Count; ++i)
 {
     @Html.TextBoxFor(m => m.SomeCollectionProperty[i])
 }

That said, if you do need to create a custom model binder for a more complex scenario, you simply need to implement an IModelBinder or override e.g. the BindProperty method of the DefaultModelBinder and register it with the MVC framework.

In the first case, you register your custom binder in the Application_Start of your global.asax like so:

ModelBinders.Binders.Add(typeof(MyFancyType), new MyFancyTypeModelBinder());

In the second case, you replace the default model binder like so:

ModelBinders.Binders.DefaultBinder = new MyExtendedDefaultModelBinder();

In both of these cases, your model binder classes need to be thread-safe, since the same model binder instance will be used for all http requests.

As a third option, you can actually take full control of model binder construction by implementing an IModelBinderProvider and registering it like so:

ModelBinderProviders.BinderProviders.Add(new MyModelBinderProvider());

The final option that I am aware of is to use the ModelBinderAttribute, like so

[ModelBinder(typeof(MyCustomModelBinder))]
public class MyModelClass
{
    public class MyCustomModelBinder : DefaultModelBinder
    {
        ...
    }
    ...
}

In the above example, the model binder is actually nested inside the model class, but it can be defined separately as well.

I tend to prefer to implement IModelBinder and register it in the model binders dictionary - as that allows me easily to reuse the same type across multiple models with one simple registration. In the rare event that I need to completely customize model binding for a particular model, I will use the last approach.

Sign up to request clarification or add additional context in comments.

2 Comments

But what if I am starting with a new Object and I want to Add to the List, meaning it starts out with Count = 0. As far as I'm concerned, the code you posted would work for editing the data
Then you can populate your initial list with string.Empty for however many items you want to allow. If you want to dynamically add items, you can append a new item to the list on the post action, or do it client side by creating new elements that follow the model binding naming convention.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.