Obteniendo "La solicitud JSON era demasiado grande para ser deserializada"

203

Recibo este error:

La solicitud JSON era demasiado grande para ser deserializada.

Aquí hay un escenario donde esto ocurre. Tengo una clase de país que tiene una lista de puertos de envío de ese país.

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

Uso KnockoutJS en el lado del cliente para hacer un menú desplegable en cascada. Así que tenemos una serie de dos menús desplegables, donde el primero es el país y el segundo son los puertos de ese país.

Todo funciona bien hasta ahora, este es mi script del lado del cliente:

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

El problema ocurre cuando se selecciona un país como China, que tiene muchos puertos. Entonces, si tiene 3 o 4 veces "China" en su matriz y quiero enviarlo al servidor para guardarlo. El error ocurre.

¿Qué debo hacer para remediar esto?

Kayvan Karim
fuente
44
Para cualquier persona curiosa por qué sucede esto o escribir su serializador de cliente, eche un vistazo al código fuente de JsonValueProviderFactory.cs , parece que el equipo ASP.NET MVC puso límite intencionalmente a 1000.
nikib3ro

Respuestas:

401

Tiene que ajustar la propiedad maxJsonLength a un valor más alto web.configpara resolver el problema.

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

Establezca un valor más alto aspnet:MaxJsonDeserializerMembersen la configuración de la aplicación:

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

Si esas opciones no funcionan, puede intentar crear una fábrica de proveedores de valores json personalizados utilizando JSON.NET como se especifica en este hilo .

VJAI
fuente
57
Estaba trabajando en una aplicación MVC4 que serializaba un gran volumen (1k +) de objetos json a un controlador. El método system.web.extensions no hizo nada, pero appSettings fue la solución mágica. ¡Gracias!
TNCodeMonkey
44
aspnet:MaxJsonDeserializerMembersTrabajó para mí también. ¿Alguien sabe dónde está esto realmente documentado?
Matt Burland
1
El enlace de MSDN está roto. El enlace correcto es msdn.microsoft.com/en-us/library/…
Ido Ran
14
Funcionó para mí, pero acabo de descubrir esto: support.microsoft.com/kb/2661403 ... Aumentar este valor por encima de la configuración predeterminada aumenta la susceptibilidad de su servidor a la vulnerabilidad de denegación de servicio que se trata en el boletín de seguridad MS11- 100
Héroe
44
El valor predeterminado de aspnet: MaxJsonDeserializerMembers parece ser 1000: msdn.microsoft.com/en-us/library/hh975440.aspx .
CRice
2

Si no desea cambiar una configuración global en la configuración web

El uso de una configuración global activará grandes respuestas json en toda su aplicación, lo que podría abrirlo a un ataque de denegación de servicio.

Si se permiten algunas ubicaciones de elección, puede usar muy rápidamente otro serializador json utilizando el método de contenido de la siguiente manera:

using Newtonsoft.Json;

// ...

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