繁体   English   中英

发布后,MVC4复杂类型模型为空

[英]MVC4 Complex Type Model is null after post

这是我的模特

public class AdministrationModel
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string EmailAddress { get; set; }
  public bool IsApproved { get; set; }
}

这是我的控制器

public ActionResult GetTabContent(string id)
{
  switch (id)
  {
   case "tab3":
   model = GetAllUsersInfo();
   viewName = "Administration";
   break;
   }
   return View(viewName);
 }

  private List<AdministrationModel> GetAllUsersInfo()
  {
    List<AdministrationModel> userList = new List<AdministrationModel>();
    foreach (MembershipUser user in Membership.GetAllUsers())
    {
      UserProfile userProfile = UserProfile.GetUserProfile(user.UserName);
      userList.Add(new AdministrationModel { EmailAddress = user.Email,                       IsApproved = user.IsApproved, FirstName = userProfile.FirstName, LastName = userProfile.LastName });
    }

    return userList;
  }

这是我的观点

@model List<AdminContainerModel>
@using (Html.BeginForm("Administration", "Account"))
{
  <fieldset>
    <div>
      @foreach (AdministrationModel AM in Model)
      {
        <div>
         <div class="colFull">@Html.DisplayFor(modelItem => AM.FirstName)</div>
         <div class="colFull">@Html.DisplayFor(modelItem => AM.LastName)</div>
         <div class="colFull">@Html.DisplayFor(modelItem => AM.EmailAddress)</div>
         <div class="colPartial"><input type="checkbox" checked="@AM.IsApproved"/>            </div>
      <div class="clear"></div>
    </div>
  }
</div>
 <input type="submit" value="Update Account" />
 </fieldset>
}

当用户单击“更新帐户”按钮时,它将转到控制器

  [HttpPost]
  public ActionResult Administration(List<AdministrationModel> model)
  {
     return View();
  }

在此方法中,模型始终为null。 然而,呈现一切的视图是完美的,并展示了我想要展示的内容。 我究竟做错了什么?

使用集合时,为了正确处理它们以便它们在帖子上进行模型绑定而不需要任何额外的工作,您需要确保它们被正确编入索引,您可以通过使用for循环来完成此操作,例如:

@for (int i = 0; i < Model.Count; i++)
{
    @Html.HiddenFor(m => m[i].FirstName)
    @Html.HiddenFor(m => m[i].LastName)
    @Html.HiddenFor(m => m[i].EmailAddress)
    <div>
        <div class="colFull">@Html.DisplayFor(m => m[i].FirstName)</div>
        <div class="colFull">@Html.DisplayFor(m => m[i].LastName)</div>
        <div class="colFull">@Html.DisplayFor(m => m[i].EmailAddress)</div>
        <div class="colPartial">@Html.CheckBoxFor(m => m[i].IsApproved)</div>
        <div class="clear"></div>
    </div>
}

这应该模型绑定没有任何其他代码:)

编辑:对不起我忘了,displayFors默认情况下没有为模型绑定添加正确的属性,为没有editorFor的其他字段添加了hiddenFors

编辑2:根据评论中的其他问题,如果它是面向公众的,并且您不希望他们使用开发工具更改任何隐藏的值,请尝试以下操作:

好的,所以你不希望他们改变hiddenFors,这很好,但是你需要某种ID,这样你就知道哪个客户端在发布数据的时候,我建议不要在上面的代码中使用这些:

@Html.HiddenFor(m => m[i].FirstName)
@Html.HiddenFor(m => m[i].LastName)
@Html.HiddenFor(m => m[i].EmailAddress)

替换为:

@Html.HiddenFor(m => m[i].ClientId)

这样你就不会回复名字,姓氏或电子邮件地址,只是对未勾选的实际客户的引用。

要在关于跟踪原始值的注释中回答您的其他问题,您可以在控制器方法中从数据库中获取原始值,然后在此处检测哪些是不同的,例如:

[HttpPost]
public ActionResult Administration(List<AdministrationModel> model)
{
    var originalMatches = GetAllUsersInfo();

    var differences = (from o in originalMatches
                      join c in model on o.ClientId equals c.ClientId
                      where c.IsApproved != o.IsApproved).ToList()

    return View();
}

您的@model指令不正确,它应该是完全限定的类型名称。

在这种情况下:

 @model TheNamespace.AdministrationModel

更新后的问题。

尝试使用:

@Html.EditorFor(Model)

这将为您的列表调用专用的编辑器模板

http://blogs.msdn.com/b/nunos/archive/2010/02/08/quick-tips-about-asp-net-mvc-editor-templates.aspx

如果要在提交时返回包含模型的列表项,则需要使用for循环,而不是foreach

马蒂的回答将起作用。

如果您想避免必须指定索引(如果您有ICollection则无法工作),您可以像Xander所解释的那样定义子模板。

好处是你仍然可以在AdminContainerModel视图中获得所有强类型的智能感知,并且MVC将这些项目挂回到你的列表中,然后开箱即用。

这是一个例子:

主编辑模板(正如Xander所说):

    @model IEnumerable<AdminContainerModel>
    @using (Html.BeginForm("Administration", "Account"))
    {
      <fieldset>
        <div>
          @Html.EditorForModel()
        </div?
      </fieldset>
    }

AdminContainerModel编辑器模板(为列表中的每个项调用此模板,因为您调用了@ Html.EditorForModel:

@model AdminContainerModel
<div>
    <div class="colFull">@Html.DisplayFor(modelItem => AM.FirstName)</div>
    <div class="colFull">@Html.DisplayFor(modelItem => AM.LastName)</div>
    <div class="colFull">@Html.DisplayFor(modelItem => AM.EmailAddress)</div>
    <div class="colPartial"><input type="checkbox" checked="@AM.IsApproved"/>            
</div>
<div class="clear"></div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM