3

アクション内で PartialView() を呼び出してレイアウトを使用する必要がありますか?

これが私のアクションです:

public ActionResult SomeAction()
{
    if (Request.IsAjaxRequest())
        return PartialView();
    else
        return View();

}

ここに私の _ViewStart.cshtml があります:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

シナリオ 1 : アクションは、レイアウトが指定されていないビューを呼び出します。

@{
    //Layout = "~/Views/Shared/_SomeLayout.cshtml";
}
<h2>View!</h2>
  • ビューの結果: ビューはレイアウトでラップされます
  • PartialView の結果: ビューはレイアウトにラップされていません

これは、Darin Dimitrov からのこの応答によって裏付けられています。

シナリオ #2 : アクションは、指定されたレイアウトでビューを呼び出します。

@{
    Layout = "~/Views/Shared/_SomeLayout.cshtml";
}
<h2>View!</h2>
  • ビューの結果: ビューはレイアウトでラップされます
  • PartialView の結果: ビューはまだレイアウトにラップされています

これは、Darin Dimitrov からのこの他の応答によっても裏付けられているようです。(注:彼の答えはAJAXリクエストの包括的なものですが、これはOPに2つのビュー(1つは完全でもう1つは部分)があるという質問への回答でした。)

最初に、Darin は、レイアウトが必要ない場合は PartialView() を使用すると説明していますが、2 つ目では、レイアウトが必要ない場合は回避策があると言っています。

私が欠けているものがあるかどうか、またはなぜそれがこのようになっているのか、誰かが私に説明できますか. Darin が何を言ったかに関係なく、レイアウトのみを設定した場合_ViewStart.cshtmlは PartialView() で無視できますが、ビュー自体に別のレイアウトを設定した場合は無視できません。

これは理にかなっていますか?両方のレイアウトを無視できるようにする必要がありますか? そうでない場合、なぜですか?

4

1 に答える 1

4

ページ全体または部分ページのレンダリング プロセスは、Razor では同じ基本クラスを使用しているため、同じです。レンダリング プロセスでは、フル ページと部分ページの両方で RazorView オブジェクトを作成しますが、コンストラクター パラメーターは異なります。ソース コードから、これらはビューをレンダリングするための 2 つの方法です。System.Web.Mvc 名前空間RazorViewEngine.cs

protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        return new RazorView(controllerContext, partialPath,
                                 layoutPath: null, runViewStartPages: false, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator)
        {
                DisplayModeProvider = DisplayModeProvider
        };
    }

protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        var view = new RazorView(controllerContext, viewPath,
                                     layoutPath: masterPath, runViewStartPages: true, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator)
        {
                DisplayModeProvider = DisplayModeProvider
        };
        return view;
    }

コンストラクターのパラメーターで、部分ビューを作成するときにそれを参照してlayoutPath:null,runViewStartPages:falseください。シナリオ 1 では、これが View がレイアウトにラップされているのに、partialView がラップされていない理由です。これらのメソッドによると、PartialView を返すときは ViewStart は実行されませんが、View を返すときは実行されます。

partialView のデフォルト レイアウトは、コンストラクター パラメーターで指定されているように null です。ただし、ViewActionResult が返された後、オーバーライドされたレイアウトが指定されている可能性があります。それが、シナリオ 2 で起こることです。宣言Layout = "~/Views/Shared/_SomeLayout.cshtml";することにより、あるパスにプロパティを指定WebPageBase.Layoutしていて、これがオーバーライドされますlayoutPath:null。PartialView() かみそりを返しても、完全なビューが生成されます。同じよう Layout = null;に、ビューで宣言した場合、コントローラーから View() を返した場合でも、Razor は partialView を生成します。したがって、ビューが部分ビューになるか完全ビューになるかは、または を返すView()かどうかによって決まりませんPartialView()。これは、Layout プロパティが null か何らかのパスかによって決まります。そのため、コードをより読みやすくするために、partialView を使用return PartialView()してビュー内で Layout を定義しない場合に使用します。

于 2015-08-15T13:41:07.243 に答える