在MVC中,使用JsonResult返回对象时,当序列化的对象长度过长,默认好像是4M,则会出现异常。
异常信息:
Type : System.InvalidOperationException, mscorlib, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : 使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串
的长度超过了为 maxJsonLength 属性设置的值。
Source : System.Web.Extensions
Help link :
Data : System.Collections.ListDictionaryInternal
TargetSite : Void Serialize(System.Object, System.Text.StringBuilder,
SerializationFormat)
Stack Trace : 在
System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj,
StringBuilder output, SerializationFormat serializationFormat)
在 System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object
obj, SerializationFormat serializationFormat)
在 System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object
解决方案:
在配置文件web.config中添加节点:
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="20971520"/>
</webServices>
</scripting>
</system.web.extensions>
直接添加节点运行网站,好像会报错。(网上看见的):分析器错误消息: 无法识别的配置节 system.web.extensions。
解决办法:web.config中添加节点(一篇博客中看见的,没试过)
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
要想使用配置中的值,只能自定义一个JsonResult,重写原JsonResult的ExecuteResult方法,否则使用的还是默认的值。于是定义一个ConfigurableJsonResult,代码如下:
ConfigurableJsonResult
public class ConfigurableJsonResult : JsonResult
{
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.");
}
HttpResponseBase response = context.HttpContext.Response;
if (!String.IsNullOrEmpty(ContentType))
{
response.ContentType = ContentType;
}
else
{
response.ContentType = "application/json";
}
if (ContentEncoding != null)
{
response.ContentEncoding = ContentEncoding;
}
if (Data != null)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
ScriptingJsonSerializationSection section = ConfigurationManager.GetSection("system.web.extensions/scripting/webServices/jsonSerialization") as ScriptingJsonSerializationSection;
if (section != null)
{
serializer.MaxJsonLength = section.MaxJsonLength;
serializer.RecursionLimit = section.RecursionLimit;
}
response.Write(serializer.Serialize(Data));
}
}
}
使用demo:
public JsonResult DoWork()
{
return new ConfigurableJsonResult { Data = new { Status = "success", code = code, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}