Cleanest way to model bind Accept header in .NET MVC Cleanest way to model bind Accept header in .NET MVC json json

Cleanest way to model bind Accept header in .NET MVC


I'm not seeing any better alternatives to a custom model binder. I'll post my implementation of the binder here in case anyone else sees this. Using a model binder allows the Accept header to be strongly bound to a direct input on the action, allowing for direct testing of the return types and doesn't force you to artificially have more actions than you need, nor result to the dynamic typed viewdata/bag.

Here's the Model Binder with a supporting enum type:

public enum RequestAcceptType{    NotSpecified,    Json,    Xml}public class RequestAcceptTypeModelBinder : IModelBinder{    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)    {        if (bindingContext == null)        {            throw new ArgumentNullException("bindingContext");        }        RequestAcceptType acceptType = RequestAcceptType.NotSpecified;        // Try for Json        if (controllerContext.HttpContext.Request.AcceptTypes.Contains("application/json") || controllerContext.HttpContext.Request.Url.Query.Contains("application/json"))        {            acceptType = RequestAcceptType.Json;        }        // Default to Xml        if (acceptType == RequestAcceptType.NotSpecified)        {            acceptType = RequestAcceptType.Xml;        }        return acceptType;    }}

Here's the relevant bit in Global.asax in the Application_Start method:

ModelBinders.Binders[typeof(RequestAcceptType)] = new RequestAcceptTypeModelBinder();

Then to use it in your actions, just make an argument (any name) with the enum type:

public ActionResult Index(RequestAcceptType acceptType)

If nobody responds with a better method in a couple days, I'll accept this as the answer.