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


 jQuery提供的ajax方法能很方便的实现客户端与服务器的异步交互,在asp.net mvc 框架使用jQuery能很方便地异步获取提交数据,给用户提供更好的体验!

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

 1  /* 对象序列化为字符串 */
 2  String.toSerialize  =   function (obj) {
 3       var  ransferCharForJavascript  =   function (s) {
 4           var  newStr  =  s.replace(
 5           / [\x26\x27\x3C\x3E\x0D\x0A\x22\x2C\x5C\x00] / g,
 6           function (c) {
 7              ascii  =  c.charCodeAt( 0 )
 8               return   ' \\u00 '   +  (ascii  <   16   ?   ' 0 '   +  ascii.toString( 16 ) : ascii.toString( 16 ))
 9          }
10      );
11           return  newStr;
12      }
13       if  (obj  ==   null ) {
14           return   null
15      }
16       else   if  (obj.constructor  ==  Array) {
17           var  builder  =  [];
18          builder.push( " [ " );
19           for  ( var  index  in  obj) {
20               if  ( typeof  obj[index]  ==   " function " continue ;
21               if  (index  >   0 ) builder.push( " , " );
22              builder.push(String.toSerialize(obj[index]));
23          }
24          builder.push( " ] " );
25           return  builder.join( "" );
26      }
27       else   if  (obj.constructor  ==  Object) {
28           var  builder  =  [];
29          builder.push( " { " );
30           var  index  =   0 ;
31           for  ( var  key  in  obj) {
32               if  ( typeof  obj[key]  ==   " function " continue ;
33               if  (index  >   0 ) builder.push( " , " );
34              builder.push(String.format( " \ " { 0 }\ " :{1} " , key, String.toSerialize(obj[key])));
35              index ++ ;
36          }
37          builder.push( " } " );
38           return  builder.join( "" );
39      }
40       else   if  (obj.constructor  ==  Boolean) {
41           return  obj.toString();
42      }
43       else   if  (obj.constructor  ==  Number) {
44           return  obj.toString();
45      }
46       else   if  (obj.constructor  ==  String) {
47           return  String.format( ' "{0}" ' , ransferCharForJavascript(obj));
48      }
49       else   if  (obj.constructor  ==  Date) {
50           return  String.format( ' {"__DataType":"Date","__thisue":{0}} ' , obj.getTime()  -  ( new  Date( 1970 0 1 0 0 0 )).getTime());
51      }
52       else   if  ( this .toString  !=  undefined) {
53           return  String.toSerialize(obj);
54      }
55  }
56 


 jQuery异步请求:

 1   $( function () {
 2               /* 按钮点击事件 */
 3              $( " #btn_post_test " ).click( function () {
 4                   var  data  =  [
 5                      { UserId:  " 11 " , UserName: { FirstName:  " 323 " , LastName:  " 2323 "  }, Keys: [ " xiaoming " " xiaohong " ] },
 6                      { UserId:  " 22 " , UserName: { FirstName:  " 323 " , LastName:  " 2323 "  }, Keys: [ " xiaoming " " xiaohong " ] },
 7                      { UserId:  " 33 " , UserName: { FirstName:  " 323 " , LastName:  " 2323 "  }, Keys: [ " xiaoming " " xiaohong " ] }
 8                  ];
 9 
10                  $.post( " Home/Test " , { users: String.toSerialize(data) },  function (text) {
11                      alert(String.toSerialize(text));
12                  },  " json " );
13              }); 
14          });


 点击按钮提交数据,监控浏览器,可以发现提交的数据是json对象的序列化后的内容:

 

 1  POST /Home/Test HTTP/1.1
 2  x-requested-with: XMLHttpRequest
 3  Accept-Language: zh-cn
 4  Referer: http://localhost:3149/test.html
 5  Accept: application/json, text/javascript, */*
 6  Content-Type: application/x-www-form-urlencoded
 7  Accept-Encoding: gzip, deflate
 8  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)
 9  Host: localhost:3149
10  Content-Length: 501
11  Connection: Keep-Alive
12  Cache-Control: no-cache
13  Cookie: CookieGlobalLoginUserID=16063
14 
15  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


 其次,后台服务器处理参数绑定:

 1  using  System.Collections.Generic;
 2  using  System.Web.Mvc;
 3  using  Newtonsoft.Json;
 4  using  Newtonsoft.Json.Linq;
 5 
 6  namespace  WebOS.Controllers
 7  {
 8      [HandleError]
 9       public   class  HomeController : Controller
10      {
11           ///   <summary>
12           ///  测试方法
13           ///   </summary>
14           ///   <param name="users"> 用户数据 </param>
15           ///   <returns> 提交的用户数组 </returns>
16           public  ActionResult Test([ModelBinder( typeof (JsonBinder < User > ))]List < User >  users)
17          { 
18               return  Json(users, JsonRequestBehavior.AllowGet);
19          }
20 
21      }
22       ///   <summary>
23       ///  对象实体
24       ///   </summary>
25      [JsonObject]
26       public   class  User
27      {
28          [JsonProperty( " UserName " )]
29           public  UserName Name {  get set ; }
30          [JsonProperty( " UserId " )]
31           public   string  UserId {  get set ; }
32          [JsonProperty( " Keys " )]
33           public  List < string >  Keys {  get set ; }
34 
35 
36      }
37       ///   <summary>
38       ///  对象实体
39       ///   </summary>
40      [JsonObject]
41       public   class  UserName
42      {
43          [JsonProperty( " FirstName " )]
44           public   string  FirstName {  get set ; }
45          [JsonProperty( " LastName " )]
46           public   string  LastName {  get set ; }
47 
48      }
49       ///   <summary>
50       ///  Json数据绑定类
51       ///   </summary>
52       ///   <typeparam name="T"></typeparam>
53       public   class  JsonBinder < T >  : IModelBinder
54      {
55          
56           public   object  BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
57          {
58               // 从请求中获取提交的参数数据
59              var json  =  controllerContext.HttpContext.Request.Form[bindingContext.ModelName]  as   string ;
60               // 提交参数是对象
61               if  (json.StartsWith( " { " &&  json.EndsWith( " } " ))
62              {
63                  JObject jsonBody  =  JObject.Parse(json);
64                  JsonSerializer js  =   new  JsonSerializer();
65                   object  obj  =  js.Deserialize(jsonBody.CreateReader(),  typeof (T));
66                   return  obj;
67              }
68               // 提交参数是数组
69               if  (json.StartsWith( " [ " &&  json.EndsWith( " ] " ))
70              {
71                  IList < T >  list  =   new  List < T > ();
72                  JArray jsonRsp  =  JArray.Parse(json);
73 
74                   if  (jsonRsp  !=   null )
75                  {
76                       for  ( int  i  =   0 ; i  <  jsonRsp.Count; i ++ )
77                      {
78                          JsonSerializer js  =   new  JsonSerializer();
79                           object  obj  =  js.Deserialize(jsonRsp[i].CreateReader(),  typeof (T));
80                          list.Add((T)obj);
81                      }
82                  }
83                   return  list;
84              }
85               return   null ;
86          }
87      }
88  }
89 


 前端获取到后台返回的数据,结果就是用户提交的数据:

 

 

后台json反序列化使用了Newtonsoft.Json 组件,有关资料请参考:http://james.newtonking.com/

 

 

 

 

转载于:https://www.cnblogs.com/cask118/archive/2010/05/07/1729737.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值