Reading these two questions/answers I was able to run an Asp.net 5 app on IIS 8.5 server.
Asp.net vNext early beta publish to IIS in windows server
How to configure an MVC6 app to work on IIS?
The problem is that the web app is still using env.EnvironmentName
with value Development
even when run on IIS.
Also, I want to run two versions of the same Web (Staging, Production) on the same server, so I need a method to set the variable for each Web separately.
How to do this?
Properties\launchSettings.json
to simulate another environment for debugging in Visual Studio.
This answer was originally written for ASP.NET Core RC1. In RC2 ASP.NET Core moved from generic httpPlafrom handler to aspnetCore specific one. Note that step 3 depends on what version of ASP.NET Core you are using.
Turns out environment variables for ASP.NET Core projects can be set without having to set environment variables for user or having to create multiple commands entries.
Go to your application in IIS and choose Configuration Editor. Select Configuration Editor Choose system.webServer/aspNetCore (RC2 and RTM) or system.webServer/httpPlatform (RC1) in Section combobox Choose Applicationhost.config ... in From combobox. Right click on enviromentVariables element, select 'environmentVariables' element, then Edit Items. Set your environment variables. Close the window and click Apply. Done
This way you do not have to create special users for your pool or create extra commands entries in project.json
. Also, adding special commands for each environment breaks "build once, deploy many times" as you will have to call dnu publish
separately for each environment, instead of publish once and deploying resulting artifact many times.
Updated for RC2 and RTM, thanks to Mark G and tredder.
Update web.config with an
<configuration>
<system.webServer>
<aspNetCore .....>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</configuration>
Or to avoid losing this setting when overwriting web.config, make similar changes to applicationHost.config specifying the site location as @NickAb suggests.
<location path="staging.site.com">
<system.webServer>
<aspNetCore>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
<location path="production.site.com">
<system.webServer>
<aspNetCore>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
Target configuration object '/system.webServer/aspNetCore/environmentVariables/environmentVariable is not found ...
Normally to set some variable I would write something like this: Set-WebConfigurationProperty -PSPath IIS:\ -location example.com -filter /system.webServer/aspNetCore/environmentVariables/environmentVariable -name ASPNETCORE_ENVIRONMENT -value Staging
what Im I missing?
appcmd
instead.
Set-WebConfigurationProperty -PSPath IIS:\ -Location example.com -Filter /system.webServer/aspNetCore/environmentVariables -Name . -Value @{ Name = 'ASPNETCORE_ENVIRONMENT'; Value = 'Staging' }
You could alternatively pass in the desired ASPNETCORE_ENVIRONMENT
into the dotnet publish command as an argument using:
/p:EnvironmentName=Staging
e.g.:
dotnet publish /p:Configuration=Release /p:EnvironmentName=Staging
This will generate out the web.config with the correct environment specified for your project:
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
</environmentVariables>
Edit: as of RC2 and RTM releases, this advice is out of date. The best way I have found to accomplish this in release is to edit the following web.config sections in IIS for each environment:
system.webServer/aspNetCore
:
Edit the environmentVariable entry and add an environment variable setting:
ASPNETCORE_ENVIRONMENT
: < Your environment name >
As an alternative to drpdrp's approach, you can do the following:
In your project.json, add commands that pass the ASPNET_ENV variable directly to Kestrel: "commands": { "Development": "Microsoft.AspNet.Server.Kestrel --ASPNET_ENV Development", "Staging": "Microsoft.AspNet.Server.Kestrel --ASPNET_ENV Staging", "Production": "Microsoft.AspNet.Server.Kestrel --ASPNET_ENV Production" }
When publishing, use the --iis-command option to specify an environment: dnu publish --configuration Debug --iis-command Staging --out "outputdir" --runtime dnx-clr-win-x86-1.0.0-rc1-update1
I found this approach to be less intrusive than creating extra IIS users.
Other than the options mentioned above, there are a couple of other Solutions which works well with automated deployments or require fewer configuration changes.
1. Modifying the project file (.CsProj) file
MSBuild supports the EnvironmentName
Property which can help to set the right environment variable as per the Environment you wish to Deploy. The environment name would be added in the web.config during the Publish phase.
Simply open the project file (*.csProj) and add the following XML.
<!-- Custom Property Group added to add the Environment name during publish
The EnvironmentName property is used during the publish for the Environment variable in web.config
-->
<PropertyGroup Condition=" '$(Configuration)' == '' Or '$(Configuration)' == 'Debug'">
<EnvironmentName>Development</EnvironmentName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' != '' AND '$(Configuration)' != 'Debug' ">
<EnvironmentName>Production</EnvironmentName>
</PropertyGroup>
Above code would add the environment name as Development
for Debug configuration or if no configuration is specified. For any other Configuration the Environment name would be Production
in the generated web.config file. More details here
2. Adding the EnvironmentName Property in the publish profiles.
We can add the <EnvironmentName>
property in the publish profile as well. Open the publish profile file which is located at the Properties/PublishProfiles/{profilename.pubxml}
This will set the Environment name in web.config when the project is published. More Details here
<PropertyGroup>
<EnvironmentName>Development</EnvironmentName>
</PropertyGroup>
3. Command line options using dotnet publish
Additionaly, we can pass the property EnvironmentName
as a command line option to the dotnet publish
command. Following command would include the environment variable as Development
in the web.config file.
dotnet publish -c Debug -r win-x64 /p:EnvironmentName=Development
I have my web applications (PRODUCTION, STAGING, TEST) hosted on IIS web server. So it was not possible to rely on ASPNETCORE_ENVIRONMENT operative's system enviroment variable, because setting it to a specific value (for example STAGING) has effect on others applications.
As work-around, I defined a custom file (envsettings.json) within my visualstudio solution:
https://i.stack.imgur.com/RdNfP.png
with following content:
{
// Possible string values reported below. When empty it use ENV variable value or Visual Studio setting.
// - Production
// - Staging
// - Test
// - Development
"ASPNETCORE_ENVIRONMENT": ""
}
Then, based on my application type (Production, Staging or Test) I set this file accordly: supposing I am deploying TEST application, i will have:
"ASPNETCORE_ENVIRONMENT": "Test"
After that, in Program.cs file just retrieve this value and then set the webHostBuilder's enviroment:
public class Program
{
public static void Main(string[] args)
{
var currentDirectoryPath = Directory.GetCurrentDirectory();
var envSettingsPath = Path.Combine(currentDirectoryPath, "envsettings.json");
var envSettings = JObject.Parse(File.ReadAllText(envSettingsPath));
var enviromentValue = envSettings["ASPNETCORE_ENVIRONMENT"].ToString();
var webHostBuilder = new WebHostBuilder()
.UseKestrel()
.CaptureStartupErrors(true)
.UseSetting("detailedErrors", "true")
.UseContentRoot(currentDirectoryPath)
.UseIISIntegration()
.UseStartup<Startup>();
// If none is set it use Operative System hosting enviroment
if (!string.IsNullOrWhiteSpace(enviromentValue))
{
webHostBuilder.UseEnvironment(enviromentValue);
}
var host = webHostBuilder.Build();
host.Run();
}
}
Remember to include the envsettings.json in the publishOptions (project.json):
"publishOptions":
{
"include":
[
"wwwroot",
"Views",
"Areas/**/Views",
"envsettings.json",
"appsettings.json",
"appsettings*.json",
"web.config"
]
},
This solution make me free to have ASP.NET CORE application hosted on same IIS, independently from envoroment variable value.
After extensive googling I found a working solution, which consists of two steps.
The first step is to set system wide environment variable ASPNET_ENV to Production and Restart the Windows Server. After this, all web apps are getting the value 'Production' as EnvironmentName.
The second step (to enable value 'Staging' for staging web) was rather more difficult to get to work correctly, but here it is:
Create new windows user, for example StagingPool on the server. For this user, create new user variable ASPNETCORE_ENVIRONMENT with value 'Staging' (you can do it by logging in as this user or through regedit) Back as admin in IIS manager, find the Application Pool under which the Staging web is running and in Advanced Settings set Identity to user StagingPool. Also set Load User Profile to true, so the environment variables are loaded. <- very important! Ensure the StagingPool has access rights to the web folder and Stop and Start the Application Pool.
Now the Staging web should have the EnvironmentName set to 'Staging'.
Update: In Windows 7+ there is a command that can set environment variables from CMD prompt also for a specified user. This outputs help plus samples:
>setx /?
Just add
<PropertyGroup>
<EnvironmentName>Development</EnvironmentName>
</PropertyGroup>
That information gets copied to web.config. (Don't set web.config manually since it gets overwritten.)
Source: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments
Similar to other answers, I wanted to ensure my ASP.NET Core 2.1 environment setting persisted across deployments, but also only applied to the specific site.
According to Microsoft's documentation, it is possible to set the environment variable on the app pool using the following PowerShell command in IIS 10:
$appPoolName = "AppPool"
$envName = "Development"
cd "$env:SystemRoot\system32\inetsrv"
.\appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='$appPoolName'].environmentVariables.[name='ASPNETCORE_ENVIRONMENT',value='$envName']" /commit:apphost
I unfortunately still have to use IIS 8.5 and thought I was out of luck. However, it is still possible to run a simple PowerShell script to set a site-specific environment variable value for ASPNETCORE_ENVIRONMENT:
Import-Module -Name WebAdministration
$siteName = "Site"
$envName = "Development"
Set-WebConfigurationProperty -PSPath IIS:\ -Location $siteName -Filter /system.webServer/aspNetCore/environmentVariables -Name . -Value @{ Name = 'ASPNETCORE_ENVIRONMENT'; Value = $envName }
To extend on @tredder's answer you can alter the environmentVariables using appcmd
Staging
%windir%\system32\inetsrv\appcmd set config "staging.example.com" /section:system.webServer/aspNetCore /+environmentVariables.[name='ASPNETCORE_ENVIRONMENT',value='Staging'] /commit:APPHOST
Production
%windir%\system32\inetsrv\appcmd set config "example.com" /section:system.webServer/aspNetCore /+environmentVariables.[name='ASPNETCORE_ENVIRONMENT',value='Production'] /commit:APPHOST
What you need to know in one place:
For environment variables to override any config settings, they must be prefixed with ASPNETCORE_.
If you want to match child nodes in your JSON config, use : as a separater. If the platform doesn't allow colons in environment variable keys, use __ instead.
You want your settings to end up in ApplicationHost.config. Using the IIS Configuration Editor will cause your inputs to be written to the application's Web.config -- and will be overwritten with the next deployment!
For modifying ApplicationHost.config, you want to use appcmd.exe to make sure your modifications are consistent. Example: %systemroot%\system32\inetsrv\appcmd.exe set config "Default Web Site/MyVirtualDir" -section:system.webServer/aspNetCore /+"environmentVariables.[name='ASPNETCORE_AWS:Region',value='eu-central-1']" /commit:site
Characters that are not URL-safe can be escaped as Unicode, like %u007b for left curly bracket.
To list your current settings (combined with values from Web.config): %systemroot%\system32\inetsrv\appcmd.exe list config "Default Web Site/MyVirtualDir" -section:system.webServer/aspNetCore
If you run the command to set a configuration key multiple times for the same key, it will be added multiple times! To remove an existing value, use something like %systemroot%\system32\inetsrv\appcmd.exe set config "Default Web Site/MyVirtualDir" -section:system.webServer/aspNetCore /-"environmentVariables.[name='ASPNETCORE_MyKey',value='value-to-be-removed']" /commit:site.
/commit:site
the changes are written in the web.config, in order to save them in the ApplicationHost.config
one should use /commit:apphost
-section:system.webServer/aspNetCore /-"environmentVariables.
(with minus to remove environment variable) fails to be executed during Azure release pipeline. The error is hresult:80070032, message:Command execution failed
. However clear config "Default Web Site/$(webSiteName)" -section:system.webServer/aspNetCore /commit:site
works fine. It clears the whole aspNetCore section for the web site but it is not a problem since it is parametrized during the release.
@tredder solution with editing applicationHost.config is the one that works if you have several different applications located within virtual directories on IIS.
My case is:
I do have API project and APP project, under the same domain, placed in different virtual directories
Root page XXX doesn't seem to propagate ASPNETCORE_ENVIRONMENT variable to its children in virtual directories and...
...I'm unable to set the variables inside the virtual directory as @NickAb described (got error The request is not supported. (Exception from HRESULT: 0x80070032) during saving changes in Configuration Editor):
Going into applicationHost.config and manually creating nodes like this:
and restarting the IIS did the job.
I know a lot of answers has been given but in my case I added web.{Environment}.config versions in my project and when publishing for a particular environment the value gets replaced.
For example, for Staging (web.Staging.config)
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<location>
<system.webServer>
<aspNetCore>
<environmentVariables xdt:Transform="InsertIfMissing">
<environmentVariable name="ASPNETCORE_ENVIRONMENT"
value="Staging"
xdt:Locator="Match(name)"
xdt:Transform="InsertIfMissing" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
</configuration>
For Release or Production I will do this (web.Release.config)
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<location>
<system.webServer>
<aspNetCore>
<environmentVariables xdt:Transform="InsertIfMissing">
<environmentVariable name="ASPNETCORE_ENVIRONMENT"
value="Release"
xdt:Locator="Match(name)"
xdt:Transform="InsertIfMissing" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
</configuration>
Then when publishing I will choose or set the environment name. And this will replace the value of the environment in the eventual web.config file.
For those of you looking to this in an azure devops pipeline, this can be achieved by adding the PowerShell on target machines task and running the following script:
$envVariables = (
@{name='VARIABLE1';value='Value1'},
@{name='VARIABLE2';value='Value2'}
)
Set-WebConfigurationProperty -PSPath IIS:\ -Location $('mySite') -Filter /system.webServer/aspNetCore/environmentVariables -Name . -Value $envVariables
To get the details about the error I had to add ASPNETCORE_ENVIRONMENT
environment variable for the corresponding Application Pool system.applicationHost/applicationPools
.
Note: the web application in my case was ASP.NET Core 2
web application hosted on IIS 10
. It can be done via Configuration Editor
in IIS Manager
(see Editing Collections with Configuration Editor to figure out where to find this editor in IIS Manager
).
I have created a repository for publishing IIS with the environment configuration in Web.config.
https://github.com/expressiveco/AspnetCoreWebConfigForEnvironment
Setup Get the sections from .csproj and .user.csproj files into your project files. Get the MyAspNetEnvironment.props, web.development.config and web.production.config files.
Get the sections from .csproj and .user.csproj files into your project files.
Get the MyAspNetEnvironment.props, web.development.config and web.production.config files.
Configuration Change the value of ASPNETCORE_ENVIRONMENT property in user.csproj relevantly.
Change the value of ASPNETCORE_ENVIRONMENT property in user.csproj relevantly.
I have modified the answer which @Christian Del Bianco is given. I changed the process for .net core 2 and upper as project.json file now absolute.
First, create appsettings.json file in root directory. with the content {
// Possible string values reported below. When empty it use ENV
variable value or Visual Studio setting.
// - Production
// - Staging
// - Test
// - Development
"ASPNETCORE_ENVIRONMENT": "Development"
}
Then create another two setting file appsettings.Development.json and appsettings.Production.json with the necessary configuration. Add necessary code to set up the environment to Program.cs file. public class Program
{
public static void Main(string[] args)
{
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
***var currentDirectoryPath = Directory.GetCurrentDirectory();
var envSettingsPath = Path.Combine(currentDirectoryPath, "envsettings.json");
var envSettings = JObject.Parse(File.ReadAllText(envSettingsPath));
var enviromentValue = envSettings["ASPNETCORE_ENVIRONMENT"].ToString();***
try
{
***CreateWebHostBuilder(args, enviromentValue).Build().Run();***
}
catch (Exception ex)
{
//NLog: catch setup errors
logger.Error(ex, "Stopped program because of setup related exception");
throw;
}
finally
{
NLog.LogManager.Shutdown();
}
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args, string enviromentValue) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup
Success story sharing
system.webServer/aspNetCore
instead.