Click here to Skip to main content
Click here to Skip to main content

ASP.NET MVC Custom Model Binder

, 22 Jun 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
MVC custom binding.

Introduction

In the example below I would like to break up the date into three fields: Day, Month, and Year, on my view, but I would like my model to have just one property that can store the combination of these fields.

Background

Recently I was looking at an unusual problem where we had to add custom fields to a view on an ad hoc basis. Not really a problem if it was an MVC app talking directly to a data source. But mine was over several REST based services that were talking to a CRM dynamics backend, spread across multiple domains. Which meant we had to change the data models through out the system. That's when it occurred to  me that we can have one dedicated field  that can store all the ad hoc field data using JASON or xml and we append it to one of the existing fields. Probably not the ideal solution, but that's when I came across custom binding for MVC. I would like to share with you how simple and easy it is to use custom binding to solve similar issues.

Using the Code

View 

In my view I am going to provision three fields for the date within my form.

<form id="Home" action="" method="POST">
    Day     <input id="Day" name="Day" value="" type="text" />
    Month   <input id="Month" name="Month" value="" type="text" />
    Year    <input id="Year" name="Year" value="" type="text" />    
            <input id="Submit" type="Submit" value="Submit" />
</form>

Model 

In my model I will only have one property for the three fields called a Date:

public class HomePageModels
{
    public string Title { get; set; }
    public string Date { get; set; }
}

Custom Binding  

The custom binding class needs to inherit form IModelBinder. Here we capture the current request and extract the Form fields individually. Then we can manipulate these fields any way we like. In this example as you can see I am adding them to a single property called Date.

public class HomeCustomBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, 
                            ModelBindingContext bindingContext)
    {
        HttpRequestBase request = controllerContext.HttpContext.Request;

        string title = request.Form.Get("Title");
        string day = request.Form.Get("Day");
        string month = request.Form.Get("Month");
        string year = request.Form.Get("Year");

        return new HomePageModels
                   {
                       Title = title,
                       Date = day +"/"+ month +"/"+ year
                   };
    }
} 

Alternatively if we do not want to implement  custom binding for each and every Model and Property in our application we can inherit from the DefaultModelBinder and override the BindModel method  as below

public class HomeCustomDataBinder : DefaultModelBinder
    {

        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType == typeof(HomePageModels))
            {
                HttpRequestBase request = controllerContext.HttpContext.Request;

                string title = request.Form.Get("Title");
                string day = request.Form.Get("Day");
                string month = request.Form.Get("Month");
                string year = request.Form.Get("Year");

                return new HomePageModels
                {
                    Title = title,
                    Date = day + "/" + month + "/" + year
                };

                //// call the default model binder this new binding context
                //return base.BindModel(controllerContext, newBindingContext);
            }
            else
            {
                return base.BindModel(controllerContext, bindingContext);
            }
        }

    } 

Once we have completed coding our custom class we will need to register the class which I do in the Global.asax under Application_Start().

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    AuthConfig.RegisterAuth();
    ModelBinders.Binders.Add(typeof(HomePageModels), new HomeCustomBinder());
}

Controller

Finally we need to inform the controller as to the binding we want it to use. This we can specify using attributes [ModelBinder(typeof(HomeCustomBinder))] as below:

[HttpPost]
public ActionResult Index([ModelBinder(typeof(HomeCustomBinder))] HomePageModels home)
{
    if (ModelState.IsValid)
    {
        ViewBag.Title = home.Title;
        ViewBag.Date = home.Date;
    }
    return View();
}

Points of Interest 

While you could argue that we can achieve the same by manually capturing the requests inside the controller and manipulating how the property is populated, the idea behind using custom binding is to facilitate reuse and thus avoid manually wiring up views and models. 

License

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

Share

About the Author

Ritesh Ramesh
Architect Infosolvex Solutions Inc
Australia Australia
Ritesh is an IT consultant with over ten years of experience in the IT industry varying from consultation, architecture, design, development to technical management. He has a strong background in solutions and applications architecture with a focus on Microsoft’s .Net platform. His area of expertise spans design and implementation of client/server, database and web-based systems. He has worked with C#, ASP.NET 1.1 and 2.0, ADO.NET, Web Services and SQL technology on several enterprise class projects.
 

 

Freedom is not worth having if it does not include the freedom to make mistakes.
Mahatma Gandhi

Comments and Discussions

 
QuestionNice and easy to follow PinmemberZiaur Rahman24-Dec-14 23:09 
QuestionVery nice example..keeps the good work PinmemberJameel M20-Feb-14 18:55 
QuestionASP.NET MVC Custom Model Binder Pinmemberrajacsharp527-Nov-13 23:15 
Questionnice one Pinmemberdiouf_zyj15-Oct-13 11:03 
GeneralMy vote of 4 PinmemberJhonathan Izquierdo24-Jun-13 4:39 
SuggestionPretty Good PinmemberSteve072818-Jun-13 6:51 
GeneralRe: Pretty Good PinmemberRitesh Ramesh18-Jun-13 16:09 
GeneralRe: Pretty Good PinmemberSteve072819-Jun-13 4:24 
GeneralMy vote of 5 PinmemberSERokon13-Jun-13 20:23 
QuestionArticle title PinmemberKarthik. A12-Jun-13 4:15 
AnswerRe: Article title PinmemberRitesh Ramesh12-Jun-13 13:37 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 23 Jun 2013
Article Copyright 2013 by Ritesh Ramesh
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid