4

これは私のモデルです

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です。ただし、すべてをレンダリングするビューは完璧で、表示したいものを表示します。私は何が間違っているのですか?

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

送信時にモデルとともにリストアイテムを返したい場合は、foreachではなくforループを使用する必要があります

于 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 Editorテンプレート(@ 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 に答える