1

このビューは、ブール値に基づいてモデルの各アイテムに対して強く型付けされたチェックボックスを作成するモデルのリストに基づいています。

これが私の見解です:

@using MyApp.Models
@model IList<MyApp.Models.ObjInfo>

@{
    ViewBag.Title = "Obj Inventory";
}

<h2>Search Inventory</h2>

<p>
    @using (Html.BeginForm())
    {
        (Many search filters which are non-relevant)
        <p>
            Send Items: @Html.ActionLink("Click Here", "SendItems")
        </p>
    }
<table>
    <tr>
        <th>
            Obj Name
        </th>
        <th>
            Number In Stock
        </th>
        (...)
        <th>
            Select Item
        </th>
    </tr>
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.OtherObj.m_Name)
        </td>
        (...)
        <td>
            @Html.CheckBoxFor(modelItem => item.m_IsSelected)
        </td>
    </tr>
}

</table>

プロセス全体が正常に機能し、モデルのリストの各項目のチェックボックスを備えたビューを実際に生成できます。

ここで私の質問は、チェックされたリスト内のアイテムのみを再グループ化してコントローラーに送信するリストを作成したいということです。どうすればそれができますか?誰かが私を助けたり、私に働く方法を提案したりできますか?

ありがとうございました!

* 編集 *

以下に説明するように、アイテムのリストを取得するために使用されるHttpPostメソッドは次のとおりです。

//
        // GET: /Inventory/SendItems
        [HttpPost]
        public ActionResult SendItems(IList<ObjInfo> listToSend)
        {
            m_ListObjToSend = new List<ObjInfo>();

            foreach (var item in listToSend.Where(item => item.m_IsSelected))
            {
                m_ListObjToSend .Add(item);
            }

            return View(m_ListObjToSend );
        }

しかし、私は多くの問題に遭遇しました:

  • [HttpPost]属性を設定すると、このメソッドは機能しません(「見つかりません」と表示されます)。
    • 私が受け取ることになっているリストはnullです。
    • チェックボックスにリンクされている各非表示フィールドのデフォルト値は、チェックされた値がtrueを示している場合でもfalseです。
    • ボタンを使いたくないので、アクションリンクを使用しています。すでに別の仕事をしているボタンがあります。

コメントやヘルプをお待ちしております。ありがとうございます。

4

1 に答える 1

3

CheckBoxForヘルパーを使用してチェックボックスを生成すると、各チェックボックスとともに追加の非表示フィールドが生成されることに気付くでしょう。これは、すべての値がコントローラーに送信され、チェックされた値をコントローラーでフィルター処理する必要があることを意味します。

また、適切なモデルバインディングを確保するために、インデックスを使用することをお勧めします。ビューに渡す前に、ビューモデルでメソッドまたは拡張メソッドを呼び出すことで簡単に実現できるIList<ObjInfo>orを使用する必要があります。ObjInfo[].ToList().ToArray()

@using MyApp.Models
@model IList<ObjInfo>
...
@for (var i = 0; i < Model.Count; i++) 
{
    <tr>
        <td>
            @Html.DisplayFor(x => x[i].OtherObj.m_Name)
        </td>
        (...)
        <td>
            @Html.CheckBoxFor(x => x[i].m_IsSelected)
        </td>
    </tr>
}
...

そして今、あなたのコントローラーアクションはアイテムのリストを直接取ることができます:

[HttpPost]
public ActionResult SomeAction(IEnumerable<ObjInfo> model)
{
    ...
}

選択した値を見つけたい場合は、LINQから簡単に取得できます。

[HttpPost]
public ActionResult SomeAction(IEnumerable<ObjInfo> model)
{
    var selectedItems = model.Where(x => x.m_IsSelected);
    ...
}

備考: C#m_Nameのプロパティの命名規則m_IsSelected悲惨なほど悪いものです。


アップデート:

コードに関するもう1つの問題はHtml.BeginForm、入力フィールドが含まれていないことです。明らかにGETリクエストのみを実行するActionLinkは1つだけです。値を送信する場合は、テーブル全体をフォームでラップし、アクションリンクではなく送信ボタンを使用する必要があります。

@using MyApp.Models
@model IList<ObjInfo>

@{
    ViewBag.Title = "Obj Inventory";
}

<h2>Search Inventory</h2>

<p>
    @using (Html.BeginForm("SendItems", null, FormMethod.Post))
    {
        (Many search filters which are non-relevant)

        <table>
            <tr>
                <th>Obj Name</th>
                <th>Number In Stock</th>
                (...)
                <th>Select Item</th>
           </tr>
        @for (var i = 0; i < Model.Count; i++) 
        {
            <tr>
                <td>
                    <!-- 
                    This will not be sent to your controller because it's only a label.
                    You will need a corresponding hidden field if you want to get that value back
                    -->
                    @Html.DisplayFor(x => x[i].OtherObj.m_Name)
                </td>
                (...)
                <td>
                    @Html.CheckBoxFor(x => x[i].m_IsSelected)
                </td>
            </tr>
        }
        </table>

        <p>
            Send Items: <button type="submit">Click Here</button>
        </p>
    }
</p>

だから本当に、あなたが学ぶべき2つのこと:

  1. naming conventionリストにバインドするときにデフォルトのモデルバインダーが期待する
  2. サーバーに送信されるすべての値を検査し、1で学習した規則を尊重しているかどうかをすぐに認識できるようにする、javascriptデバッグツール(FireBugやChrome Developperツールバーなど)の使用方法。
于 2013-03-07T16:55:17.837 に答える