具有级联部分的剃刀嵌套布局

我有一个使用Razor作为其视图引擎的MVC3站点。我希望我的网站可以换肤。大多数可能的皮肤都足够相似,可以从共享的主布局中获得。 因此,我正在考虑这个设计: 但是,我希望能够在底层调用
RenderSection
_Common.cshtml
,并让它渲染一个在顶层定义的部分,
Detail.cshtml
。这不起作用:
RenderSection
显然只渲染下一层定义的部分。 当然,我可以定义每个皮肤中的每个部分。例如,如果
_Common
需要为
Detail
中定义的部分调用
RenderSection("hd")
,我只需将其放在每个
_Skin
中它就可以了:
@section hd {
    @RenderSection("hd")
}
这导致一些代码重复(因为每个皮肤现在必须具有相同的部分)并且通常感觉很乱。我还是Razor的新手,似乎我可能会遗漏一些明显的东西。 调试时,我可以在WebViewPage.SectionWritersStack中看到已定义部分的完整列表。如果我可以告诉RenderSection在放弃之前查看整个列表,它会找到我需要的部分。唉,SectionWritersStack是非公开的。 或者,如果我可以访问布局页面的层次结构并尝试在每个不同的上下文中执行RenderSection,我可以找到我需要的部分。我可能错过了什么,但我认为没有办法做到这一点。 除了我已经概述的方法之外,还有一些方法可以实现这个目标吗?     
已邀请:
事实上,这在今天使用公共API是不可能的(除了使用部分重定义方法)。使用私人反思可能会有一些运气,但这当然是一种脆弱的方法。我们将研究在下一版Razor中使这个场景更容易。 与此同时,这里有几篇关于这个主题的博客文章: http://blogs.msdn.com/b/marcinon/archive/2010/12/08/optional-razor-sections-with-default-content.aspx http://blogs.msdn.com/b/marcinon/archive/2010/12/15/razor-nested-layouts-and-redefined-sections.aspx     
@helper ForwardSection( string section )
{
   if (IsSectionDefined(section))
   {
       DefineSection(section, () => Write(RenderSection(section)));
   }
}
这可以做到这一点吗?     
我不确定这是否可能在MVC 3中,但在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);
    }
如果你运行上面的代码,你应该得到一个内容为
Skin1.cshtml
_Common.cshtml
的HTML页面 简而言之,您将为(皮肤)布局页面设置布局。     
不确定这是否会对你有所帮助,但我写了一些扩展方法来帮助部分内部“冒泡”部分,这也适用于嵌套布局。 使用Razor View Engine从部分视图ASP.NET MVC 3中将内容注入特定部分 在子布局/视图/部分中声明
@using (Html.Delayed()) {
    <b>show me multiple times, @Model.Whatever</b>
}
在任何父级中渲染
@Html.RenderDelayed();
有关更多用例,请参阅答案链接,例如,即使在重复视图中声明,也只渲染一个延迟块,渲染特定延迟块等。     

要回复问题请先登录注册