Obtendo “A solicitação JSON era muito grande para ser desserializada”

203

Estou recebendo este erro:

A solicitação JSON era muito grande para ser desserializada.

Aqui está um cenário em que isso ocorre. Eu tenho uma classe de país que possui uma lista de portos desse país

public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Port> Ports { get; set; }
}

Eu uso o KnockoutJS no lado do cliente para criar uma lista suspensa em cascata. Portanto, temos uma série de duas caixas suspensas, onde a primeira é o país e a segunda são os portos desse país.

Tudo está funcionando bem até agora, este é o meu script do lado do cliente:

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,
        };
    } (); 

O problema ocorre quando um país como a China é selecionado, com muitos portos. Então, se você tem 3 ou 4 vezes "China" em sua matriz e eu quero enviá-lo ao servidor para salvar. O erro ocorre.

O que devo fazer para remediar isso?

Kayvan Karim
fonte
4
Para qualquer um curioso por que isso acontece ou escrever sua serializer cliente - dê uma olhada no código fonte do JsonValueProviderFactory.cs - Parece que a equipe ASP.NET MVC intencionalmente colocar limite em 1000.
nikib3ro

Respostas:

401

Você precisa ajustar a propriedade maxJsonLength para um valor mais alto web.configpara resolver o problema.

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

Defina um valor mais alto para aspnet:MaxJsonDeserializerMembersno appSettings:

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

Se essas opções não estiverem funcionando, você pode tentar criar uma fábrica de provedor de valor json personalizada usando JSON.NET, conforme especificado neste encadeamento .

VJAI
fonte
57
Eu estava trabalhando em um aplicativo MVC4 que estava serializando um grande volume (1k +) de objetos json em um controlador. O método system.web.extensions não fez nada, mas o appSettings foi a correção mágica. Obrigado!
TNCodeMonkey
4
aspnet:MaxJsonDeserializerMemberstrabalhou para mim também. Alguém sabe onde isso está realmente documentado?
Matt Burland
1
O link do MSDN está quebrado. O link correto é msdn.microsoft.com/en-us/library/…
Ido Ran
14
Funcionou para mim, mas acabei de descobrir o seguinte: support.microsoft.com/kb/2661403 ... Aumentar esse valor acima da configuração padrão aumenta a suscetibilidade do seu servidor à vulnerabilidade de negação de serviço discutida no boletim de segurança MS11- 100
Herói
4
O valor padrão do aspnet: MaxJsonDeserializerMembers parece ser 1000: msdn.microsoft.com/en-us/library/hh975440.aspx .
CRice
2

Se você não deseja alterar uma configuração global na configuração da web

O uso de uma configuração global ativará grandes respostas json em todo o aplicativo, o que pode abrir um ataque de negação de serviço.

Se alguns locais de escolha forem permitidos, você poderá usar muito rapidamente outro serializador json usando o método Content da seguinte maneira:

using Newtonsoft.Json;

// ...

public ActionResult BigOldJsonResponse() 
{
    var response = ServiceWhichProducesLargeObject();
    return Content(JsonConvert.SerializeObject(response));
}
// ...
Gburton
fonte