簡體   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