上一篇使用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 " );
});
$( " #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添加属性,对参数进行预处理:
///
/// Filter处理参数测试方法
///
///
///
[JsonFilter( typeof (User), " user " )]
public ActionResult TestFilter(User user)
{
// 输入接收到的参数的json字符串
return Json(user, JsonRequestBehavior.AllowGet);
}
/// Filter处理参数测试方法
///
///
///
[JsonFilter( typeof (User), " user " )]
public ActionResult TestFilter(User user)
{
// 输入接收到的参数的json字符串
return Json(user, JsonRequestBehavior.AllowGet);
}
Filter代码,对参数反序列化,转换成对象:
///
/// json参数处理类
///
public class JsonFilterAttribute : ActionFilterAttribute
{
///
/// 构造方法
///
/// 参数类型,如果是数组请输入数组元素类型
/// 参数名称
public JsonFilterAttribute(Type type, string modelName)
{
DataType = type;
ModelName = modelName;
}
protected Type DataType { get ; set ; }
protected string ModelName { get ; set ; }
///
/// 参数转换处理
///
///
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);
}
}
}
/// json参数处理类
///
public class JsonFilterAttribute : ActionFilterAttribute
{
///
/// 构造方法
///
/// 参数类型,如果是数组请输入数组元素类型
/// 参数名称
public JsonFilterAttribute(Type type, string modelName)
{
DataType = type;
ModelName = modelName;
}
protected Type DataType { get ; set ; }
protected string ModelName { get ; set ; }
///
/// 参数转换处理
///
///
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
或许有更好的方式可以解决,但是我没发现。