Отримання запиту 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>
  <add key="aspnet:MaxJsonDeserializerMembers" value="150000" />
</appSettings>

Якщо ці параметри не працюють, ви можете спробувати створити власну фабрику постачальника цін json за допомогою JSON.NET, як зазначено в цій темі .


57
Я працював над програмою MVC4, яка серіалізувала великий об'єм (1k +) об'єктів json до контролера. Метод system.web.extensions нічого не зробив, але магічне виправлення було застосовано застосунками. Дякую!
TNCodeMonkey

4
aspnet:MaxJsonDeserializerMembersпрацював і для мене. Хтось знає, де це насправді зафіксовано?
Метт Берланд

1
Посилання MSDN розірвано. Правильне посилання - msdn.microsoft.com/en-us/library/…
Ido Ran

14
Це працювало для мене, але щойно це з’ясувалося: support.microsoft.com/kb/2661403 ... Підвищення цього значення вище за замовчуванням збільшує сприйнятливість вашого сервера до вразливості сервісу, яка обговорюється в бюлетені безпеки MS11- 100.
Герой

4
Значення за замовчуванням aspnet: MaxJsonDeserializerMembers, здається, 1000: msdn.microsoft.com/en-us/library/hh975440.aspx .
CRice

2

Якщо ви не хочете змінювати глобальний параметр у веб-конфігурації

Використання глобальної настройки активує великі відповіді json у всій вашій програмі, що може відкрити вас до атаки відмови у сервісі.

Якщо це дозволено декількома місцями вибору, ви можете дуже швидко використовувати інший json серіалізатор, використовуючи такий метод Content:

using Newtonsoft.Json;

// ...

public ActionResult BigOldJsonResponse() 
{
    var response = ServiceWhichProducesLargeObject();
    return Content(JsonConvert.SerializeObject(response));
}
// ...
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.