得到“JSON 请求太大而无法反序列化”

Posted

技术标签:

【中文标题】得到“JSON 请求太大而无法反序列化”【英文标题】:Getting "The JSON request was too large to be deserialized" 【发布时间】:2012-06-13 13:04:41 【问题描述】:

我收到此错误:

JSON 请求太大而无法反序列化。

这是发生这种情况的一个场景。我有一个国家类别,其中包含该国家/地区的航运港口列表

public class Country

    public int Id  get; set; 
    public string Name  get; set; 
    public List<Port> Ports  get; set; 

我在客户端使用 KnockoutJS 进行级联下拉菜单。所以我们有两个下拉列表,第一个是国家,第二个是那个国家的港口。

到目前为止一切正常,这是我的客户端脚本:

var k1 = k1 || ;
$(document).ready(function () 

    k1.MarketInfoItem = function (removeable) 
        var self = this;
        self.CountryOfLoadingId = ko.observable();
        self.PortOfLoadingId = ko.observable();
        self.CountryOfDestinationId = ko.observable();
        self.PortOfDestinationId = ko.observable();  
    ;

    k1.viewModel = function () 
        var marketInfoItems = ko.observableArray([]),
            countries = ko.observableArray([]),

            saveMarketInfo = function () 
                var jsonData = ko.toJSON(marketInfoItems);
                $.ajax(
                    url: 'SaveMarketInfos',
                    type: "POST",
                    data: jsonData,
                    datatype: "json",
                    contentType: "application/json charset=utf-8",
                    success: function (data) 
                        if (data) 
                            window.location.href = "Fin";
                         else 
                            alert("Can not save your market information now!");
                        

                    ,
                    error: function (data)  alert("Can not save your contacts now!"); 
                );
            ,

            loadData = function () 
                $.getJSON('../api/ListService/GetCountriesWithPorts', function (data) 
                    countries(data);
                );
            ;
        return 
            MarketInfoItems: marketInfoItems,
            Countries: countries,
            LoadData: loadData,
            SaveMarketInfo: saveMarketInfo,
        ;
     (); 

The problem occurs when a country like China is selected, which has lots of ports.因此,如果您的阵列中有 3 或 4 次“中国”,我想将其发送到服务器进行保存。发生错误。

我应该怎么做才能解决这个问题?

【问题讨论】:

对于任何好奇为什么会发生这种情况或编写他们的客户序列化程序的人 - 看看 source code of JsonValueProviderFactory.cs - 似乎 ASP.NET MVC 团队故意将限制设置为 1000。 【参考方案1】:

您必须将maxJsonLength 属性调整为web.config 中的更高值才能解决此问题。

<system.web.extensions>
    <scripting>
        <webServices>
            <jsonSerialization maxJsonLength="2147483644"/>
        </webServices>
    </scripting>
</system.web.extensions>

在 appSettings 中为aspnet:MaxJsonDeserializerMembers 设置更高的值:

<appSettings>
  <add key="aspnet:MaxJsonDeserializerMembers" value="150000" />
</appSettings>

如果这些选项不起作用,您可以尝试使用 thread 中指定的 JSON.NET 创建自定义 json 值提供程序工厂。

【讨论】:

我正在开发一个 MVC4 应用程序,该应用程序将大量 (1k+) json 对象序列化到控制器。 system.web.extensions 方法没有做任何事情,但 appSettings 是神奇的修复。谢谢! aspnet:MaxJsonDeserializerMembers 也为我工作。有人知道这实际记录在哪里吗? MSDN 链接已损坏。正确的链接是msdn.microsoft.com/en-us/library/… 它对我有用,但刚刚发现:support.microsoft.com/kb/2661403 ... 将此值增加到高于默认设置会增加您的服务器对安全公告中讨论的拒绝服务漏洞的敏感性MS11-100。 aspnet:MaxJsonDeserializerMembers 的默认值好像是 1000 : msdn.microsoft.com/en-us/library/hh975440.aspx.【参考方案2】:

如果您不想更改网络配置中的全局设置

使用全局设置将激活整个应用程序中的大型 json 响应,这可能会使您面临拒绝服务攻击。

如果允许几个选择位置,您可以使用 Content 方法非常快速地使用另一个 json 序列化器,如下所示:

using Newtonsoft.Json;

// ...

public ActionResult BigOldJsonResponse() 

    var response = ServiceWhichProducesLargeObject();
    return Content(JsonConvert.SerializeObject(response));

// ...

【讨论】:

【参考方案3】:

设置并不总是有效。 处理这个问题的最好方法是通过控制器, 您必须编写自己的序列化 JSON 方法。 这就是我解决返回一个非常大的 json 序列化的方法 对象作为对 jquery .Ajax 调用的响应。

C#:将 JsonResult 数据类型替换为 ContentResult

// GET: Manifest/GetVendorServiceStagingRecords
[HttpGet]
public ContentResult GetVendorServiceStagingRecords(int? customerProfileId, int? locationId, int? vendorId, DateTime? invoiceDate, int? transactionId, int? transactionLineId)

    try
    
        var result = Manifest.GetVendorServiceStagingRecords(customerProfileId, locationId, vendorId, invoiceDate, null, null, transactionId, transactionLineId);
        return SerializeJSON(result);
    
    catch (Exception ex)
    
        Log.Error("Could not get the vendor service staging records.", ex);

        throw;
    


private ContentResult  SerializeJSON(object toSerialize)

    javascriptSerializer serializer = new JavaScriptSerializer();
    serializer.MaxJsonLength = Int32.MaxValue; // Wahtever max length you want here
    var resultData = toSerialize; //Whatever value you are serializing
    ContentResult result = new ContentResult();
    result.Content = serializer.Serialize(resultData);
    result.ContentType = "application/json";
    return result;

然后在 Web.config 文件中增加到最大大小

<system.web.extensions>
  <scripting>
    <webServices>
      <jsonSerialization maxJsonLength="999999999" />
    </webServices>
  </scripting>
</system.web.extensions>

这对我有用。

【讨论】:

以上是关于得到“JSON 请求太大而无法反序列化”的主要内容,如果未能解决你的问题,请参考以下文章

aspnet:MaxJsonDeserializerMembers 与 maxRequestLength

无法反序列化 Json 文件虽然得到了响应

xmljson反序列化得到相应的类

反序列化时需要一个列表,但得到一个带有嵌套对象的类 java.util.HashMap

Jackson关于Boolean类型反序列化问题

反序列化 xml,包括命名空间