Erhalten "Die JSON-Anfrage war zu groß, um deserialisiert zu werden"

203

Ich erhalte diesen Fehler:

Die JSON-Anforderung war zu groß, um deserialisiert zu werden.

Hier ist ein Szenario, in dem dies auftritt. Ich habe eine Länderklasse, die eine Liste der Schifffahrtshäfen dieses Landes enthält

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

Ich verwende KnockoutJS auf der Clientseite, um kaskadierende Dropdowns zu erstellen. Wir haben also eine Reihe von zwei Dropdowns, von denen der erste das Land und der zweite die Häfen dieses Landes ist.

Bisher funktioniert alles einwandfrei, dies ist mein clientseitiges Skript:

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

Das Problem tritt auf, wenn ein Land wie China ausgewählt wird, das viele Häfen hat. Wenn Sie also drei- oder viermal "China" in Ihrem Array haben und ich es zum Speichern an den Server senden möchte. Der Fehler tritt auf.

Was soll ich tun, um dies zu beheben?

Kayvan Karim
quelle
4
Für alle, die neugierig sind, warum dies passiert oder ihren Kunden-Serializer schreiben - werfen Sie einen Blick auf den Quellcode von JsonValueProviderFactory.cs - scheint das ASP.NET MVC-Team absichtlich das Limit auf 1000 gesetzt zu haben.
nikib3ro

Antworten:

401

Sie müssen die Eigenschaft maxJsonLength auf einen höheren Wert einstellen web.config, um das Problem zu beheben.

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

aspnet:MaxJsonDeserializerMembersLegen Sie in den appSettings einen höheren Wert für fest:

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

Wenn diese Optionen nicht funktionieren, können Sie versuchen, mit JSON.NET eine benutzerdefinierte json value provider-Factory zu erstellen, wie in diesem Thread angegeben .

VJAI
quelle
57
Ich habe an einer MVC4-Anwendung gearbeitet, die ein großes Volumen (1k +) von JSON-Objekten auf einem Controller serialisiert hat. Die system.web.extensions-Methode hat nichts getan, aber die appSettings waren die magische Lösung. Vielen Dank!
TNCodeMonkey
4
aspnet:MaxJsonDeserializerMembersarbeitete auch für mich. Weiß jemand, wo dies tatsächlich dokumentiert ist?
Matt Burland
1
Die MSDN-Verbindung ist unterbrochen. Der richtige Link ist msdn.microsoft.com/en-us/library/…
Ido Ran
14
Es hat bei mir funktioniert, aber ich habe gerade Folgendes herausgefunden: support.microsoft.com/kb/2661403 ... Wenn Sie diesen Wert über die Standardeinstellung erhöhen, erhöht sich die Anfälligkeit Ihres Servers für die im Security Bulletin MS11- beschriebene Denial-of-Service-Sicherheitsanfälligkeit. 100.
Held
4
Der Standardwert von aspnet: MaxJsonDeserializerMembers scheint 1000 zu sein: msdn.microsoft.com/en-us/library/hh975440.aspx .
CRice
2

Wenn Sie eine globale Einstellung in der Webkonfiguration nicht ändern möchten

Wenn Sie eine globale Einstellung verwenden, werden große JSON-Antworten in Ihrer gesamten Anwendung aktiviert, wodurch Sie möglicherweise einem Denial-of-Service-Angriff ausgesetzt sind.

Wenn einige ausgewählte Speicherorte dies zulassen, können Sie sehr schnell einen anderen JSON-Serialisierer verwenden, indem Sie die Content-Methode wie folgt verwenden:

using Newtonsoft.Json;

// ...

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