使用jQuery向asp.net Mvc传递复杂json数据-ModelBinder篇


Posted in Javascript onMay 07, 2010

调用jQuery的ajax方法时,jQuery会根据post或者get协议对参数data进行序列化;

如果提交的数据使用复杂的json数据,例如:

{userId:32323,userName:{firstName:"李",lastName:"李大嘴"}}

那么服务器是无法正常接收到完整的参数,因为jQuery对data的序列化,是使用了键值对拼装的方式;

参数拼装成 userId=32323&userName=object ; userName所指向的对象被序列化成字符串"object"

如何才能把一个复杂的object对象提交到后台的action参数中呢?

首先,解决jQuery对于参数序列化的问题:

/*对象序列化为字符串*/ 
String.toSerialize = function(obj) { 
var ransferCharForJavascript = function(s) { 
var newStr = s.replace( 
/[\x26\x27\x3C\x3E\x0D\x0A\x22\x2C\x5C\x00]/g, 
function(c) { 
ascii = c.charCodeAt(0) 
return '\\u00' + (ascii < 16 ? '0' + ascii.toString(16) : ascii.toString(16)) 
} 
); 
return newStr; 
} 
if (obj == null) { 
return null 
} 
else if (obj.constructor == Array) { 
var builder = []; 
builder.push("["); 
for (var index in obj) { 
if (typeof obj[index] == "function") continue; 
if (index > 0) builder.push(","); 
builder.push(String.toSerialize(obj[index])); 
} 
builder.push("]"); 
return builder.join(""); 
} 
else if (obj.constructor == Object) { 
var builder = []; 
builder.push("{"); 
var index = 0; 
for (var key in obj) { 
if (typeof obj[key] == "function") continue; 
if (index > 0) builder.push(","); 
builder.push(String.format("\"{0}\":{1}", key, String.toSerialize(obj[key]))); 
index++; 
} 
builder.push("}"); 
return builder.join(""); 
} 
else if (obj.constructor == Boolean) { 
return obj.toString(); 
} 
else if (obj.constructor == Number) { 
return obj.toString(); 
} 
else if (obj.constructor == String) { 
return String.format('"{0}"', ransferCharForJavascript(obj)); 
} 
else if (obj.constructor == Date) { 
return String.format('{"__DataType":"Date","__thisue":{0}}', obj.getTime() - (new Date(1970, 0, 1, 0, 0, 0)).getTime()); 
} 
else if (this.toString != undefined) { 
return String.toSerialize(obj); 
} 
}

jQuery异步请求:

$(function() { 
/*按钮点击事件*/ 
$("#btn_post_test").click(function() { 
var data = [ 
{ UserId: "11", UserName: { FirstName: "323", LastName: "2323" }, Keys: ["xiaoming", "xiaohong"] }, 
{ UserId: "22", UserName: { FirstName: "323", LastName: "2323" }, Keys: ["xiaoming", "xiaohong"] }, 
{ UserId: "33", UserName: { FirstName: "323", LastName: "2323" }, Keys: ["xiaoming", "xiaohong"] } 
]; 
$.post("Home/Test", { users: String.toSerialize(data) }, function(text) { 
alert(String.toSerialize(text)); 
}, "json"); 
}); 
});

