博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.NET MVC JSON JavaScriptSerializer 字符串的长度超过 maxJsonLength 值问题的解决
阅读量:7047 次
发布时间:2019-06-28

本文共 10034 字,大约阅读时间需要 33 分钟。

1 [ArgumentException: 使用 JSON JavaScriptSerializer 序列化或还原序列化期间发生错误。字符串的长度超过在 maxJsonLength 属性上设定的值。2 参数名称: input]3    System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit) +1684    System.Web.Mvc.JsonValueProviderFactory.GetDeserializedObject(ControllerContext controllerContext) +2135    System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext) +166    System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext) +697    System.Web.Mvc.ControllerBase.get_ValueProvider() +30  

 

于前端 Post 到 Action 的参数太大,超过了2M,还没进入后台的 Action 方法就报错了。这个问题困扰了很久,一直未解决。网上找了几个方法都无效。

在 web.config 中加入这些,没有作用:

 
1
2
3
4
<
appSettings
>
  
<
add
key="aspnet:MaxJsonDeserializerMembers" value="2147483647" />
  
<
add
key="aspnet:UpdatePanelMaxScriptLength" value="2147483647" />
</
appSettings
>

在 web.config 中加入这些,也没有作用:

 
1
2
3
4
5
6
7
8
<
system.web.extensions
>
  
<
scripting
>
    
<
webServices
>
      
<
jsonSerialization
maxJsonLength="2147483647">
      
</
jsonSerialization
>
    
</
webServices
>
  
</
scripting
>
</
system.web.extensions
>

仔细看了一下异常信息,发现,是在System.Web.Mvc.JsonValueProviderFactory 里调用的 JavaScriptSerializer:

于是查了一下 ,发现 JsonValueProviderFactory 在 System.Web.Mvc.dll 程序集里的:

反编译 System.Web.Mvc.dll 找到 JsonValueProviderFactory 类:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
using
System;
using
System.Collections;
using
System.Collections.Generic;
using
System.Collections.Specialized;
using
System.Configuration;
using
System.Globalization;
using
System.IO;
using
System.Web.Mvc.Properties;
using
System.Web.Script.Serialization;
namespace
System.Web.Mvc
{
    
public
sealed
class
JsonValueProviderFactory : ValueProviderFactory
    
{
        
private
class
EntryLimitedDictionary
        
{
            
private
static
int
_maximumDepth = JsonValueProviderFactory.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 > JsonValueProviderFactory.EntryLimitedDictionary._maximumDepth)
                
{
                    
throw
new
InvalidOperationException(MvcResources.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;
            
}
        
}
        
private
static
void
AddToBackingStore(JsonValueProviderFactory.EntryLimitedDictionary backingStore,
string
prefix,
object
value)
        
{
            
IDictionary<
string
,
object
> dictionary = value
as
IDictionary<
string
,
object
>;
            
if
(dictionary !=
null
)
            
{
                
foreach
(KeyValuePair<
string
,
object
> current
in
dictionary)
                
{
                    
JsonValueProviderFactory.AddToBackingStore(backingStore, JsonValueProviderFactory.MakePropertyKey(prefix, current.Key), current.Value);
                
}
                
return
;
            
}
            
IList list = value
as
IList;
            
if
(list !=
null
)
            
{
                
for
(
int
i = 0; i < list.Count; i++)
                
{
                    
JsonValueProviderFactory.AddToBackingStore(backingStore, JsonValueProviderFactory.MakeArrayKey(prefix, i), list[i]);
                
}
                
return
;
            
}
            
backingStore.Add(prefix, value);
        
}
        
private
static
object
GetDeserializedObject(ControllerContext controllerContext)
        
{
            
if
(!controllerContext.HttpContext.Request.ContentType.StartsWith(
"application/json"
, StringComparison.OrdinalIgnoreCase))
            
{
                
return
null
;
            
}
            
StreamReader streamReader =
new
StreamReader(controllerContext.HttpContext.Request.InputStream);
            
string
text = streamReader.ReadToEnd();
            
if
(
string
.IsNullOrEmpty(text))
            
{
                
return
null
;
            
}
            
// 问题就出在这里,没有给 javaScriptSerializer.MaxJsonLength 赋值,其默认值是 2097152 字节,即2M
            
JavaScriptSerializer javaScriptSerializer =
new
JavaScriptSerializer();
            
return
javaScriptSerializer.DeserializeObject(text);
        
}
        
public
override
IValueProvider GetValueProvider(ControllerContext controllerContext)
        
{
            
if
(controllerContext ==
null
)
            
{
                
throw
new
ArgumentNullException(
"controllerContext"
);
            
}
            
object
deserializedObject = JsonValueProviderFactory.GetDeserializedObject(controllerContext);
            
if
(deserializedObject ==
null
)
            
{
                
return
null
;
            
}
            
Dictionary<
string
,
object
> dictionary =
new
Dictionary<
string
,
object
>(StringComparer.OrdinalIgnoreCase);
            
JsonValueProviderFactory.EntryLimitedDictionary backingStore =
new
JsonValueProviderFactory.EntryLimitedDictionary(dictionary);
            
JsonValueProviderFactory.AddToBackingStore(backingStore,
string
.Empty, deserializedObject);
            
return
new
DictionaryValueProvider<
object
>(dictionary, CultureInfo.CurrentCulture);
        
}
        
private
static
string
MakeArrayKey(
string
prefix,
int
index)
        
{
            
return
prefix +
"["
+ index.ToString(CultureInfo.InvariantCulture) +
"]"
;
        
}
        
private
static
string
MakePropertyKey(
string
prefix,
string
propertyName)
        
{
            
if
(!
string
.IsNullOrEmpty(prefix))
            
{
                
return
prefix +
"."
+ propertyName;
            
}
            
return
propertyName;
        
}
    
}
}

