jQuery提供的ajax方法能很方便的实现客户端与服务器的异步交互,在asp.net mvc 框架使用jQuery能很方便地异步获取提交数据,给用户提供更好的体验!
调用jQuery的ajax方法时,jQuery会根据post或者get协议对参数data进行序列化;
如果提交的数据使用复杂的json数据,例如:
{userId:32323,userName:{firstName:"李",lastName:"李大嘴"}}
那么服务器是无法正常接收到完整的参数,因为jQuery对data的序列化,是使用了键值对拼装的方式;
参数拼装成 userId=32323&userName=object ; userName所指向的对象被序列化成字符串"object"
如何才能把一个复杂的object对象提交到后台的action参数中呢?
首先,解决jQuery对于参数序列化的问题:
1
/*
对象序列化为字符串
*/
2
String.toSerialize
=
function
(obj) {
3
var
ransferCharForJavascript
=
function
(s) {
4
var
newStr
=
s.replace(
5
/
[\x26\x27\x3C\x3E\x0D\x0A\x22\x2C\x5C\x00]
/
g,
6
function
(c) {
7
ascii
=
c.charCodeAt(
0
)
8
return
'
\\u00
'
+
(ascii
<
16
?
'
0
'
+
ascii.toString(
16
) : ascii.toString(
16
))
9
}
10
);
11
return
newStr;
12
}
13
if
(obj
==
null
) {
14
return
null
15
}
16
else
if
(obj.constructor
==
Array) {
17
var
builder
=
[];
18
builder.push(
"
[
"
);
19
for
(
var
index
in
obj) {
20
if
(
typeof
obj[index]
==
"
function
"
)
continue
;
21
if
(index
>
0
) builder.push(
"
,
"
);
22
builder.push(String.toSerialize(obj[index]));
23
}
24
builder.push(
"
]
"
);
25
return
builder.join(
""
);
26
}
27
else
if
(obj.constructor
==
Object) {
28
var
builder
=
[];
29
builder.push(
"
{
"
);
30
var
index
=
0
;
31
for
(
var
key
in
obj) {
32
if
(
typeof
obj[key]
==
"
function
"
)
continue
;
33
if
(index
>
0
) builder.push(
"
,
"
);
34
builder.push(String.format(
"
\
"
{
0
}\
"
:{1}
"
, key, String.toSerialize(obj[key])));
35
index
++
;
36
}
37
builder.push(
"
}
"
);
38
return
builder.join(
""
);
39
}
40
else
if
(obj.constructor
==
Boolean) {
41
return
obj.toString();
42
}
43
else
if
(obj.constructor
==
Number) {
44
return
obj.toString();
45
}
46
else
if
(obj.constructor
==
String) {
47
return
String.format(
'
"{0}"
'
, ransferCharForJavascript(obj));
48
}
49
else
if
(obj.constructor
==
Date) {
50
return
String.format(
'
{"__DataType":"Date","__thisue":{0}}
'
, obj.getTime()
-
(
new
Date(
1970
,
0
,
1
,
0
,
0
,
0
)).getTime());
51
}
52
else
if
(
this
.toString
!=
undefined) {
53
return
String.toSerialize(obj);
54
}
55
}
56
jQuery异步请求:
1
$(
function
() {
2
/*
按钮点击事件
*/
3
$(
"
#btn_post_test
"
).click(
function
() {
4
var
data
=
[
5
{ UserId:
"
11
"
, UserName: { FirstName:
"
323
"
, LastName:
"
2323
"
}, Keys: [
"
xiaoming
"
,
"
xiaohong
"
] },
6
{ UserId:
"
22
"
, UserName: { FirstName:
"
323
"
, LastName:
"
2323
"
}, Keys: [
"
xiaoming
"
,
"
xiaohong
"
] },
7
{ UserId:
"
33
"
, UserName: { FirstName:
"
323
"
, LastName:
"
2323
"
}, Keys: [
"
xiaoming
"
,
"
xiaohong
"
] }
8
];
9
10
$.post(
"
Home/Test
"
, { users: String.toSerialize(data) },
function
(text) {
11
alert(String.toSerialize(text));
12
},
"
json
"
);
13
});
14
});
点击按钮提交数据,监控浏览器,可以发现提交的数据是json对象的序列化后的内容:
1
POST /Home/Test HTTP/1.1
2
x-requested-with: XMLHttpRequest
3
Accept-Language: zh-cn
4
Referer: http://localhost:3149/test.html
5
Accept: application/json, text/javascript, */*
6
Content-Type: application/x-www-form-urlencoded
7
Accept-Encoding: gzip, deflate
8
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C; .NET4.0E)
9
Host: localhost:3149
10
Content-Length: 501
11
Connection: Keep-Alive
12
Cache-Control: no-cache
13
Cookie: CookieGlobalLoginUserID=16063
14
15
users=%5B%7B%22UserId%22%3A%2211%22%2C%22Name%22%3A%7B%22FirstName%22%3A%22323%22%2C%22LastName%22%3A%222323%22%7D%2C%22Keys%22%3A%5B%22xiaoming%22%2C%22xiaohong%22%5D%7D%2C%7B%22UserId%22%3A%2222%22%2C%22Name%22%3A%7B%22FirstName%22%3A%22323%22%2C%22LastName%22%3A%222323%22%7D%2C%22Keys%22%3A%5B%22xiaoming%22%2C%22xiaohong%22%5D%7D%2C%7B%22UserId%22%3A%2233%22%2C%22Name%22%3A%7B%22FirstName%22%3A%22323%22%2C%22LastName%22%3A%222323%22%7D%2C%22Keys%22%3A%5B%22xiaoming%22%2C%22xiaohong%22%5D%7D%5D
其次,后台服务器处理参数绑定:
1
using
System.Collections.Generic;
2
using
System.Web.Mvc;
3
using
Newtonsoft.Json;
4
using
Newtonsoft.Json.Linq;
5
6
namespace
WebOS.Controllers
7
{
8
[HandleError]
9
public
class
HomeController : Controller
10
{
11
///
<summary>
12
///
测试方法
13
///
</summary>
14
///
<param name="users">
用户数据
</param>
15
///
<returns>
提交的用户数组
</returns>
16
public
ActionResult Test([ModelBinder(
typeof
(JsonBinder
<
User
>
))]List
<
User
>
users)
17
{
18
return
Json(users, JsonRequestBehavior.AllowGet);
19
}
20
21
}
22
///
<summary>
23
///
对象实体
24
///
</summary>
25
[JsonObject]
26
public
class
User
27
{
28
[JsonProperty(
"
UserName
"
)]
29
public
UserName Name {
get
;
set
; }
30
[JsonProperty(
"
UserId
"
)]
31
public
string
UserId {
get
;
set
; }
32
[JsonProperty(
"
Keys
"
)]
33
public
List
<
string
>
Keys {
get
;
set
; }
34
35
36
}
37
///
<summary>
38
///
对象实体
39
///
</summary>
40
[JsonObject]
41
public
class
UserName
42
{
43
[JsonProperty(
"
FirstName
"
)]
44
public
string
FirstName {
get
;
set
; }
45
[JsonProperty(
"
LastName
"
)]
46
public
string
LastName {
get
;
set
; }
47
48
}
49
///
<summary>
50
///
Json数据绑定类
51
///
</summary>
52
///
<typeparam name="T"></typeparam>
53
public
class
JsonBinder
<
T
>
: IModelBinder
54
{
55
56
public
object
BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
57
{
58
//
从请求中获取提交的参数数据
59
var json
=
controllerContext.HttpContext.Request.Form[bindingContext.ModelName]
as
string
;
60
//
提交参数是对象
61
if
(json.StartsWith(
"
{
"
)
&&
json.EndsWith(
"
}
"
))
62
{
63
JObject jsonBody
=
JObject.Parse(json);
64
JsonSerializer js
=
new
JsonSerializer();
65
object
obj
=
js.Deserialize(jsonBody.CreateReader(),
typeof
(T));
66
return
obj;
67
}
68
//
提交参数是数组
69
if
(json.StartsWith(
"
[
"
)
&&
json.EndsWith(
"
]
"
))
70
{
71
IList
<
T
>
list
=
new
List
<
T
>
();
72
JArray jsonRsp
=
JArray.Parse(json);
73
74
if
(jsonRsp
!=
null
)
75
{
76
for
(
int
i
=
0
; i
<
jsonRsp.Count; i
++
)
77
{
78
JsonSerializer js
=
new
JsonSerializer();
79
object
obj
=
js.Deserialize(jsonRsp[i].CreateReader(),
typeof
(T));
80
list.Add((T)obj);
81
}
82
}
83
return
list;
84
}
85
return
null
;
86
}
87
}
88
}
89
前端获取到后台返回的数据,结果就是用户提交的数据:
后台json反序列化使用了Newtonsoft.Json 组件,有关资料请参考:http://james.newtonking.com/