ViewModel имеет значение Null в методе HttpPost
я использую ASP.NET MVC 4 и я построили эти 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>();
}
}
Мое Мнение :
@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" />
}
мой метод HttpGet заполняет мою ViewModel и возвращает его.
[HttpGet]
public ActionResult Preferences(long idUser)
{
context = new MainDatabaseEntities();
List<NotificationViewModel> notifications = new List<NotificationViewModel>();
SettingsViewModel settings = new SettingsViewModel();
//Population...
return View(settings);
}
однако, когда я хочу сохранить изменения, у меня есть ViewModel, который равен null, и я не понимаю, почему. Есть идеи, ребята?
редактировать: мой метод сообщения:
[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-код генерируется :
<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>
5 ответов
List<T>
может быть сложно при modelbinding, так как он сильно зависит от индексированных ключей. Помощники должны знать индекс, но путем присвоения notif
в вашем цикле for они теряют ссылку. Вместо этого попробуйте что-то вроде следующего:
@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/>
}
, который затем должен предоставить вам что-то вроде:
<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>
кроме того, не забудьте проверить ModelState.IsValid
в вашем опубликованном действии, чтобы подтвердить, что модель была привязана правильно. Если нет, вы должны увидеть список ошибок в ModelState
это даст вам некоторое представление о том, где он мог потерпеть неудачу.
кроме того, я не вижу, чтобы вы сваливали GroupDesc
в любом месте (за исключением выходных). Если это необходимо для входящей модели, вы можете использовать @Html.HiddenFor(x => x.ListNotifications[i].GroupDesc)
.
вы неправильно строите свой HTML. Что передается обратно не будет пути связыватель модели ожидает.
подумайте о замене этого:
@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/>
}
С этого:
@Html.DisplayModelFor(m => m.ListNotification)
и добавьте такой шаблон в /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>
моим первым предложением было бы попытаться добавить некоторое случайное свойство в вашу SettingValueModel и добавить его в форму как скрытый.
что-то вроде
public class SettingsViewModel
{
public List<NotificationViewModel> ListNotification { get; set; }
public string TestValue { get; set; }
public SettingsViewModel()
{
ListNotification = new List<NotificationViewModel>();
TestValue = "Test";
}
}
затем на ваш взгляд добавить
@Html.HiddenFor(s=> s.TestValue)
когда вы отправляете свою форму, проверьте, не является ли SettingsViewModel нулевым. Если проблема заключается только в сериализации ListNotification, вы можете получить объект с TestValue уведомлений "Test" и null List. Если это кейс, по крайней мере, вы знаете, что проблема в ListNotifications.
также попробуйте изменить цикл for На этот
@for (int i = 0; i < Model.ListNotification.Count(); i++ )
{
<tr>
<td>@Model.ListNotification[i].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>
также я не думаю, что FormMethod.Post требуется в определении формы. Попробуйте все это. Если никто из них не поможет, то я могу только предположить, что ваш компьютер преследует=)
в моем случае у меня были мои сеттеры как внутренние в моем определении модели представления по какой-то странной причине, поэтому привязка не могла быть установлена и сохранена:
public int PaymentType { get; internal set; }
в POST action вы используете правильный тип модели?
[HttpPost]
public ActionResult Preferences(PortailT2A.Models.SettingsViewModel model)
{
//...
}