2016-04-04 36 views
1

我想在asp.net mvc 6中做一個後期操作,期待複雜的屬性集合被正確初始化。但它總是空的。asp.net mvc 6模型綁定到複雜的集合 - IList <T>

我創建輸入html元素具有適當指數:

編輯的HTML(這是爲POST一個HTML FORM)

@model MainObject 
<form asp-action="create" method="post"> 
    <input asp-for="ChildObjects[0].RollNumber" /> 
    <input type="submit" value="create" /> 
</form> 

控制器代碼

public async Task<IActionResult> Create(MainObject mainObj) 
{ 
    // The mainObj.ChildObjects remains empty. 
} 

我的觀點將只包含一個子對象條目,這就是爲什麼只使用0索引。

表單數據中包含上述按鍵與價值,但是當它到達控制器動作的集合屬性爲空即MainObject.ChildObjects具有計數爲0(注:ChildObjects列表在我MainObject構造已初始化)

型號:

public class MainObject { 
    public MainObject() { 
     this.ChildObjects = new List<ChildObjects>(); 
    } 

    public IList<ChildObject> ChildObjects {get; private set;} 
} 

在在調試模式構造仰視的ModelState屬性,它顯示ChildObjects關鍵的一個錯誤,但錯誤信息是太普通了 - >對象引用不設置到對象的實例。

我跟着網上的許多文章模型綁定複雜的收集,但一些如何它不適合我。

任何幫助將不勝感激。

+0

您對'asp-for'的使用是可疑的,您可能需要'value = Model.ChildObjects [0] .RollNumber'。但是如果你有一個空的引用,你需要在你實例化這個MainObject的地方發佈你的控制器代碼,並將它轉發給視圖。 –

+0

asp-for創建一個名稱標籤,這是預期的。值屬性用於實際值。添加了控制器代碼 – Jash

+0

@StaffordWilliams'asp-for'是標籤助手的MVC6(或者MVC核心,如果你喜歡)語法。 – DavidG

回答

6

private set聲明子對象集合會阻止綁定器設置集合值。 setter必須是public,所以MVC6可以設置回發中的值;

public IList<ChildObject> ChildObjects {get; private set;} // empty on postback 
public IList<ChildObject> ChildObjects {get; set;} // populated on postback 

收集仍然但是實例化(而不是空的,因此count == 0)當模型綁定調用聲明該參數的構造函數。

+0

哇,所以這是個問題。刪除私人setter後,它的工作。謝謝斯塔福德。另外,如果我想擁有私人二傳手,那麼有什麼替代方案嗎? – Jash

+0

@Jash由於某種業務邏輯,你可能希望它是私人的。不要將業務邏輯粘在模型中,它們應該只是將數據從控制器傳輸到視圖進行綁定的shell。在將數據粘貼到視圖中之前,將業務邏輯放在任何數據中。 –

+0

我認爲,我們應該始終將collection屬性設置爲只讀,並且它與業務邏輯無關,但更多的是最佳編碼實踐。 https://msdn.microsoft.com/zh-cn/library/ms182327(VS.80).aspx – Jash