My last post on wiring up JSON to ASP.NET MVC showed how to use an ActionFilter to deserialize JSON into .NET objects. However, using a custom IModelBinder is a cleaner and in many ways the more correct solution:
using System;
using System.Web.Mvc;
using System.Text;
using System.Xml;
using System.Runtime.Serialization.Json;
namespace NRPC.Citation.Web.Controllers
{
public class JsonBinderAttribute : CustomModelBinderAttribute
{
public override IModelBinder GetBinder()
{
return new JsonModelBinder();
}
public class JsonModelBinder : IModelBinder
{
public ModelBinderResult BindModel(ModelBindingContext bindingContext)
{
Encoding requestEncoding = bindingContext.HttpContext.Request.ContentEncoding;
byte[] stringBytes = requestEncoding.GetBytes(bindingContext.HttpContext.Request.Form[bindingContext.ModelName]);
XmlDictionaryReader rdr = JsonReaderWriterFactory.CreateJsonReader(stringBytes, XmlDictionaryReaderQuotas.Max);
object o = new DataContractJsonSerializer(bindingContext.ModelType).ReadObject(rdr);
return new ModelBinderResult(o);
}
}
}
}
public ActionResult postDTO([JsonBinder]GridStateDTO colState){ ... }
Ext.Ajax.request({
url: '/myURL.mvc/postDTO',
success: success,
failure: failure,
params: { 'colState': strDTO }
});
Note how in this case I’m passing the JSON as a form value. This is notable in part because the code in my last post assumed the entire post body was JSON; while this code can co-exist with other form data.