サンプルMVC 3アプリケーションには、以下に示すSimpleModel
とComplexModel
の2つのモデルがあります。
public class SimpleModel
{
public string Status { get; set; }
}
public class ComplexModel
{
public ComplexModel()
{
Simple = new SimpleModel();
}
public SimpleModel Simple{ get; set; }
}
このモデルのビューを定義しました:
_SimplePartial.cshtml
:
@model SimpleModel
@Html.LabelFor(model => model.Status)
@Html.EditorFor(model => model.Status)
およびComplex.cshtml
:
@model ComplexModel
@using (Html.BeginForm()) {
@Html.Partial("_SimplePartial", Model.Simple)
<input type="submit" value="Save" />
}
Status
フィールドにランダムな値を入力してフォームを送信すると、値はモデルにバインドされません。コントローラーアクションでモデルをチェックしているとき、Status
フィールドはNULL
です。
[HttpPost]
public ActionResult Complex(ComplexModel model)
{
// model.Simple.Status is NULL, why ?
}
なぜバインドされていないのですか?モデルを継承したくありません。このような単純なケースでは、カスタムモデルバインダーを作成する必要がありますか?
よろしく。
の代わりに:
@Html.Partial("_SimplePartial", Model.Simple)
Editorテンプレートを使用することをお勧めします。
@model ComplexModel
@using (Html.BeginForm())
{
@Html.EditorFor(x => x.Simple)
<input type="submit" value="Save" />
}
~/Views/Shared/EditorTemplates/SimpleModel.cshtml
または~/Views/Home/EditorTemplates/SimpleModel.cshtml
内に単純なパーシャルを配置します。ここで、Home
はコントローラーの名前です。
@model SimpleModel
@Html.LabelFor(model => model.Status)
@Html.EditorFor(model => model.Status)
もちろん、パーシャルをいくつかの特別な場所に置き、慣例に従わない場合(なぜですか?)、場所を指定できます。
@Html.EditorFor(x => x.Simple, "~/Views/SomeUnexpectedLocation/_SimplePartial.cshtml")
その後、すべてが期待どおりに配置されます。
ダニエルホールが彼のブログで提案しているように 、ViewDataDictionary
にTemplateInfo
を渡します。ここで、HtmlFieldPrefix
はSimpleModelプロパティの名前に設定されます。
@Html.Partial("_SimplePartial", Model.Simple, new ViewDataDictionary(ViewData)
{
TemplateInfo = new System.Web.Mvc.TemplateInfo
{
HtmlFieldPrefix = "Simple"
}
})