2012-04-02 74 views
4

我有以下模型,視圖和控制器。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; } 
    } 

查看

<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(......); 
     } 
    } 

基於上述的那些代碼,我喜歡問三個問題。

  1. 如果我們使用的公共領域,而不是性能,串行不序列化JSON對象爲C#模式,使我總是空在控制器「名稱」字段。爲什麼會發生這種情況?

  2. 如果我將NumArr屬性的類型更改爲List,那麼它不起作用。我們如何使用List而不是int []?我知道我從JS傳遞數組。我們還可以通過JS的List嗎?

  3. 我在JavaScript代碼塊中使用「traditional:true」,因爲序列化不適用於「traditional:false」。我聽說jQuery有三個版本的Json序列化器。 ASP.NET MVC的序列化器只支持舊版本。這是真的嗎?

3.1。如果這是真的,我想知道你什麼時候能夠獲得支持jQuery最新版本的最新版MVC序列化器。

3.2。是否有任何方法可以註冊自定義Javascript序列化器,就像我們可以註冊自定義視圖引擎一樣?我的朋友建議我可以註冊自定義值提供程序或自定義模型聯編程序,並在自定義值提供程序/模型聯編程序中使用自定義JS序列化程序。

在此先感謝。如果你不清楚我的問題,請隨時告訴我。謝謝!

回答

14

1)如果我們使用的公共領域,而不是性能,串行不序列化JSON對象爲C#模式,使我總是空在控制器 「名稱」字段。爲什麼會發生這種情況?

因爲模型聯編程序僅與屬性一起工作。這是設計。通常情況下,字段應該是私人的。他們是實現細節。使用屬性向外界展示一些行爲。

2)如果我將NumArr屬性的類型更改爲List,那麼它不會 工作。我們如何使用List而不是int []?我知道我通過了JS的 數組。我們還可以通過JS的List嗎?

它應該工作。無論您使用List<int>,IEnumerable<int>還是int[],它都是一樣的,它的工作原理。如果您想使用一些複雜對象的集合,例如List<SomeComplexType>(請參閱下面的答案以獲得解決方案),那麼不起作用的是。

3)我在Javascript代碼塊中使用「traditional:true」,因爲 序列化不適用於「traditional:false」。我聽說 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腳本。

+0

非常感謝您的詳細解答!謝謝! – 2012-04-02 15:56:57