MVC3/4项目开发中遇到的ajax提交Json数据到后台Controller处理(接收参数:多重JSON)

前端之家收集整理的这篇文章主要介绍了MVC3/4项目开发中遇到的ajax提交Json数据到后台Controller处理(接收参数:多重JSON)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

注:(原文链接:http://www.cnblogs.com/aehyok/archive/2013/05/18/3085499.html)本文只做收藏,方便以后学习使用

我这边通过原文的理解做了部分修改,没有使用JsonNet.js这个文件对json数据进行序列化,而是直接使用jquery.js的JSON.stringify()

前言

  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文件中(原文使用)

@H_502_32@String.format = function @H_502_32@() {
if @H_502_32@(arguments.length == 0)
return null @H_502_32@;
var @H_502_32@str = arguments[0];
for @H_502_32@( var @H_502_32@i = 1; i < arguments.length; i++) {
var @H_502_32@re = new @H_502_32@RegExp( '\\{' @H_502_32@+ (i - 1) + '\\}' @H_502_32@, 'gm' @H_502_32@);
@H_502_32@str = str.replace(re,arguments[i]);
@H_502_32@}
return @H_502_32@str;
@H_502_32@}
@H_502_32@String.toSerialize = function @H_502_32@(obj) {
var @H_502_32@ransferCharForJavascript = function @H_502_32@(s) {
var @H_502_32@newStr = s.replace(
@H_502_32@/[\x26\x27\x3C\x3E\x0D\x0A\x22\x2C\x5C\x00]/g,
function @H_502_32@(c) {
@H_502_32@ascii = c.charCodeAt(0)
return '\\u00' @H_502_32@+ (ascii < 16 ? '0' @H_502_32@+ ascii.toString(16) : ascii.toString(16))
@H_502_32@});
return @H_502_32@newStr;
@H_502_32@}
if @H_502_32@(obj == null @H_502_32@) {
return null
@H_502_32@}
else if @H_502_32@(obj.constructor == Array) {
var @H_502_32@builder = [];
@H_502_32@builder.push( "[" @H_502_32@);
for @H_502_32@( var @H_502_32@index in @H_502_32@obj) {
if @H_502_32@( typeof @H_502_32@obj[index] == "function" @H_502_32@) continue @H_502_32@;
if @H_502_32@(index > 0) builder.push( "," @H_502_32@);
@H_502_32@builder.push(String.toSerialize(obj[index]));
@H_502_32@}
@H_502_32@builder.push( "]" @H_502_32@);
return @H_502_32@builder.join( "" @H_502_32@);
@H_502_32@}
else if @H_502_32@(obj.constructor == Object) {
var @H_502_32@builder = [];
@H_502_32@builder.push( "{" @H_502_32@);
var @H_502_32@index = 0;
for @H_502_32@( var @H_502_32@key in @H_502_32@obj) {
@H_17_403@ if @H_502_32@( typeof @H_502_32@obj[key] == "function" @H_502_32@) continue @H_502_32@;
if @H_502_32@(index > 0) builder.push( "," @H_502_32@);
@H_502_32@builder.push(String.format( "\"{0}\":{1}" @H_502_32@,key,String.toSerialize(obj[key])));
@H_502_32@index++;
@H_502_32@}
@H_502_32@builder.push( "}" @H_502_32@);
return @H_502_32@builder.join( "" @H_502_32@);
@H_502_32@}
else if @H_502_32@(obj.constructor == Boolean) {
return @H_502_32@obj.toString();
@H_502_32@}
else if @H_502_32@(obj.constructor == Number) {
return @H_502_32@obj.toString();
@H_502_32@}
else if @H_502_32@(obj.constructor == String) {
return @H_502_32@String.format( '"{0}"' @H_502_32@,ransferCharForJavascript(obj));
@H_502_32@}
else if @H_502_32@(obj.constructor == Date) {
return @H_502_32@String.format( '{"__DataType":"Date","__thisue":{0}}' @H_502_32@,obj.getTime() - ( new @H_502_32@Date(1970,1,0)).getTime());
@H_502_32@}
else if @H_502_32@( this @H_502_32@.toString != undefined) {
return @H_502_32@String.toSerialize(obj);
@H_502_32@}
@H_502_32@}

第二步页面定义两个按钮事件,并在按钮事件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",{ UserId: "33","xiaohong"] }
            ];
            $.post("../Home/TestList",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则是使用String.toSerialize(data),否则使用jquery自带的JSON.stringify(data);

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

下载后解压

各个.net FrameWork的版本文件都有只需要在项目中引用对应的版本即可,这个文件在vs2012里面已经集成直接引用就好了

第四步(这一部分很重要) 就是编写针对Json处理的自动绑定Model,这个步骤需要引入刚才那个Newtonsoft.Json的命名空间;

using Newtonsoft.Json.Linq;
using Newtonsoft.Json;

之前有一篇简单的请求参数绑定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>,或者是嵌套的都可以。

//[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进行参数化绑定即可。

示例代码下载地址http://url.cn/HRz2JC

最后感谢作者:aehyok

猜你在找的Ajax相关文章