使用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 form 验证函数 当前比较流行的错误提示
Jun 23 Javascript
关于JS控制代码暂停的实现方法分享
Oct 11 Javascript
Jquery为单选框checkbox绑定单击click事件
Dec 18 Javascript
JAVASCRIPT模式窗口中下载文件无法接收iframe的流
Oct 11 Javascript
利用cookie记住背景颜色示例代码
Nov 04 Javascript
通过JS动态创建一个html DOM元素并显示
Oct 15 Javascript
jquery渐隐渐显的图片幻灯闪烁切换实现方法
Feb 26 Javascript
js格式化时间的方法
Dec 18 Javascript
用原生js统计文本行数的简单示例
Aug 19 Javascript
详解Vue 开发模式下跨域问题
Jun 06 Javascript
js断点调试心得分享(必看篇)
Dec 08 Javascript
webpack中的模式(mode)使用详解
Feb 20 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
外媒评选出10支2020年最受欢迎的Dota2战队
2021/03/05 DOTA
yii2中LinkPager增加总页数和总记录数的实例
2017/08/28 PHP
laravel项目利用twemproxy部署redis集群的完整步骤
2018/05/11 PHP
PHP+Ajax简单get验证操作示例
2019/03/02 PHP
关于laravel 日志写入失败问题汇总
2019/10/17 PHP
tp5修改(实现即点即改)
2019/10/18 PHP
JavaScript判断按钮被点击的方法
2015/12/13 Javascript
JS+CSS实现DIV层的展开、收缩效果
2016/01/28 Javascript
js 判断附件后缀的简单实现方法
2016/10/11 Javascript
浅谈js中的变量名和函数名重名
2017/02/13 Javascript
Vue实现路由跳转和嵌套
2017/06/20 Javascript
了解javascript中变量及函数的提升
2019/05/27 Javascript
Vue.js组件props数据验证实现详解
2019/10/19 Javascript
详解Vue串联过滤器的使用场景
2020/04/30 Javascript
js实现表单项的全选、反选及删除操作示例
2020/06/05 Javascript
简单了解vue 插值表达式Mustache
2020/07/22 Javascript
vue接口请求加密实例
2020/08/11 Javascript
Python库urllib与urllib2主要区别分析
2014/07/13 Python
在Python中使用全局日志时需要注意的问题
2015/05/06 Python
python实现将html表格转换成CSV文件的方法
2015/06/28 Python
Django如何实现内容缓存示例详解
2017/09/24 Python
python实现汉诺塔算法
2021/03/01 Python
Python对象与引用的介绍
2019/01/24 Python
pygame编写音乐播放器的实现代码示例
2019/11/19 Python
Tensorflow tf.nn.depthwise_conv2d如何实现深度卷积的
2020/04/20 Python
纯CSS3实现图片无间断轮播效果
2016/08/25 HTML / CSS
GNC健安喜官方海外旗舰店:美国著名保健品牌
2017/01/04 全球购物
新教师岗前培训方案
2014/06/05 职场文书
物理分数没达标检讨书
2014/09/13 职场文书
2014年医院后勤工作总结
2014/12/06 职场文书
节水倡议书
2015/01/19 职场文书
导游词创作书写原则以及开场白技巧怎么学?
2019/09/25 职场文书
PHP命令行与定时任务
2021/04/01 PHP
怎么用Python识别手势数字
2021/06/07 Python
Pandas 稀疏数据结构的实现
2021/07/25 Python
MySQL约束超详解
2021/09/04 MySQL