在 JavaScriptSerializer 没有设置 MaxJsonLength,默认值是 2097152 字节,即2M。 

解决此问题的方法就是 把 javaScriptSerializer.MaxJsonLength = int.MaxValue; (int.MaxValue 值是 2147483647 字节,即2048M)

自己重写类 JsonValueProviderFactory 命名为 MyJsonValueProviderFactory:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
using
System;
using
System.Collections;
using
System.Collections.Generic;
using
System.Collections.Specialized;
using
System.Configuration;
using
System.Globalization;
using
System.IO;
using
System.Web.Mvc;
using
System.Web.Mvc.Properties;
using
System.Web.Script.Serialization;
namespace
XXX
{
    
public
sealed
class
MyJsonValueProviderFactory : ValueProviderFactory
    
{
        
private
class
EntryLimitedDictionary
        
{
            
private
static
int
_maximumDepth = 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 > _maximumDepth)
                
{
                    
//throw new InvalidOperationException(MvcResources.JsonValueProviderFactory_RequestTooLarge);
                    
throw
new
InvalidOperationException(
"itemCount is over maximumDepth"
);
                
}
                
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;
            
}
        
}
 
        
private
static
void
AddToBackingStore(EntryLimitedDictionary backingStore,
string
prefix,
object
value)
        
{
            
IDictionary<
string
,
object
> dictionary = value
as
IDictionary<
string
,
object
>;
            
if
(dictionary !=
null
)
            
{
                
foreach
(KeyValuePair<
string
,
object
> current
in
dictionary)
                
{
                    
AddToBackingStore(backingStore, MakePropertyKey(prefix, current.Key), current.Value);
                
}
                
return
;
            
}
            
IList list = value
as
IList;
            
if
(list !=
null
)
            
{
                
for
(
int
i = 0; i < list.Count; i++)
                
{
                    
AddToBackingStore(backingStore, MakeArrayKey(prefix, i), list[i]);
                
}
                
return
;
            
}
            
backingStore.Add(prefix, value);
        
}
 
        
private
static
object
GetDeserializedObject(ControllerContext controllerContext)
        
