80

ビューエンジンとしてRazorを使用しているMVC3サイトがあります。自分のサイトをスキニングできるようにしたい。可能なスキンのほとんどは、共有マスターレイアウトから派生できるほど十分に類似しています。

したがって、私はこの設計を検討しています。

平面図

RenderSectionただし、最下層のを呼び出して、最上層_Common.cshtmlで定義されたセクションをレンダリングできるようにしたいと思いますDetail.cshtml。これは機能しません。RenderSection明らかに、次のレイヤーで定義されているセクションのみをレンダリングします。

もちろん、各スキンの各セクションを定義できます。たとえば、で定義されたセクション_Commonを呼び出す必要がある場合は、これをそれぞれに配置するだけで機能します。RenderSection("hd")Detail_Skin

@section hd {
    @RenderSection("hd")
}

これにより、コードが重複し(各スキンに同じセクションが必要になるため)、一般的に乱雑に感じます。私はまだRazorを初めて使用しているので、明らかな何かが欠けているようです。

デバッグ時に、WebViewPage.SectionWritersStackで定義されたセクションの完全なリストを確認できます。諦める前にリスト全体を調べるようにRenderSectionに指示できれば、必要なセクションが見つかります。残念ながら、SectionWritersStackは非公開です。

または、レイアウトページの階層にアクセスして、それぞれの異なるコンテキストでRenderSectionの実行を試みることができれば、必要なセクションを見つけることができます。私はおそらく何かが足りないのですが、これを行う方法がわかりません。

すでに概説した方法以外に、この目標を達成する方法はありますか?

4

4 に答える 4

36

これは、実際には、パブリックAPIを使用して(セクション再定義アプローチを使用する場合を除いて)今日は不可能です。プライベートリフレクションを使用して運が良かったかもしれませんが、それはもちろん壊れやすいアプローチです。Razorの次のバージョンでは、このシナリオをより簡単にすることを検討します。

それまでの間、私がこのテーマについて書いたブログ投稿をいくつか紹介します。

于 2011-04-03T04:48:30.583 に答える
17
@helper ForwardSection( string section )
{
   if (IsSectionDefined(section))
   {
       DefineSection(section, () => Write(RenderSection(section)));
   }
}

これは仕事をしますか?

于 2011-10-15T21:37:44.377 に答える
4

これがMVC3で可能かどうかはわかりませんが、MVC 5では、次のトリックを使用してこれを正常に行うことができます。

~/Views/Shared/_Common.cshtmlのような一般的なHTMLコードを記述します。

<!DOCTYPE html>
<html lang="fa">
<head>
    <title>Skinnable - @ViewBag.Title</title>
</head>
<body>
@RenderBody()
</body>
</html>

~/Views/_ViewStart.cshtml

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

今、あなたがしなければならないのは、すべてのスキンの_Common.cshtmlとしてを使用することです。Layoutたとえば、~/Views/Shared/Skin1.cshtml

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

<p>Something specific to Skin1</p>

@RenderBody()

これで、基準に基づいて、コントローラーまたはビューでスキンをレイアウトとして設定できます。例えば:

    public ActionResult Index()
    {
        //....
        if (user.SelectedSkin == Skins.Skin1)
            return View("ViewName", "Skin1", model);
    }

上記のコードを実行すると、との両方のコンテンツを含むHTMLページが表示されますSkin1.cshtml_Common.cshtml

つまり、(スキン)レイアウトページのレイアウトを設定します。

于 2013-12-29T15:13:42.610 に答える
1

これが役立つかどうかはわかりませんが、パーシャル内からセクションを「バブルアップ」するのに役立つ拡張メソッドをいくつか作成しました。これは、ネストされたレイアウトでも機能するはずです。

RazorViewEngineを使用した部分ビューASP.NETMVC3から特定のセクションにコンテンツを挿入する

子のレイアウト/ビュー/部分で宣言する

@using (Html.Delayed()) {
    <b>show me multiple times, @Model.Whatever</b>
}

任意の親でレンダリング

@Html.RenderDelayed();

繰り返しビューで宣言されている場合でも1つの遅延ブロックのみをレンダリングする、特定の遅延ブロックをレンダリングするなど、その他のユースケースについては、回答リンクを参照してください。

于 2014-12-09T20:46:04.707 に答える