Click here to Skip to main content
15,868,141 members
Articles / Web Development / ASP.NET
Tip/Trick

Model Binding using IModelBinder and DefaultModelBinder in ASP.NET MVC

Rate me:
Please Sign up or sign in to vote.
4.81/5 (16 votes)
11 Aug 2014CPOL3 min read 99.2K   11   11   9
In this tip, we will learn custom model binder in MVC application.

Introduction

Model binding is one of the magic things in MVC framework. We know that if the model property matches exactly with view, then MVC architecture automatically takes care of the model binding process. This is very simple and straight forward.

But, if the model property is not matched exactly with the view? Then how do we bind model in time of data submission?

In this post, we will understand how to bind model when model property is incompatible with View. To implement our custom model binding mechanism, we have to implement either IModelBinder interface in our custom class or we can derive our custom class from DefaultModelBinder class.

The DefaultModelBinder class implements the IModelBinder interface. So, let’s see the definition of IModelBinder. It contains only one method called BindModel and it takes two parameters; one is ControllerContext and the other is ModelBindingContext. Have a look at the below definition of IModelBinder.

C#
public interface IModelBinder
    {
        // Summary:
        //     Binds the model to a value by using the specified controller context and
        //     binding context.
        //
        // Parameters:
        //   controllerContext:
        //     The controller context.
        //
        //   bindingContext:
        //     The binding context.
        //
        // Returns:
        //     The bound value.
        object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext);
    }

Here is the diagram which shows that the DefaultModelBinder class has implemented IModelBinder interface.

Image 1

Now, let’s look at the definition of DefaultModelBinder class. The class contains many methods including BindMode() method. Have a look at the below screen, though it’s not full class definition. The BindModel() method is defined as virtual method which means we can implement the method in our own way.

Image 2

Ok, let’s try to implement our custom model binding mechanism; first we will implement IModelBinder class in our custom binder class.

So, let’s create one simple model class called Person and it contains only two properties. The first property is name which will be a combination of three different properties called “first_name” ,”middle_name” and “last_name” that we will define in view.

C#
namespace ModelBinder.Models
{
    public class Person
    {
        [Required]
        [MaxLength(50,ErrorMessage="Full name should be within 50 character")]
        public string full_name { get; set; }

        [Range(18,80)]
        [Required(ErrorMessage="Please provide age")]
        public Int32 Age { get; set; }
    }
}

Here is the view which will be mapped with the Person mode. We are seeing that there are three different properties which will construct the full name.

HTML
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div>
            @{Html.BeginForm("PostData", "Customodelbinder");
                <table>
                    <tr>
                        <td>First Name : </td>
                        <td>@Html.TextBox("first_name")</td>
                    </tr>
                    <tr>
                        <td>Middle Name : </td>
                        <td>@Html.TextBox("middle_name")</td>
                    </tr>
                    <tr>
                        <td>Surname :</td>
                        <td> @Html.TextBox("last_name")</td>
                    </tr>
                    <tr>
                        <td>Age:</td>
                        <td> @Html.TextBox("age") </td>
                    </tr>
                    <tr>
                        <td></td>
                        <td>
                            <input type="submit" name="Save" value="Save" />
                        </td>
                    </tr>
                </table>
            }
    </div>
</body>
</html>

Now, the fact is clear that the property of model is not mapped with property of View, then we have to write our own mapping logic to bind the view data in model.

Create one class and implement IModelBinder interface within it. In the below snippet, we have created “PersonModelBinder” custom binding class and implemented IModelBinder interface. We have seen that IModelBinder contains only one method called BindModel and we have implemented the logic to map view property with the model property.

C#
public class PersonModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var request = controllerContext.HttpContext.Request;

            string first_name = request.Form.Get("first_name");
            string middle_name = request.Form.Get("middle_name");
            string last_name = request.Form.Get("last_name");
            int Age = Convert.ToInt32(request.Form.Get("age"));
            return new Person { full_name = first_name + middle_name + last_name, Age = Age };
        }
    }

The implementation is very simple, just we are combining first_name, middle_name and last_name to combine full name and returning Person object accordingly. Fine, now we will create the controller which will contain PostData() action and as parameter, it will take Person type object after binding in our custom PersonModelBinder class. Here is the simple implementation.

C#
public class CustomodelbinderController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public void PostData([ModelBinder(typeof(PersonModelBinder))] Person person)
        {

        }
    }

Now, we have to register the custom binder class in MVC pipeline. Just add the below line in global.asax page.

C#
//Register Custom Model binder
ModelBinders.Binders.Add(typeof(Person), new PersonModelBinder());

Fine, we have setup everything to bind model using our custom class. Let’s run the application and we should see the below view.

Image 3

I have given few arbitrary data and in controller we are seeing that the first_name, middle_name and last_name property have combined within single property called full_name.

Image 4

Now, as we said, we can use DefaultModelBinder class too to implement BindModel method, Just we have to override the method. Here is the sample implementation.

C#
public class PersonModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var request = controllerContext.HttpContext.Request;

        string first_name = request.Form.Get("first_name");
        string middle_name = request.Form.Get("middle_name");
        string last_name = request.Form.Get("last_name");
        int Age = Convert.ToInt32(request.Form.Get("age"));
        return new Person { full_name = first_name + middle_name + last_name, Age = Age };
    }
}

Border Line

In this tip, we have learned to implement custom model binding when model property is not matched with the view. Hope it will help you to understand custom model binding.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer DELL International
India India
I am software developer from INDIA. Beside my day to day development work, i like to learn new technologies to update myself. I am passionate blogger and author in various technical community including dotnetfunda.com , c-sharpcorner.com and codeproject. My area of interest is modern web technology in Microsoft stack. Visit to my personal blog here.

http://ctrlcvprogrammer.blogspot.in/

Comments and Discussions

 
QuestionVery good article Pin
Roxana Cor29-Jul-16 0:16
Roxana Cor29-Jul-16 0:16 
QuestionDoes the ModelBinder attribute before the Person object parameter is really needed? Pin
yanivher23-Jul-15 23:51
yanivher23-Jul-15 23:51 
Since you already registered your Custom Model Binder in the Global.asax.
QuestionGood Article Pin
ashok rathod22-Feb-15 18:34
professionalashok rathod22-Feb-15 18:34 
GeneralMy vote of 3 Pin
pdamp18-Nov-14 2:54
pdamp18-Nov-14 2:54 
NewsMarvellous Tutorial Pin
Pavan Navule24-Aug-14 19:28
Pavan Navule24-Aug-14 19:28 
QuestionVote 5 :) Pin
Tridip Bhattacharjee11-Aug-14 21:35
professionalTridip Bhattacharjee11-Aug-14 21:35 
QuestionNice article :) Pin
Tridip Bhattacharjee11-Aug-14 21:34
professionalTridip Bhattacharjee11-Aug-14 21:34 
AnswerRe: Nice article :) Pin
Sourav Kayal17-Aug-14 1:26
Sourav Kayal17-Aug-14 1:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.