{
            
if
(!controllerContext.HttpContext.Request.ContentType.StartsWith(
"application/json"
, StringComparison.OrdinalIgnoreCase))
            
{
                
return
null
;
            
}
            
StreamReader streamReader =
new
StreamReader(controllerContext.HttpContext.Request.InputStream);
            
string
text = streamReader.ReadToEnd();
            
if
(
string
.IsNullOrEmpty(text))
            
{
                
return
null
;
            
}
            
JavaScriptSerializer javaScriptSerializer =
new
JavaScriptSerializer();
            
// 解决这个问题:
            
// 使用 JSON JavaScriptSerializer 序列化或还原序列化期间发生错误。字符串的长度超过在 maxJsonLength 属性上设定的值。
            
javaScriptSerializer.MaxJsonLength =
int
.MaxValue;
            
// ----------------------------------------
            
return
javaScriptSerializer.DeserializeObject(text);
        
}
 
        
public
override
IValueProvider GetValueProvider(ControllerContext controllerContext)
        
{
            
if
(controllerContext ==
null
)
            
{
                
throw
new
ArgumentNullException(
"controllerContext"
);
            
}
            
object
deserializedObject = GetDeserializedObject(controllerContext);
            
if
(deserializedObject ==
null
)
            
{
                
return
null
;
            
}
            
Dictionary<
string
,
object
> dictionary =
new
Dictionary<
string
,
object
>(StringComparer.OrdinalIgnoreCase);
            
EntryLimitedDictionary backingStore =
new
EntryLimitedDictionary(dictionary);
            
AddToBackingStore(backingStore,
string
.Empty, deserializedObject);
            
return
new
DictionaryValueProvider<
object
>(dictionary, CultureInfo.CurrentCulture);
        
}
 
        
private
static
string
MakeArrayKey(
string
prefix,
int
index)
        
{
            
return
prefix +
"["
+ index.ToString(CultureInfo.InvariantCulture) +
"]"
;
        
}
 
        
private
static
string
MakePropertyKey(
string
prefix,
string
propertyName)
        
{
            
if
(!
string
.IsNullOrEmpty(prefix))
            
{
                
return
prefix +
"."
+ propertyName;
            
}
            
return
propertyName;
        
}
    
}
}

然后在 Global.asax 中的 Application_Start() 方法里,加入如下代码,用 MyJsonValueProviderFactory 类代替 System.Web.Mvc.dll 程序集中的 JsonValueProviderFactory 类。

 
1
2
ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.OfType<JsonValueProviderFactory>().FirstOrDefault());
ValueProviderFactories.Factories.Add(
new
MyJsonValueProviderFactory());

 至此,.NET MVC 超出 maxJsonLength 的问题终于解决了!

转载地址:http://qazol.baihongyu.com/

你可能感兴趣的文章
[置顶] webservice系列3---chain
查看>>
hibernate XML配置文件》cfg
查看>>
ExtJS2.0实用简明教程 - ExtJS的组件
查看>>
员工离职原因,只有两点最真实,其他都是扯淡!
查看>>
删除dataGridview中选中的一行或多行
查看>>
使用包ldap3进行Python的LDAP操作
查看>>
#4 Move Find into Model
查看>>
html5 canvas模拟的爆炸效果
查看>>
nodejs中几个excel模块的简单对比
查看>>
面向对象三大特征
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
Ansible学习01-常用模块
查看>>
Java基础学习总结(21)——数组
查看>>
Redis——订阅
查看>>
RAID磁盘阵列笔记
查看>>
CloudStack Site-to-Site & Remote Access ××× 应用案例
查看>>
php过滤提交数据 防止sql注入***(6)
查看>>
flv视频网站制作 使用Flex和PHP创建自己的视频应用
查看>>
用Windows Server 2003配置×××
查看>>