Reputation: 280
We are building a web-application using the new ASP .NET 5 platform. I am configuring the build and deployment automation tools and I want to have the ability to change the application settings during deployment (like changing the web-service url). In ASP .NET 5 we don't have web.config files anymore, only the new json configuration files. Is there a mechanism in ASP .NET 5 similar to web.config transformation in the previous versions of ASP .NET?
Upvotes: 4
Views: 2958
Reputation: 579
I know that web.configs are not really supported, but they are still used in ASP.Net under IIS.
I had a desire to apply transforms as well as I wanted to control the environment variable from the config like so:
<aspNetCore>
<environmentVariables xdt:Transform="Replace">
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
</environmentVariables>
</aspNetCore>
If you really want to transform them in ASP.Net core / 5 you can use the following method:
Add as many different web.config transform files as you want to your project. For example, you can add Web.Development.config, Web.Staging.config, and Web.Production.config, etc... Name them however you like.
Modify your project.json file to output the files by adding this line to the publishoptions right below your current web.config line: "web.*.config"
Create a publish profile and modify your powershell script for your publish profile (located at Web Project\Properties\PublishProperties\profilename-publish.ps1) to add the below modifications:
Add this function above the try catch (I found this function here Web.Config transforms outside of Microsoft MSBuild?, slightly modified.) :
function XmlDocTransform($xml, $xdt)
{
if (!$xml -or !(Test-Path -path $xml -PathType Leaf)) {
throw "File not found. $xml";
}
if (!$xdt -or !(Test-Path -path $xdt -PathType Leaf)) {
throw "File not found. $xdt";
}
"Transforming $xml using $xdt";
$scriptPath = (Get-Variable MyInvocation -Scope 1).Value.InvocationName | split-path -parent
#C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.Tasks.dll
Add-Type -LiteralPath "${Env:ProgramFiles(x86)}\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.XmlTransform.dll"
$xmldoc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
$xmldoc.PreserveWhitespace = $true
$xmldoc.Load($xml);
$transf = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdt);
if ($transf.Apply($xmldoc) -eq $false)
{
throw "Transformation failed."
}
$xmldoc.Save($xml);
}
Add these lines ABOVE the Publish-AspNet call:
$xdtFiles = Get-ChildItem $packOutput | Where-Object {$_.Name -match "^web\..*\.config$"};
$webConfig = $packOutput + "web.config";
foreach($xdtFile in $xdtFiles) {
XmlDocTransform -xml $webConfig -xdt "$packOutput$xdtFile"
}
Upvotes: 4
Reputation: 38457
As indicated by @tugberk, you can use environment variables instead which is a much better way of handling this situation. If you are running in a development environment and want to store passwords or connection strings you can also use user secrets to add them. After all that you can also still use environment specific config files like so (This is a ASP.NET 5 Beta 5 Sample):
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(
applicationEnvironment.ApplicationBasePath);
// Add configuration from the config.json file.
configurationBuilder.AddJsonFile("config.json");
// Add configuration from an optional config.development.json, config.staging.json or
// config.production.json file, depending on the environment. These settings override the ones in the
// config.json file.
configurationBuilder.AddJsonFile($"config.{hostingEnvironment.EnvironmentName}.json", optional: true);
if (hostingEnvironment.IsEnvironment(EnvironmentName.Development))
{
// This reads the configuration keys from the secret store. This allows you to store connection strings
// and other sensitive settings on your development environment, so you don't have to check them into
// your source control provider. See http://go.microsoft.com/fwlink/?LinkID=532709 and
// http://docs.asp.net/en/latest/security/app-secrets.html
configurationBuilder.AddUserSecrets();
}
// Add configuration specific to the Development, Staging or Production environments. This config can
// be stored on the machine being deployed to or if you are using Azure, in the cloud. These settings
// override the ones in all of the above config files.
// Note: To set environment variables for debugging navigate to:
// Project Properties -> Debug Tab -> Environment Variables
// Note: To get environment variables for the machine use the following command in PowerShell:
// $env:[VARIABLE_NAME]
// Note: To set environment variables for the machine use the following command in PowerShell:
// $env:[VARIABLE_NAME]="[VARIABLE_VALUE]"
// Note: Environment variables use a colon separator e.g. You can override the site title by creating a
// variable named AppSettings:SiteTitle. See
// http://docs.asp.net/en/latest/security/app-secrets.html
configurationBuilder.AddEnvironmentVariables();
IConfiguration configuration = configurationBuilder.Build();
Upvotes: 0
Reputation: 58444
You don't really need config transforms in ASP.NET 5 as it has out of the box support for chained configuration sources. For example, take this sample:
public class Startup
{
private readonly IConfiguration _configuration;
public Startup(IApplicationEnvironment appEnv, IHostingEnvironment env)
{
_configuration = new ConfigurationBuilder(appEnv.ApplicationBasePath)
.AddJsonFile("config.json")
.AddEnvironmentVariables()
.Build();
}
// ...
}
We add two config sources and building the configuration our of them. if I ask for a config key, it will try to get a value for that key by looking at the sources from last to first order. In the above case, I can work with a config.json file during development and I can ovveride the that by providing the proper configuration from environment variables.
Look at the Configuration docs for more information.
Upvotes: 3