点击按钮提交数据,监控浏览器,可以发现提交的数据是json对象的序列化后的内容:
POST /Home/Test HTTP/1.1 
x-requested-with: XMLHttpRequest 
Accept-Language: zh-cn 
Referer: http://localhost:3149/test.html 
Accept: application/json, text/javascript, */* 
Content-Type: application/x-www-form-urlencoded 
Accept-Encoding: gzip, deflate 
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) 
Host: localhost:3149 
Content-Length: 501 
Connection: Keep-Alive 
Cache-Control: no-cache 
Cookie: CookieGlobalLoginUserID=16063 
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

其次,后台服务器处理参数绑定:
using System.Collections.Generic; 
using System.Web.Mvc; 
using Newtonsoft.Json; 
using Newtonsoft.Json.Linq; 
namespace WebOS.Controllers 
{ 
[HandleError] 
public class HomeController : Controller 
{ 
/// <summary> 
/// 测试方法 
/// </summary> 
/// <param name="users">用户数据</param> 
/// <returns>提交的用户数组</returns> 
public ActionResult Test([ModelBinder(typeof(JsonBinder<User>))]List<User> users) 
{ 
return Json(users, JsonRequestBehavior.AllowGet); 
} 
} 
/// <summary> 
/// 对象实体 
/// </summary> 
[JsonObject] 
public class User 
{ 
[JsonProperty("UserName")] 
public UserName Name { get; set; } 
[JsonProperty("UserId")] 
public string UserId { get; set; } 
[JsonProperty("Keys")] 
public List<string> Keys { get; set; } 
} 
/// <summary> 
/// 对象实体 
/// </summary> 
[JsonObject] 
public class UserName 
{ 
[JsonProperty("FirstName")] 
public string FirstName { get; set; } 
[JsonProperty("LastName")] 
public string LastName { get; set; } 
} 
/// <summary> 
/// Json数据绑定类 
/// </summary> 
/// <typeparam name="T"></typeparam> 
public class JsonBinder<T> : IModelBinder 
{ 
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
{ 
//从请求中获取提交的参数数据 
var json = controllerContext.HttpContext.Request.Form[bindingContext.ModelName] as string; 
//提交参数是对象 
if (json.StartsWith("{") && json.EndsWith("}")) 
{ 
JObject jsonBody = JObject.Parse(json); 
JsonSerializer js = new JsonSerializer(); 
object obj = js.Deserialize(jsonBody.CreateReader(), typeof(T)); 
return obj; 
} 
//提交参数是数组 
if (json.StartsWith("[") && json.EndsWith("]")) 
{ 
IList<T> list = new List<T>(); 
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(), typeof(T)); 
list.Add((T)obj); 
} 
} 
return list; 
} 
return null; 
} 
} 
}

前端获取到后台返回的数据,结果就是用户提交的数据:
使用jQuery向asp.net Mvc传递复杂json数据-ModelBinder篇
后台json反序列化使用了Newtonsoft.Json 组件,有关资料请参考:http://james.newtonking.com/
Javascript 相关文章推荐
javascript 语法基础 想学习js的朋友可以看看
Dec 16 Javascript
jquery tab插件制作实现代码
Jun 22 Javascript
asp.net 30分钟掌握无刷新 Repeater
Sep 16 Javascript
jquery slibings选取同级其他元素的实现代码
Nov 15 Javascript
JavaScript中的常见问题解决方法(乱码,IE缓存,代理)
Nov 28 Javascript
jquery操作复选框(checkbox)的12个小技巧总结
Feb 04 Javascript
javascript实现json页面分页实例代码
Feb 20 Javascript
javascript Array 数组常用方法
Apr 05 Javascript
Bootstrap源码解读网格系统(3)
Dec 22 Javascript
JavaScript实现前端分页控件
Apr 19 Javascript
Angular4表单验证代码详解
Sep 03 Javascript
JS实现导出Excel的五种方法详解【附源码下载】
Mar 15 Javascript
javascript 通用简单的table选项卡实现
May 07 #Javascript
jQuery 创建Dom元素
May 07 #Javascript
10个基于jQuery或JavaScript的WYSIWYG 编辑器整理
May 06 #Javascript
jQuery Selector选择器小结
May 06 #Javascript
Jquery 动态添加按钮实现代码
May 06 #Javascript
jquery DOM操作 基于命令改变页面
May 06 #Javascript
JQuery 学习笔记01 JQuery初接触
May 06 #Javascript
You might like
正则表达式语法
2006/10/09 Javascript
PHP数据库万能引擎类adodb配置使用以及实例集锦
2014/06/12 PHP
php将html转成wml的WAP标记语言实例
2015/07/08 PHP
PHP获取二维数组中某一列的值集合
2015/12/25 PHP
php 数组字符串搜索array_search技巧
2016/07/05 PHP
php的扩展写法总结
2019/05/14 PHP
Yii框架连表查询操作示例
2019/09/06 PHP
laravel框架select2多选插件初始化默认选中项操作示例
2020/02/18 PHP
javascript(jquery)利用函数修改全局变量的代码
2009/11/02 Javascript
JQuery中SetTimeOut传参问题探讨
2013/05/10 Javascript
js调用AJAX时Get和post的乱码解决方法
2013/06/04 Javascript
JavaScript中pop()方法的使用教程
2015/06/09 Javascript
javascript字符串循环匹配实例分析
2015/07/17 Javascript
js时间戳转为日期格式的方法
2015/12/28 Javascript
Bootstrap布局之栅格系统详解
2016/06/13 Javascript
详解VueJS 数据驱动和依赖追踪分析
2017/07/26 Javascript
微信小程序中遇到的iOS兼容性问题小结
2018/11/14 Javascript
elementUI select组件默认选中效果实现的方法
2019/03/25 Javascript
JavaScript实现文件下载并重命名代码实例
2019/12/12 Javascript
Python的Flask框架中集成CKeditor富文本编辑器的教程
2016/06/13 Python
Python编程实现两个文件夹里文件的对比功能示例【包含内容的对比】
2017/06/20 Python
Python调用ctypes使用C函数printf的方法
2017/08/23 Python
Python3实现计算两个数组的交集算法示例
2019/04/03 Python
python中对数据进行各种排序的方法
2019/07/02 Python
python 使用matplotlib 实现从文件中读取x,y坐标的可视化方法
2019/07/04 Python
浅谈Python_Openpyxl使用(最全总结)
2019/09/05 Python
Python 实现将numpy中的nan和inf,nan替换成对应的均值
2020/06/08 Python
Django实现内容缓存实例方法
2020/06/30 Python
Python新建项目自动添加介绍和utf-8编码的方法
2020/12/26 Python
HTML5 history新特性pushState、replaceState及两者的区别
2015/12/26 HTML / CSS
美国最大和最受信任的二手轮胎商店:Bestusedtires.com
2020/06/02 全球购物
中餐厅经理岗位职责
2014/04/11 职场文书
建筑横幅标语
2014/10/09 职场文书
大学生旷课检讨书1000字
2015/02/19 职场文书
教你用Python+selenium搭建自动化测试环境
2021/06/18 Python
vue实现列表垂直无缝滚动
2022/04/08 Vue.js