4

This is my model

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

This is my controller

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;
  }

This is my View

@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>
}

When the user clicks the Update Account button it goes to the controller

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

inside this method, model is always null. however the View that renders everything is perfect and shows what I want it to show. What am I doing wrong?

4

4 回答 4

10

使用集合时,为了正确处理它们,以便它们在帖子上绑定模型而无需任何额外的工作,您需要确保它们被正确索引,您可以通过使用 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

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

好的,所以您不希望他们更改 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();
}
于 2012-04-19T16:56:52.617 回答
1

您的@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

于 2012-04-18T21:24:01.353 回答
0

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

于 2013-09-26T16:25:06.337 回答
0

马蒂的回答会奏效。

如果您想避免必须指定索引(如果您有 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>
于 2014-01-15T16:32:52.293 回答