การรับ“ คำขอ JSON มีขนาดใหญ่เกินกว่าที่จะทำการ deserialized ได้”


203

ฉันได้รับข้อผิดพลาดนี้:

คำร้องขอ JSON มีขนาดใหญ่เกินกว่าที่จะทำการ deserialized

นี่คือสถานการณ์ที่เกิดขึ้น ฉันมีชั้นของประเทศที่เก็บรายชื่อของพอร์ตการขนส่งของประเทศนั้น

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

ปัญหาเกิดขึ้นเมื่อประเทศเช่นจีนถูกเลือกซึ่งมีจำนวนมากของพอร์ต ดังนั้นถ้าคุณมี "China" 3 หรือ 4 เท่าในอาร์เรย์ของคุณและฉันต้องการส่งไปยังเซิร์ฟเวอร์เพื่อบันทึก ข้อผิดพลาดเกิดขึ้น

ฉันควรทำอย่างไรเพื่อแก้ไขปัญหานี้


4
สำหรับใครสงสัยว่าทำไมสิ่งนี้เกิดขึ้นหรือเขียน serializer ลูกค้าของพวกเขา - ดูรหัสแหล่งที่มาของ JsonValueProviderFactory.cs - ดูเหมือนว่าทีม ASP.NET MVC จงใจ จำกัด ที่ 1,000
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 ตามที่ระบุไว้ในหัวข้อนี้


57
ฉันกำลังทำงานกับแอปพลิเคชัน MVC4 ที่ทำให้ซีเรียล json เป็นจำนวนมาก (1k +) กับวัตถุในคอนโทรลเลอร์ วิธี system.web.extensions ไม่ได้ทำอะไร แต่ appSettings คือการแก้ไขมายากล ขอบคุณ!
TNCodeMonkey

4
aspnet:MaxJsonDeserializerMembersทำงานให้ฉันด้วย มีใครรู้บ้างว่าเอกสารนี้ถูกจัดทำขึ้นจริงหรือไม่?
Matt Burland

1
ลิงก์ MSDN ใช้งานไม่ได้ ลิงก์ที่ถูกต้องคือmsdn.microsoft.com/en-us/library/…
Ido Ran 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 serializer อื่นได้อย่างรวดเร็วโดยใช้วิธีการของเนื้อหาดังนี้:

using Newtonsoft.Json;

// ...

public ActionResult BigOldJsonResponse() 
{
    var response = ServiceWhichProducesLargeObject();
    return Content(JsonConvert.SerializeObject(response));
}
// ...
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.