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


    调用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(
    /[x26x27x3Cx3Ex0Dx0Ax22x2Cx5Cx00]/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;
    }
    }
    }


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

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

  • 相关阅读:
    使用NPOI将多张图片导入execl
    Oracle计算时间差函数
    Oracle_spatial的函数介绍[转]
    FDO error:Failed to label layer(XXX) for class Default
    您属于哪个版本的程序员[转]
    关于oracle-12514错误的修改方法
    ArcGis在Oracle中常用的sql
    读取XML绑定TreeNode
    HTML中图片热区的使用
    如何查看目前正在使用的Windows10是哪个版本?
  • 原文地址:https://www.cnblogs.com/0to9/p/5072345.html
Copyright © 2020-2023  润新知