MVC 3 - JSON序列 [英] MVC 3 - JSON serializer

查看:121
本文介绍了MVC 3 - JSON序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的模型,视图和控制器。

型号

 公共类Person {
        公共字符串名称; // {搞定;组; }
        公共字符串职业{搞定;组; }
        公众诠释薪水{搞定;组; }
        公众诠释[] {NumArr获得;组; }
    }

查看

 <输入类型=按钮ID =测试值=测试/>@section的Javascript {
<脚本类型=文/ JavaScript的>
    $(函数(){
        $(#测试)。点击(函数(){
            VAR数据= {名称:迈克尔·汤姆,职业:程序员,月薪:8500,NumArr:[2,6,4,9]};
            VAR URL =首页/的getJSON
            $阿贾克斯({
                网址:网址,
                数据类型:JSON
                键入:POST,
                数据:数据,
                传统:真实,
                成功:函数(结果){                }
            });        });
    });
< / SCRIPT>
}

控制器

 公共类HomeController的:控制器
    {
        公众的ActionResult指数()
        {
            返回查看();
        }        公共JsonResult的getJSON(人人){            返回JSON(......);
        }
    }

根据这些code以上,我想问三个问题。


  1. 如果我们使用的公共领域,而不是性能,串行不序列JSON对象为C#模式,使我总是得到空的名称字段中的控制器。为什么会发生这样?


  2. 如果我改变NumArr属性的类型列表中,则它不工作。我们如何使用列表,而不是为int []?我知道我从路过的JS数组。我们可以从JS传名单中呢?


  3. 我使用的是传统:真正的鉴于Javascript的code座,因为序列化不符合:传统的假工作。听说jQuery的有三个版本的JSON序列化的。 ASP.NET MVC的串行器只支持旧​​版本。是真的吗?


3.1。如果这是真的,我想知道你什么时候得到的最新版本,支持jQuery的最新版本的MVC的序列化。

3.2。有没有什么办法可以注册一个自定义的javascript串行就像我们可以注册自定义视图引擎?我的朋友建议我说,我可以注册自定义值提供商或自定义模型粘结剂,在我的自定义值提供商/模型绑定使用自定义JS串行。

在此先感谢。请随时让我知道,如果你是不是清楚我的问题。谢谢!


解决方案

  

1),如果我们使用的公共领域,而不是性能,串行不序列JSON对象为C#模式,使我总是空的
  在控制器的名称字段。为什么会发生这样?


由于模型绑定仅适用于属性。这是由设计。通常域应该在你的类的私人。它们是实现细节。使用属性来揭露一些行为​​的外部世界。


  

2)如果我改变NumArr属性的类型列表中,则它不
  工作。我们如何使用列表,而不是为int []?我知道我路过
  从阵列JS。我们可以从JS传名单中呢?


它应该工作。无论你使用列表&LT; INT&GT; 的IEnumerable&LT; INT&GT; INT [] ,这是相同的,它的作品。什么是行不通的是,如果你想使用例如像列表与LT一些复杂的物体的集合; SomeComplexType&GT; (见我的回答如下的解决这个)<。 / p>


  

3)我使用的是传统:真正的在视图,因为Javascript的code座
  序列化不:传统的假工作。我听说
  jQuery的有三个版本的JSON序列化的。 ASP.NET MVC的串行
  只支持旧版本。是真的吗?


是的,传统参数在jQuery的1.4推出的时候,他们改变jQuery的序列化参数的方式。这种变化碰巧与模型粘结剂MVC使用时的绑定列表的。

所以下载一个JavaScript调试工具,如萤火,并开始播放。你会看到在jQuery的发送,当你设置此参数请求的方式上存在差异。


这一切是说,我会建议您发送JSON EN codeD请求到控制器的动作。这将与任何复杂对象工作,你不必问自己,你正在使用或任何其中的jQuery的版本,因为JSON是一个标准的可互操作的格式。一个标准的可互操作的格式的好处是,你使用的无论哪个系统,你应该能够让他们说话相同的语言(当然,除非有这些系统漏洞和他们不尊重定义的标准)。

但现在你能告诉我,<一个href=\"http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1\">application/x-www-form-urlen$c$cd也是一个标准和inetroperable格式。这是真的。问题是,该模型粘结剂结合输入字段的名称时到您的机型性能使用惯例。和本公约还远远没有被东西互操作性,行业标准。

因此​​,例如,你可以有一个模型层次:

 公共类Person
{
    公共字符串名称{;组; }
    公共字符串职业{搞定;组; }
    公众诠释薪水{搞定;组; }
    公开名单&LT;&子对象GT;子对象{搞定;组; }
}公共类子对象
{
    公众诠释标识{搞定;组; }
    公共字符串名称{;组; }
}

您能想象你喜欢的任何复杂的层次结构(在此不被JSON格式支持循环引用除外)。

