使用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实现自定义对话框的代码
Jun 15 Javascript
通过js动态操作table(新增,删除相关列信息)
May 23 Javascript
使用jquery清空、复位整个输入域
Apr 02 Javascript
jQuery实现右键菜单、遮罩等效果代码
Sep 27 Javascript
微信小程序 教程之小程序配置
Oct 17 Javascript
Angular 常用指令实例总结整理
Dec 13 Javascript
jQuery选择器之表单元素选择器详解
Sep 19 jQuery
vue2中使用sass并配置全局的sass样式变量的方法
Sep 04 Javascript
深入浅析js原型链和vue构造函数
Oct 25 Javascript
详解vue中axios请求的封装
Apr 08 Javascript
Vue中keep-alive的两种应用方式
Jul 15 Javascript
three.js 如何制作魔方
Jul 31 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
PHP开发中四种查询返回结果分析
2011/01/02 PHP
php把session写入数据库示例
2014/02/26 PHP
PHP基于MySQL数据库实现对象持久层的方法
2015/06/17 PHP
Linux环境下php实现给网站截图的方法
2016/05/03 PHP
javascript创建函数的20种方式汇总
2015/06/23 Javascript
jQuery的bind()方法使用详解
2015/07/15 Javascript
javascript实现类似java中getClass()得到对象类名的方法
2015/07/27 Javascript
基于jQuery实现的双11天猫拆红包抽奖效果
2015/12/01 Javascript
D3.js实现文本的换行详解
2016/10/14 Javascript
一道面试题引发的对javascript类型转换的思考
2017/03/06 Javascript
jquery中$.fn和图片滚动效果实现的必备知识总结
2017/04/21 jQuery
Vue2.0实现将页面中表格数据导出excel的实例
2017/08/09 Javascript
Angular 5.0 来了! 有这些大变化
2017/11/15 Javascript
JavaScript new对象的四个过程实例浅析
2018/07/31 Javascript
js实现点击展开隐藏效果(实例代码)
2018/09/28 Javascript
jQuery+Ajax+js实现请求json格式数据并渲染到html页面操作示例
2020/06/02 jQuery
JavaScript仿京东轮播图效果
2021/02/25 Javascript
在Python的Django框架中加载模版的方法
2015/07/16 Python
Python中函数eval和ast.literal_eval的区别详解
2017/08/10 Python
对numpy中数组元素的统一赋值实例
2018/04/04 Python
Python3.5内置模块之shelve模块、xml模块、configparser模块、hashlib、hmac模块用法分析
2019/04/27 Python
基于python实现从尾到头打印链表
2019/11/02 Python
Python decorator拦截器代码实例解析
2020/04/04 Python
浅谈CSS3特性查询(Feature Query: @supports)功能简介
2017/07/31 HTML / CSS
俄罗斯在线购买飞机票、火车票、巴士票网站:Tutu.ru
2020/03/16 全球购物
北承题目(C++)
2012/05/16 面试题
自我评价的正确写法
2013/09/19 职场文书
护理毕业生自我鉴定
2014/02/11 职场文书
小学优秀班干部事迹材料
2014/05/25 职场文书
寒山寺导游词
2015/02/03 职场文书
课外活动总结
2015/02/04 职场文书
英语教师个人总结
2015/02/09 职场文书
特此通知格式
2015/04/27 职场文书
教师远程研修感悟
2015/11/18 职场文书
《认识钟表》教学反思
2016/02/16 职场文书
使用 MybatisPlus 连接 SqlServer 数据库解决 OFFSET 分页问题
2022/04/22 SQL Server