ビューにコレクションにタイプされたビューがあるとします。 List<ItemViewModel>
:NameForは、エディタテンプレートのコレクションを反復処理するときに不正な名前を生成します。
@model List<ItemViewModel>
@for(int i = 0; i < Model.Count; i++)
{
@Html.EditorFor(m => m[i].Foo)
@Html.EditorFor(m => m[i].Bar)
}
Foo
とBar
は、単純に文字列プロパティです。
[i].Foo
と[i].Bar
という形式のHTML名前属性を生成します。これはもちろん正しい形式であり、フォームに投稿すると正しくバインドされます。
次に上記ビューはそうようにレンダリングされるエディタテンプレート、(Model.Items
がList<ItemViewModel>
である)であることが、代わりに、仮定:
@model WrappingViewModel
@Html.EditorFor(m => m.Items)
突然、エディタテンプレート内で生成名 - Items.[i].Foo
のような形式です。デフォルトのモデルバインダーは、Items[i].Foo
という形式を想定しているため、バインドできません。
これは、最初のシナリオでは正常に動作します - ビューは、エディタのテンプレートではありません - と、コレクションではなく、モデル全体よりも、財産です正常に動作します:
@Html.EditorFor(m => m.Items[i].Foo)
それはときにのみ失敗しますモデル自体はコレクションとです。ビューはエディタテンプレートです。
この回避作業のいくつかの方法がありますが、いずれも理想的です。
- タイプ
ItemViewModel
の個々のインスタンスに、エディタテンプレートは - これは、問題の実際のテンプレートが追加のマークアップが含まれていると良くありませんコレクションに追加する/削除するテンプレート内のコレクション全体を操作できるようにする必要があります。 - 別のプロパティでを実装するなどして別のプロパティをラップしてテンプレートに渡します。これは不必要なラッピングビューモデルで混乱することのないエンタープライズアプリケーションであるため、これは理想的ではありません。
- 正しい名前を生成するために、内部エディタテンプレートのマークアップを手動で生成します。これは現在行っていることですが、HtmlHelpersの柔軟性を失うため避けたいと思います。
だから、質問:それはわずかな変化のために正常に動作したときに、なぜ展示は、この特定のシナリオでは、この動作NameFor
(したがってEditorFor
)ない(すなわち、それは意図的であると、もしそうなら、なぜ)?上記の欠点もなくこの問題を回避する簡単な方法はありますか?
モデル::
public class WrappingViewModel
{
[UIHint("_ItemView")]
public List<ItemViewModel> Items { get; set; }
public WrappingViewModel()
{
Items = new List<ItemViewModel>();
}
}
public class ItemViewModel
{
public string Foo { get; set; }
public string Bar { get; set; }
}
コントローラのアクション:
public ActionResult Index()
{
var model = new WrappingViewModel();
model.Items.Add(new ItemViewModel { Foo = "Foo1", Bar = "Bar1" });
model.Items.Add(new ItemViewModel { Foo = "Foo2", Bar = "Bar2" });
return View(model);
}
インデックス再現する要求された、完全なコードとして
。CSHTML:
@model WrappingViewModel
@using (Html.BeginForm())
{
@Html.EditorFor(m => m.Items)
<input type="submit" value="Submit" />
}
_ItemView.cshtml(エディタテンプレート):
@model List<ItemViewModel>
@for(int i = 0; i < Model.Count; i++)
{
@Html.EditorFor(m => m[i].Foo)
@Html.EditorFor(m => m[i].Bar)
}
名前がFoo
属性とBar
入力フォームModel.[i].Property
のものであろうとしてアクションメソッドに投稿された際に戻って結合しません署名。上記のように、Items
をメインビューまたはに戻した場合は、WrappingViewModel
を取り除き、トップレベルモデルをList<ItemViewModel>
にしてModel
に直接反復すると、これはうまく動作します。この特定のシナリオでのみ失敗します。
ように、コードのその部分をラップする方が良いでしょうか?あなたはどんなパラメーターを期待していますか? –
@AlexanderSimonov少し後で問題を再現するためのソースコードを投稿します。 –
@AlexanderSimonov要求に応じて、完全な再現可能なコードが掲載されています。 –