Environment-specific customSection properties in Web.config - c#

I'm trying to do a bunch of environment-specific configuration in an asp.net MVC3 web application I'm building. I'm somewhat new to the platform and am running into a bit of an issue with environment specific configuration.
I have 3 configuration files:
Web.config
Web.Debug.config
Web.Release.config
I've placed my connectionString configuration in the Debug/Release files and it works, so I know asp.net recognizes at least some notion of my Debug/Release setup.
I've also added some custom configuration sections in Web.config like this:
<configSections>
<section name="GitHubConfig" type="SmartGigs.Controllers.GitHubConfig" />
<section name="JanRainConfig" type="SmartGigs.Services.JanRainConfig" />
</configSections>
Then I actually define them like this in Web.config:
<GitHubConfig ClientId="c" Secret="s" />
And attempt to load them like this:
var jrConfig = (JanRainConfig)WebConfigurationManager.GetSection("JanRainConfig");
var gitHubConfig = (GitHubConfig) WebConfigurationManager.GetSection("GitHubConfig");
Finally, I add a Debug-specific property into Web.Debug.config:
<JanRainConfig Key="key" TokenUrl="http://localhost:55739/Account/LogOn" />
The problem
If I get the property I defined in Web.config, it works perfectly. If I try to only define a property in Web.config or define it in Web.Debug.config and override it (and add xdt:Transform="Replace"), the property settings are either blank (in the former case) or contain the settings in Web.config (in the latter) - as though my configuration in Web.Debug.config is being ignored.
What is the correct way to accomplish what I'm trying to do?

Web.config transformations are only applied when publishing a project. You are certainly not the first, to get this wrong (me included). I suggest using a debug-configuration in the default web.config and apply only custom logic in the .release.config file.
It is somewhat sad, that the transformed web.config isn't picked up by VS when starting the project directly, but AFAIR the transformation process is a custom MSBuild Task, so one might be able to add execute it during compilation.

Related

How to Transform .Config on build for JetBrains Rider?

I'm trying to create custom configuration depending on the environment and it seems that the best way is to use config transforms. I'm trying to have the transform happen on build (to test locally), but the changes don't seem to work. Any ideas? Also what is the correct way to have "layered config" for environment on asp.net ?
have a go at this for me...
in the web.config (base)
add this configuration under the appSettings node
..
<appSettings>
<!-- Application Settings -->
<add key="IsTest" value="true" />
then in then right click the web.config and add a transformation (Add Config Transform) if you haven't already
and in that config you will only add the transform for that case in particular
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<add key="IsTest" value="false" xdt:Transform="Replace" xdt:Locator="Match(key)" />
...
If you are debugging from visual studio your try to keep your "Debug" values in the root config, and then lets say if you add a UAT_Release configuration and a UAT_Release transformation then when publishing your application check that the transforms have applied to your web config (these should be merged back in the base config)
for none web.config transforms (app.config for example)
these do seem to get transformed based on the build configuration
the underlying issue with web configs is that the "original" can not be preserved because the bin for www uses the .config from the project directly. it is not staged as part of the build so applying the transform would perm change the the web config.
(there was an attempt extension to solve this for VS but not seeing one for rider just yet)
my solution was to
add a local build profile that was a copy of debug just with a diff name.
crate xdt transforms for all my "develop" settings
right click preview transform and manually apply this transform to web.config (its manual but best i got so far, the perform transform does seem to fail for web.config for me or would us that)
build project using same config as applied to web and all other configs seemed to auto transform for me.

ASP.NET and web.config transforms not working when developing

I am working on an ASP.NET C# project, where I would like to make use of web.config transforms.
I therefor installed the extension "Configuration Transform" and added a Web.Debug.config and Web.Release.config.
Within the Web.config I have not declared anything specific to my application. The debug config contains my testing/developing settings while the release config contains tokens #{someVar}# that later will get replaced by TFS.
When I publish my application the Web.config gets correctly created according to the configuration (debug/release). Also Preview config transform gives the correct result (besides the line breaks).
However when starting the application from within Visual Studio 2017 with debug configuration it complains about missing tags.
Why is that and how can I fix this?
Web.config
<!-- Does not contain the request tag -->
Web.Debug.Config
<request xdt:Transform="Insert">
<mysetting>MyDevelopmentSetting</mysetting>
</request>
Web.Release.config
<request xdt:Transform="Insert">
<mysetting>#{MyTokenThatWillGetReplacedByTFS}#</mysetting>
</request>
Web config transforms do not run in Visual Studio (when you press F5/run the app in VS). They only run on builds when publishing.
Since your web.config doesn't have the setting and the application is expecting it, it's properly complaining about the missing tag.
You will need to add this tag to your web.config.

How to define web.config local variables

