Friday, July 7, 2017

ASP.Net MVC - Custom Model Binding

custom-model-binding
In last article, we have discussed about what is ASP.NET Model binding and saw a basic introduction to the Model Binder. In this post we will see creating Custom Model Binding in ASP.Net MVC with simple example.

Model Binder in ASP.NET MVC

For model binding MVC uses the following types-

IModelBinder interface - This defines methods that are required for a Model Binder, like the BindModelAsync method. This method is responsible for binding a model to some values using ModelBindingContext

IModelBinderProvider interface - This interface contains methods that enables dynamic implementation of model binding for classes which implement the IModelBinder interface. This is used to manage the custom binder for the type of data posted by the end-user in views.

Creating Custom Model Binder

We creating our custom model binder by implementing the IModelBinder and IModelBinderProvider interfaces. Let see how we will do that.

Note :I have used ASP.Net MVC Core project here.All the codes are in ASP.Net MVC Core.


View Page
We have below form for adding new Student. There are three fields Student ID, First Name and Last Name(to keep it simple).
aspnet-mvc-form

Model
In my model, I will only have one property StudentName for saving Student Name.
namespace MVCCustomModelBinding.Models
{
    public class Student
    {
        public int StudentID { get; set; }
        public string StudentName { get; set; }
        
    }
}
Action Method
In controller, we have below action method for adding new student record.
[HttpPost]
        /// 
        /// Action Method for adding new student record
        /// 
        /// 
        public IActionResult Create(Student student)
        {            
            /*Code for saving student in database*/
            return View("Index");
        }
Custom Binding
As you can see above, we have two fields Fisrt Name and Last Name in our Student form while in our action method we have passed Student model object as parameter which have only one property StudentName. Here we are going to create our custom model binder to capture the current request and extract the Form fields individually. Then we will manipulate Fisrt Name and Last Name fields any way we like. In this example as you can see I am adding them to a single property called StudentName. Below is the code-
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using MVCCustomModelBinding.Models;
using System;
using System.Threading.Tasks;

namespace MVCCustomModelBinding.CustomBinder
{
    /// 
    /// Custom Model Binder
    /// 
    public class StudentCustomBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null) throw new ArgumentNullException(nameof(bindingContext));

            HttpRequest request = bindingContext.HttpContext.Request;
            string stdName = request.Form["StudentFirstName"] + " " + request.Form["StudentLastName"];
            string stdId = request.Form["StudentID"];
            bindingContext.Result = ModelBindingResult.Success(new Student { StudentID = int.Parse(stdId), StudentName = stdName });
            return Task.CompletedTask;
        }
    }
    /// 
    /// Custom Model Binder Provider
    /// 
    public class StudentCustomBinderProvider : IModelBinderProvider
    {
        public IModelBinder GetBinder(ModelBinderProviderContext context)
        {
            //Return null if model type is not Student
            if (context.Metadata.ModelType != typeof(Student))
            {
                return null;
            }
            return new StudentCustomBinder();
        }
    }
}
Register Custom Binder
We will add the above custom model provider class in the application, so that application will load it in the model binder process. Open Startup.cs and add the following line ConfigureServices method.

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
   // Add framework services.
  services.AddApplicationInsightsTelemetry(Configuration);
  services.AddMvc().AddMvcOptions(options=> {
         options.ModelBinderProviders.Insert(0, new StudentCustomBinderProvider());
      });
 }

Output
aspnet-mvc-custombinder

Conclusion
Custom Model Binder provides a mechanism using which we can map the data from the request to our ASP.NET MVC Model.

I hope this will be helpful for you. Please leave your feedback,criticism and everything in between.

No comments:

Post a Comment

If You Enjoyed This Post Please Take 5 Seconds To Share It.

^ Scroll to Top hgpromo