MVC3 отправить модель пусто - PullRequest
2 голосов
/ 25 февраля 2012

У меня есть проблема, которую я не понимаю, и, кажется, нет простого способа отладить проблему. Я уверен, что это просто.

@model StartStop.ServiceResources.UserSettings

мой вид MVC3 привязан к конкретной модели;

 public class Setting
{
    public Int64 SettingID { get; set; }
    public Int64 UserID { get; set; }
    public int PreferenceType { get; set; }
    public string PreferenceName { get; set; }
    public bool PreferenceBool { get; set; }
    public int PreferenceInt { get; set; }
    public string PreferenceString { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ModifiedOn { get; set; }

}

public class UserSettings
{
    public Int64 UserID { get; set; }
    public List<Setting> Settings { get; set; }
}

представление перечисляет флажки, которые представляют список;

  @using (Html.BeginForm("ManageAccount","Account", FormMethod.Post))
        {
            <table class="tbl" cellspacing="0">

                <tr>
                    <th>Preference</th>
                    <th>Setting</th>
                </tr>

                @if (Model != null)
                {
                    foreach (var item in Model.Settings.ToList())
                    {
                        <tr>
                            <td>@item.PreferenceName
                            </td>
                            <td>
                                @if (item.PreferenceType == 2)
                                {
                                    @Html.CheckBoxFor(modelItem => item.PreferenceBool)
                                }
                            </td>
                        </tr>

                    }
                }
            </table>

            <input type="submit" value="Save Changes" class="action medium" />

        }

Все хорошо, я загружаю данные в представление, оно отображает и подбирает правильные настройки. Однако, когда я делаю пост внизу, модель представления возвращает ноль! Я не уверен, почему ...

 [HttpPost]
    [Authorize]
    public ActionResult ManageAccount(StartStop.ServiceResources.UserSettings model)
    {
        if (ModelState.IsValid)
        {

            foreach (StartStop.ServiceResources.Setting oSetting in model.Settings)
            {
                StartStop.Helpers.UserPreferences.SaveUserSetting(oSetting);
            }
        }
        return View(model); 
    }

Кто-нибудь может помочь?

1 Ответ

5 голосов
/ 25 февраля 2012

Проблема, по вашему мнению, в следующей строке:

@Html.CheckBoxFor(modelItem => item.PreferenceBool)

Я вижу, как люди часто пишут следующее лямбда-выражение modelItem => item.SomeProperty в своих представлениях и спрашивают, почему механизм связывания моделей неправильно связывает свойства коллекции в своих моделях представления.

Это не сгенерирует правильное имя для флажка, чтобы связыватель модели по умолчанию мог воссоздать коллекцию настроек. Я бы порекомендовал вам прочитать следующую запись в блоге , чтобы лучше понять правильный формат, который ожидает связующее для модели.

Попробуй так:

@model StartStop.ServiceResources.UserSettings
@using (Html.BeginForm("ManageAccount", "Account", FormMethod.Post))
{
    <table class="tbl" cellspacing="0">
        <tr>
            <th>Preference</th>
            <th>Setting</th>
       </tr>

       @if (Model != null)
       {
           for (var i = 0; i < Model.Settings.Count; i++)
           {
               <tr>
                   <td>@Model.Settings[i].PreferenceName</td>
                   <td>
                       @if (Model.Settings[i].PreferenceType == 2)
                       {
                           @Html.CheckBoxFor(x => x.Settings[i].PreferenceBool)
                       }
                    </td>
                </tr>
           }
       }
    </table>

    <input type="submit" value="Save Changes" class="action medium" />
}

При этом я бы порекомендовал вам использовать шаблоны редакторов, например:

@using (Html.BeginForm("ManageAccount","Account", FormMethod.Post))
{
    <table class="tbl" cellspacing="0">
        <tr>
            <th>Preference</th>
            <th>Setting</th>
       </tr>

       @if (Model != null)
       {
           @Html.EditorFor(x => x.Settings)
       }
    </table>

    <input type="submit" value="Save Changes" class="action medium" />
}

и затем определите пользовательский шаблон редактора, который будет автоматически отображаться для каждого элемента Settings коллекции (~/Views/Shared/EditorTemplates/Setting.cshtml):

@model StartStop.ServiceResources.Setting
<tr>
    <td>@Model.PreferenceName</td>
    <td>
         @if (Model.PreferenceType == 2)
         {
             @Html.CheckBoxFor(x => x.PreferenceBool)
         }
     </td>
 </tr>

Также единственное поле ввода, которое я вижу в этой форме, - это флажок, связанный со свойством PreferenceBool в вашей модели. Таким образом, в вашем действии контроллера POST вы инициализируете свойство списка настроек, но не ожидаете найти какие-либо значения для других свойств в этом классе Setting, если, конечно, вы не включите поля ввода для них в форму (а более точно шаблон редактора, который я показал).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...