現在、強く型付けされた2つのビューで構成されるフォームを投稿しようとしています。この質問は似ていますが、答えがありません。
MVC 3 Razor Form Post w /複数の厳密に型指定された部分ビューがバインドされていない
フォームを送信すると、コントローラーに送信されたモデルは常にnullです。これを機能させるために数時間費やしました。これは簡単なはずです。ここに何かが足りませんか?コントローラーに投稿して新しいページをレンダリングできるようにするだけで、ajaxを実行する必要はありません。
ありがとう
私のビューコードは次のとおりです。
<div>
@using (Html.BeginForm("TransactionReport", "Reports", FormMethod.Post, new {id="report_request"}))
{
ViewContext.FormContext.ValidationSummaryId = "valSumId";
@Html.ValidationSummary(false, "Please fix these error(s) and try again.", new Dictionary<string, object> { { "id", "valSumId" } });
@Html.Partial("_ReportOptions", Model.ReportOptions);
@Html.Partial("_TransactionSearchFields", new ViewDataDictionary(viewData) { Model = Model.SearchCriteria });
}
コントローラ内のコードは次のとおりです。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult TransactionReport(TransactionReportRequest reportRequest)
{
var reportInfo = new List<TransactionReportItem>();
if (ModelState.IsValid)
{
var reportData = _reportDataService.GetReportData(Search.MapToDomainSearchCriteria(reportRequest.SearchCriteria));
if (reportData!=null)
{
reportInfo = reportData.ToList();
}
return View(reportInfo);
}
return View(reportInfo);
}
部分ビュー自体は、モデルに入札して表示するだけなので、かなり無関係です。
パーシャルはここへ行く方法ではありません。 EditorTemplatesを探しています。これらはあなたが望むもののために作られています。この場合、プロパティはモデルにうまくバインドされます(送信する)。
メインビューには次の形式があります(EditorFor
の代わりにPartial
のみを使用する必要があることに注意してください。この場合、おそらくviewBagなどにそのviewDataパラメーターを配置する必要があります)。
@using (Html.BeginForm("TransactionReport", "Reports", FormMethod.Post, new {id="report_request"}))
{
ViewContext.FormContext.ValidationSummaryId = "valSumId";
@Html.ValidationSummary(false, "Please fix these error(s) and try again.", new Dictionary<string, object> { { "id", "valSumId" } });
@Html.EditorFor(model => model.ReportOptions);
@Html.EditorFor(model = Model.SearchCriteria });
}
これで、パーシャルをフォルダにドラッグするだけで_~/Shared/EditorTemplates/
そして、それらをエディタテンプレートのモデル名と一致するように名前を変更します。
の中に ~/Shared/EditorTemplates/
フォルダー、新しい「ビュー」、例「SearchCriteria.cshtml」を作成します。内部に、エディタテンプレートを作成するクラスのタイプを「モデル」として配置します。例(サンプルクラスにはプロパティName
およびOtherCriteria
があります):
@model MyNamespace.SearchCriteria
<ul>
<!-- Note that I also use EditorFor for the properties; this way you can "nest" editor templates or create custom editor templates for system types (like DateTime or String or ...). -->
<li>@Html.LabelFor(m => m.Name): @Html.EditorFor(m => m.Name)</li>
<li>@Html.LabelFor(m => OtherCriteria): @Html.EditorFor(m => m.OtherCriteria</li>
</ul>
それらについてのいくつかの良い読書:
PartialViewのフィールドにプレフィックスを追加する必要があります。これにより、データを正しくバインドできます。
代わりに:
@Html.Partial("_ReportOptions", Model.ReportOptions);
使用する:
@Html.Partial("_ReportOptions", Model.ReportOptions, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "ReportOptions" }})
@Styxxyと@Tonyに同意します。エディターテンプレートがより良いソリューションです。ただし、問題はサブモデルを部分ビューに供給していることです。したがって、部分ビューがレンダリングされるとき、それがより大きなモデルの一部であることを認識せず、正しい名前属性を生成しません。
エディターテンプレートではなくパーシャルを使用することを主張する場合は、モデルをパーシャルに渡すだけで、各パーシャルにModel.Whatever.Fooを実行させると、バインディングの正しい名前属性が生成されます。
Partialsの代わりにEditorTemplatesを使用してみてください http://coding-in.net/asp-net-mvc-3-how-to-use-editortemplates/ 。
@Html.Partial("_ReportOptions", Model.Contact, new ViewDataDictionary()
{
TemplateInfo = new TemplateInfo()
{
HtmlFieldPrefix = "Contact"
}
})
)
@Html.Partial("_TransactionSearchFields", Model.SearchCriteria, new
ViewDataDictionary()
{
TemplateInfo = new TemplateInfo()
{
HtmlFieldPrefix = "SearchCriteria"
}
})