如何使用jQuery向asp.net Mvc传递复杂json数据-Filter篇?

上一篇使用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>,只能使用普通数组方式。

或许有更好的方式可以解决,但是我没发现。