上一篇使用ModelBinder解决了asp.net Mvc下接收使用jQuery异步提交复杂对象参数的问题;
在asp.net Mvc框架下,解决问题的方法并不是唯一的,只要在Action方法真正本调用之前,对Context.ActionParameters对象中的参数进行处理,就能解决此问题。
下面的代码是使用ActionFilter处理参数。
首先,把要提交的对象参数序列化成字符串,再异步提交:
/*
按钮点击事件
*/
$(
"
#btn_post_test
"
).click(
function
() {
var
data
=
{
UserId:
"
11
"
,
UserName: { FirstName:
"
323
"
, LastName:
"
2323
"
},
Keys: [
"
xiaoming
"
,
"
xiaohong
"
]
};
$.post(
"
Home/TestFilter
"
, { user: String.toSerialize(data) },
function
(text) {
alert(String.toSerialize(text));
},
"
json
"
);
});
在Action添加属性,对参数进行预处理:
///
<summary>
///
Filter处理参数测试方法
///
</summary>
///
<param name="user"></param>
///
<returns></returns>
[JsonFilter(
typeof
(User),
"
user
"
)]
public
ActionResult TestFilter(User user)
{
//
输入接收到的参数的json字符串
return
Json(user, JsonRequestBehavior.AllowGet);
}
Filter代码,对参数反序列化,转换成对象:
///
<summary>
///
json参数处理类
///
</summary>
public
class
JsonFilterAttribute : ActionFilterAttribute
{
///
<summary>
///
构造方法
///
</summary>
///
<param name="type">
参数类型,如果是数组请输入数组元素类型
</param>
///
<param name="modelName">
参数名称
</param>
public
JsonFilterAttribute(Type type,
string
modelName)
{
DataType
=
type;
ModelName
=
modelName;
}
protected
Type DataType {
get
;
set
; }
protected
string
ModelName {
get
;
set
; }
///
<summary>
///
参数转换处理
///
</summary>
///
<param name="filterContext"></param>
public
override
void
OnActionExecuting(ActionExecutingContext filterContext)
{
//
获取客户端提交的字符串
string
json
=
filterContext.HttpContext.Request.Form[ModelName];
//
判断提交对象是object对象还是Array对象
if
(json.StartsWith(
"
{
"
)
&&
json.EndsWith(
"
}
"
))
{
//
object对象反序列化
JObject jsonBody
=
JObject.Parse(json);
JsonSerializer js
=
new
JsonSerializer();
object
obj
=
js.Deserialize(jsonBody.CreateReader(), DataType);
filterContext.ActionParameters[ModelName]
=
obj;
}
if
(json.StartsWith(
"
[
"
)
&&
json.EndsWith(
"
]
"
))
{
//
Array对象反序列化
ArrayList list
=
new
ArrayList();
JArray jsonRsp
=
JArray.Parse(json);
if
(jsonRsp
!=
null
)
{
for
(
int
i
=
0
; i
<
jsonRsp.Count; i
++
)
{
JsonSerializer js
=
new
JsonSerializer();
object
obj
=
js.Deserialize(jsonRsp[i].CreateReader(), DataType);
list.Add(obj);
}
}
filterContext.ActionParameters[ModelName]
=
list.ToArray(DataType);
}
}
}
使用Filter处理参数与ModelBinder的方式有一个不一致的地方,由于Filter不能使用泛型,接收数组参数是,不能转换成泛型数组对象IList<T>,只能使用普通数组方式。
或许有更好的方式可以解决,但是我没发现。