Puis-je définir une longueur illimitée pour maxJsonLength dans le web.config?
j'utilise la fonctionnalité autocomplete de jQuery. Quand j'essaie de récupérer la liste de plus de 17000 enregistrements (chacun n'aura pas plus de 10 char de longueur), il dépasse la longueur et jette l'erreur:
informations D'Exception:
Type d'Exception: exception InvalidOperationException
Message d'Exception: erreur lors de la sérialisation ou de la desérialisation en utilisant le JavaScriptSerializer JSON. Le 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 maxJsonLength
dans web.config
? Dans la négative, Quelle est la longueur maximale que je peux fixer?
27 réponses
NOTE: cette réponse s'applique uniquement aux services Web, si vous retournez JSON à partir d'une méthode de contrôleur, assurez-vous de lire cette réponse ainsi ci-dessous: https://stackoverflow.com/a/7207539/1246870
la propriété MaxJsonLength ne peut pas être illimitée, est une propriété entière par défaut à 102400 (100k).
vous pouvez définir le MaxJsonLength propriété 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 aussi.
si vous recevez toujours l'erreur:
- après avoir fixé la propriété
maxJsonLength
à 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 une méthode de service web pour la sérialisation JavaScript
votre problème est probablement que:
la valeur de la propriété MaxJsonLength s'applique uniquement à L'instance JavaScriptSerializer interne qui est utilisée par la couche de communication asynchrone pour invoquer des méthodes de services Web. ( MSDN: ScriptingJsonSerializationSection.MaxJsonLength Propriété )
fondamentalement, le" interne " JavaScriptSerializer
respecte la valeur de maxJsonLength
lorsqu'il est appelé d'une méthode web; l'utilisation directe d'un JavaScriptSerializer
(ou l'utilisation via un MVC action-method/Controller) ne pas respecte la propriété maxJsonLength
, du moins pas de la section systemWebExtensions.scripting.webServices.jsonSerialization
de web.config.
comme solution de contournement, vous pouvez faire ce qui suit dans votre Controller (ou n'importe où en fait):
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 ce asp.net forum answer .
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 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
);
vous pouvez configurer la longueur maximale pour les requêtes json dans votre web.fichier de configuration:
<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 en ASP.NET formulaires Web. Il ignorait complètement le web.paramètres de fichier de configuration donc j'ai 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 regarder dans une approche différente.
si vous avez encore une erreur après web.paramètre de configuration 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 réparé.
//your Json data here
string json_object="........";
JavaScriptSerializer jsJson = new JavaScriptSerializer();
jsJson.MaxJsonLength = 2147483644;
MyClass obj = jsJson.Deserialize<MyClass>(json_object);
ça marche très bien.
si, après avoir implémenté l'ajout ci-dessus dans votre web.config, vous obtenez un " système de section de configuration non reconnu.Web.extension."erreur alors essayez d'ajouter ceci à 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>
j'ai suivi la réponse de vestigal et suis arrivé à cette solution:
quand j'avais besoin de poster un gros json à une action dans un contrôleur, j'obtenais la fameuse "erreur lors de la desérialisation en utilisant le JavaScriptSerializer JSON. La longueur de la chaîne dépasse la valeur définie sur la propriété maxJsonLength.\r\nParameter nom: saisissez la valeur de fournisseur".
ce que j'ai fait est de créer un nouveau ValueProviderFactory, Largejsonvaluproviderfactory, et de mettre le 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;
}
}
}
puis, dans la méthode Application_Start de Global.asax.cs, remplacer le 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);
}
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 à partir du Miniprofileur dans MVC alors vous pouvez augmenter la valeur en définissant la propriété MiniProfiler.Settings.MaxJsonResponseSize
à la valeur désirée. Par défaut, cet outil semble ignorer la valeur définie dans la configuration.
MiniProfiler.Settings.MaxJsonResponseSize = 104857600;
Courtesy mvc-mini-profiler .
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;
je suggère de le mettre sur Int32.MaxValue.
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
Que dirais-tu d'un attribut magique?
[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;
}
}
}
}
alors vous pouvez soit l'appliquer globalement en utilisant la configuration du filtre global, soit le controller/action-wise.
la question est vraiment de savoir si vous devez vraiment retourner les disques de 17k? Comment prévoyez-vous de gérer toutes les données du navigateur? Les utilisateurs ne vont pas défiler 17000 lignes de toute façon.
une meilleure approche consiste à récupérer seulement un" petit nombre " d'enregistrements et à en charger plus au besoin.
pour ceux qui ont des problèmes avec MVC3 avec JSON qui est automatiquement désérialisé pour un classeur de modèle et est trop grand, voici une solution.
- Copiez le code de la classe JsonValueProviderFactory à partir du code source MVC3 dans une nouvelle classe.
- ajouter une ligne pour changer la longueur maximale de JSON avant que l'objet soit désérialisé.
- remplacer la classe JsonValueProviderFactory par votre nouvelle, modifié la classe.
merci à http://blog.naver.com/techshare/100145191355 et https://gist.github.com/DalSoft/1588818 pour m'avoir indiqué la bonne direction. Le dernier lien sur le premier site contient le code source complet de la solution.
vient de tomber sur ça. Je reçois plus de 6 000 dossiers. Juste décidé que je venais de faire certains d'échange. Comme dans, j'accepte un nombre de page dans mon MVC JsonResult endpoint, qui est par défaut à 0 donc ce n'est pas nécessaire, comme cela:
public JsonResult MyObjects(int pageNumber = 0)
puis 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. Puis, en JavaScript, à la place 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 ajoutez vos dossiers à ce que vous faisiez avec eux. Ou juste attendre que tous les appels finissent et cobble les résultats ensemble.
il semble qu'il n'y ait pas de valeur" illimitée". La valeur par défaut est 2097152 caractères, ce qui est équivalent à 4 Mo de données Unicode chaîne.
comme nous l'avons déjà observé, 17 000 enregistrements sont difficiles à utiliser dans le navigateur. Si vous présentez une vue agrégée il peut être beaucoup plus efficace de faire de l'agrégation sur le serveur et le transfert uniquement un résumé dans le navigateur. Par exemple, considérez un brower de système de fichiers, nous ne voyons que le haut de l'arbre, puis émit d'autres demandes pendant que nous forons vers le bas. Le nombre d'enregistrements renvoyés dans chaque demande est relativement faible. Une arborescence de présentation peut bien fonctionner pour les grands ensembles de résultats.
vous pouvez le configurer dans la configuration comme d'autres l'ont dit, ou vous pouvez configurer une instance individuelle du serializer comme:
var js = new JavaScriptSerializer() { MaxJsonLength = int.MaxValue };
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 genre de problème en vue, vous pouvez utiliser la méthode ci-dessous pour résoudre cela. Ici Iused Newtonsoft paquet .
@using Newtonsoft.Json
<script type="text/javascript">
var partData = @Html.Raw(JsonConvert.SerializeObject(ViewBag.Part));
</script>
utiliser lib\Newtonsoft.Json.dll
public string serializeObj(dynamic json) {
return JsonConvert.SerializeObject(json);
}
Solution for WebForms UpdatePanel:
Ajouter un paramètre à Web.config:
<configuration>
<appSettings>
<add key="aspnet:UpdatePanelMaxScriptLength" value="2147483647" />
</appSettings>
</configuration>
https://support.microsoft.com/en-us/kb/981884
ScriptRegistrationManager
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);
nous n'avons pas besoin de modifications côté serveur. vous pouvez corriger cela seulement modifier par web.fichier de configuration cela m'a aidé. essayez
<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>
Alternative ASP.NET fixation MVC 5:
(Mine est similaire à la réponse MFCs ci-dessus avec quelques petites modifications)
Je n'étais pas prêt à changer pour Json.NET juste pour l'instant et dans mon cas, l'erreur se produisait pendant la requête. La meilleure approche dans mon scénario était de modifier le JsonValueProviderFactory
qui applique le correctif au projet global et qui peut être fait en éditant le fichier global.cs
comme tel.
JsonValueProviderConfig.Config(ValueProviderFactories.Factories);
ajouter un web.entrée de configuration:
<add key="aspnet:MaxJsonLength" value="20971520" />
et ensuite créer 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.Mvc
mais avec l'ajout d'un web configurable.config appsetting valeur 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;
}
}
si cette valeur de 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>
vous n'avez pas besoin de faire avec le web.config Vous pouvez utiliser la propriété courte pendant la valeur de capture de la liste passante 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 des proportions courtes comme BC =code à barres BE = édition de livres et ainsi de suite