問題は、ビューが生成されるときに各項目に対して生成される名前にあります。モデル バインダーは、名前と値のペアを使用して、コントローラーで予期されるビュー モデルにフォームの値をマップする方法を見つけます。
を使用していた場合@Html.HiddenFor(m=>m[i].Id)
は問題なく、HTML に次の name 属性が生成されます。
name="[0].ModelId"
後のものは
name="[5].ModelId"
など。
ビューで生成される HTML は次のとおりです。
ここには 2 つの問題があります。
- 名前の先頭に値「selection」が表示されます
- 配列インデックスとしてゼロを2回使用しています
これは、末尾に for を持つすべての HTML タグ (HiddenFor、TextboxFor など) が機能するために発生します。ラムダ式に基づいて名前属性を決定します-m => m[0].ModelId
最初のもので使用[0].ModelId
していたため、名前として使用されました。2番目では、を使用するm=> selection[0].ModelId
ため、使用selection[i].ModelId
されます(ラムダの一部として使用した変数はすべて削除されます.
それで、これをどのように修正しますか?
現在のセットアップでは、2 つの方法のいずれかでこれにアプローチできます。ループの外側でカウンターを使用してそれを配列インデックスとして使用するか、追加の非表示フィールドをインデックス フィールドとして使用することができます。どちらのアプローチでも、生成される HTML 要素の名前を手動で設定できるように、厳密に型指定された HiddenFor/TextBoxFor を削除し、代わりに Hidden/TextBox を使用する必要があります。
インデックス フィールドで何が起こるかは、次のようなアイテム名を持っていることです。
<input type="hidden" name="Index" value="Model1"/>
<input type="hidden" name="[Model1].ModelId" value="1"/>
<input type="hidden" name="[Model1].ModelValue" value="Some value"/>
最初の入力タグでは、これを index と呼び、この関連する一連の値のインデックスとして機能する値を設定しました。残りのものでは、最初の値として設定された値を配列インデックスとして使用し、次にプロパティの名前のみを使用しました。このアプローチは、リストにアイテムを追加/削除している状況にあり、ポストバックするときにすべての番号が順番にあることを保証できない場合に特に役立ちます.
Razor コードは次のようになります。
for (int i = 0; i < selection.Count(); i++) {
@Html.Hidden("Index", "Model"+selection[i].ModelId)
@Html.Hidden("[Model"+selection[i].ModelId + "].ModelId", selection[i].ModelId)
@Html.Hidden("[Model"+selection[i].ModelId + "].CreateDate", selection[i].CreateDate)
@Html.Hidden("[Model"+selection[i].ModelId + "].ModelValue", selection[i].ModelValue)
補足として、インデックスの一部として「モデル」という単語を含めることを選択したので、配列内の番号の場所ではなく、辞書のようなエントリとして参照していることを確実に認識できます。絶対にそのようにする必要があるかどうかはわかりません。実際に他の方法を試したことはありません。ModelId をインデックス値として使用しました。これは、一意の値であることが望ましいためです。
最終結果は、次のような HTML を生成する必要があります (name 属性に関して):
うまくいけば、それは役に立ちます!