Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you define sections with default content in MVC 6?

I am currently trying to migrate an ASP.net MVC 5 project to MVC 6.

How would I migrate the following code:

public static class SectionExtensions
{
    public static HelperResult RenderSection(this WebPageBase webPage, [RazorSection] string name, Func<dynamic, HelperResult> defaultContents)
    {
        return webPage.IsSectionDefined(name) ? webPage.RenderSection(name) : defaultContents(null);
    }
}

[RazorSection] is part of the JetBrains.Annotations assembly.

like image 969
Cool Breeze Avatar asked Jan 14 '16 07:01

Cool Breeze


People also ask

What is the default layout for an ASP Net core app known as?

By default, every layout must call RenderBody .

What are sections in ASP.NET MVC?

Sections usage In ASP.NET MVC, a section is a piece of code that we want to render in a layout page. This allows us to render a specific view content in any location of a layout. In order to declare a section in a view, we use the @section keyword followed by the name of the section.

What is _ViewImports Cshtml?

The purpose of the _ViewImports. cshtml file is to provide a mechanism to centralise directives that apply to Razor pages so that you don't have to add them to pages individually. The default Razor Pages template includes a _ViewImports. cshtml file in the Pages folder - the root folder for Razor pages.


1 Answers

Instead of WebPageBase I used RazorPage in Microsoft.AspNet.Mvc.Razor

namespace Stackoverflow
{
    public static class SectionExtensions
    {
        public static IHtmlContent RenderSection(this RazorPage page, [RazorSection] string name, Func<dynamic, IHtmlContent> defaultContents)
        {
            return page.IsSectionDefined(name) ? page.RenderSection(name) : defaultContents(null);
        }
    }
}

Then reference the class in the razor page @using static Stackoverflow.SessionExtensions, and call it like so:

@this.RenderSection("extra", @<span>This is the default!</span>))

An alternative way would be to just do this in the view (I prefer this way, seems a lot simpler):

@if (IsSectionDefined("extra"))
{
    @RenderSection("extra", required: false)
}
else
{
    <span>This is the default!</span>
}

I hope this helps.

Update 1 (from comments)

by referencing the namespace

@using Stackoverflow

you don't have to include the static keyword, but when calling it, you will have to reference the actual class in the namespace and also pass 'this' into the function.

@SectionExtensions.RenderSection(this, "extra", @<span>This is the default!</span>)

Update 2

There is a bug in razor that does not allow you to call template delegates Func <dynamic, object> e = @<span>@item</span>; within a section. Please see https://github.com/aspnet/Razor/issues/672

A current workaround:

public static class SectionExtensions
{
    public static IHtmlContent RenderSection(this RazorPage page, [RazorSection] string name, IHtmlContent defaultContents)
    {
        return page.IsSectionDefined(name) ? page.RenderSection(name) : defaultContents;
    }
}

and then the razor page:

section test {
    @this.RenderSection("extra", new HtmlString("<span>this is the default!</span>")); 
}
like image 103
Nick De Beer Avatar answered Sep 22 '22 12:09

Nick De Beer