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?
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>
Si vous utilisez MVC 4 , assurez-vous de vérifier cette réponse ainsi que.
Si vous recevez toujours l'erreur:
maxJsonLength
sur sa valeur maximale dans web.configvotre 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 .
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
);
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
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.
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.
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.
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);
}
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>
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.
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 .
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;
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.
Je suggère de le mettre à Int32.MaxValue.
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
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.
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 };
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.
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.
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.
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();
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>
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.
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;
}
}
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>
utiliser lib\Newtonsoft.Json.dll
public string serializeObj(dynamic json) {
return JsonConvert.SerializeObject(json);
}
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);