Monday, December 14, 2009

ASP.NET MVC XML Model Binder

Update 12/14/2011
This is one of my most highly viewed posts. Unfortunately, this post applies to version 1 of ASP.NET MVC (it might also work with version 2 with some small modifications). If that is what you are looking for, then please read on! Otherwise, for more relevant coverage of this topic I recommend Jimmy Bogard's post

I needed a way to receive raw XML in my action methods, rather than form-encoded values. Model binding makes it a piece of cake:

public class XmlModelBinder : IModelBinder
{
object IModelBinder.BindModel(
ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
var stream = controllerContext.HttpContext.Request.InputStream;
using (var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}


In my action method all I have to do is apply the model binder attribute:

public ActionResult Edit(
[ModelBinder(typeof(XmlModelBinder))] string xml)
{
//...
}
view raw Controller1.cs hosted with ❤ by GitHub


Now the edit action receives an XML string. Even better, I can get a strongly typed object if it is serializable:

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


Now my action method looks like this:

public ActionResult Edit(
[ModelBinder(typeof(XmlModelBinder))] MyXmlSerializableClass xml)
{
//...
}
view raw Controller2.cs hosted with ❤ by GitHub


The model binder attribute is a little too verbose for my taste, so I wrote a custom model binder attribute:

public class BindXmlAttribute : CustomModelBinderAttribute
{
public override IModelBinder GetBinder()
{
return new XmlModelBinder();
}
}


Finally my action method is nice and readable:

public ActionResult Edit(
[BindXml] MyXmlSerializableClass xml)
{
//...
}
view raw Controller3.cs hosted with ❤ by GitHub

No comments:

Post a Comment