So, I have a view that requires several different objects and lists of objects that need to be transferred and deleted, for which I created a viewmodel. My viewmodel looks like this
public class EditUserViewModel { public ManageUsersViewModel ManageUsersViewModel { get; set; } public IEnumerable<StateModel> StateModel { get; set; } }
In the part I'm having problems with, there is a StateModel that looks like
public class StateModel { public bool IsChecked { get; set; } public States States { get; set; } public UsersInStates UsersInStates { get; set; } }
and contains it
[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; } }
In my opinion, I am more or less trying to iterate over states and enter user input for UsersInStates. This is how I try to do this, but my entire StateModel is returning null. Going to the StateModel.States view has data, but UsersInStates does not. This is what seems in my opinion
@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> }
Any advice would be highly appreciated. Everything displays as it should, and part of the ManageUsersViewModel works fine, but the StateModel data returning to the controller is zero, and I'm not quite sure how to make this work the way I would like.
Here is what the generated html looks like for the beginning of the table and the first row as requested
<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>
Answer:
So, to solve this problem, I used a for loop as described in both of the links listed in the answer below
@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> }
Also a note for anyone looking at this, I had to change the IEnumerable in my EditUsersViewModel to IList so that I could index.