zoukankan      html  css  js  c++  java
  • asp.net mvc自定义JsonResult类来防止MaxJsonLength超过限制

    前不久在做一个项目的时候,我用到了mvc的webapi返回了一个大数据,结果报了500错误,如下图所示:

    Server Error in ‘/’ Application.


    Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

    Exception Details: System.InvalidOperationException: Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.

    Source Error: 

    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

    Stack Trace: 

    [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) +551497
       System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, SerializationFormat serializationFormat) +74
       System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj) +6
       System.Web.Mvc.JsonResult.ExecuteResult(ControllerContext context) +341
       System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +10
       System.Web.Mvc.<>c__DisplayClass14.<InvokeActionResultWithFilters>b__11() +20
       System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +251
       System.Web.Mvc.<>c__DisplayClass16.<InvokeActionResultWithFilters>b__13() +19
       System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +178
       System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +314
       System.Web.Mvc.Controller.ExecuteCore() +105
       System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +39
       System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7
       System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__4() +34
       System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
       System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
       System.Web.Mvc.Async.WrappedAsyncResult`1.End() +59
       System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +44
       System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +7
       System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8682542
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
    

    Version Information: Microsoft .NET Framework Version:2.0.50727.4952; ASP.NET Version:2.0.50727.4955

    从上面可以看出错误的原因是对象在JavaScriptSerializer序列化的时候超过了默认的最大限制,所以我们需要一个类来重写JsonResult从而允许更大的数据。

    using System;
    using System.Web.Script.Serialization;
     
    namespace System.Web.Mvc
    {
        public class LargeJsonResult : JsonResult
        {
            const string JsonRequest_GetNotAllowed = "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.";
            public LargeJsonResult()
            {
                MaxJsonLength = 1024000;
                RecursionLimit = 100;
            }
     
            public int MaxJsonLength { get; set; }
            public int RecursionLimit { get; set; }
     
            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( JsonRequest_GetNotAllowed );
                }
     
                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() { MaxJsonLength = MaxJsonLength, RecursionLimit = RecursionLimit };
                    response.Write( serializer.Serialize( Data ) );
                }
            }
        }
    }
    

      你可以在Action里面使用return new LargeJsonResult(){ Data = data }  来替代 return Json(data).
    当然你也可以自己控制JavaScriptSerializer的MaxJsonLength:

    return new LargeJsonResult() { Data = output, MaxJsonLength = int.MaxValue };

    转载自:https://brianreiter.org/2011/01/03/custom-jsonresult-class-for-asp-net-mvc-to-avoid-maxjsonlength-exceeded-exception/

  • 相关阅读:
    Linux 进程学习(四) sigaction 函数
    Netty 编解码奥秘
    我的博客即将同步至 OSCHINA 社区,这是我的 OSCHINA ID:护国小将,邀请大家一同入驻:https://www.oschina.net/sharingplan/apply
    Netty数据如何在 pipeline 中流动
    PLM系统安装四:主卷服务安装(FSC缓存服务器plm4IP:42.20)
    Linux系统信息和进程相关命令(CPU,内存,进程)
    SAN交换机配置的备份还原,固件升级
    san交换机的级联
    PLM系统安装五(2):Corporate服务安装plm1IP:42.106
    第三步:服务器虚拟化XenServer实施部署文档
  • 原文地址:https://www.cnblogs.com/jake-ge/p/5606443.html
Copyright © 2011-2022 走看看