Defining Default Content For A Razor Layout Section

    Razor中的布局与Web窗体中的母版页具有相同的目的。它们使您可以为网站指定布局,并切出一些占位符部分以实现视图。
    例如,这是一个具有主体部分和页脚部分的简单布局。

    1. <!DOCTYPE html>
    2. <html>
    3. <head><title>Sample Layout</head>
    4. <body>
    5. <div>@RenderBody()</div>
    6. <footer>@RenderSection("Footer")</footer>
    7. </body>
    8. </html>

    为了使用此布局,您的视图可能看起来像。

    1. @{
    2. Layout = "MyLayout.cshtml";
    3. }
    4. <h1>Main Content!</h1>
    5. @section Footer {
    6. This is the footer.
    7. }

    注意,我们使用@section语法为已定义的页脚节指定内容。
    但是,如果我们还有其他未为页脚部分指定内容的视图怎么办?他们将抛出一个异常,指出未定义“脚”部分。
    要使一个部分可选,我们需要调用重载 RenderSection并指定falserequired参数。

    1. <!DOCTYPE html>
    2. <html>
    3. <head><title>Sample Layout</head>
    4. <body>
    5. <div>@RenderBody()</div>
    6. <footer>@RenderSection("Footer", false)</footer>
    7. </body>
    8. </html>

    但是,如果在视图中未定义该节的情况下定义一些默认内容,那会更好吗?
    好吧,这是一种方法。这有点丑陋,但可以。

    1. <footer>
    2. @if (IsSectionDefined("Footer")) {
    3. RenderSection("Footer");
    4. }
    5. else {
    6. <span>This is the default yo!</span>
    7. }
    8. </footer>

    那是丑陋的代码。如果只有一种方法可以编写该版本 RenderSection,则可以接受一些Razor标记作为该方法的参数。
    模板化剃刀代表救援!看,我告诉你这些事情会派上用场。
    我们可以在上面编写一个扩展方法WebPageBase来封装这部分难看的样板代码。这是实现。

    1. public static class Helpers {
    2. public static HelperResult RenderSection(this WebPageBase webPage,
    3. string name, Func<dynamic, HelperResult> defaultContents) {
    4. if (webPage.IsSectionDefined(name)) {
    5. return webPage.RenderSection(name);
    6. }
    7. return defaultContents(null);
    8. }
    9. }

    比这段代码更有趣的是我们现在如何使用它。我的布局现在可以执行以下操作以定义页脚部分:

    1. <footer>
    2. @this.RenderSection("Footer", @<span>This is the default!</span>)
    3. </footer>

    那更干净!但是我们可以做得更好。请注意,这个丑陋的this关键字怎么了?这是必要的,因为当您在当前类上编写扩展方法时,必须使用thiskewyord对其进行调用 。
    还记得我写过有关如何更改Razor视图的基本类型的文章吗?在这种情况下,这确实很方便。
    我们可以做的是编写我们自己的自定义基本页面类型(例如CustomWebViewPage我在该博客文章中使用的 类),然后将RenderSection上面的方法添加 为该类的实例方法。我将其留给读者练习。
    最终结果将使您执行以下操作:

    1. <footer>
    2. @RenderSection("Footer", @<span>This is the default!</span>)
    3. </footer>

    非常漂亮!
    您可能想知道为什么我们不仅仅在Razor中包含此功能。我的猜测是我们想要但只是时间用光了。希望这将在下一版的Razor中实现。