228 votes

Obtenir "La requête JSON était trop grande pour être désérialisée".

J'obtiens cette erreur :

La requête JSON était trop grande pour être désérialisée.

Voici un scénario dans lequel cela se produit. J'ai une classe de pays qui contient une liste des ports d'expédition de ce pays.

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

J'utilise KnockoutJS du côté client pour créer des listes déroulantes en cascade. Nous avons donc un tableau de deux listes déroulantes, où la première est le pays, et la seconde les ports de ce pays.

Tout fonctionne bien jusqu'à présent, c'est mon script côté client :

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

Le problème survient lorsqu'on choisit un pays comme la Chine, qui a lots de ports. Donc si vous avez 3 ou 4 fois "China" dans votre tableau et que je veux l'envoyer au serveur pour le sauvegarder. L'erreur se produit.

Que dois-je faire pour y remédier ?

4 votes

Si vous êtes curieux de savoir pourquoi cela se produit ou si vous écrivez votre sérialiseur client, consultez le site suivant code source de JsonValueProviderFactory.cs - Il semble que l'équipe d'ASP.NET MVC ait intentionnellement fixé la limite à 1000.

444voto

Mark Points 12663

Vous devez ajuster le maxJsonLength à une valeur plus élevée dans web.config pour résoudre le problème.

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

Définissez une valeur plus élevée pour aspnet:MaxJsonDeserializerMembers dans l'appSettings :

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

Si ces options ne fonctionnent pas, vous pouvez essayer de créer une usine de fournisseurs de valeurs json personnalisée à l'aide de JSON.NET, comme indiqué dans ce document. filetage .

57 votes

Je travaillais sur une application MVC4 qui sérialisait un grand volume (1k+) d'objets json vers un contrôleur. La méthode system.web.extensions n'a rien fait, mais l'appSettings a été la solution magique. Merci !

4 votes

aspnet:MaxJsonDeserializerMembers a également fonctionné pour moi. Quelqu'un sait-il où cela est documenté ?

1 votes

Le lien MSDN est cassé. Le lien correct est msdn.microsoft.com/fr/us/library/

2voto

gburton Points 551

Si vous ne souhaitez pas modifier un paramètre global dans la configuration web

L'utilisation d'un paramètre global activera des réponses json volumineuses dans l'ensemble de votre application, ce qui pourrait vous exposer à une attaque par déni de service.

Si quelques emplacements de choix sont autorisés, vous pouvez très rapidement utiliser un autre sérialiseur json en utilisant la méthode Content comme suit :

using Newtonsoft.Json;

// ...

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

0voto

Le réglage ne fonctionne pas toujours. La meilleure façon de gérer cela est de passer par le contrôleur, Vous devriez écrire votre propre méthode Serialize JSON. C'est ainsi que j'ai résolu le problème du retour d'un très gros objet JSON sérialisé en réponse à un appel Ajax de jquery.

C# : remplacer le type de données JsonResult par ContentResult

// GET: Manifest/GetVendorServiceStagingRecords
[HttpGet]
public ContentResult GetVendorServiceStagingRecords(int? customerProfileId, int? locationId, int? vendorId, DateTime? invoiceDate, int? transactionId, int? transactionLineId)
{
    try
    {
        var result = Manifest.GetVendorServiceStagingRecords(customerProfileId, locationId, vendorId, invoiceDate, null, null, transactionId, transactionLineId);
        return SerializeJSON(result);
    }
    catch (Exception ex)
    {
        Log.Error("Could not get the vendor service staging records.", ex);

        throw;
    }
}

private ContentResult  SerializeJSON(object toSerialize)
{
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    serializer.MaxJsonLength = Int32.MaxValue; // Wahtever max length you want here
    var resultData = toSerialize; //Whatever value you are serializing
    ContentResult result = new ContentResult();
    result.Content = serializer.Serialize(resultData);
    result.ContentType = "application/json";
    return result;
}

Puis, dans le fichier Web.config, augmentez la taille maximale.

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

Ça marche pour moi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X