asp.net - MVC 3 - JSON 序列化器

标签 asp.net json asp.net-mvc-3 jquery jsonserializer

我有以下模型、 View 和 Controller 。

型号

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

Controller

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

        public JsonResult GetJson(Person person) {            

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

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

  1. 如果我们使用公共(public)字段而不是属性,序列化程序不会将 json 对象序列化为 C# 模型,因此 Controller 中的“Name”字段总是为 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 序列化器,就像我们可以注册自定义 View 引擎一样?我的 friend 建议我可以注册自定义值提供程序或自定义模型绑定(bind)程序,并在我的自定义值提供程序/模型绑定(bind)程序中使用自定义 JS 序列化程序。

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

最佳答案

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?

因为模型绑定(bind)器仅适用于属性。这是设计使然。通常,类中的字段应该是私有(private)的。它们是实现细节。使用属性向外部世界公开某些行为。

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?

它应该可以工作。无论您是否使用List<int> , IEnumerable<int>int[] ,它是相同的并且有效。如果您想使用一些复杂对象的集合,例如 List<SomeComplexType> ,则行不通。 (请参阅下面我的回答以获取解决方案)。

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?

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

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

<小时/>

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

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

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

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 header 设置为 application/json指示内置 JSON 值提供程序工厂该请求是 JSON 编码的(使用 JSON.stringify 方法),并且它会将其解析回您的强类型模型。 JSON.stringify方法本身内置于现代浏览器中,但如果您想支持旧版浏览器,您可以包含 json2.js将脚本添加到您的页面。

关于asp.net - MVC 3 - JSON 序列化器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9978254/

相关文章:

python - 在 Django 中使用 Python 解析 JSON 文件

asp.net-mvc - MVC 区域 - 非区域路由解析为区域

asp.net - 该模型项的类型为CookMeIndexViewModel,但需要一个模型项的类型为IEnumerable <CookMeIndexViewModel>

javascript - 将字符串参数传递给 JavaScript 函数

c# - 大表的最佳主键格式

c# - 如何引用 LINQ 中使用保留字命名的字段?

jquery - MVC 3,重用部分 View 和jquery,不与DOM冲突

c# - 如何从 GridView 中删除重复数据?

Java\JSON : UnrecognizedPropertyException: Unrecognized field "CefMessagesGenerators" error

javascript - 缩短表格中的数据数量