ASP.NET MVC Custom Model Binding

Posted by: Malcolm Sheridan , on 10/2/2010, in Category ASP.NET MVC
Views: 119283
Abstract: The following article demonstrates how to create a custom model binder to accept a strongly typed object from a HTML multi select control.
One item I take for granted when I'm using ASP.NET MVC is the powerful feature that is model binding. Model binding is ASP.NET MVC's mechanism for mapping HTTP request data directly into action method parameters and custom .Net objects. Each time your application receives an HTTP request containing the form's data as a pair of key/value pairs, the ControllerActionInvoker invokes the DefaultModelBinder to transform that raw HTTP request into something more meaningful to you, which would be a .Net object. This just works and I love it. Sometimes you need to customize the default model binding to work a little differently. For example, if you were expecting a strongly typed collection of values posted from a multi select control, the default model binding won't work as expected. I'll demonstrate one workaround for this so your action can expect a strongly typed object, and not just an array of strings.
Open visual studio 2010 and create a new ASP.NET MVC 2 empty web application. The model for this will be simple as I want to illustrate the technique of model binding. Here's the model below:
public class Car
{
      public string Make { get; set; }
       public int Id { get; set; }
 
       public static List<Car> GetCars()
       {
            return new List<Car>
                           {
                               new Car { Id = 1, Make = "Ford"},
                               new Car { Id = 2, Make = "Holden"},
                               new Car { Id = 3, Make = "Chevrolet"}
                           };
       }
}
 
 
Now to fast track things. I've got an action that receives HTTP post request and its signature is below:
 [HttpPost]
public ActionResult PostCars(List<Car> cars)
{
      return Content("Ok");
}
 
The action's parameter is a generic list of Car objects. If you post the data using a multi select HTML control, the default model binding won't work as expected.
image_1
The model binder doesn’t know how to bind the incoming values to a generic list of cars. This is where you can create a custom model binder to do this for you. To create a custom model binder, all that’s required is a class that inherits the IModelBinder interface. From there you implement the BindModel method. Here’s the code below:
public class SelectListModelBinder : IModelBinder
{
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            // Get the raw attempted value from the value provider
            var incomingData = bindingContext.ValueProvider.GetValue("cars").AttemptedValue;
            return incomingData.Split(new char[1] { ',' }).Select(data => Car.GetCars().FirstOrDefault(o => o.Id == int.Parse(data))).ToList();
        }
}
 
The incoming data can be viewed thanks to the binding context parameter:
 
var incomingData = bindingContext.ValueProvider.GetValue("cars").AttemptedValue;
 
The cars values is being passed into the action through the Request.Forms["cars"] value. From there I return a Car object populated with the values from incoming data. Nice and easy.
 
To use this function I can either register the model binder in the global.asax file, which means it will available to any action that accept a list of cars:
 
protected void Application_Start()
{
      AreaRegistration.RegisterAllAreas();
       ModelBinders.Binders.Add(typeof (List<Car>), new SelectListModelBinder());
       RegisterRoutes(RouteTable.Routes);
}
 
 
If I wanted to target particular actions, I can prefix the model binder to the parameter:
 
public ActionResult PostCars([ModelBinder(typeof(SelectListModelBinder))] List<Car> cars)
{
      return Content("Ok");
}
 
 
Model binding is a powerful feature in ASP.NET MVC and it can help you out in sticky situations.
 
The entire source code of this article can be downloaded over here

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @malcolmsheridan


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by james on Saturday, October 9, 2010 5:08 AM
What is  IModelBinder interface. I want know.
<a href="http://www.viteb.com/custom-software-development/">software web app development</a>
Comment posted by Malcolm Sheridan on Saturday, October 9, 2010 10:28 PM
@james
It's an interface that defines the methods for model binding.
Comment posted by dkdi on Wednesday, October 13, 2010 1:09 AM
nice
Comment posted by kumar on Thursday, February 9, 2012 7:08 AM
I cannot download the source attached, the page just refreshes over there..

can you please check that or send that code..
Comment posted by Andru on Monday, February 27, 2012 9:38 AM
It's not working throw a nullreference exception on var incomingData = bindingContext.ValueProvider.GetValue("cars").AttemptedValue;
Comment posted by kannan on Wednesday, March 21, 2012 3:33 AM
i want to send the text box values in the form to another form textbox in asp.net mvc2 by using a model binder concept can any one help me
Comment posted by Devmonster on Friday, September 14, 2012 3:37 AM
Thank you. I was actually just looking on an example on how to use custom model binding and you've shown me right into it.
Comment posted by Rom on Thursday, March 21, 2013 3:53 AM
Exact solution for the problem I was facing. Seems to be an old post but still very helpful, even now. Thanks.
Comment posted by Cameron Pulcifer on Thursday, December 5, 2013 11:49 AM
Thank you. I was able to apply to nullable boolean, like so:

var param = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (param != null)
        {
            var value = param.AttemptedValue;
            return value == "true,false";
        }
        return false;

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

C# .NET BOOK

C# Book for Building Concepts and Interviews

Tags

JQUERY COOKBOOK

jQuery CookBook