737 Stimmen

Kann ich eine unbegrenzte Länge für maxJsonLength in web.config festlegen?

Ich verwende die Autocomplete-Funktion von jQuery. Wenn ich versuche, die Liste von mehr als 17000 Datensätze abzurufen (jeder wird nicht mehr als 10 Zeichen Länge haben), es ist die Länge überschreiten und wirft den Fehler:

Informationen zu Ausnahmen:
Art der Ausnahme: InvalidOperationException
Ausnahmemeldung: Fehler bei der Serialisierung oder Deserialisierung mit dem JSON JavaScriptSerializer. Die Länge der Zeichenfolge überschreitet den Wert der Eigenschaft maxJsonLength.

Kann ich eine unbegrenzte Länge festlegen für maxJsonLength において web.config ? Wenn nicht, was ist die maximale Länge, die ich einstellen kann?

45voto

Flea Punkte 10932

Ich hatte dieses Problem in ASP.NET Web Forms. Es war völlig ignoriert die web.config-Datei-Einstellungen, so dass ich dies tat:

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        serializer.MaxJsonLength = Int32.MaxValue; 

        return serializer.Serialize(response);

Natürlich ist dies insgesamt eine schreckliche Praxis. Wenn Sie so viele Daten in einem Webdienstaufruf senden, sollten Sie einen anderen Ansatz wählen.

37voto

Byt3 Punkte 481

Ich habe die Antwort von Vestigal befolgt und bin zu dieser Lösung gekommen:

Wenn ich brauchte, um eine große json zu einer Aktion in einem Controller zu posten, würde ich die berühmte "Fehler während der Deserialisierung mit dem JSON JavaScriptSerializer erhalten. Die Länge der Zeichenfolge überschreitet den Wert auf die maxJsonLength-Eigenschaft festgelegt. \r\nParameter name: input value provider".

Was ich getan habe, ist eine neue ValueProviderFactory, LargeJsonValueProviderFactory, erstellen und die MaxJsonLength = Int32.MaxValue in der GetDeserializedObject-Methode festlegen

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

Ersetzen Sie dann in der Methode Application_Start aus Global.asax.cs die ValueProviderFactory durch die neue:

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

24voto

Mario Arrieta Punkte 231

Ich habe es repariert.

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

Das funktioniert sehr gut.

17voto

Setzen Sie einfach den Wert MaxJsonLength in der MVC-Methode Action

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

17voto

bkdraper Punkte 789

Wenn Sie nach der Implementierung des obigen Zusatzes in Ihre web.config die Fehlermeldung "Unrecognized configuration section system.web.extensions." erhalten, dann versuchen Sie, dies zu Ihrer web.config im Abschnitt <ConfigSections> Abschnitt:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X