Click here to Skip to main content
15,891,767 members
Articles / Web Development / ASP.NET / ASP.NETvNext

Custom Formatter and Data Binding in MVC

Rate me:
Please Sign up or sign in to vote.
4.83/5 (5 votes)
31 Oct 2016CPOL2 min read 11.3K   6   2
Custom formatter and data binding in MVC

Introduction

The purpose of the article is to overcome such scenario where we want to handle custom data binding in MVC application. We know that data binding and Request/Response processing is one of the key extensible point of MVC Framework.

Custom Formatter

Let’s start with custom formatter. This is very useful when we want to send/get data structure other than JSON or XML. We know that MVC supports both data encoding scheme by default. Probably the other solution to red off the problem is just to prepare XML or JSON format of your data before send to API. But the better solution could be writing your custom formatter and hook up in MVC framework. Say we have some comma separated information which we want to feed to API. In this example, we will see how to process such value using custom formatter. Here is our simplest DTO class.

public class Person
{
    public string Name { get; set; }
    public string Surname { get; set; }
}

Now we have created CommaFormatter which is derived from "BufferedMediaTypeFormatter". The mime type is chosen in constructor.

public class CommaFormatter : BufferedMediaTypeFormatter
    {
        public CommaFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/colon"));
        }
        public override bool CanReadType(Type type)
        {
            if (type == typeof(Person) || type == typeof(List<Person>))
                return true;
            else
                return false;
        }
        public override bool CanWriteType(Type type)
        {
            if (type == typeof(Person) || type == typeof(List<Person>))
                return true;
            else
                return false;
        }

        public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            List<Person> Obj = new List<Person>();
            Person p = null;
            StreamReader reader = new StreamReader(readStream);
            string str = reader.ReadToEnd();
            string []propArr = str.Split(',');
            foreach (var item in propArr)
            {
                string[] propAttribute = item.Split('|');
                p = new Person();
                foreach (var item1 in propAttribute)
                {
                    string[] propAttribute1 = item1.Split('=');
                    if (propAttribute1[0].ToLower().Trim().Equals("name"))
                    {
                        p.Name = propAttribute1[1];
                    }
                    if (propAttribute1[0].ToLower().Trim().Equals("surname"))
                    {
                        p.Surname = propAttribute1[1];
                    }
                }
                Obj.Add(p);
            }
            return Obj;
        }
    }

Now it’s time to hook up the formatter in Global page so that it got registered in MVC.

GlobalConfiguration.Configuration.Formatters.Add(new CommaFormatter());

In the Post method of API we are trying to pass list of "Person"

public class CustomController : ApiController
{
    [HttpPost]
    public void Post(List<Person> p)
    {

    }
}

Please make sure that the "Content-Type" is set in request header.

Image 1

You can observe that the payload is as per our custom data format.

Image 2

And it’s bound to action method.

Custom model binding

This is another way to bind unformatted data to MVC endpoint. Just think of one scenario where data is coming from a query string. We know that if the key of query string matches with the model property then MVC is intelligent enough to bind by default. But what if the query string does not match with model property? The custom model binding comes into the picture. We took a simple Person model to demonstrate the example.

public class Person
{
    public string Name { get; set; }
    public string Surname { get; set; }
}

Here we have created PersonModelBinder which is derived from DefaultModelBinder and overrides the BindModel method. In this method, we are getting the value of query string from request context and returning as concrete object of person model.

public class PersonModelBinder : DefaultModelBinder
    { 
        public PersonModelBinder()
        {

        }
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var request = controllerContext.HttpContext.Request;
            string name = request.QueryString["name"];
            string surname = request.QueryString["surname"];
            return new Person { Name = name, Surname = surname };
        }
    }

Here is the procedure to hook up the custom formatter in MVC pipeline.

ModelBinders.Binders.Add(typeof(Person), new PersonModelBinder());

To receive data as a parameter we have to use ModelBinder attribute.

public class CustomController : Controller
    {
        public void Post([ModelBinder(typeof(PersonModelBinder))]  Person p)
        {
           
        }
    }

We are seeing that the value is binded in action.

Image 3

Conclusion: In these two examples we have seen how to handle custom data format in MVC. The formatter is useful when you don’t want to convert your data to XML or JSON prior to sending to the API and custom model binder is suitable when the amount of data is small and short enough to pass as query string.

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

 
GeneralMy vote of 5 Pin
Tridip Bhattacharjee31-Oct-16 19:05
professionalTridip Bhattacharjee31-Oct-16 19:05 
QuestionOne image is missing Pin
Tridip Bhattacharjee31-Oct-16 19:04
professionalTridip Bhattacharjee31-Oct-16 19:04 

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.