I have a web application in C# with .NET Framework 4.0 and I'm trying to find a way to define a variable in Web.Config that can be referenced elsewhere within the Web.Config.
I want something like this.
<?xml version="1.0" encoding="utf-8"?>
<LocalWebConfigVars>
<add key="Var1" value="ServerName1"/>
<add key="Var2" value="DatabaseName1"/>
</LocalWebConfigVars>
<configuration>
<connectionStrings>
<add name="AppConnectionString" connectionString="DATA SOURCE=#Var2 ServerName=#Var1"/>
<add name="OtherStuff" value="#Var1"/>
etc...
Currently I have to keep 3 or 4 hard-coded values (some embedded others just the value) updated to the same thing and would like to make it easier to keep in sync.
Is this possible?
Thanks.
Edit:
Just some background. The reason this is becoming problematic is that we define the apps database instance (among other instance specific setting) in the web.config. We have multiple database instances in our test and production environments and if I need to switch to a different one them while testing something and miss one of the hand full of references I get some strange results. I'm trying to avoid this by defining it once and referencing it everywhere else.
Would not doing a simply .config transformation for each of your environments work, by setting up a project configuration & transform, you would be able to swap from environment to environment by the use of solutions configuration dropdown.
See this link
for more info on transforms on .config files

How can I make a C# project's settings be user specific?

I am writing a Web API 2.0 project and a test project using Visual Studio 2013.
In the test project, I saved some information in the Settings.settings file (under TestProject->Properties in the Solution Explorer). One of the things saved there is the connection string to a database that is stored locally.
Unfortunately, the connection string will be slightly different on each person's computer when they download the repo. When people push their code to the master repo it overwrites the connection string, affecting everyone else.
What is the best way to make this configurable for each user such that everyone can have their own database path, but pushing to master repo won't affect anyone?
Edit
I don't think this is exactly a duplicate of that other question. Although, yes, my configuration settings are stored in app.config (since they happen to be application settings rather than user settings), following the solution in the other answer will lead me with the same problem. The app.config will contain configSource="otherconfig.config", and when people push that file to the master repo, it will still clobber other people's values. I need something that allows the custom configurations to be source-controlled without affecting the other users of the project.
Visual Studio handles this automatically for WEB projects through Web.config transformations
You'll need to install a separate plugin for use with App.config and non-web projects. http://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859
The plugin basically adds the same functionality to app.config files, and works with the same syntax in the transform files.
Your best approach to this is to use Build Profiles. Have a developer-specific Web.developer.config and with that you get each user to choose their name in Configuration Manager. Then just make the new config, which is technically an XSLT make the changes needed for each team member.
Think of it as Debug vs Release configs, except in your case you'll have many Debug (one for each user). The Build profile you set doesn't get checked into TFS, so you're fine.
This is what a subconfig looks like:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an attribute "name" that has a value of "MyDB".
-->
<connectionStrings>
<add name="RavenDB" connectionString="Url=http://xxx/databases/xxx" xdt:Transform="Replace" xdt:Locator="Match(name)"/>
</connectionStrings>
<appSettings>
<add key="BaseUrl" value="http://xxx" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
</appSettings>
<system.net>
<defaultProxy enabled="true" />
<mailSettings>
<smtp xdt:TrandeliveryMethod="Network" transform="Replace">
<network xdt:Transform="Replace" host="xxx" defaultCredentials="true" />
</smtp>
</mailSettings>
</system.net>
</configuration>
More info on web.config transforms
http://www.hanselman.com/blog/ManagingMultipleConfigurationFileEnvironmentsWithPreBuildEvents.aspx
The way I handle this problem is by adding a folder into my app that has only assets that don't get included in the build/publish. One of the things I include in that folder is DeveloperName.App.config files for each of my developers. Then I leave the the actual App.config file out of source control. When they check out the project, they copy their personalized DeveloperName.App.config file to the project folder and rename it to App.config.
This isn't perfect, but it gives you at least most of the goals you're looking for: The developers each get their own App.config file they can maintain and keep in source control. And the changes they make to App.config don't clobber each other every check-in.

How to make the Setting works for Class Library project in C# 2.0?

I am putting the setting under the property of one of my C# Class Library project for app setting:
EUCAccountService_ConnectionString
EUCTelcoDB_ConnectionString
In the development, it works nicely. Until I deported to production, I realise that the component that use those thing .. it just hang. I found that under \BIN when it compiled dewaCorp.EUC.TelcoDB.Data.dll.config and open up that file and turn out nothing.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>
How to make this works? I thought by compiling it, it turned to some sort config file or something. But it didn't.
I am appreciated your comment.
The properties are not stored in the .config file they are stored in the windows user profiles.
To store setting in the .config file add a config file to the executing assembly (take note is important to use the executing assembly) and store add the settings there for connection strings there is a special note for them.
<ConnectionStrings>
<ConnectionString />
</ConnectionStrings>
You'd better take a look at similar projects, such as log4net, and Enterprise Library.
http://logging.apache.org/log4net/index.html
http://www.codeplex.com/entlib

Categories

Resources