Bắt đầu Yêu cầu JSON quá lớn để được khử lưu trữ


203

Tôi đang gặp lỗi này:

Yêu cầu JSON quá lớn để được giải tuần tự hóa.

Đây là một kịch bản nơi điều này xảy ra. Tôi có một lớp quốc gia chứa danh sách các cảng vận chuyển của quốc gia đó

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

Tôi sử dụng KnockoutJS ở phía máy khách để thực hiện thả xuống tầng. Vì vậy, chúng tôi có một loạt gồm hai lần thả xuống, trong đó cái đầu tiên là quốc gia và cái thứ hai là cảng của quốc gia đó.

Mọi thứ đều hoạt động tốt cho đến nay, kịch bản phía máy khách của tôi:

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

Vấn đề xảy ra khi một quốc gia như Trung Quốc được chọn, nơi có rất nhiều cảng. Vì vậy, nếu bạn có 3 hoặc 4 lần "Trung Quốc" trong mảng của mình và tôi muốn gửi nó đến máy chủ để lưu. Xảy ra lỗi.

Tôi nên làm gì để khắc phục điều này?


4
Đối với bất kỳ ai tò mò tại sao điều này xảy ra hoặc viết serializer khách hàng của họ - hãy xem mã nguồn của JsonValueProviderFactory.cs - có vẻ như nhóm ASP.NET MVC cố tình đặt giới hạn ở 1000.
nikib3ro

Câu trả lời:


401

Bạn phải điều chỉnh thuộc tính maxJsonLpm thành giá trị cao hơn web.configđể giải quyết vấn đề.

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

Đặt giá trị cao hơn cho aspnet:MaxJsonDeserializerMemberstrong ứng dụng Cài đặt :

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

Nếu các tùy chọn đó không hoạt động, bạn có thể thử tạo một nhà máy cung cấp giá trị json tùy chỉnh bằng JSON.NET như được chỉ định trong luồng này .


57
Tôi đã làm việc trên một ứng dụng MVC4 đang tuần tự hóa một khối lượng lớn (1k +) đối tượng json sang bộ điều khiển. Phương thức system.web.extensions không làm gì cả, nhưng cài đặt appS là cách khắc phục kỳ diệu. Cảm ơn!
TNCodeMonkey

4
aspnet:MaxJsonDeserializerMemberslàm việc cho tôi quá Có ai biết nơi này thực sự được ghi nhận?
Matt Burland

1
Liên kết MSDN bị hỏng. Liên kết chính xác là msdn.microsoft.com/en-us/l Library / từ
Ido Ran

14
Nó hoạt động với tôi, nhưng chỉ cần phát hiện ra điều này: support.microsoft.com/kb/2661403 ... Việc tăng giá trị này lên trên cài đặt mặc định sẽ làm tăng tính nhạy cảm của máy chủ của bạn đối với lỗ hổng Từ chối dịch vụ được thảo luận trong bản tin bảo mật MS11- 100.
Anh hùng

4
Giá trị mặc định của aspnet: MaxJsonDeserializerMembers dường như là 1000: msdn.microsoft.com/en-us/l Library / hh975440.aspx .
CRice

2

Nếu bạn không muốn thay đổi cài đặt chung trong cấu hình web

Sử dụng cài đặt toàn cục sẽ kích hoạt các phản hồi json lớn trong toàn bộ ứng dụng của bạn, điều này có thể mở ra cho bạn một cuộc tấn công từ chối dịch vụ.

Nếu một vài vị trí lựa chọn được cho phép điều này, bạn có thể nhanh chóng sử dụng một bộ nối tiếp json khác bằng phương thức Nội dung như sau:

using Newtonsoft.Json;

// ...

public ActionResult BigOldJsonResponse() 
{
    var response = ServiceWhichProducesLargeObject();
    return Content(JsonConvert.SerializeObject(response));
}
// ...
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.