使用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 相关文章推荐
js setTimeout()函数介绍及应用以倒计时为例
Dec 12 Javascript
Jquery 获取指定标签的对象及属性的设置与移除
May 29 Javascript
js代码实现的加入收藏效果并兼容主流浏览器
Jun 23 Javascript
拥Bootstrap入怀——导航栏篇
May 30 Javascript
jQuery学习笔记——jqGrid的使用记录(实现分页、搜索功能)
Nov 09 Javascript
QRCode.js:基于JQuery的生成二维码JS库的使用
Jun 23 jQuery
node.js文件上传重命名以及移动位置的示例代码
Jan 19 Javascript
vue+webpack实现异步加载三种用法示例详解
Apr 24 Javascript
分享5个好用的javascript文件上传插件
Sep 16 Javascript
微信小程序登录数据解密及状态维持实例详解
May 06 Javascript
vue中 v-for循环的用法详解
Feb 19 Javascript
jQuery实现的解析本地 XML 文档操作示例
Apr 30 jQuery
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 PHP
php中通过curl模拟登陆discuz论坛的实现代码
2012/02/16 PHP
header跳转和include包含问题详解
2012/09/08 PHP
PHP OPP机制和模式简介(抽象类、接口和契约式编程)
2014/06/09 PHP
PHP中怎样防止SQL注入分析
2014/10/23 PHP
PHP开启opcache提升代码性能
2015/04/26 PHP
CodeIgniter多语言实现方法详解
2016/01/20 PHP
RR vs IO BO3 第二场2.13
2021/03/10 DOTA
jQuery 选择器理解
2010/03/16 Javascript
jQuery源码分析-04 选择器-Sizzle-工作原理分析
2011/11/14 Javascript
js 遍历对象的属性的代码
2011/12/29 Javascript
jquery自动填充勾选框即把勾选框打上true
2014/03/24 Javascript
js 操作符汇总
2014/11/08 Javascript
NodeJs中的VM模块详解
2015/05/06 NodeJs
jquery动态创建div与input的实例代码
2016/10/12 Javascript
详解JS几种变量交换方式以及性能分析对比
2016/11/25 Javascript
详解js的六大数据类型
2016/12/27 Javascript
如何将你的AngularJS1.x应用迁移至React的方法
2018/02/01 Javascript
解决vue-cli单页面手机应用input点击手机端虚拟键盘弹出盖住input问题
2018/08/25 Javascript
js中获取URL参数的共用方法getRequest()方法实例详解
2018/10/24 Javascript
深入浅出vue图片路径的实现
2019/09/04 Javascript
[04:11]2014DOTA2国际邀请赛 CIS遗憾出局梦想不灭
2014/07/09 DOTA
Python中支持向量机SVM的使用方法详解
2017/12/26 Python
树莓派与PC端在局域网内运用python实现即时通讯
2019/06/22 Python
python3获取当前目录的实现方法
2019/07/29 Python
Pytorch .pth权重文件的使用解析
2020/02/14 Python
python实现简单的五子棋游戏
2020/09/01 Python
python使用smtplib模块发送邮件
2020/12/17 Python
用pushplus+python监控亚马逊到货动态推送微信
2021/01/29 Python
如何用 Python 制作 GitHub 消息助手
2021/02/20 Python
世界上最大的乐器零售商:Guitar Center
2017/11/07 全球购物
暑期培训班招生方案
2014/08/26 职场文书
大学生考试作弊检讨书1000字
2014/10/14 职场文书
2014年中职班主任工作总结
2014/12/16 职场文书
2015年维修工作总结
2015/04/25 职场文书
浪漫婚礼主持词开场白
2015/11/24 职场文书