2016-07-11 16 views
-1

Während Auktionsdaten von Blizzard (a 6 MB JSON-Datei) herunterladen, auf dekodieren konnte ich den Fehler, dies verfolgen:Dekodierung großen JSON-Dateien in C#

„Fehler bei der Serialisierung oder Deserialisierung der Verwendung von . JSON JavaScriptSerializer die Länge der Zeichenfolge überschreitet den Wert auf der Eigenschaft maxJsonLength gesetzt \ r \ nParameter Name:. Eingang“

wie kann ich die maxJsonLength ändern 20 MB zu sagen (wie einige der JSON kann ich analysieren so groß sein) in der folgenden Klasse?

public sealed class DynamicJsonConverter : JavaScriptConverter 
{ 
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) 
    { 
     if (dictionary == null) 
      throw new ArgumentNullException("dictionary"); 

     return type == typeof(object) ? new DynamicJsonObject(dictionary) : null; 
    } 

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override IEnumerable<Type> SupportedTypes 
    { 
     get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(object) })); } 
    } 

    #region Nested type: DynamicJsonObject 

    private sealed class DynamicJsonObject : DynamicObject 
    { 
     private readonly IDictionary<string, object> _dictionary; 

     public DynamicJsonObject(IDictionary<string, object> dictionary) 
     { 
      if (dictionary == null) 
       throw new ArgumentNullException("dictionary"); 
      _dictionary = dictionary; 
     } 

     public override string ToString() 
     { 
      var sb = new StringBuilder("{"); 
      ToString(sb); 
      return sb.ToString(); 
     } 

     private void ToString(StringBuilder sb) 
     { 
      var firstInDictionary = true; 
      foreach (var pair in _dictionary) 
      { 
       if (!firstInDictionary) 
        sb.Append(","); 
       firstInDictionary = false; 
       var value = pair.Value; 
       var name = pair.Key; 
       if (value is string) 
       { 
        sb.AppendFormat("{0}:\"{1}\"", name, value); 
       } 
       else if (value is IDictionary<string, object>) 
       { 
        new DynamicJsonObject((IDictionary<string, object>)value).ToString(sb); 
       } 
       else if (value is ArrayList) 
       { 
        sb.Append(name + ":["); 
        var firstInArray = true; 
        foreach (var arrayValue in (ArrayList)value) 
        { 
         if (!firstInArray) 
          sb.Append(","); 
         firstInArray = false; 
         if (arrayValue is IDictionary<string, object>) 
          new DynamicJsonObject((IDictionary<string, object>)arrayValue).ToString(sb); 
         else if (arrayValue is string) 
          sb.AppendFormat("\"{0}\"", arrayValue); 
         else 
          sb.AppendFormat("{0}", arrayValue); 

        } 
        sb.Append("]"); 
       } 
       else 
       { 
        sb.AppendFormat("{0}:{1}", name, value); 
       } 
      } 
      sb.Append("}"); 
     } 

     public override bool TryGetMember(GetMemberBinder binder, out object result) 
     { 
      if (!_dictionary.TryGetValue(binder.Name, out result)) 
      { 
       // Return null to avoid exception. The caller can check for null this way... 
       result = null; 
       return true; 
      } 

      result = WrapResultObject(result); 
      return true; 
     } 

     public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) 
     { 
      if (indexes.Length == 1 && indexes[0] != null) 
      { 
       if (!_dictionary.TryGetValue(indexes[0].ToString(), out result)) 
       { 
        // Return null to avoid exception. The caller can check for null this way... 
        result = null; 
        return true; 
       } 

       result = WrapResultObject(result); 
       return true; 
      } 

      return base.TryGetIndex(binder, indexes, out result); 
     } 

     private static object WrapResultObject(object result) 
     { 
      var dictionary = result as IDictionary<string, object>; 
      if (dictionary != null) 
       return new DynamicJsonObject(dictionary); 

      var arrayList = result as ArrayList; 
      if (arrayList != null && arrayList.Count > 0) 
      { 
       return arrayList[0] is IDictionary<string, object> 
        ? new List<object>(arrayList.Cast<IDictionary<string, object>>().Select(x => new DynamicJsonObject(x))) 
        : new List<object>(arrayList.Cast<object>()); 
      } 

      return result; 
     } 
    } 

    #endregion 
} 

Oder in der aufrufenden Methode:

public static dynamic DecodeJson(this string str) 
    { 
     var serializer = new JavaScriptSerializer(); 
     serializer.RegisterConverters(new[] { new DynamicJsonConverter() }); 
     dynamic result = null; 
     try 
     { 
      result = serializer.Deserialize(str, typeof(object)); 
     } catch (ArgumentException ae) 
     { 
      Log.Output(ae.InnerException.Message); 
     } 
     return result; 
    } 
+1

Es scheint, als spät jeder Frage ich die desrialization Klasse Post auf, jemand hat einen Drive-by-downvote. Wenn Sie ein Problem mit der Frage selbst haben, geben Sie bitte an, was Ihr Problem ist, damit es angesprochen werden kann. –

+0

Keine Antwort, aber da Sie C# verwenden, könnten Sie einen der JSerializer von Drittanbietern wie JIL oder JSON.NET in Erwägung ziehen, die im Allgemeinen viel schneller sind, besonders für große Dateien wie diese. Diese erfordern offensichtlich eine Abhängigkeit. –

+2

Die Fehlermeldung ist sehr klar über die JavaScriptSerializer-Eigenschaft MaxJsonLength. Ein kurzer Blick auf die Dokumente hatte Ihnen die Lösung gesagt. Ich bin nicht überrascht über den Downvote –

Antwort

5

Sie die JavaScriptSerializer.MaxJsonLength Property

Die maximale Länge von JSON-Strings ändern sollte. Der Standardwert ist 2097152 Zeichen, , was 4 MB Unicode-Zeichenfolgedaten entspricht.

public static dynamic DecodeJson(this string str) 
{ 
    var serializer = new JavaScriptSerializer(); 
    serializer.MaxJsonLength = Int.MaxValue; // The value of this constant is 2,147,483,647 
    serializer.RegisterConverters(new[] { new DynamicJsonConverter() }); 
    dynamic result = null; 
    try 
    { 
     result = serializer.Deserialize(str, typeof(object)); 
    } catch (ArgumentException ae) 
    { 
     Log.Output(ae.InnerException.Message); 
    } 
    return result; 
} 
+0

Ausgezeichnet. Vielen Dank :) –