mvc3提交模型为空

时间:2012-02-25 09:49:19

标签: asp.net-mvc-3

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

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

        }

一切都很好,我将数据加载到视图中,呈现视图并获取正确的设置。但是,当我在底部发帖时,视图模型返回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); 
    }

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:5)

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

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

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

这不会为复选框生成正确的名称,以便默认模型绑定器能够重新创建Settings集合。我建议你阅读following blog post以更好地理解模型绑定器所期望的正确格式。

试试这样:

@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控制器操作中,您将初始化Settings列表属性,但不希望在此Setting类中找到其他属性的任何值,除非您在表单中包含它们的输入字段(以及更多)正是在我所展示的编辑器模板中。