Ottenere "La richiesta JSON era troppo grande per essere deserializzata"


203

Ricevo questo errore:

La richiesta JSON era troppo grande per essere deserializzata.

Ecco uno scenario in cui ciò si verifica. Ho una classe di paese che detiene un elenco di porti di spedizione di quel paese

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

Uso KnockoutJS sul lato client per effettuare una discesa a cascata. Quindi abbiamo una serie di due menu a discesa, in cui il primo è il paese e il secondo sono i porti di quel paese.

Finora tutto funziona bene, questo mio script lato client:

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

Il problema si verifica quando viene selezionato un paese come la Cina, che ha molti porti. Quindi, se hai 3 o 4 volte "China" nel tuo array e voglio inviarlo al server per salvarlo. L'errore si è verificato.

Cosa devo fare per porre rimedio a questo?


4
Per chiunque sia curioso di sapere perché questo accade o di scrivere il proprio serializzatore clienti - dai un'occhiata al codice sorgente di JsonValueProviderFactory.cs - sembra che il team ASP.NET MVC abbia intenzionalmente posto un limite a 1000.
nikib3ro

Risposte:


401

Devi risolvere la proprietà maxJsonLength su un valore più alto web.configper risolvere il problema.

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

Imposta un valore più alto per aspnet:MaxJsonDeserializerMembersin AppSettings:

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

Se tali opzioni non funzionano, è possibile provare a creare una factory del provider di valori json personalizzata utilizzando JSON.NET come specificato in questo thread .


57
Stavo lavorando su un'applicazione MVC4 che stava serializzando un grande volume (1k +) di oggetti json su un controller. Il metodo system.web.extensions non ha fatto nulla, ma l'appSettings è stata la soluzione magica. Grazie!
TNCodeMonkey,

4
aspnet:MaxJsonDeserializerMembersha funzionato anche per me. Qualcuno sa dove questo è effettivamente documentato?
Matt Burland,

1
Il collegamento MSDN è interrotto. Il link corretto è msdn.microsoft.com/en-us/library/…
Ido Ran,

14
Ha funzionato per me, ma ho appena scoperto questo: support.microsoft.com/kb/2661403 ... L'aumento di questo valore al di sopra dell'impostazione predefinita aumenta la suscettibilità del server alla vulnerabilità Denial of Service descritta nel bollettino sulla sicurezza MS11- 100.
Eroe

4
Il valore predefinito di aspnet: MaxJsonDeserializerMembers sembra essere 1000: msdn.microsoft.com/en-us/library/hh975440.aspx .
CRice,

2

Se non si desidera modificare un'impostazione globale nella configurazione Web

L'uso di un'impostazione globale attiverà risposte json di grandi dimensioni nell'intera applicazione che potrebbero aprirti a un attacco di negazione del servizio.

Se sono consentite alcune posizioni scelte, è possibile utilizzare molto rapidamente un altro serializzatore json utilizzando il metodo Content in questo modo:

using Newtonsoft.Json;

// ...

public ActionResult BigOldJsonResponse() 
{
    var response = ServiceWhichProducesLargeObject();
    return Content(JsonConvert.SerializeObject(response));
}
// ...
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.