exclude attribute on the
EnvironmentTagHelper lets you easily tell the
EnvironmentTagHelper to render in all Environments EXCEPT the one(s) you specify. There’s also a new
include attribute that behaves the same as
names did in ASP.NET Core 1.
A comparison between ASP.NET Core 1 and 2:
Environments in ASP.NET Core
In ASP.NET 4 (and previous versions), there was no concept of an Environment. Even though in almost every job, there are the concepts of Environments such as Dev, Staging, UAT, QA, Production, etc. You were essentially on your own to implement your concept of Environments. Sometimes enlisting the help of something horrible like compiler directives.
In ASP.NET Core, they built the Environment concept right into the stack. There are 3 Environments by default – Development, Staging, and Production, but you can add your own custom ones if you want. The Environment is controlled by an Environment variable called
ASPNETCORE_ENVIRONMENT. This allows you to inspect the current Environment using an
IHostingEnvironment and run code like this:
|public void Configure(IApplicationBuilder app, IHostingEnvironment env)|
|// if we're in Development|
|// Show the Light Blue Screen of Death if there's an unhandled exception (RIP Yellow Screen of Death of ASP.NET 4)|
|// In any other Environment redirect the user to /Home/Error if there's an unhandled exception|
You can find more on Environments on the official documentation here: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments.
Environment Tag Helpers in ASP.NET Core 1
IHostingEnvironment, In ASP.NET Core 1 you could conditionally load some markup based on the Environment you were in via an
|<h1>This only renders in the Development Environment!</h1>|
|<h1>This only renders in the Staging and Production Environments!</h1>|
But that was a little brittle, given you can make your own custom Environments, in addition to the built-in Development, Staging, and Production Environments. Essentially, if you introduce a custom Environment, then you have to CTRL + F for all your
EnvironmentTagHelpers and add in your new custom environment. That’s a real pain.
exclude attributes on the Environment Tag Helper in ASP.NET Core 2
To solve this, the ASP.NET team introduced the
exclude attributes on the
EnvironmentTagHelper. Let’s look at
Exclude does about what you would think. It will only render the contents of the EnvironmentTagHelper if the current environment does NOT match the Environment specified. So
<Environment exclude="Development"> would NOT render the contents in Development, but would render in any other Environment (such as Staging, Production, or a custom Environment you specified).
Include, on the other hand, operates the same as the
names attribute we had in ASP.NET Core 1. It’s just there to provide consistent naming as the opposite of
exclude. It will only run if the current environment DOES match the Environment specified.
So those used together would look a little something like this:
|<h1>This only renders in the Development Environment</h1>|
|<h1>This renders in anything except the Development Environment (Staging, Production, or any custom environment).</h1>|
names attribute still exists… but don’t use it
names attribute still exists for backwards compatibility, but I don’t see a reason to use it anymore over
include. I don’t have a crystal ball, but I’d say it’s likely
names will be removed in a later version of ASP.NET Core now that we have
exclude. Although the team seems committed to backwards compatibility at this point in time.
Personally, I think it’d be cool if the ASP.NET team shipped codemods in the form of Roslyn Analyzers to auto upgrade your code to the latest API’s, and then just make a clean break. In this case, anywhere you’d use
names would automatically upgrade to use
include. As a developer, you could still inspect the changes the Roslyn Analyzer made when reviewing your Commit/Pull Request to make sure the Analyzer did the right thing. The React team at Facebook does this, but they also have a financial incentive to ship upgrade-friendly stuff like that when Facebook has over 10M lines of code. So…. yeah…
What if I use include and exclude in the same Tag Helper and use the same Environment in both?
If you screw up like this, ASP.NET Core will do the “safe” thing by default and NOT render in that environment. This is very similar to how NTFS works where a deny will take precedence over an allow.
So if you do something like this:
|<environment include="Development, Staging" exclude="Development">|
|<h1>This will not show in Development or Production, but it will show in Staging.</h1>|
Then the content will not show in the Development or Production Environments, but it will show in Staging, since it is part of the
include and not in the
In real life, I don’t know why you’d use both together. I would always just pick a whitelist (
include) or a blacklist (
exclude). But it’s probably a good thing to keep in mind.
This will make life so much simpler to deal with the
EnvironmentTagHelper especially when used with custom Environments.
If you’re interested in the ideas they threw around to solve this problem, before ultimately landing on
exclude, you can read the GitHub issue here. You can also see the commit that went into making this feature work.
I was playing around with ASP.NET Core 2.0 before I give a talk on what’s new on it in 4 days, and I came across this and just had to share… now it’s back to rehearsing!