it-swarm.it

Posso impostare una lunghezza illimitata per maxJsonLength in web.config?

Sto usando la funzione di completamento automatico di jQuery. Quando provo a recuperare l'elenco di più di 17000 record (ognuno non avrà più di 10 caratteri), sta superando la lunghezza e genera l'errore:

Informazioni di eccezione:
Tipo di eccezione: InvalidOperationException
Messaggio di eccezione: errore durante la serializzazione o deserializzazione mediante JavaScript JSerializer. La lunghezza della stringa supera il valore impostato sulla proprietà maxJsonLength.

Posso impostare una lunghezza illimitata per maxJsonLength in web.config? In caso contrario, qual è la lunghezza massima che posso impostare?

617
Prasad

NOTA: questa risposta si applica solo ai servizi Web, se si restituisce JSON da un metodo Controller, assicurarsi di leggere anche questa risposta SO di seguito: https: // stackoverflow. it/a/7207539/1246870


La proprietà MaxJsonLength non può essere illimitata, è una proprietà intera che ha come valore predefinito 102400 (100k).

È possibile impostare la proprietà MaxJsonLength sul proprio web.config:

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

Se stai usando MVC 4 , assicurati di controllare anche questa risposta.


Se stai ancora ricevendo l'errore:

  • dopo aver impostato la proprietà maxJsonLength sul valore massimo in web.config
  • e tu sai che la lunghezza dei tuoi dati è inferiore a questo valore
  • e non stai utilizzando un metodo di servizio web per la serializzazione JavaScript

il tuo problema è probabile che:

Il valore della proprietà MaxJsonLength si applica solo all'istanza di JavaScriptSerializer interna utilizzata dal livello di comunicazione asincrono per richiamare i metodi dei servizi Web. ( MSDN: proprietà ScriptingJsonSerializationSection.MaxJsonLength )

In sostanza, il JavaScriptSerializer "interno" rispetta il valore di maxJsonLength quando viene chiamato da un metodo web; l'uso diretto di un JavaScriptSerializer (o l'uso tramite un metodo/controller di azione MVC) fa not rispetta la proprietà maxJsonLength, almeno non dalla sezione systemWebExtensions.scripting.webServices.jsonSerialization di web.config.

Come soluzione alternativa, puoi eseguire le seguenti operazioni all'interno del tuo Controller (o ovunque):

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;

Questa risposta è la mia interpretazione di questa risposta del forum asp.net .

430
David Murdoch

In MVC 4 puoi fare:

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
    };
}

nel tuo controller.

Aggiunta:

Per chiunque perplesso dai parametri che devi specificare, una chiamata potrebbe apparire come questa:

Json(
    new {
        field1 = true,
        field2 = "value"
        },
    "application/json",
    Encoding.UTF8,
    JsonRequestBehavior.AllowGet
);
314
fanisch

Puoi configurare la lunghezza massima per le richieste json nel tuo file web.config:

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

Il valore predefinito per maxJsonLength è 102400 . Per ulteriori dettagli, vedere questa pagina MSDN: http://msdn.Microsoft.com/en-us/library/bb763183.aspx

58
M4N

Stavo avendo questo problema in Web Form ASP.NET. Stava ignorando completamente le impostazioni del file web.config, così ho fatto questo:

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        serializer.MaxJsonLength = Int32.MaxValue; 

        return serializer.Serialize(response);

Naturalmente nel complesso questa è una pratica terribile. Se si inviano molti dati in una chiamata di servizio Web, è necessario considerare un approccio diverso.

33
Flea

se ricevi ancora errori dopo l'impostazione di web.config come segue:

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

L'ho risolto seguendo:

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

Spero che questo dovrebbe aiutare.

27
Ravi Anand

L'ho riparato.

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

Funziona molto bene.

21
Mario Arrieta

se, dopo aver implementato l'aggiunta di cui sopra nel tuo web.config, ottieni un errore "System.web.extensions" della sezione di configurazione non riconosciuta. Quindi prova ad aggiungerlo al tuo web.config nella sezione <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

Ho seguito la risposta di Vestigal e sono arrivato a questa soluzione:

Quando ho dovuto inviare un grande json a un'azione in un controller, otterrei il famoso "Errore durante la deserializzazione usando JavaScript JSerializer.La lunghezza della stringa supera il valore impostato sulla proprietà maxJsonLength.\R\nParameter name: input fornitore di valore ".

Quello che ho fatto è creare una nuova ValueProviderFactory, LargeJsonValueProviderFactory e impostare MaxJsonLength = Int32.MaxValue nel metodo 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;
    }
}

}

Quindi, nel metodo Application_Start di Global.asax.cs, sostituire ValueProviderFactory con quello nuovo:

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);
}
14
MFA

puoi scrivere questa linea in Controller

json.MaxJsonLength = 2147483644;

puoi anche scrivere questa riga in web.config

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

