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?
Just Add @RenderSection("Scripts", required: false)
in end of </body>
tag.
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.
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.
See this link for more information: Working with Multiple Environments
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With