web-dev-qa-db-ja.com

複数の部分ビューを持つフォームを投稿する

現在、強く型付けされた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);
}

部分ビュー自体は、モデルに入札して表示するだけなので、かなり無関係です。

33
dalcantara

パーシャルはここへ行く方法ではありません。 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>

それらについてのいくつかの良い読書:

53
Styxxy

PartialViewのフィールドにプレフィックスを追加する必要があります。これにより、データを正しくバインドできます。

代わりに:

@Html.Partial("_ReportOptions", Model.ReportOptions);

使用する:

@Html.Partial("_ReportOptions", Model.ReportOptions, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "ReportOptions" }})
13

@Styxxyと@Tonyに同意します。エディターテンプレートがより良いソリューションです。ただし、問題はサブモデルを部分ビューに供給していることです。したがって、部分ビューがレンダリングされるとき、それがより大きなモデルの一部であることを認識せず、正しい名前属性を生成しません。

エディターテンプレートではなくパーシャルを使用することを主張する場合は、モデルをパーシャルに渡すだけで、各パーシャルにModel.Whatever.Fooを実行させると、バインディングの正しい名前属性が生成されます。

10

Partialsの代わりにEditorTemplatesを使用してみてください http://coding-in.net/asp-net-mvc-3-how-to-use-editortemplates/

4
magritte
@Html.Partial("_ReportOptions", Model.Contact, new ViewDataDictionary()
           {
               TemplateInfo = new TemplateInfo()
                   {
                       HtmlFieldPrefix = "Contact"
                   }
           })

)


@Html.Partial("_TransactionSearchFields", Model.SearchCriteria, new  
 ViewDataDictionary()
           {
               TemplateInfo = new TemplateInfo()
                   {
                       HtmlFieldPrefix = "SearchCriteria"
                   }
           })
2
Kesikan K