Получение «JSON-запрос был слишком велик для десериализации»

203

Я получаю эту ошибку:

Запрос 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,
        };
    } (); 

Проблема возникает, когда выбирается такая страна, как Китай, которая имеет много портов. Так что если у вас есть 3 или 4 раза «Китай» в вашем массиве, и я хочу отправить его на сервер для сохранения. Ошибка возникает.

Что я должен сделать, чтобы исправить это?

Кайван Карим
источник
4
Для всех, кто интересуется, почему это происходит, или для написания своего клиентского сериализатора - взгляните на исходный код JsonValueProviderFactory.cs - кажется, что команда ASP.NET MVC намеренно установила лимит в 1000.
nikib3ro

Ответы:

401

Вы должны настроить свойство maxJsonLength на более высокое значение, web.configчтобы решить проблему.

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

Установите более высокое значение aspnet:MaxJsonDeserializerMembersв appSettings:

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

Если эти параметры не работают, вы можете попробовать создать собственную фабрику провайдеров значений json с использованием JSON.NET, как указано в этой теме .

VJAI
источник
57
Я работал над приложением MVC4, которое сериализовало большой объем (1k +) объектов json на контроллер. Метод system.web.extensions ничего не делал, но appSettings было волшебным исправлением. Спасибо!
TNCodeMonkey
4
aspnet:MaxJsonDeserializerMembersработал для меня тоже. Кто-нибудь знает, где это на самом деле задокументировано?
Мэтт Берлэнд
1
Ссылка MSDN не работает. Правильная ссылка: msdn.microsoft.com/en-us/library/…
Идо Ран
14
Это сработало для меня, но только что выяснил это: support.microsoft.com/kb/2661403 ... Увеличение этого значения выше значения по умолчанию увеличивает подверженность вашего сервера уязвимости отказ в обслуживании, которая обсуждается в бюллетене по безопасности MS11- 100.
Герой
4
По умолчанию значение aspnet: MaxJsonDeserializerMembers равно 1000: msdn.microsoft.com/en-us/library/hh975440.aspx .
Крис
2

Если вы не хотите изменять глобальные настройки в веб-конфигурации

Использование глобального параметра активирует большие ответы json во всем приложении, что может привести к атаке типа «отказ в обслуживании».

Если это разрешено в нескольких местах, вы можете очень быстро использовать другой сериализатор json, используя метод Content, например:

using Newtonsoft.Json;

// ...

public ActionResult BigOldJsonResponse() 
{
    var response = ServiceWhichProducesLargeObject();
    return Content(JsonConvert.SerializeObject(response));
}
// ...
gburton
источник