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.