2013-05-13 137 views
4

所以我有一個視圖,需要幾個不同的對象和對象列表傳入和傳出,我創建了一個viewmodel。我的視圖模型看起來像這樣MVC 4模型返回null

public class EditUserViewModel 
{ 
    public ManageUsersViewModel ManageUsersViewModel { get; set; } 
    public IEnumerable<StateModel> StateModel { get; set; } 
} 

我遇到的,看起來像這樣

public class StateModel 
{ 
    public bool IsChecked { get; set; } 
    public States States { get; set; } 
    public UsersInStates UsersInStates { get; set; } 
} 

的StateModel麻煩的一部分,包含此

[Table("States")] 
public class States 
{ 
    [Key] 
    public int StateId { get; set; } 
    public string State { get; set; } 
} 

[Table("UsersInStates")] 
public class UsersInStates 
{ 
    [Key, Column(Order = 1)] 
    public int UserId { get; set; } 
    [Key, Column(Order = 2)] 
    public int StateId { get; set; } 
    public string LicenseNumber { get; set; } 
} 

在我看來,我或多或少試圖循環訪問狀態併爲UsersInStates提供用戶輸入。這是我試圖完成它,但我的整個StateModel返回null。進入視圖StateModel.States有數據,UsersInStates沒有。這是我看來的樣子

@foreach (var state in Model.StateModel) 
{ 
    @Html.HiddenFor(m => state) 
    <tr> 
     <td> 
      @Html.CheckBoxFor(m => state.IsChecked) 
     </td> 
     <td> 
      @Html.Label(state.States.State) 
     </td> 
     <td> 
      @Html.EditorFor(m => state.UsersInStates.LicenseNumber) 
     </td> 
    </tr> 
} 

任何意見將不勝感激。一切都顯示,因爲它應該和ManageUsersViewModel部分工作正常,它只是返回到控制器的StateModel數據爲空,我不完全確定如何使其按照我喜歡的方式工作。

這是生成的HTML是什麼樣子的表的起始和要求

<table style="margin-left:auto; margin-right:auto; text-align:center"> 
<input id="state" name="state" type="hidden" value="WebSiteNew.Models.StateModel" />     <tr> 
       <td> 
        <input data-val="true" data-val-required="The IsChecked field is  required." id="state_IsChecked" name="state.IsChecked" type="checkbox" value="true" /> <input name="state.IsChecked" type="hidden" value="false" /> 
       </td> 
       <td> 
        <label for="Alabama">Alabama</label> 
       </td> 
       <td> 
        <input class="text-box single-line" id="state_UsersInStates_LicenseNumber" name="state.UsersInStates.LicenseNumber" type="text" value="" /> 
       </td> 
      </tr> 

答案的第一行:

確定,所以解決這個我用一個for循環下面

@for (int i = 0; i < Model.StateModel.Count(); i++) 
{ 
    <tr> 
     <td> 
      @Html.HiddenFor(m => m.StateModel[i].States.StateId) 
      @Html.HiddenFor(m => m.StateModel[i].States.State) 
      @Html.CheckBoxFor(m => m.StateModel[i].IsChecked) 
     </td> 
     <td> 
      @Html.Label(Model.StateModel[i].States.State) 
     </td> 
     <td> 
      @Html.EditorFor(m => m.StateModel[i].UsersInStates.LicenseNumber) 
     </td> 
    </tr> 
} 

也記在回答中列出的任何人看着這兩個引用解釋,我不得不改變IEnu可以在我的EditUsersViewModel中添加到IList中,以便進行索引。

+0

你能展示生成的HTML看起來像什麼嗎? – CorrugatedAir 2013-05-13 14:31:01

+0

是的,我更新了我的文章 – aw04 2013-05-13 14:38:04

+0

添加控制器的回發方法 – 2013-05-13 14:59:07

回答

6

所以你的問題是模型綁定沒有正確地發生。

說你有這兩款車型:

public class ParentModel 
{ 
    public string Name {get;set;} 
    public ChildModel Child {get;set;} 
} 

public class ChildModel 
{ 
    public string ChildName {get;set;} 
    public int SomeNumber {get;set;} 
} 

你生成的HTML(您的模型綁定正確地發生)需要像這樣:

<input name="Name" value="(Not relevant to this example)"/> 
<input name="Child.ChildName" value="(Not relevant to this example)" /> 

注name字段是如何構成的 - 這是MVC如何確定哪些輸入值映射到視圖模型中的哪些屬性。使用嵌套屬性時,屬性名稱必須位於其前面。

對於集合,它變得更加複雜。模型聯編程序需要知道哪些值與屬性的哪個實例一起使用。

例如,如果我們假設ChildModel的類型是在前面的例子IEnumerable的,你的HTML可能看起來像這樣以模型綁定正確:

<input name="Name" value="(Not relevant to this example)"/> 
<input name="Child[0].ChildName" value="(Not relevant to this example)" /> 
<input name="Child[0].SomeNumber" value="(Not relevant to this example)"/> 
<input name="Child[1].ChildName" value="(Not relevant to this example)" /> 
<input name="Child[1].SomeNumber" value="(Not relevant to this example)"/> 

看看這些關於如何修復:

http://seesharpdeveloper.blogspot.com/2012/05/mvc-model-binding-to-list-of-complex.html http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

編輯 - 同樣重要的是要注意的是,當HTML輔助摹enerate name的值,它是基於對傳入的λ值。所以

@Html.CheckBoxFor(m => state.IsChecked) 

會生成以下名稱

name="state.IsChecked" 

既然你是一個foreach中,你得到了錯誤的名字的價值。

+0

很好的解釋,謝謝。現在看看它。 – aw04 2013-05-13 15:02:42

1

你想用@Html.HiddenFor(m => state)來完成什麼 - 從呈現的HTML看起來就像是你的罪魁禍首。 @Html.HiddenFor(m => state.StateId)會更合適嗎?

此外,您可以將它放入第一個<td>元素中,因爲它是隱藏的,並且會保持您的HTML有效。

+0

好的地方在那裏我想我自己與我自己的命名約定混爲一談......應該是@ Html.HiddenFor(m => state.States)或@Html。 HiddenFor(m => state.States.State)和@ Html.HiddenFor(m => state.States.StateId)。這不是問題,但我仍然得到一個空值。 – aw04 2013-05-13 14:53:43