MVC项目开发中那些用到的知识点(Jquery ajax提交Json后台处理)

前言

  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对于参数序列化的问题: 引用前台处理Js文件,主要是将Json字符串进行处理将其封装到JsonNet.js文件中

String.format = function () {
    if (arguments.length == 0)
        return null;
    var str = arguments[0];
    for (var i = 1; i < arguments.length; i++) {
        var re = new RegExp('\\{' + (i - 1) + '\\}', 'gm');
        str = str.replace(re, arguments[i]);
    }
    return str;
}

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);
    }
} 

 第二步在页面定义两个按钮事件,并在按钮事件JavaScrpit中进行调用

@{
    ViewBag.Title = "主页";
}
    <script src="@Url.Content("~/Scripts/JsonNet.js")" type="text/javascript"></script>
    <script type="text/javascript">
        function Test() {
            var data={UserId:"11",UserName:"2211"};
            $.post("../Home/Test", { User: String.toSerialize(data) }, function (data) { alert(String.toSerialize(data)); });
        }

        function TestList() {
            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/TestList", { User: String.toSerialize(data) }, function (data) { alert(String.toSerialize(data)); });
        }
    </script>
<h2>@ViewBag.Message</h2>
<p>
    若要了解有关 ASP.NET MVC 的更多信息,请访问 <a href="http://asp.net/mvc" title="ASP.NET MVC 网站">http://asp.net/mvc</a>。
</p>
<input type="button" value="testList" onclick="TestList()" />
<input type="button" value=test onclick="Test()" />

当然还要引用刚刚封装的Js文件。

第三步在后台控制器要使用Json专类来处理,所以要专门下载类库文件进行引用http://json.codeplex.com

下载后解压

各个.net FrameWork的版本文件都有只需要在项目中引用对应的版本即可。

第四步就是编写针对Json处理的自动绑定Model。之前有一篇简单的请求参数绑定http://www.cnblogs.com/aehyok/archive/2013/05/01/3052697.html

namespace MvcApplication3.Helper
{
    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();
                        try
                        {
                            object obj = js.Deserialize(jsonRsp[i].CreateReader(), typeof(T));
                            list.Add((T)obj);
                        }
                        catch (Exception e)
                        {
                            throw e;
                        }
                    }
                }
                return list;
            }
            return null;
        }
    }
}

提交的Json可以为单个对象实体类,也可以为实体类的数组List<T>,或者是嵌套的都可以。 第五步在Action进行绑定。

        //[JsonObject]
        public class UserInfo
        {
            public string UserId{get;set;}

            public UserName UserName{get;set;}
            public List<string> keys { get; set; }

        }
        public class UserName
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
        }

        [HttpPost]
        public ActionResult TestList([ModelBinder(typeof(JsonBinder<UserInfo>))]List<UserInfo> User)
        {
            List<UserInfo> list = User;
            return Json(list, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult Test([ModelBinder(typeof(JsonBinder<UserInfo>))]UserInfo User)
        {
            UserInfo Userinfo = User;
            return Json(User, JsonRequestBehavior.AllowGet);
        }

定义了两个简单的实体类并进行关联和上面通过jQuery Ajax提交过来的Json数据格式一致。 主要是通过实现了IModelBinder进行参数化绑定即可。

最后一步进行F5运行测试。

通过代码可以看出我是将Json字符串传递到服务端,服务端对其进行解析然后又转换为Json返回到客户端的。

总结

 没有做不到,只有想不到,你想怎么传就怎么传了,想传什么样格式的数据,只要定义好即可。

示例代码下载地址http://share.weiyun.com/2081c8cd3b40fb3487c2b7c54b67719b

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏GreenLeaves

C# 多线程系列之异步回调(委托)

本文参考自C#基础:线程之异步回调(委托),纯属读书笔记 在解析异步回调之前,先看同步回调的执行过程,以及代码原理。 1、线程的同步执行 同步执行:在主线程执...

42150
来自专栏.NET技术

.net平台的MongoDB使用

  最近花了点时间玩了下MongoDB.Driver,进行封装了工具库,平常也会经常用到MongoDB,因此写一篇文章梳理知识同时把自己的成果分享给大家。

14920
来自专栏小灰灰

Java 动手写爬虫: 二、 深度爬取

第二篇 前面实现了一个最基础的爬取单网页的爬虫,这一篇则着手解决深度爬取的问题 简单来讲,就是爬了一个网页之后,继续爬这个网页中的链接 1. 需求背景 背景...

766100
来自专栏vue

.Net—反射

新建一个空白解决方案,添加一个控制台应用程序和一个名为Common的类库。在Common里面添加一个Person类和Student类,代码如下

24130
来自专栏王磊的博客

linq to entity常用操作

一、聚合函数查询 double sum = 0; using (xxxEntities db = new xxxEntities()) { sum = ...

38160
来自专栏liulun

ASP.NET Core教程【三】实体字段属性、链接标签、并发数据异常、文件上传及读取

前文索引: ASP.NET Core教程【二】从保存数据看Razor Page的特有属性与服务端验证 ASP.NET Core教程【一】关于Razor Page...

31460
来自专栏芋道源码1024

哪个更快:Java 堆还是本地内存

使用Java的一个好处就是你可以不用亲自来管理内存的分配和释放。当你用new关键字来实例化一个对象时,它所需的内存会自动的在Java堆中分配。堆会被垃圾回收器进...

12640
来自专栏大内老A

像TransactionScope一样使用DbTransaction

System.Transactions.TransactionScope为了提供一种非常方便的实现分布式事务的方式,但是在某些情况下为了阻止本地事务向分布式事务...

53070
来自专栏待你如初见

Java爬虫及分布式部署

36050
来自专栏大内老A

我的WCF之旅(5):面向服务架构(SOA)和面向对象编程(OOP)的结合——如何实现Service Contract的重载(Overloading)

对于.NET重载(Overloading)——定义不同参数列表的同名方法(顺便提一下,我们但可以在参数列表上重载方法,我们甚至可以在返回类型层面来重载我们需要的...

28960

扫码关注云+社区

领取腾讯云代金券