ASP.NET MVC 3かみそりのViewStartファイルで異なるレイアウトを指定するにはどうすればよいですか?


313

アプリケーションに2つの個別のレイアウトを設定したいのですが。1つはWebサイトのパブリックセクション用で、もう1つはメンバー側用だとします。

簡単にするために、これらの各サイトのすべてのロジックが2つの異なるコントローラーにきれいにラップされているとしましょう。

  • PublicController
  • StaffController

そして、それらはそれぞれ、その下のすべてのビューに対応するレイアウトを持っています。

  • _PublicLayout.cshtml
  • _StaffLayout.cshtml

_ViewStart.cshtmlファイルを使用して、「パブリック」の下のすべてのビュー/アクションがPublicLayoutを使用し、「スタッフ」の下のすべてがStaffLayoutを使用することを指定するにはどうすればよいですか?

ありがとう!


4
念のため:特定のRazorビューのレイアウトを削除する場合は、次のように設定してくださいLayout = null;
Leniel Maccaferri '19 / 03/14

3
例に対するコメントと同様に、PublicおよびStaffという名前のコントローラーはおそらくないはずです。ほとんどの場合、コントローラーは、EventController、UserControllerなどの特定の主要なビジネスエンティティに対するCRUDのようなアクションへのエントリポイントとして実装されます。アプリケーションがかなり大きい場合は、Public / Staffコントローラーの責任が大きくなります。代わりにエリアを検討してください。msdn.microsoft.com/en-us/library/ee671793%28VS.100%29.aspxあなたはこれに気づいているかもしれませんが、これを読んでいる誰かが間違った考えを持っているかもしれません。
Alex

回答:


558

フォルダ_ViewStart.cshtml内の/Views/Publicデフォルトのファイルをオーバーライドするファイルをフォルダ内に/Views配置し、目的のレイアウトを指定できます。

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

類推すると_ViewStart.cshtml、次のように/Views/Staffフォルダ内に別のファイルを置くことができます:

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

コントローラアクション内でビューを返すときに使用するレイアウトを指定することもできますが、これはアクションごとです。

return View("Index", "~/Views/Shared/_StaffLayout.cshtml", someViewModel);

さらに別の可能性は、レイアウトをオーバーライドするカスタムアクションフィルターです。あなたがこれを達成するための多くの可能性を見ることができるように。シナリオに最適なものを選択するのはあなた次第です。


更新:

コメントセクションで要求されているように、マスターページを選択するアクションフィルターの例を次に示します。

public class LayoutInjecterAttribute : ActionFilterAttribute
{
    private readonly string _masterName;
    public LayoutInjecterAttribute(string masterName)
    {
        _masterName = masterName;
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.MasterName = _masterName;
        }
    }
}

次に、必要なレイアウトを指定するこのカスタム属性を使用して、コントローラーまたはアクションを装飾します。

[LayoutInjecter("_PublicLayout")]
public ActionResult Index()
{
    return View();
}

1
@DarinDimitrov私が作成する場所LayoutInjecterAttribute。?特定の場所はありますか?
kbvishnu 2012

2
@VeeKeyBee、それをActionFiltersサブフォルダー内に置くことができます。
Darin Dimitrov

の1つの潜在的な問題LayoutInjecterAttribute:これは、コントローラーのメソッドのに呼び出されOnExceptionます。したがって、例外処理中にコントローラーがビュー結果を提供する場合、レイアウトは設定されません。
Jeff Sharp 14

MVCの新しい人として、この回答でたくさん教えてくれてありがとう。しかし、私は内部で何が起こっているのか理解できませんOnActionExecuted。答えを更新してください。
Imad

29

もう1つの方法は、ビュー内のレイアウトを定義することです。

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

他の方法がここにあります。これが誰かの役に立つことを願っています。


1
これは機能しません-別の_ViewStart.cshtmlがないと、ビューは他のレイアウトの@RenderBody()メソッド内でレンダリングされます。
Tillman32、2016

この!なぜあなたがやらなければならないのに、誰もがこれらの非常に複雑なプロセスを進めているのですか?
George Harnwell、2018

15

このメソッドは、初心者がASP.NET MVCアプリケーションでレイアウトのレンダリングを制御する最も簡単な方法です。コントローラを識別し、レイアウトを標準コントローラとしてレンダリングできます。これを行うには、Viewsフォルダのルートディレクトリにある_ViewStartファイルにコードを記述します。次の例は、その方法を示しています。

@{
    var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
    string cLayout = "";

    if (controller == "Webmaster")
        cLayout = "~/Views/Shared/_WebmasterLayout.cshtml";
    else
        cLayout = "~/Views/Shared/_Layout.cshtml";

    Layout = cLayout;
}

完全な記事を読むここでは、「ASP.NET MVCで異なるレイアウトをレンダリングする方法」

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.