.NET JSON.decode()对于大型数组失败

时间:2014-08-07 03:52:59

标签: javascript .net arrays json serialization

MVC 4 ASP.NET Web API应用程序:

我有一个形式为JSON的数组:

var json = "{
    'mapset':
    [
        {
            'id': '1',
            'key': 'key1',
            'value': 'value1',
            'timestamp': '2014-02-12T08:50:54.594Z'
        },
        {
            'id': '2',
            'key': 'key2',
            'value': 'value2',
            'timestamp': '2014-02-12T08:50:54.594Z'
        },
    ]
}";

dynamic data = System.Web.Helpers.JSON.decode(json);

对于每个大约1K字节的10K元素的数组,JSON.Decode()就像魅力一样。

对于100K元素失败并出现错误:

  

System.ArgumentException:使用JSON JavaScriptSerializer进行序列化或反序列化时出错。字符串的长度超过maxJsonLength属性上设置的值。参数名称:在System.Web.Helpers的System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer序列化程序,字符串输入,类型类型,Int32 depthLimit)处输入。 Json.Decode(字符串值)

如何设置更高的限制?

我知道关于这个主题的另一篇文章:

Can I set an unlimited length for maxJsonLength in web.config?

然而,那里提供的答案并没有解决我的具体问题。

我在MVC4应用中直接使用JSON.Decode(),因此web.config设置的修改将不适用。并且JSON.Decode()将JSON字符串反序列化为.NET JSON对象(而不是将.NET JSON对象序列化为JSON字符串)。

2 个答案:

答案 0 :(得分:0)

System.Web.Script.Serialization.JavaScriptSerializer为我做了诀窍。

我认为这很难看,但是使用JavaScriptSerializer,我可以将maxJsonLength设置为一个很大的值:

JavaScriptSerializer ser = new JavaScriptSerializer();
ser.MaxJsonLength = Int32.MaxValue; // <-- should probably not use that huge value
var jsonArtikel = ser.Serialize(Model);

答案 1 :(得分:0)

Michael Witty的

This blog article说明了如何解决该问题。基本上,虽然不可能直接覆盖MaxJsonLength使用的基础JavaScriptSerializer的{​​{1}},但是可以很容易地用几行并由此复制System.Web.Helpers.Json.Decode控制最大长度。

以下是经过测试且可以正常运行的DynamicJsonObjectFormatter。它有一个静态方法System.Web.Helpers.Json.Decode,它可以复制dynamic DynamicJsonObjectFormatter.Decode(string json),但可以控制最大长度:

System.Web.Helpers.Json.Decode

(注意:public class DynamicJsonObjectFormatter : BufferedMediaTypeFormatter { private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); public static dynamic Decode(string json, int maxLength=0) { try { if (string.IsNullOrEmpty(json)) return null; var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); if( maxLength>0) { serializer.MaxJsonLength = maxLength; } var deserialized = serializer.DeserializeObject(json); if (deserialized != null) { var dictValues = deserialized as IDictionary<string, object>; if (dictValues != null) return new DynamicJsonObject(dictValues); var arrayValues = deserialized as object[]; if (arrayValues != null) { return new DynamicJsonArray(arrayValues); } } log.Error("Internal: Attempt to deserialize unrecognized JSON string as DynamicJsonObject"); } catch (Exception ex) { log.Error("Internal: exception deserializing JSON", ex); } return null; } override public object ReadFromStream(Type type, System.IO.Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger) { System.IO.StreamReader strdr = null; try { strdr = new System.IO.StreamReader(readStream); string json = strdr.ReadToEnd(); int maxLength = 33554432; //Int32.MaxValue; return Decode(json, maxLength); } catch (Exception ex) { log.Error("Internal: exception deserializing JSON", ex); } finally { if (strdr != null) { strdr.Dispose(); } } return null; } public DynamicJsonObjectFormatter() { SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json")); SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/json")); //SupportedEncodings.Add(new UTF8Encoding(false, true)); } public override bool CanReadType(Type type) { return (type == typeof(DynamicJsonObject)) || (type == typeof(DynamicJsonArray)); } public override bool CanWriteType(Type type) { return false; } } 可能还会给您带来大文件问题。它的大小限制可以通过

来控制
strdr.ReadToEnd()

在您的Web.config文件中。参见this article。)