web-dev-qa-db-fra.com

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

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

Information d'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 dans la propriété maxJsonLength.

Puis-je définir une longueur illimitée pour maxJsonLength dans web.config? Si non, quelle est la longueur maximale que je peux définir?

634
Prasad

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


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

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

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

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


Si vous recevez toujours l'erreur:

  • après avoir défini la propriété maxJsonLength sur 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 des méthodes de services Web. ( MSDN: ScriptingJsonSerializationSection.MaxJsonLength, propriété )

Fondamentalement, la variable "interne" JavaScriptSerializer respecte la valeur de maxJsonLength lorsqu'elle est appelée à partir d'une méthode Web; L'utilisation directe d'une JavaScriptSerializer (ou via une action-méthode/contrôleur MVC) ne ne respecte pas la propriété maxJsonLength, du moins pas dans la section systemWebExtensions.scripting.webServices.jsonSerialization de web.config.

Pour contourner le problème, vous pouvez effectuer les opérations suivantes dans votre contrôleur (ou ailleurs):

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 du forum asp.net .

441
David Murdoch

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.

Ajout:

Pour ceux qui sont déroutés 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
);
322
fanisch

Vous pouvez configurer la longueur maximale pour les 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 pour maxJsonLength est 102400 . Pour plus de détails, voir cette page MSDN: http://msdn.Microsoft.com/en-us/library/bb763183.aspx

58
M4N

J'avais ce problème dans ASP.NET Web Forms. Il ignorait complètement les paramètres du fichier web.config, alors je l'ai fait:

        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.

33
Flea

si vous obtenez toujours une erreur après le paramétrage de 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.

29
Ravi Anand

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.

21
Mario Arrieta

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

Lorsque je devais envoyer un JSON volumineux à une action dans un contrôleur, je rencontrais le fameux "Erreur lors de la désérialisation à l'aide du JSON JavaScriptSerializer. La longueur de la chaîne dépasse la valeur définie pour la propriété maxJsonLength.\R\nNom du paramètre: entrée fournisseur de valeur ".

Ce que j'ai fait est de créer un nouveau ValueProviderFactory, LargeJsonValueProviderFactory et de définir 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);
}
17
MFA

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

            <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>
16
bkdraper

vous pouvez écrire cette ligne dans le contrôleur

json.MaxJsonLength = 2147483644;

vous pouvez aussi écrire cette ligne dans web.config

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

`

Pour être sûr, utilisez les deux.

10
Pankaj Sapkal

Si vous obtenez cette erreur de MiniProfiler dans MVC, vous pouvez augmenter la valeur en définissant la propriété MiniProfiler.Settings.MaxJsonResponseSize sur 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 .

9
WolfyUK

Définissez simplement la propriété MaxJsonLength dans la méthode Action MVC

JsonResult json= Json(classObject, JsonRequestBehavior.AllowGet);
json.MaxJsonLength = int.MaxValue;
return json;
9

Que diriez-vous de la 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;
            }
        }
    }
}

Vous pouvez ensuite l'appliquer globalement à l'aide de la configuration de filtre globale ou du contrôleur/action.

7
Balázs

Je suggère de le mettre à Int32.MaxValue.

JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
6
Santhosh

La question est vraiment de savoir si vous devez vraiment retourner 17k disques? Comment envisagez-vous de gérer toutes les données du navigateur? Les utilisateurs ne vont quand même pas parcourir 17 000 lignes.

Une meilleure approche consiste à extraire uniquement les "quelques meilleurs" enregistrements et à en charger davantage si nécessaire.

4
Chetan Sastry

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

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

Pour ceux qui rencontrent des problèmes dans MVC3 avec JSON qui sont automatiquement désérialisés pour un classeur de modèle et 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 maximale de JSON avant la désérialisation de l'objet.
  3. Remplacez la classe JsonValueProviderFactory par votre nouvelle classe modifiée.

Merci à http://blog.naver.com/techshare/100145191355 et https://Gist.github.com/DalSoft/1588818 pour m'avoir orienté dans la bonne direction pour comment faire cela. Le dernier lien sur le premier site contient le code source complet de la solution.

3
vestigal

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 sous forme de chaîne Unicode.

Comme déjà observé, 17 000 enregistrements sont difficiles à utiliser dans le navigateur. Si vous présentez une vue agrégée, il peut s'avérer beaucoup plus efficace de procéder à 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 requêtes lors de l’exploration. Le nombre d'enregistrements renvoyés dans chaque demande est relativement faible. Une présentation en arborescence peut convenir aux ensembles de résultats volumineux.

2
djna

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();
2
jfabrizio

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

@using Newtonsoft.Json
<script type="text/javascript">
    var partData = @Html.Raw(JsonConvert.SerializeObject(ViewBag.Part));
</script>
2
dush88c

Juste couru dans cela. Je reçois plus de 6 000 enregistrements. J'ai juste décidé de faire de la pagination. En tant que, j'accepte un numéro de page dans mon point de terminaison MVC JsonResult, dont la valeur par défaut est 0, ce qui n'est 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 ceci:

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 annexez vos registres à ce que vous faisiez avec eux en premier lieu. Ou attendez simplement que tous les appels se terminent et bricolez les résultats.

2
vbullinger

Solution de remplacement ASP.NET MVC 5:

(Le mien est similaire aux MFC, répondez ci-dessus avec quelques petites modifications)

Je n'étais pas prêt à changer pour Json.NET pour l'instant et dans mon cas, l'erreur se produisait lors de la demande. La meilleure approche dans mon scénario consistait à modifier le JsonValueProviderFactory actuel, qui applique le correctif au projet global et peut être effectué en modifiant le fichier global.cs 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 d’une copie exacte de l’implémentation par défaut trouvée dans System.Web.Mvc, mais avec l’ajout d’une valeur configurable d’application web.config 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;
    }
}
1

Nous n'avons besoin d'aucun changement côté serveur. vous ne pouvez corriger cela que 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>
0
isanka thalagala

utiliser lib\Newtonsoft.Json.dll

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

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

La classe ScriptRegistrationManager 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);
0
Der_Meister