使用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 相关文章推荐
jquery 插件开发 extjs中的extend用法小结
Jan 04 Javascript
js实现多选项切换导航菜单的方法
Feb 06 Javascript
举例讲解AngularJS中的模块
Jun 17 Javascript
Node.js+Express配置入门教程
May 19 Javascript
bootstrapvalidator之API学习教程
Jun 29 Javascript
react-native 完整实现登录功能的示例代码
Sep 11 Javascript
vue mint-ui 实现省市区街道4级联动示例(仿淘宝京东收货地址4级联动)
Oct 16 Javascript
详解如何优雅地在React项目中使用Redux
Dec 28 Javascript
JavaScript基于对象方法实现数组去重及排序操作示例
Jul 10 Javascript
浅谈Vue为什么不能检测数组变动
Oct 14 Javascript
Vue.js组件通信之自定义事件详解
Oct 19 Javascript
vue element 中的table动态渲染实现(动态表头)
Nov 21 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
打造计数器DIY三步曲(上)
2006/10/09 PHP
PHP中实现汉字转区位码应用源码实例解析
2010/06/14 PHP
php中的三元运算符使用说明
2011/07/03 PHP
php简单的留言板与回复功能具体实现
2014/02/19 PHP
PHP数据库表操作的封装类及用法实例详解
2016/07/12 PHP
PHP微信发送推送消息乱码的解决方法
2019/02/28 PHP
laravel-admin 管理平台获取当前登陆用户信息的例子
2019/10/08 PHP
jQuery 自动增长的文本输入框实现代码
2010/04/02 Javascript
js获取网页高度(详细整理)
2012/12/28 Javascript
javascript实现简单的分页特效
2015/08/12 Javascript
Javascript removeChild()删除节点及删除子节点的方法
2015/12/27 Javascript
浅谈js内置对象Math的属性和方法(推荐)
2016/09/19 Javascript
Jquery AJAX POST与GET之间的区别详细介绍
2016/10/17 Javascript
详解小程序缓存插件(mrc)
2018/08/17 Javascript
解决vuejs项目里css引用背景图片不能显示的问题
2018/09/13 Javascript
jQuery表单元素过滤选择器用法实例分析
2019/02/20 jQuery
通过实例解析chrome如何在mac环境中安装vue-devtools插件
2020/07/10 Javascript
py中的目录与文件判别代码
2008/07/16 Python
python实现一次创建多级目录的方法
2015/05/15 Python
selenium+python设置爬虫代理IP的方法
2018/11/29 Python
python在TXT文件中按照某一字符串取出该字符串所在的行方法
2018/12/10 Python
Python字典遍历操作实例小结
2019/03/05 Python
Windows上安装tensorflow  详细教程(图文详解)
2020/02/04 Python
python读取与处理netcdf数据方式
2020/02/14 Python
python传到前端的数据,双引号被转义的问题
2020/04/03 Python
灵活运用CSS3特性绘制简易版围棋效果
2016/09/28 HTML / CSS
法国购买二手电子产品网站:Asgoodasnew
2020/03/27 全球购物
大学生就业求职信
2014/06/12 职场文书
群众路线党员个人整改措施
2014/10/27 职场文书
2014年政务公开工作总结
2014/12/09 职场文书
婚礼答谢词
2015/01/04 职场文书
大学生入党群众意见书
2015/06/02 职场文书
企业宣传稿范文
2015/07/23 职场文书
python使用glob检索文件的操作
2021/05/20 Python
Win10 heic文件怎么打开 ? Win10 heic文件打开教程
2022/04/06 数码科技
Python中itertools库的四个函数介绍
2022/04/06 Python