Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does RenderSection() work inside ASP.NET Core's <environment> tag-helper?

Layout has this:

<!DOCTYPE html>
<html>
<head>
  <environment names="Development">@RenderSection("devCss", required: false)</environment>
  <environment names="Staging,Production">@RenderSection("staproCss", required: false)</environment>
</head>
<body>
  @RenderBody()
  <environment names="Development">@RenderSection("devJs", required: false)</environment>
  <environment names="Staging,Production">@RenderSection("staproJs", required: false)</environment>
</body>
</html>

View has this:

@section devCss { <link rel="stylesheet" href="foo.css" asp-append-version="true" /> }
@section staproCss { <link rel="stylesheet" href="foo.min.css" asp-append-version="true" /> }
@section devJs {}
@section staproJs {}

<h1>hello</h1>

When RenderSection() is outside the <environment> tag, everything works.

When inside, as in above example, it fails with the unhelpful error of InvalidOperationException: The following sections have been defined but have not been rendered by the page at '_Layout.cshtml': 'staproCss, staproJs'. To ignore an unrendered section call IgnoreSection("sectionName").

That obviously makes no sense, as all sections were defined. And it complained about some, and not the others.

Does the <environment> tag-helper allow RenderSection() within it?

like image 945
grokky Avatar asked Oct 27 '16 16:10

grokky


3 Answers

Just Add @RenderSection("Scripts", required: false) in end of </body> tag.

like image 53
Roohi Avatar answered Oct 10 '22 19:10

Roohi


This answer is thanks to a comment by @user2818985.

The environment which is not defined, will not emit the content within. Which means it won't emit the RenderSection() call. Which means the view will define a section foo { ... } which doesn't exist. Which fails, and thus the exception.

To accomplish my original goal, I updated the layout:

@inject Microsoft.AspNetCore.Hosting.IHostingEnvironment _env
<!DOCTYPE html>
<html>
<head>
    <environment names="Development">
        @RenderSection("devCss", required: false)
    </environment>
    <environment names="Staging,Production">
        @RenderSection("staproCss", required: false)
    </environment>
    @if (_env.EnvironmentName == "Development" && IsSectionDefined("staproCss"))
    {
        IgnoreSection("staproCss"); 
    }
    @if (_env.EnvironmentName == "Staging,Production" && IsSectionDefined("devCss"))
    { 
        IgnoreSection("devCss"); 
    }
</head>
<body>
    @RenderBody()
    <environment names="Development">
        @RenderSection("devJs", required: false)
    </environment>
    <environment names="Staging,Production">
        @RenderSection("staproJs", required: false)
    </environment>
    @if (_env.EnvironmentName == "Development" && IsSectionDefined("staproJs")) 
    { 
        IgnoreSection("staproJs"); 
    }
    @if (_env.EnvironmentName == "Staging,Production" && IsSectionDefined("devJs")) 
    { 
        IgnoreSection("devJs"); 
    }
</body>
</html>

So the sections are always defined, and so the child views never throw.

like image 44
grokky Avatar answered Oct 10 '22 20:10

grokky


No, the environment tag is used to render different HTML based upon the environment defined by the ASPNET_ENV environment variable. For example, a different set of CSS definitions can be used for a development environment as compared to a production environment.

This link may also be helpful: A Complete Guide to the MVC 6 Tag Helpers

You can use the environment variable value in your website logic as shown here. enter image description here

See this link for more information: Working with Multiple Environments

like image 26
JohnH Avatar answered Oct 10 '22 18:10

JohnH