`

Per essere al sicuro, usa entrambi.

10
Pankaj Sapkal

Se ricevi questo errore da MiniProfiler in MVC, puoi aumentare il valore impostando la proprietà MiniProfiler.Settings.MaxJsonResponseSize sul valore desiderato. Per impostazione predefinita, questo strumento sembra ignorare il valore impostato in config.

MiniProfiler.Settings.MaxJsonResponseSize = 104857600;

Cortesia mvc-mini-profiler .

9
WolfyUK

Basta impostare la proprietà MaxJsonLength nel metodo MVC Action

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

Suggerisco di impostarlo su Int32.MaxValue.

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

Che ne dici di qualche attributo magico?

[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;
            }
        }
    }
}

Quindi è possibile applicarlo globalmente utilizzando la configurazione del filtro globale o il controller/action-wise.

6
Balázs

La domanda è davvero se hai davvero bisogno di restituire i record 17k? Come pensi di gestire tutti i dati nel browser? Gli utenti non hanno intenzione di scorrere tra le 17000 righe comunque.

Un approccio migliore consiste nel recuperare solo i record "top" e caricarne altri in base alle esigenze.

4
Chetan Sastry

Puoi impostarlo nella configurazione come altri hanno detto, oppure puoi impostare su una singola istanza del serializzatore come:

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

Per coloro che hanno problemi con MVC3 con JSON che viene automaticamente deserializzato per un modello di legatura ed è troppo grande, ecco una soluzione.

  1. Copia il codice per la classe JsonValueProviderFactory dal codice sorgente MVC3 in una nuova classe.
  2. Aggiungi una linea per modificare la lunghezza massima JSON prima che l'oggetto venga deserializzato.
  3. Sostituisci la classe JsonValueProviderFactory con la tua nuova classe modificata.

Grazie a http://blog.naver.com/techshare/100145191355 e https://Gist.github.com/DalSoft/1588818 per avermi indicato nella giusta direzione per come farlo. L'ultimo link sul primo sito contiene il codice sorgente completo per la soluzione.

3
vestigal

Sembra che non ci sia un valore "illimitato". Il valore predefinito è 2097152 caratteri, che equivale a 4 MB di dati di stringa Unicode.

Come già osservato, nel browser sono difficili da utilizzare 17.000 record. Se si sta presentando una vista aggregata, potrebbe essere molto più efficiente eseguire l'aggregazione sul server e trasferire solo un sommario nel browser. Ad esempio, prendi in considerazione un brower del file system, vediamo solo la parte superiore dell'albero, quindi emettiamo ulteriori richieste mentre analizziamo. Il numero di record restituiti in ciascuna richiesta è relativamente piccolo. Una presentazione con vista ad albero può funzionare bene per insiemi di risultati di grandi dimensioni.

2
djna

Ho risolto il problema aggiungendo questo codice:

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

Se si verifica questo tipo di problema in Visualizza, è possibile utilizzare il metodo riportato di seguito per risolverlo. Qui ho usato Newtonsoft package.

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

Mi sono imbattuto in questo. Sto superando i 6.000 dischi. Ho appena deciso di fare un po 'di impaginazione. Come in, accetto un numero di pagina nel mio endpoint MVC JsonResult, che per impostazione predefinita è 0, quindi non è necessario, in questo modo:

public JsonResult MyObjects(int pageNumber = 0)

Quindi invece di dire:

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

Dico:

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

È molto semplice. Quindi, in JavaScript, invece di questo:

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

Io invece dico:

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

E aggiungi i tuoi record a qualsiasi cosa tu stia facendo con loro, in primo luogo. O semplicemente aspetta fino a quando tutte le chiamate finiscono e cobble i risultati insieme.

2
vbullinger

Correzione alternativa di ASP.NET MVC 5:

(Il mio è simile alla risposta di MFC sopra con alcune piccole modifiche)

Non ero ancora pronto per passare a Json.NET e nel mio caso l'errore si stava verificando durante la richiesta. Il miglior approccio nel mio scenario era la modifica del JsonValueProviderFactory effettivo che applica la correzione al progetto globale e può essere fatto modificando il file global.cs come tale.

JsonValueProviderConfig.Config(ValueProviderFactories.Factories);

aggiungi una voce web.config:

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

e quindi creare le due seguenti classi

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

Questa è fondamentalmente una copia esatta dell'implementazione predefinita trovata in System.Web.Mvc ma con l'aggiunta di un valore di appetting web.config configurabile 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

Non abbiamo bisogno di modifiche al lato server. puoi correggere questa modifica solo dal file web.config Questo mi ha aiutato. prova questo

<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

usa lib\Newtonsoft.Json.dll

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

Soluzione per WebForms UpdatePanel:

Aggiungi un'impostazione a Web.config:

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

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

La classe ScriptRegistrationManager contiene il seguente codice:

// 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