Custom MVC Model Binder

When you expect data in non-standard way and you want it to magically bind to your model, custom model binders could be a way to go.

Let’s say we want to post xml data to our controller method and we have a model for it.

public class XmlModel
        {
            public int Number { get; set; }
        }

Which we want to accept in our controller method:

public ActionResult Xml(XmlModel xmlModel)
        {
            return Content(xmlModel.Number.ToString());
        }

Now, let’s add our xml binder:

public class XmlModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var modelType = bindingContext.ModelType;
            return new XmlSerializer(modelType).Deserialize(controllerContext.HttpContext.Request.InputStream);
        }
    }

And XMLModelBinderProvider:

public class XMLModelBinderProvider : IModelBinderProvider
    {      
        public IModelBinder GetBinder(Type modelType)
        {
            var contentType = HttpContext.Current.Request.ContentType;
            if (string.Compare(contentType, @"text/xml", StringComparison.OrdinalIgnoreCase) != 0)
            {
                return null;
            }

            return new XmlModelBinder();
        }
    }

Add the provider to our Application_Start method in the Global.asax:

ModelBinderProviders.BinderProviders.Insert(0, new XMLModelBinderProvider()); 

To test this we can use Composer from Fiddler:
http://localhost/home/xml
User-Agent: Fiddler
Content-Type: text/xml

Request Body:

<XmlModel>
<Number>42</Number>
</XmlModel>

If we add breakpoint in our controller, we should see 42 coming through in our model.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.