我有一个使用Razor作为其视图引擎的MVC3站点.我希望我的网站可以换肤.大多数可能的皮肤都足够相似,可以从共享的主布局中获得.
因此,我正在考虑这个设计:

但是,我希望能够RenderSection在底层调用_Common.cshtml,并让它渲染一个在顶层定义的部分,Detail.cshtml.这不起作用:RenderSection显然只渲染下一层定义的部分.
当然,我可以定义每个皮肤中的每个部分.例如,如果_Common需要调用RenderSection("hd")中定义的部分Detail,我只需将其放在每个部分中_Skin并且它可以工作:
@section hd {
@RenderSection("hd")
}
Run Code Online (Sandbox Code Playgroud)
这导致一些代码重复(因为每个皮肤现在必须具有相同的部分)并且通常感觉很乱.我还是Razor的新手,似乎我可能会遗漏一些明显的东西.
调试时,我可以在WebViewPage.SectionWritersStack中看到已定义部分的完整列表.如果我可以告诉RenderSection在放弃之前查看整个列表,它会找到我需要的部分.唉,SectionWritersStack是非公开的.
或者,如果我可以访问布局页面的层次结构并尝试在每个不同的上下文中执行RenderSection,我可以找到我需要的部分.我可能错过了什么,但我认为没有办法做到这一点.
除了我已经概述的方法之外,还有一些方法可以实现这个目标吗?
给定这个嵌套的布局结构:
~/Views/Shared/_layoutBase.cshtml ~/Views/Shared/_layout.cshtml
_layoutBase.cshtml布局在哪里_layout.cshtml.
布局文件中定义的任何部分都会在其下的页面中呈现其内容 ~/Views/...
但是,对于区域中的视图,从不渲染这些部分.
_layoutBase:
<script type="text/javascript">
@RenderSection("footerScripts", false)
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
_layout.cshtml:
@section footerScripts{
@RenderSection("footerScripts", false)
}
Run Code Online (Sandbox Code Playgroud)
"内容"观点:
@section footerScripts{
$(function () {
SetFocusOnForm("CaptchaCode", "NextButton");
});
}
Run Code Online (Sandbox Code Playgroud)
段的内容footerScripts永远不会在区域的视图中呈现.它确实在~/Views文件夹下的视图中呈现.
面积_ViewStart.cshtml:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
Run Code Online (Sandbox Code Playgroud)
你能看到什么问题吗?!