2012-03-19 70 views
8

有問題讓ASP.NET MVC3綁定我包含列表的複雜JSON對象。MVC3複雜的JSON列表綁定

這是我對我的物體的結構。

public class PageModel 
{ 
    public PageModel() { } 
    public CustomObject1 CustomObject { get; set; } 
    public IEnumerable<CustomObject2> Objects { get; set; } 

} 

public class CustomObject1 
{ 
    public CustomObject1() { } 
    [Required] 
    public int CustomId1 { get; set; } 
    public string CustomName { get; set; } 
} 

public class CustomObject2 
{ 
    public CustomObject2() { } 
    [Required] 
    public int Custom2Id { get; set; } 
    public CustomObject3 SubItem { get; set; } 
    public int SubItemId { get; set; } 
} 

你可以假設CustomObject3是結構相似 - 不需要重複又由階級,所以我想你可以用你的想象力:)

下面是使用Javascript/jQuery的,使POST調用(假設所有的JS導致這一正確的數據提供):

//$obj1 has all data for the first object 
var firstObj = { }; 
firstObj.CustomId1 = $obj1.Id; 
firstObj.CustomName = $obj1.Name; 

var i = 0; 

//$objects is an array with all the data 
$.each($objects, function() { 
    objsArray[i] = { 
    Custom2Id: $(this).Id, 
    SubItemId: $(this).itemId 
    }; 

    ++i; 
}); 

$.ajax({ 
    type: 'POST', 
    url: '/Action/Method', 
    data: { CustomObject: firstObj, Objects: objsArray }, 
    //Success/error handlers here 
}); 

最後(我知道,很長一段代碼),這裏的方法的概述,我有:

public class ActionController : Controller { 
    public JsonResult Method(PageModel model) { 
     //Gets here - model.CustomObject is filled correctly, and model.Objects has a correct count of whatever data I passed to the method - but all of the properties are empty! 
    } 
} 

正如我所說的,第一個對象被填充,所有的數據在那裏,當我調試,並通過。如果我在JSON對象的Objects數組中傳遞兩個對象,我在控制器中看到一個爲Count,但Custom2IdSubItemId爲空。是什麼賦予了?

當我在我的$.ajax調用中指定contentType'application/json'時,MVC會抱怨傳遞的數據。還嘗試將MVC方法中的model參數拆分爲兩個單獨的參數,但它沒有幫助。

任何幫助非常感謝 - 這一個讓我難住!

回答

5

因此,這個特定問題的解決方案是在SO上其他地方找到的兩個或多個解決方案的組合(其中一個可能是Jakub的回答圍繞使用泛型集合類型 - IEnumerable - 而不是更具體的一個 - List)。

首先,服務器端代碼不需要改變 - 一切都很好。所有需要進行的更改都是客戶端,特別是jQuery和Javascript如何將數據發送到服務器。

這裏是老的Javascript:

$.ajax({ 
    type: 'POST', 
    url: '/Action/Method', 
    data: { CustomObject: firstObj, Objects: objsArray }, 
    //Success/error handlers here 
}); 

首先這裏的問題是,JavaScript並不是在'/Action/Method'通知服務器究竟你要發送(是二進制的,是它的參數的組合,或者是它的JSON?)所以添加一個contentType: 'application/json'行將用於此目的。當你這樣做的時候,服務器知道它必須解碼JSON ...

但是就像現在這樣,在代碼甚至進入你的方法之前解碼將會失敗,拋出一個異常(「Invalid JSON primitive」) MVC處理解碼和綁定)。在上面的AJAX調用中,我在$.ajax選項中構建了一個新的JSON對象,但發送的JSON不會通過JSON驗證器(James Kyburz提到了一個很棒的JSON驗證器:JSONLint Validator)。相反,在調用$.ajax之前創建JSON對象,並對該對象進行字符串化以使其處於正確的JSON格式。總之,這裏的AJAX調用應該是什麼樣子:

var dataObj = { CustomObject: firstObj, Objects: objsArray }; 

$.ajax({ 
    type: 'POST', 
    url: '/Action/Method', 
    contentType: 'application/json', 
    data: JSON.stringify(dataObj), 
    //Success/error handlers here 
}); 
+0

感謝這有助於很多:)! – Rookian 2012-11-28 17:02:23

+0

經過數小時尋求完整功能的代碼,這解決了我的問題!謝謝!! – 2013-08-12 17:22:22

3

變化public IEnumerable<CustomObject2> Objects { get; set; }List<CustomObject2>

型粘合劑不知道如何創建IEnumerable接口的一個實例,它需要更具體的東西。

你也需要改變這一點:

data: { CustomObject: firstObj, Objects: objsArray }

data: { model: { CustomObject: firstObj, Objects: objsArray } }

model部分在動作參數的名稱相匹配。

+0

我已經打得四處這一點 - 'IEnumerable','IList','List'都產生相同的結果 - 用正確數量的對象列表,沒有價值。 – Mattygabe 2012-03-19 14:18:17

+0

我不同意你的第二部分 - 儘管它在某些情況下可能有所幫助,但MVC3足夠聰明,可以辨別出我傳遞給它的數據屬於我的「模型」參數。我上面描述的工作解決方案沒有指定額外的對象層來安撫MVC - 它能夠辨別我在做什麼。 – Mattygabe 2012-03-21 19:03:54