Puis-je définir une longueur illimitée pour maxJsonLength dans web.config?

663

J'utilise la fonction de saisie semi-automatique de jQuery. Lorsque j'essaie de récupérer la liste de plus de 17000 enregistrements (chacun n'aura pas plus de 10 caractères), cela dépasse la longueur et génère l'erreur:

Informations sur l'exception:
Type d'exception: InvalidOperationException
Message d'exception: Erreur lors de la sérialisation ou de la désérialisation à l'aide de JSON JavaScriptSerializer. La longueur de la chaîne dépasse la valeur définie sur la propriété maxJsonLength.

Puis-je définir une longueur illimitée pour maxJsonLengthin web.config? Sinon, quelle est la longueur maximale que je peux définir?

Prasad
la source
1
Quelque chose à mentionner qui peut être assez évident, alors veuillez m'excuser si vous y avez déjà pensé; la chaîne Json inclut également les accolades autour de chaque enregistrement, les guillemets autour de chaque nom de champ [et valeur], ainsi que le nom et la valeur du champ. Il peut donc être utile de définir le nom du champ comme un seul caractère et de vous assurer également que si la valeur n'est pas une chaîne, que vous définissez correctement le type de champ afin qu'il ne contienne pas de guillemets.
MichaelJTaylor

Réponses:

720

REMARQUE: cette réponse ne s'applique qu'aux services Web.Si vous renvoyez JSON à partir d'une méthode Controller, assurez-vous de lire également cette réponse SO ci-dessous: https://stackoverflow.com/a/7207539/1246870


La propriété MaxJsonLength ne peut pas être illimitée, est une propriété entière dont la valeur par défaut est 102400 (100k).

Vous pouvez définir la MaxJsonLengthpropriété sur votre web.config:

<configuration> 
   <system.web.extensions>
       <scripting>
           <webServices>
               <jsonSerialization maxJsonLength="50000000"/>
           </webServices>
       </scripting>
   </system.web.extensions>
</configuration> 
CMS
la source
153
Il s'agit d'un entier, la valeur maximale que vous pouvez définir est donc: 2147483644
David Espart
58
@despart: Vous voulez dire 2 147 483 647.
Dercsár
6
@ kmcc049, IMO les valeurs ne sont pas fausses car si vous regardez la question, l'OP ne demande pas "quelle est la valeur par défaut de maxJsonLength?" (BTW, la deuxième réponse la plus votée répond à cette question, mauvaise question), il essaie de définir cette propriété sur "illimité", mais comme il s'agit d'un entier, la valeur maximale possible est 2147483647comme le soulignent @depsart et @ Descár.
CMS
11
Génial, mais notez la réponse de @David Murdoch ci-dessous si vous rencontrez ce problème lors de l'utilisation de MVC return Json()ou de quelque chose
BritishDeveloper
3
@ Dercsár: à quoi ça sert? 2147483644 est le plus grand entier parfaitement divisible par 1024.
naveen
461

Si vous utilisez MVC 4 , assurez-vous de vérifier également cette réponse .


Si vous recevez toujours l'erreur:

  • après avoir défini la maxJsonLengthpropriété à sa valeur maximale dans web.config
  • et vous savez que la longueur de vos données est inférieure à cette valeur
  • et vous n'utilisez pas de méthode de service Web pour la sérialisation JavaScript

votre problème est probable que:

La valeur de la propriété MaxJsonLength s'applique uniquement à l'instance interne JavaScriptSerializer utilisée par la couche de communication asynchrone pour appeler les méthodes des services Web. ( MSDN: propriété ScriptingJsonSerializationSection.MaxJsonLength )

Fondamentalement, le "interne" JavaScriptSerializerrespecte la valeur de maxJsonLengthlorsqu'il est appelé à partir d'une méthode Web; l'utilisation directe d'un JavaScriptSerializer(ou l'utilisation via une méthode d'action / contrôleur MVC) ne respecte pas la maxJsonLengthpropriété, du moins pas dans la systemWebExtensions.scripting.webServices.jsonSerializationsection de web.config.

Comme solution de contournement, vous pouvez effectuer les opérations suivantes dans votre contrôleur (ou n'importe où vraiment):

var serializer = new JavaScriptSerializer();

// For simplicity just use Int32's max value.
// You could always read the value from the config section mentioned above.
serializer.MaxJsonLength = Int32.MaxValue;

var resultData = new { Value = "foo", Text = "var" };
var result = new ContentResult{
    Content = serializer.Serialize(resultData),
    ContentType = "application/json"
};
return result;

Cette réponse est mon interprétation de cette réponse au forum asp.net .

David Murdoch
la source
5
Votre réponse a été très utile car j'utilise la Json()méthode du résultat d'action dans asp.net mvc.
jessegavin
3
Oui, j'étais un Json () souffrir aussi. Merci!
BritishDeveloper
3
Bien qu'il soit complètement correct et mérite sa place, c'est l'une de ces questions où il vaut la peine de lire après la première réponse :). Merci!
Nigel
3
Si vous utilisez MVC4, veuillez également consulter la réponse @fanisch.
Beyers
4
Et la désérialisation? J'ai rencontré cette erreur lors de la liaison du modèle d'action.
guogangj
345

Dans MVC 4, vous pouvez faire:

protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior)
{
    return new JsonResult()
    {
        Data = data,
        ContentType = contentType,
        ContentEncoding = contentEncoding,
        JsonRequestBehavior = behavior,
        MaxJsonLength = Int32.MaxValue
    };
}

dans votre contrôleur.

Une addition:

Pour toute personne perplexe par les paramètres que vous devez spécifier, un appel pourrait ressembler à ceci:

Json(
    new {
        field1 = true,
        field2 = "value"
        },
    "application/json",
    Encoding.UTF8,
    JsonRequestBehavior.AllowGet
);
fanisch
la source
6
Je peux confirmer que ce qui précède fonctionne comme un charme dans MVC 4, merci fanisch.
Beyers
9
Je peux également confirmer. Mettre ce code à l'intérieur d'un contrôleur de base est certainement l'approche la plus propre proposée.
parlement
15
Cela fonctionne également en ajoutant simplement "MaxJsonLength = Int32.MaxValue" au résultat de l'action individuelle. Dans le cas où le changement n'est pas souhaité pour le contrôleur ou le projet.
Hypnovirus
3
C'est la meilleure réponse. Le MaxJsonLength peut être configuré par contrôleur.
liang
3
ATTENTION: cette solution désactive la compression (si demandée) de la réponse. Ajoutez ce filtre sur votre action: stackoverflow.com/questions/3802107/…
Gorgi Rankovski
60

Vous pouvez configurer la longueur maximale des requêtes json dans votre fichier web.config:

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

La valeur par défaut de maxJsonLength est 102400 . Pour plus de détails, consultez cette page MSDN: http://msdn.microsoft.com/en-us/library/bb763183.aspx

M4N
la source
1
Quelle est la valeur stockée dans cet entier représentant? Est-ce une sorte de compte de caractère? Je suppose que ce que je demande, c'est pourquoi un entier est utilisé? Merci!
eaglei22
@ eaglei22 le nombre représente le nombre d'octets pouvant être utilisés pour maxJsonLength. Comme M4N l'a mentionné, 102400 est la valeur par défaut (100 Ko).
Jacob Plonke
cela ne fonctionne pas pour moi et je n'ai pas utilisé de webservices.
kalai
42

si vous obtenez toujours une erreur après le paramètre web.config comme suit:

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

Je l'ai résolu en suivant:

   public ActionResult/JsonResult getData()
   {
      var jsonResult = Json(superlargedata, JsonRequestBehavior.AllowGet);
      jsonResult.MaxJsonLength = int.MaxValue;
      return jsonResult;
    }

J'espère que cela devrait aider.

Ravi Anand
la source
2
La définition de maxJsonLength dans le fichier web.config est difficile à établir, la définition de jsonResult.MaxJsonLength devrait suffire (du moins, cela a été le cas pour moi (MVC5))
hormberg
C'est bien parce que ce n'est pas un changement global.
rob_james
40

J'avais ce problème dans les formulaires Web ASP.NET. Il ignorait complètement les paramètres du fichier web.config, j'ai donc fait ceci:

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        serializer.MaxJsonLength = Int32.MaxValue; 

        return serializer.Serialize(response);

Bien sûr, dans l'ensemble, c'est une pratique terrible. Si vous envoyez autant de données dans un appel de service Web, vous devriez envisager une approche différente.

Puce
la source
1
est-ce que cela a fonctionné pour vous? où avez-vous placé ce code?
user1012598
Notre problème était dû au fait que nous avions une zone de texte qui permettait le HTML et que les gens incorporaient des images au format HTML, ce qui faisait que l'entrée devenait très grande et que le sérialiseur JSON échouait. Je suppose que si cela peut être fait, les utilisateurs le feront ...
Marko
Veuillez décrire où nous devrions mettre ce code ... @Flea
Koray Durudogan
@KorayDurudogan - J'ai mis cela dans la méthode Ajax qui renvoyait la réponse, donc dans mon contrôleur. J'espère que cela pourra aider!
Flea
Je ne conteste pas votre réponse, mais j'essaie de me faire une meilleure idée des meilleures approches qui existent. J'ai une requête qui, en fonction des critères de l'utilisateur, déterminera la taille du résultat. Je retourne un JsonResult, cela importerait-il si je retournais un fichier Excel?
eaglei22
22

Je l'ai corrigé.

//your Json data here
string json_object="........";
JavaScriptSerializer jsJson = new JavaScriptSerializer();
jsJson.MaxJsonLength = 2147483644;
MyClass obj = jsJson.Deserialize<MyClass>(json_object);

Il fonctionne très bien.

Mario Arrieta
la source
Impressionnant! C'est la seule solution qui a fonctionné pour moi et c'est mieux de toute façon car ce n'est pas un changement global. Merci!
Sealer_05
20

J'ai suivi la réponse de vestigal et suis arrivé à cette solution:

Lorsque j'avais besoin de publier un grand json dans une action dans un contrôleur, j'obtenais la fameuse "Erreur lors de la désérialisation à l'aide de JSON JavaScriptSerializer. La longueur de la chaîne dépasse la valeur définie sur la propriété maxJsonLength. \ R \ nNom du paramètre: entrée fournisseur de valeur ".

Ce que j'ai fait, c'est créer un nouveau ValueProviderFactory, LargeJsonValueProviderFactory et définir la MaxJsonLength = Int32.MaxValue dans la méthode GetDeserializedObject

public sealed class LargeJsonValueProviderFactory : ValueProviderFactory
{
private static void AddToBackingStore(LargeJsonValueProviderFactory.EntryLimitedDictionary backingStore, string prefix, object value)
{
    IDictionary<string, object> dictionary = value as IDictionary<string, object>;
    if (dictionary != null)
    {
        foreach (KeyValuePair<string, object> keyValuePair in (IEnumerable<KeyValuePair<string, object>>) dictionary)
            LargeJsonValueProviderFactory.AddToBackingStore(backingStore, LargeJsonValueProviderFactory.MakePropertyKey(prefix, keyValuePair.Key), keyValuePair.Value);
    }
    else
    {
        IList list = value as IList;
        if (list != null)
        {
            for (int index = 0; index < list.Count; ++index)
                LargeJsonValueProviderFactory.AddToBackingStore(backingStore, LargeJsonValueProviderFactory.MakeArrayKey(prefix, index), list[index]);
        }
        else
            backingStore.Add(prefix, value);
    }
}

private static object GetDeserializedObject(ControllerContext controllerContext)
{
    if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
        return (object) null;
    string end = new StreamReader(controllerContext.HttpContext.Request.InputStream).ReadToEnd();
    if (string.IsNullOrEmpty(end))
        return (object) null;

    var serializer = new JavaScriptSerializer {MaxJsonLength = Int32.MaxValue};

    return serializer.DeserializeObject(end);
}

/// <summary>Returns a JSON value-provider object for the specified controller context.</summary>
/// <returns>A JSON value-provider object for the specified controller context.</returns>
/// <param name="controllerContext">The controller context.</param>
public override IValueProvider GetValueProvider(ControllerContext controllerContext)
{
    if (controllerContext == null)
        throw new ArgumentNullException("controllerContext");
    object deserializedObject = LargeJsonValueProviderFactory.GetDeserializedObject(controllerContext);
    if (deserializedObject == null)
        return (IValueProvider) null;
    Dictionary<string, object> dictionary = new Dictionary<string, object>((IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase);
    LargeJsonValueProviderFactory.AddToBackingStore(new LargeJsonValueProviderFactory.EntryLimitedDictionary((IDictionary<string, object>) dictionary), string.Empty, deserializedObject);
    return (IValueProvider) new DictionaryValueProvider<object>((IDictionary<string, object>) dictionary, CultureInfo.CurrentCulture);
}

private static string MakeArrayKey(string prefix, int index)
{
    return prefix + "[" + index.ToString((IFormatProvider) CultureInfo.InvariantCulture) + "]";
}

private static string MakePropertyKey(string prefix, string propertyName)
{
    if (!string.IsNullOrEmpty(prefix))
        return prefix + "." + propertyName;
    return propertyName;
}

private class EntryLimitedDictionary
{
    private static int _maximumDepth = LargeJsonValueProviderFactory.EntryLimitedDictionary.GetMaximumDepth();
    private readonly IDictionary<string, object> _innerDictionary;
    private int _itemCount;

    public EntryLimitedDictionary(IDictionary<string, object> innerDictionary)
    {
        this._innerDictionary = innerDictionary;
    }

    public void Add(string key, object value)
    {
        if (++this._itemCount > LargeJsonValueProviderFactory.EntryLimitedDictionary._maximumDepth)
            throw new InvalidOperationException("JsonValueProviderFactory_RequestTooLarge");
        this._innerDictionary.Add(key, value);
    }

    private static int GetMaximumDepth()
    {
        NameValueCollection appSettings = ConfigurationManager.AppSettings;
        if (appSettings != null)
        {
            string[] values = appSettings.GetValues("aspnet:MaxJsonDeserializerMembers");
            int result;
            if (values != null && values.Length > 0 && int.TryParse(values[0], out result))
                return result;
        }
        return 1000;
     }
  }
}

Ensuite, dans la méthode Application_Start de Global.asax.cs, remplacez ValueProviderFactory par le nouveau:

protected void Application_Start()
{
    ...

    //Add LargeJsonValueProviderFactory
    ValueProviderFactory jsonFactory = null;
    foreach (var factory in ValueProviderFactories.Factories)
    {
        if (factory.GetType().FullName == "System.Web.Mvc.JsonValueProviderFactory")
        {
            jsonFactory = factory;
            break;
        }
    }

    if (jsonFactory != null)
    {
        ValueProviderFactories.Factories.Remove(jsonFactory);
    }

    var largeJsonValueProviderFactory = new LargeJsonValueProviderFactory();
    ValueProviderFactories.Factories.Add(largeJsonValueProviderFactory);
}
MFA
la source
1
J'ai fait tout ce que je peux, seule votre réponse m'a sauvé la journée, cela aurait dû être accepté
Muhammad Waqas Aziz
Avec ce code, nous sommes en mesure de remplacer la limite de désérialisation du contrôleur MVC max json de 4 Mo, mais existe-t-il un moyen de remplacer la limite de désérialisation max du contrôleur web-api
Muhammad Waqas Aziz
17

si, après avoir implémenté l'ajout ci-dessus dans votre web.config, vous obtenez une «section de configuration non reconnue system.web.extensions». erreur, essayez d'ajouter ceci à votre web.config dans la <ConfigSections>section:

            <sectionGroup name="system.web.extensions" type="System.Web.Extensions">
              <sectionGroup name="scripting" type="System.Web.Extensions">
                    <sectionGroup name="webServices" type="System.Web.Extensions">
                          <section name="jsonSerialization" type="System.Web.Extensions"/>
                    </sectionGroup>
              </sectionGroup>
        </sectionGroup>
bkdraper
la source
4
J'avais ce problème. Cependant, cette réponse n'a pas fonctionné pour moi. Au lieu d'ajouter l'élément <sectionGroup> décrit ici, je viens de déplacer le bloc <system.web.extensions> nouvellement ajouté à la toute fin de mon web.config ... juste avant </configuration>. Ensuite, cela a fonctionné.
ClearCloud8
Cela a aidé, mais dans ma situation, j'ai dû changer votre quatrième ligne <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>, comme on le voit sur cette page: forums.asp.net/t/1446510.aspx/1
Nathan
@ ClearCloud8 Obtenez immédiatement ce commentaire sur cette page.
Jack Nutkins
11

vous pouvez écrire cette ligne dans Controller

json.MaxJsonLength = 2147483644;

vous pouvez également écrire cette ligne dans web.config

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

"

Pour être prudent, utilisez les deux.

Pankaj Sapkal
la source
10

Si vous obtenez cette erreur du MiniProfiler dans MVC, vous pouvez augmenter la valeur en définissant la propriété MiniProfiler.Settings.MaxJsonResponseSizesur la valeur souhaitée. Par défaut, cet outil semble ignorer la valeur définie dans config.

MiniProfiler.Settings.MaxJsonResponseSize = 104857600;

Courtoisie mvc-mini-profiler .

Wolfyuk
la source
10

Définissez simplement la propriété MaxJsonLength dans la méthode d'action de MVC

JsonResult json= Json(classObject, JsonRequestBehavior.AllowGet);
json.MaxJsonLength = int.MaxValue;
return json;
Aftab Ahmed Kalhoro
la source
9

Je suggère de le définir sur Int32.MaxValue.

JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
Santhosh
la source
9

Que diriez-vous d'une magie d'attribut?

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class MaxJsonSizeAttribute : ActionFilterAttribute
{
    // Default: 10 MB worth of one byte chars
    private int maxLength = 10 * 1024 * 1024;

    public int MaxLength
    {
        set
        {
            if (value < 0) throw new ArgumentOutOfRangeException("value", "Value must be at least 0.");

            maxLength = value;
        }
        get { return maxLength; }
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        JsonResult json = filterContext.Result as JsonResult;
        if (json != null)
        {
            if (maxLength == 0)
            {
                json.MaxJsonLength = int.MaxValue;
            }
            else
            {
                json.MaxJsonLength = maxLength;
            }
        }
    }
}

Ensuite, vous pouvez soit l'appliquer globalement en utilisant la configuration du filtre global ou le contrôleur / l'action.

Balázs
la source
Très bonne réponse. Belle utilisation d'attributs personnalisés. Vous vous demandez s'il existe une raison (technique) spécifique pour laquelle vous définissez la valeur par défaut à 10 Mo d'une valeur d'un octet au lieu de Max (int.MaxValue)?
Josh
@Josh Non, il n'y avait aucune raison particulière à cela.
Balázs
5

La question est vraiment de savoir si vous devez vraiment renvoyer 17k enregistrements? Comment prévoyez-vous de gérer toutes les données dans le navigateur? De toute façon, les utilisateurs ne feront pas défiler 17 000 lignes.

Une meilleure approche consiste à ne récupérer que les «premiers enregistrements» et à en charger plus au besoin.

Chetan Sastry
la source
1
La liste par défaut de json donnera 17k enregistrements. Mais la fonctionnalité de saisie semi-automatique répertorie uniquement les enregistrements qui correspondent aux caractères que l'utilisateur tape, il n'a donc pas besoin de faire défiler la liste davantage. Donc, ce dont j'ai besoin est de définir une longueur illimitée pour maxJsonLength qui peut sérialiser les données 17k.
Prasad
6
Vous pouvez utiliser une combinaison de filtrage côté serveur et côté client. Il peut être difficile de filtrer toutes les données côté client, sans parler de la latence du réseau.
Chetan Sastry
1
Arrivé à ce même problème il y a quelque temps, j'ai choisi d'implémenter un gestionnaire "onsearch" pour la saisie semi-automatique, et de demander à l'appel de service Web de passer le texte "recherche" et d'effectuer une requête Top10 en utilisant les critères de recherche comme filtre. Cela signifiait plus de demandes ajax individuelles, qui ne faisaient qu'obtenir la liste complète au chargement de la page, mais cela signifiait également que toutes les demandes / réponses étaient beaucoup plus petites.
Mike U
3

Vous pouvez le définir dans la configuration comme d'autres l'ont dit, ou vous pouvez le configurer sur une instance individuelle du sérialiseur comme:

var js = new JavaScriptSerializer() { MaxJsonLength = int.MaxValue };
Caleb Postlethwait
la source
3

Pour ceux qui ont des problèmes avec MVC3 avec JSON qui est automatiquement désérialisé pour un classeur de modèle et qui est trop volumineux, voici une solution.

  1. Copiez le code de la classe JsonValueProviderFactory du code source MVC3 dans une nouvelle classe.
  2. Ajoutez une ligne pour modifier la longueur JSON maximale avant la désérialisation de l'objet.
  3. Remplacez la classe JsonValueProviderFactory par votre nouvelle classe modifiée.

Grâce à http://blog.naver.com/techshare/100145191355 et https://gist.github.com/DalSoft/1588818 de m'avoir indiqué dans la bonne direction comment procéder. Le dernier lien sur le premier site contient le code source complet de la solution.

vestigal
la source
3

Si vous rencontrez ce type de problème dans View, vous pouvez utiliser la méthode ci-dessous pour résoudre ce problème. Ici, j'ai utilisé le package Newtonsoft .

@using Newtonsoft.Json
<script type="text/javascript">
    var partData = @Html.Raw(JsonConvert.SerializeObject(ViewBag.Part));
</script>
dush88c
la source
Est-ce à dire que je n'ai pas à me soucier de la longueur maximale si j'utilise Json.NET? Je ne pense pas qu'il existe un moyen de définir la longueur maximale dans Json.NET, donc j'espère que cela fonctionne juste hors de la boîte.
kimbaudi
1
Excellente réponse merci! Cela a également fonctionné lorsque j'essayais de charger un objet.
user1299379
3
 JsonResult result = Json(r);
 result.MaxJsonLength = Int32.MaxValue;
 result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
 return result;
Aikansh Mann
la source
2

Il semble qu'il n'y ait pas de valeur "illimitée". La valeur par défaut est 2097152 caractères, ce qui équivaut à 4 Mo de données de chaîne Unicode.

Comme cela a déjà été observé, 17 000 enregistrements sont difficiles à bien utiliser dans le navigateur. Si vous présentez une vue agrégée, il peut être beaucoup plus efficace de faire l'agrégation sur le serveur et de ne transférer qu'un résumé dans le navigateur. Par exemple, considérons un navigateur de système de fichiers, nous ne voyons que le haut de l'arborescence, puis émettons d'autres demandes au fur et à mesure que nous explorons. Le nombre d'enregistrements renvoyés dans chaque demande est relativement faible. Une présentation arborescente peut bien fonctionner pour les grands ensembles de résultats.

djna
la source
3
plutôt bizarrement la valeur par défaut dans le code (nouveau JavaScriptSerializer ()). MaxJsonLength est de 2097152 octets mais le service Web ResponseFormatJson est de 102400 octets, sauf si explicitement défini.
voler le
2

Je suis juste tombé sur ça. Je reçois plus de 6 000 enregistrements. Je viens de décider que je ferais juste quelques recherches. Comme dans, j'accepte un numéro de page dans mon point de terminaison MVC JsonResult, qui est défini par défaut sur 0, ce n'est donc pas nécessaire, comme ceci:

public JsonResult MyObjects(int pageNumber = 0)

Alors au lieu de dire:

return Json(_repository.MyObjects.ToList(), JsonRequestBehavior.AllowGet);

Je dis:

return Json(_repository.MyObjects.OrderBy(obj => obj.ID).Skip(1000 * pageNumber).Take(1000).ToList(), JsonRequestBehavior.AllowGet);

C'est très simple. Ensuite, en JavaScript, au lieu de cela:

function myAJAXCallback(items) {
    // Do stuff here
}

Je dis plutôt:

var pageNumber = 0;
function myAJAXCallback(items) {
    if(items.length == 1000)
        // Call same endpoint but add this to the end: '?pageNumber=' + ++pageNumber
    }
    // Do stuff here
}

Et ajoutez vos enregistrements à tout ce que vous faisiez avec eux en premier lieu. Ou attendez simplement que tous les appels se terminent et concoctez les résultats ensemble.

vbullinger
la source
2

J'ai résolu le problème en ajoutant ce code:

String confString = HttpContext.Current.Request.ApplicationPath.ToString();
Configuration conf = WebConfigurationManager.OpenWebConfiguration(confString);
ScriptingJsonSerializationSection section = (ScriptingJsonSerializationSection)conf.GetSection("system.web.extensions/scripting/webServices/jsonSerialization");
section.MaxJsonLength = 6553600;
conf.Save();
jfabrizio
la source
Cela semble être une solution hackeuse mais une approche intéressante malgré tout. Je l'ai trouvé utile merci! Pour moi, dans le contrôleur apsnet mvc 5, j'ai dû supprimer «Current» de l'espace de noms. J'ai fait quelques ajustements:string confString = HttpContext.Request.ApplicationPath.ToString(); var conf = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(confString); var section = (System.Web.Configuration.ScriptingJsonSerializationSection)conf.GetSection("system.web.extensions/scripting/webServices/jsonSerialization"); section.MaxJsonLength = int.MaxValue; conf.Save();
ooXei1sh
2

Correction ASP.NET MVC 5 alternative:

(Le mien est similaire à la réponse des MFC ci-dessus avec quelques petits changements)

Je n'étais pas encore prêt à passer à Json.NET et dans mon cas, l'erreur se produisait lors de la demande. La meilleure approche dans mon scénario consistait à modifier le réel JsonValueProviderFactoryqui applique le correctif au projet global et peut être effectué en modifiant le global.csfichier en tant que tel.

JsonValueProviderConfig.Config(ValueProviderFactories.Factories);

ajoutez une entrée web.config:

<add key="aspnet:MaxJsonLength" value="20971520" />

puis créez les deux classes suivantes

public class JsonValueProviderConfig
{
    public static void Config(ValueProviderFactoryCollection factories)
    {
        var jsonProviderFactory = factories.OfType<JsonValueProviderFactory>().Single();
        factories.Remove(jsonProviderFactory);
        factories.Add(new CustomJsonValueProviderFactory());
    }
}

Il s'agit essentiellement d'une copie exacte de l'implémentation par défaut trouvée dans, System.Web.Mvcmais avec l'ajout d'une valeur de paramétrage d'application web.config configurable aspnet:MaxJsonLength.

public class CustomJsonValueProviderFactory : ValueProviderFactory
{

    /// <summary>Returns a JSON value-provider object for the specified controller context.</summary>
    /// <returns>A JSON value-provider object for the specified controller context.</returns>
    /// <param name="controllerContext">The controller context.</param>
    public override IValueProvider GetValueProvider(ControllerContext controllerContext)
    {
        if (controllerContext == null)
            throw new ArgumentNullException("controllerContext");

        object deserializedObject = CustomJsonValueProviderFactory.GetDeserializedObject(controllerContext);
        if (deserializedObject == null)
            return null;

        Dictionary<string, object> strs = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
        CustomJsonValueProviderFactory.AddToBackingStore(new CustomJsonValueProviderFactory.EntryLimitedDictionary(strs), string.Empty, deserializedObject);

        return new DictionaryValueProvider<object>(strs, CultureInfo.CurrentCulture);
    }

    private static object GetDeserializedObject(ControllerContext controllerContext)
    {
        if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
            return null;

        string fullStreamString = (new StreamReader(controllerContext.HttpContext.Request.InputStream)).ReadToEnd();
        if (string.IsNullOrEmpty(fullStreamString))
            return null;

        var serializer = new JavaScriptSerializer()
        {
            MaxJsonLength = CustomJsonValueProviderFactory.GetMaxJsonLength()
        };
        return serializer.DeserializeObject(fullStreamString);
    }

    private static void AddToBackingStore(EntryLimitedDictionary backingStore, string prefix, object value)
    {
        IDictionary<string, object> strs = value as IDictionary<string, object>;
        if (strs != null)
        {
            foreach (KeyValuePair<string, object> keyValuePair in strs)
                CustomJsonValueProviderFactory.AddToBackingStore(backingStore, CustomJsonValueProviderFactory.MakePropertyKey(prefix, keyValuePair.Key), keyValuePair.Value);

            return;
        }

        IList lists = value as IList;
        if (lists == null)
        {
            backingStore.Add(prefix, value);
            return;
        }

        for (int i = 0; i < lists.Count; i++)
        {
            CustomJsonValueProviderFactory.AddToBackingStore(backingStore, CustomJsonValueProviderFactory.MakeArrayKey(prefix, i), lists[i]);
        }
    }

    private class EntryLimitedDictionary
    {
        private static int _maximumDepth;

        private readonly IDictionary<string, object> _innerDictionary;

        private int _itemCount;

        static EntryLimitedDictionary()
        {
            _maximumDepth = CustomJsonValueProviderFactory.GetMaximumDepth();
        }

        public EntryLimitedDictionary(IDictionary<string, object> innerDictionary)
        {
            this._innerDictionary = innerDictionary;
        }

        public void Add(string key, object value)
        {
            int num = this._itemCount + 1;
            this._itemCount = num;
            if (num > _maximumDepth)
            {
                throw new InvalidOperationException("The length of the string exceeds the value set on the maxJsonLength property.");
            }
            this._innerDictionary.Add(key, value);
        }
    }

    private static string MakeArrayKey(string prefix, int index)
    {
        return string.Concat(prefix, "[", index.ToString(CultureInfo.InvariantCulture), "]");
    }

    private static string MakePropertyKey(string prefix, string propertyName)
    {
        if (string.IsNullOrEmpty(prefix))
        {
            return propertyName;
        }
        return string.Concat(prefix, ".", propertyName);
    }

    private static int GetMaximumDepth()
    {
        int num;
        NameValueCollection appSettings = ConfigurationManager.AppSettings;
        if (appSettings != null)
        {
            string[] values = appSettings.GetValues("aspnet:MaxJsonDeserializerMembers");
            if (values != null && values.Length != 0 && int.TryParse(values[0], out num))
            {
                return num;
            }
        }
        return 1000;
    }

    private static int GetMaxJsonLength()
    {
        int num;
        NameValueCollection appSettings = ConfigurationManager.AppSettings;
        if (appSettings != null)
        {
            string[] values = appSettings.GetValues("aspnet:MaxJsonLength");
            if (values != null && values.Length != 0 && int.TryParse(values[0], out num))
            {
                return num;
            }
        }
        return 1000;
    }
}
Maxim Gershkovich
la source
1
Merci ça marche ... Merci beaucoup @Maxim Gershkovich
Jasper Manickaraj
1

Solution pour WebForms UpdatePanel:

Ajoutez un paramètre à Web.config:

<configuration>
  <appSettings>
    <add key="aspnet:UpdatePanelMaxScriptLength" value="2147483647" />
  </appSettings>
</configuration>

https://support.microsoft.com/en-us/kb/981884

ScriptRegistrationManager La classe contient le code suivant:

// Serialize the attributes to JSON and write them out
JavaScriptSerializer serializer = new JavaScriptSerializer();

// Dev10# 877767 - Allow configurable UpdatePanel script block length
// The default is JavaScriptSerializer.DefaultMaxJsonLength
if (AppSettings.UpdatePanelMaxScriptLength > 0) {
    serializer.MaxJsonLength = AppSettings.UpdatePanelMaxScriptLength;
}  

string attrText = serializer.Serialize(attrs);
Der_Meister
la source
1

Nous n'avons besoin d'aucune modification côté serveur. vous pouvez corriger cela uniquement modifier par le fichier web.config Cela m'a aidé. essayez ceci

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

and   

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

isanka thalagala
la source
0

utilisation lib\Newtonsoft.Json.dll

public string serializeObj(dynamic json) {        
    return JsonConvert.SerializeObject(json);
}
Buddhika De Silva
la source
0

Correctif pour ASP.NET MVC: si vous souhaitez le corriger uniquement pour une action particulière à l'origine du problème, codez comme ceci:

public JsonResult GetBigJson()
{
    var someBigObject = GetBigObject();
    return Json(someBigObject);
}

vous pouvez changer ceci:

public JsonResult GetBigJson()
{
    var someBigObject = GetBigObject();
    return new JsonResult()
    {
        Data = someBigObject,
        JsonRequestBehavior = JsonRequestBehavior.DenyGet,
        MaxJsonLength = int.MaxValue
    };
}

Et la fonctionnalité devrait être la même, vous pouvez simplement renvoyer un JSON plus grand en réponse.


Explication basée sur le code source ASP.NET MVC: vous pouvez vérifier la Controller.Jsonméthode utilisée dans le code source ASP.NET MVC

protected internal JsonResult Json(object data)
{
    return Json(data, null /* contentType */, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
}

Il appelle une autre Controller.Jsonméthode:

protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
    return new JsonResult
    {
        Data = data,
        ContentType = contentType,
        ContentEncoding = contentEncoding,
        JsonRequestBehavior = behavior
    };
}

où passé contentTypeet contentEncodingobjet sont null. Donc, fondamentalement, appeler le return Json(object)contrôleur équivaut à appeler return new JsonResult { Data = object, JsonRequestBehavior = sonRequestBehavior.DenyGet }. Vous pouvez utiliser le deuxième formulaire et le paramétrer JsonResult.

Alors, que se passe-t-il lorsque vous définissez une MaxJsonLengthpropriété (par défaut, elle est nulle)? Il est transmis à la JavaScriptSerializer.MaxJsonLengthpropriété, puis la JavaScriptSerializer.Serializeméthode est appelée :

JavaScriptSerializer serializer = new JavaScriptSerializer();
if (MaxJsonLength.HasValue)
{
    serializer.MaxJsonLength = MaxJsonLength.Value;
}

if (RecursionLimit.HasValue)
{
    serializer.RecursionLimit = RecursionLimit.Value;
}

response.Write(serializer.Serialize(Data));

Et lorsque vous ne définissez pas la MaxJsonLenghtpropriété du sérialiseur, il prend la valeur par défaut qui n'est que de 2 Mo.

Mariusz Pawelski
la source
-2

si cette valeur maxJsonLength est un int alors quelle est la taille de son int 32bit / 64bit / 16bit .... je veux juste être sûr quelle est la valeur maximale que je peux définir comme mon maxJsonLength

<scripting>
        <webServices>
            <jsonSerialization maxJsonLength="2147483647">
            </jsonSerialization>
        </webServices>
    </scripting>
mpho isaac Molelle
la source
-4

Vous n'avez pas besoin de faire avec web.config Vous pouvez utiliser une propriété courte pendant la valeur catch de la liste de passage Par exemple, déclarez un modèle comme

public class BookModel
    {
        public decimal id { get; set; }  // 1 

        public string BN { get; set; } // 2 Book Name

        public string BC { get; set; } // 3 Bar Code Number

        public string BE { get; set; } // 4 Edition Name

        public string BAL { get; set; } // 5 Academic Level

        public string BCAT { get; set; } // 6 Category
}

ici j'utilise de courtes proportions comme BC = code à barres BE = édition de livre et ainsi de suite

Md Nazrul Islam
la source
Cela n'aidera pas si la majeure partie des données se trouve dans les valeurs de la propriété
Fenêtre