I'm using ASP.NET MVC 4 and I built these ViewModels :
public class NotificationViewModel
{
public string GroupDesc { get; set; }
public bool AM { get; set; }
public bool PM { get; set; }
public int MaxNotif { get; set; }
}
public class SettingsViewModel
{
public List<NotificationViewModel> ListNotification { get; set; }
public SettingsViewModel()
{
ListNotification = new List<NotificationViewModel>();
}
}
My View :
@model PortailT2A.Models.SettingsViewModel
@{
ViewBag.Title = "Preferences";
Layout = "~/Views/Shared/_LayoutAdmin.cshtml";
}
<h2>Preferences</h2>
@using(Html.BeginForm("Preferences", "Administrateur", FormMethod.Post))
{
<table id="settingsTable">
<tr>
<th>Groupe</th>
<th></th>
<th>AM</th>
<th>PM</th>
<th>Limite de notifications</th>
</tr>
@for (int i = 0; i < Model.ListNotification.Count(); i++ )
{
var notif = Model.ListNotification[i];
<tr>
<td>@notif.GroupDesc </td>
<td>Heure de notification</td>
<td>@Html.CheckBoxFor(u => notif.AM) </td>
<td>@Html.CheckBoxFor(u => notif.PM) </td>
<td>@Html.TextBoxFor(u => notif.MaxNotif)</td>
</tr>
<tr/>
}
</table>
<input type ="submit" value="Sauvegarder" />
}
My HttpGet method populates my ViewModel and returns it.
[HttpGet]
public ActionResult Preferences(long idUser)
{
context = new MainDatabaseEntities();
List<NotificationViewModel> notifications = new List<NotificationViewModel>();
SettingsViewModel settings = new SettingsViewModel();
//Population...
return View(settings);
}
However, when I want to save the changes, I got a ViewModel which is null and I don't understand why. Any idea guys?
EDIT : My post method :
[HttpPost]
public ActionResult Preferences(SettingsViewModel sm)
{
//since here my ViewModel is null
context = new MainDatabaseEntities();
Utilisateur user = (from u in context.Utilisateurs where u.Username == User.Identity.Name select u).FirstOrDefault();
//operations...
}
HTML generated :
<tr>
<td>Groupe B </td>
<td>Heure de notification</td>
<td><input id="notif_AM" name="notif.AM" type="checkbox" value="true" /><input name="notif.AM" type="hidden" value="false" /> </td>
<td><input checked="checked" id="notif_PM" name="notif.PM" type="checkbox" value="true" /><input name="notif.PM" type="hidden" value="false" /> </td>
<td><input id="notif_MaxNotif" name="notif.MaxNotif" type="text" value="10" /></td>
</tr>
List<T>
can be tricky when modelbinding since it relies heavily on the indexed keys. The helpers need to know the index, but by assigning notif
within your for loop they're losing the reference. Instead, try something like the following:
@for (int i = 0; i < Model.ListNotification.Count(); i++ )
{
var notif = Model.ListNotification[i];
<tr>
<td>@notif.GroupDesc </td>
<td>Heure de notification</td>
<td>@Html.CheckBoxFor(u => u.ListNotification[i].AM) </td>
<td>@Html.CheckBoxFor(u => u.ListNotification[i].PM) </td>
<td>@Html.TextBoxFor(u => u.ListNotification[i].MaxNotif)</td>
</tr>
<tr/>
}
Which should then provide you with something like:
<tr>
<td>Groupe B </td>
<td>Heure de notification</td>
<td>
<input id="ListNotification[0]_AM" name="ListNotification[0].AM" type="checkbox" value="true" />
<input name="ListNotification[0].AM" type="hidden" value="false" />
</td>
<td>
<input checked="checked" id="ListNotification[0]_PM" name="ListNotification[0].PM" type="checkbox" value="true" />
<input name="ListNotification[0].PM" type="hidden" value="false" />
</td>
<td>
<input id="ListNotification[0]_MaxNotif" name="ListNotification[0].MaxNotif" type="text" value="10" />
</td>
</tr>
Also, make sure to check ModelState.IsValid
in your posted action to confirm the model was bound correctly. If not, you should see a list of errors in ModelState
that would give you some indication as to where it may have failed.
Also, I don't see you dump GroupDesc
anywhere (except to output). If this is necessary on the incoming model, you may consider using @Html.HiddenFor(x => x.ListNotifications[i].GroupDesc)
.
You're not building your HTML correctly. What is posted back will not have the paths the model binder expects.
Consider replacing this:
@for (int i = 0; i < Model.ListNotification.Count(); i++ )
{
var notif = Model.ListNotification[i];
<tr>
<td>@notif.GroupDesc </td>
<td>Heure de notification</td>
<td>@Html.CheckBoxFor(u => notif.AM) </td>
<td>@Html.CheckBoxFor(u => notif.PM) </td>
<td>@Html.TextBoxFor(u => notif.MaxNotif)</td>
</tr>
<tr/>
}
with this:
@Html.DisplayModelFor(m => m.ListNotification)
and add a template like this to /Views/{YourController}/{YourAction}/EditorTemplates/NotificationViewModel.cshtml
@model NotificationViewModel
<tr>
<td>@Model.GroupDesc</td>
<td>Heure de notification</td>
<td>@Html.CheckBoxFor(m => m.AM)</td>
<td>@Html.CheckBoxFor(m => m.PM)</td>
<td>@Html.TextBoxFor(m => m.MaxNotif)</td>
</tr>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With