MVC 3 - JSON 序列化器

Posted

技术标签:

【中文标题】MVC 3 - JSON 序列化器【英文标题】:MVC 3 - JSON serializer 【发布时间】:2012-04-16 05:18:23 【问题描述】:

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

型号

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

查看

<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>

控制器

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

        public JsonResult GetJson(Person person)             

            return Json(......);
        
    

根据上面的代码,我想问三个问题。

    如果我们使用公共字段而不是属性,则序列化程序不会将 json 对象序列化为 C# 模型,因此控制器中的“名称”字段总是为 null。为什么会这样?

    如果我将 NumArr 属性的类型更改为 List,则它不起作用。我们如何使用 List 而不是 int[]?我知道我正在从 JS 传递数组。我们也可以从 JS 传递 List 吗?

    我在 View 的 Javascript 代码块中使用“traditional: true”,因为序列化不适用于“traditional: false”。我听说 jQuery 有三个版本的 Json 序列化器。 ASP.NET MVC 的序列化程序仅支持旧版本。是真的吗?

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

3.2。有什么方法可以注册自定义 Javascript 序列化器,就像我们可以注册自定义视图引擎一样?我的朋友建议我可以注册自定义值提供者或自定义模型绑定器,并在我的自定义值提供者/模型绑定器中使用自定义 JS 序列化器。

提前致谢。如果您不清楚我的问题,请随时告诉我。谢谢!

【问题讨论】:

【参考方案1】:

1) 如果我们使用公共字段而不是属性,则序列化程序不会将 json 对象序列化为 C# 模型,所以我总是得到 null 控制器中的“名称”字段。为什么会这样?

因为模型绑定器仅适用于属性。这是设计使然。通常,字段在您的课程中应该是私有的。它们是实现细节。使用属性将某些行为暴露给外部世界。

2) 如果我将 NumArr 属性的类型更改为 List 那么它不会 工作。我们如何使用 List 而不是 int[]?我知道我正在通过 来自 JS 的数组。我们也可以从 JS 传递 List 吗?

它应该工作。无论您使用List&lt;int&gt;IEnumerable&lt;int&gt; 还是int[],都是一样的,并且可以正常工作。如果您想使用一些复杂对象的集合,例如List&lt;SomeComplexType&gt;,则行不通的方法(请参阅下面的答案以获取解决方案)。

3) 我在 View 的 Javascript 代码块中使用“traditional: true”,因为 序列化不适用于“传统:假”。我听说 jQuery 有三个版本的 Json 序列化器。 ASP.NET MVC 的序列化器 仅支持旧版本。是真的吗?

是的,traditional parameter 是在 jQuery 1.4 中引入的,当时他们改变了 jQuery 序列化参数的方式。当binding to lists 时,更改恰好与模型绑定器在 MVC 中使用的标准约定不兼容。

所以下载一个javascript调试工具,比如FireBug,开始玩吧。设置此参数时,您将看到 jQuery 发送请求的方式的不同。


话虽如此,我建议您将 JSON 编码的请求发送到您的控制器操作。这适用于任何复杂的对象,您不必问自己正在使用哪个版本的 jQuery 或其他什么,因为 JSON 是一种标准的可互操作格式。标准可互操作格式的优势在于,无论您使用哪种系统,您都应该能够使它们使用相同的语言(当然,除非这些系统中存在错误并且它们不遵守定义的标准)。

但现在你可以告诉我application/x-www-form-urlencoded 也是一种标准且不可操作的格式。这是真的。问题是模型绑定器在将输入字段的名称绑定到模型的属性时使用约定。而且这个约定远非可互操作或行业标准。

例如,您可以有一个模型层次结构:

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; 

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

然后:

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) 

    
);

我们将 Content-Type 请求 HTTP 标头设置为 application/json 以指示内置 JSON 值提供程序工厂该请求是 JSON 编码的(使用 JSON.stringify 方法)并将其解析回您的强类型模型。 JSON.stringify 方法本机内置于现代浏览器中,但如果您想支持旧版浏览器,您可以在页面中包含 json2.js 脚本。

【讨论】:

非常感谢您详细回答我!谢谢!

以上是关于MVC 3 - JSON 序列化器的主要内容,如果未能解决你的问题,请参考以下文章

mvc 使用Newtonsoft.Json进行序列化json数据

解决MVC Json序列化的循环引用问题/EF Json序列化循引用问题---Newtonsoft.Json

解决MVC Json序列化的循环引用问题/EF Json序列化循引用问题---Newtonsoft.Json

MVC 返回json数据 怎么忽略序列化某个属性

新的 ASP.NET Core 3.0 Json 序列化器遗漏了数据

如何在 Jquery 中将 MVC 表单序列化为 JSON