和则:

  VAR数据= {
    名称:迈克尔·汤姆
    职业:程序员
    工资:8500,
    子对象:
        {ID:1,名称:子1'},
        {ID:2,名称:子2},
        {ID:3,名称:子3'}
    ]
};$阿贾克斯({
    网址:首页/的getJSON
    键入:POST,
    数据:JSON.stringify({人:数据})
    的contentType:应用/ JSON,
    成功:函数(结果){    }
});

我们的Content-Type HTTP请求头设置为应用程序/ JSON 来表示内置JSON值提供程序工厂请求是JSON EN codeD(使用 JSON.stringify 法),它会分析它回到你的强类型的模型。在 JSON.stringify 方法本身内置到现代的浏览器,但如果你想支持旧版浏览器,你可以包括的json2.js 脚本到您的网页。

I have the following model, view and controller.

Model

 public class Person {
        public string Name;// { get; set; }
        public string Occupation { get; set; }
        public int Salary { get; set; }
        public int[] NumArr { get; set; }
    }

View

<input type="button" id="Test" value="Test" />

@section Javascript{
<script type="text/javascript">
    $(function () {
        $("#Test").click(function () {
            var data = { Name: "Michael Tom", Occupation: "Programmer", Salary: 8500, NumArr: [2,6,4,9] };
            var url = "Home/GetJson";
            $.ajax({
                url: url,                
                dataType: "json",
                type: "POST",
                data: data,
                traditional: true,
                success: function (result) {

                }
            });

        });
    });        
</script>
}

Controller

public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public JsonResult GetJson(Person person) {            

            return Json(......);
        }
    }

Based on those code above, I like to ask three questions.

  1. If we use public field instead of properties, the serializer doesn't serialize the json object to C# model so I always get null for "Name" field in controller. Why does it happen like that?

  2. If I changed the type of NumArr property to List then it doesn't work. How can we use List instead of the int[]? I know I'm passing the array from JS. Can we pass List from JS as well?

  3. I'm using "traditional: true" in Javascript code block of View because serialization doesn't work with "traditional: false". I heard that jQuery has three version of Json serializer. ASP.NET MVC's serializer supports only old version. Is it true?

3.1. If it's true, I like to know when you are going to get the latest version of MVC's serializer that supports jQuery's latest version.

3.2. Is there any way to register a custom Javascript Serializer just like we can register custom view engine? My friend suggested me that I can register custom value provider or custom model binder and use custom JS serializer in my custom value provider /model binder.

Thanks in advance. Please feel free to let me know if you are not clear about my questions. Thanks!

解决方案

1) If we use public field instead of properties, the serializer doesn't serialize the json object to C# model so I always get null for "Name" field in controller. Why does it happen like that?

Because the model binder works only with properties. It is by design. Normally fields should be private in your classes. They are implementation detail. Use properties to expose some behavior to the outer world.

2) If I changed the type of NumArr property to List then it doesn't work. How can we use List instead of the int[]? I know I'm passing the array from JS. Can we pass List from JS as well?

It should work. No matter whether you use List<int>, IEnumerable<int> or int[], it's the same and it works. What wouldn't work is if you wanted to use a collection of some complex object like for example List<SomeComplexType> (see my answer below for a solution to this).

3) I'm using "traditional: true" in Javascript code block of View because serialization doesn't work with "traditional: false". I heard that jQuery has three version of Json serializer. ASP.NET MVC's serializer supports only old version. Is it true?

Yes, the traditional parameter was introduced in jQuery 1.4 when they changed the way jQuery serializes parameters. The change happened to be non-compatible with the standard convention that the model binder uses in MVC when binding to lists.

So download a javascript debugging tool such as FireBug and start playing. You will see the differences in the way jQuery sends the request when you set this parameter.


All this being said I would recommend you to send JSON encoded requests to your controller actions. This will work with any complex objects and you don't have to ask yourself which version of jQuery you are using or whatever because JSON is a standard interoperable format. The advantage of a standard interoperable format is that no matter which system you use, you should be able to make them talk the same language (unless of course there are bugs in those systems and they do not respect the defined standard).

But now you could tell me that application/x-www-form-urlencoded is also a standard and inetroperable format. And that's true. The problem is that the model binder uses a convention when binding the name of the input fields into properties of your models. And this convention is far from something being interoperable or industry standard.

So for example you could have an hierarchy of models:

public class Person
{
    public string Name { get; set; }
    public string Occupation { get; set; }
    public int Salary { get; set; }
    public List<SubObject> SubObjects { get; set; }
}

public class SubObject
{
    public int Id { get; set; }
    public string Name { get; set; }
}

You could imagine any complex hierarchy you like (at the exception of circular references which are not supported by the JSON format).

and then:

var data = { 
    name: "Michael Tom", 
    occupation: "Programmer", 
    salary: 8500, 
    subObjects: [
        { id: 1, name: 'sub 1' },
        { id: 2, name: 'sub 2' },
        { id: 3, name: 'sub 3' }
    ] 
};

$.ajax({
    url: "Home/GetJson",
    type: "POST",
    data: JSON.stringify({ person: data }),
    contentType: 'application/json',
    success: function (result) {

    }
});

We set the Content-Type request HTTP header to application/json to indicate the built-in JSON value provider factory that the request is JSON encoded (using the JSON.stringify method) and it will parse it back to your strongly typed model. The JSON.stringify method is natively built into modern browsers but if you wanted to support legacy browsers you could include the json2.js script to your page.

这篇关于MVC 3 - JSON序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