MVC 3 – JSON序列化程序

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

模型

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

视图

  @section 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) { } }); }); });  } 

调节器

 public class HomeController : Controller { public ActionResult Index() { return View(); } public JsonResult GetJson(Person person) { return Json(......); } } 

基于上面的代码,我想问三个问题。

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

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

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

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

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

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

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

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

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

它应该工作。 无论你使用ListIEnumerable还是int[] ,它都是一样的并且它可以工作。 如果你想使用一些复杂对象的集合,例如List (请参阅下面的答案以获得解决方案),那么什么是List

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

是的, 传统参数是在jQuery 1.4中引入的,当时它们改变了jQuery序列化参数的方式。 这种变化恰好与模型绑定器在绑定到列表时在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 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脚本。