I've added Newton Soft to the mix and am using this blog as a template: http://wingkaiwan.com/2012/12/28/replacing-mvc-javascriptserializer-with-json-net-jsonserializer/
I now have:
public class BaseJsonController : BaseController
{
protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
return new JsonNetResult
{
Data = data,
ContentType = contentType,
ContentEncoding = contentEncoding,
JsonRequestBehavior = behavior
};
}
}
public class JsonNetResult : JsonResult
{
public JsonNetResult()
{
Settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Error
};
}
public JsonSerializerSettings Settings { get; private set; }
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
throw new ArgumentNullException("context");
if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException("JSON GET is not allowed");
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;
if (this.ContentEncoding != null)
response.ContentEncoding = this.ContentEncoding;
if (this.Data == null)
return;
var scriptSerializer = JsonSerializer.Create(this.Settings);
using (var sw = new StringWriter())
{
scriptSerializer.Serialize(sw, this.Data);
response.Write(sw.ToString());
}
}
}
Now, in my controller I did this:
[HandleError]
public class ProcurementActionsController : BaseJsonController
{
...
[GridAction]
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult AjaxGetAll(string pageFilter = null, string searchTerm = null)
{
var rawData = GetProcurementActions(pageFilter);
return new JsonNetResult
{
Data = new GridModel { Data = rawData },
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Settings = { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }
};
}
...
}
However, I am still getting the same error! According to the stack trace it is still trying to use the JavaScriptSerializer instead of the JsonSerializer:
[InvalidOperationException: Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.]
System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, StringBuilder output, SerializationFormat serializationFormat) +188
System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj) +56
System.Web.Mvc.JsonResult.ExecuteResult(ControllerContext context) +418
System.Web.Mvc.<>c__DisplayClass14.<InvokeActionResultWithFilters>b__11() +31
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +656883
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +656883
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +254
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +658100
System.Web.Mvc.Controller.ExecuteCore() +125
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__4() +48
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +15
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +85
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +51
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +454
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +263
Is it because of the Async call? If so, what do I need to override in my BaseJsonController to get this to call the correct ExecuteResult(...) method?
The only drawback to this exact solution is if it finally hits about 4GB. At that point it will probably crash most browsers unless you have a way chunk the return. I would add a check for max length and toss an error.