mvc3提交模型为空

phi*_*ird 2 asp.net-mvc-3

我有一个我不明白的问题,似乎没有一个简单的方法来调试问题.我确信这很简单.

@model StartStop.ServiceResources.UserSettings
Run Code Online (Sandbox Code Playgroud)

我的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; }
}
Run Code Online (Sandbox Code Playgroud)

视图列出了代表列表的复选框;

  @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" />

        }
Run Code Online (Sandbox Code Playgroud)

一切都很好,我将数据加载到视图中,呈现视图并获取正确的设置.但是,当我在底部发帖时,视图模型返回null!我不确定为什么......

 [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); 
    }
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙吗?

Dar*_*rov 5

问题出在您视图的以下行中:

@Html.CheckBoxFor(modelItem => item.PreferenceBool)
Run Code Online (Sandbox Code Playgroud)

我看到人们modelItem => item.SomeProperty经常在他们的视图中编写以下lambda表达式,并询问为什么模型绑定器没有正确地绑定其视图模型上的集合属性.

这不会为复选框生成正确的名称,以便默认模型绑定器能够重新创建Settings集合.我建议您阅读以下博客文章,以更好地了解模型绑定器所需的正确格式.

试试这样:

@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" />
}
Run Code Online (Sandbox Code Playgroud)

话虽如此,我建议您使用编辑器模板,如下所示:

@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" />
}
Run Code Online (Sandbox Code Playgroud)

然后定义一个自定义编辑器模板,该模板将自动为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>
Run Code Online (Sandbox Code Playgroud)

此外,我在此表单中可以看到的唯一输入字段是绑定到PreferenceBool模型属性的复选框.因此,在POST控制器操作中,您将初始化Settings列表属性,但不希望在此类中找到其他属性的任何值,Setting除非您在表单中包含它们的输入字段(更准确地说,在编辑器模板中)我已经表明了).