Web.config appSettings configSource attribute transformation - asp.net

I am trying to update the configSource attribute on the appSettings element within my web.config file using web.config transformations.
I have the following in my web.config
<appSettings configSource="Config\appSettings.local.config">
</appSettings>
I want this to be
<appSettings configSource="Config\appSettings.prod.config">
</appSettings>
when i build Release. This is not happening. I have the following in my Web.Release.config in the element
<appSettings xdt:Transform="SetAttributes(configSource)" configSource="Config\appSettings.prod.config" />

Transformations only happen when you deploy the web application (or create a deployment package). It does not happen when you simply build the solution.
http://msdn.microsoft.com/en-us/library/dd465326.aspx
"For Web application projects, ASP.NET provides tools that automate the process of changing (transforming) Web.config files when they are deployed."

You can cause the transformation to happen on build if you like though, with a little poking around in your project file. I wrote a post on this a while back, its centered on app.config but it will work for web.config you can just miss a few steps out!
http://www.chrissurfleet.co.uk/post/2011/07/27/Faking-Webconfig-transformations-in-appConfig.aspx

Related

Private web.config for each developer

Consider a group of developers working on an ASP.net web application. Each developer would like to have a private version of the web.config.
By "private" I mean that a developer can freely change the file to suit their dev/test needs at any given moment, without it affecting other team members and without ending up in source control.
How can one go about achieving this with Visual Studio 2015?
My closest solution so far is to have a "private" Solution Configuration with a matching Web.config Transformation file ("web.private.config") that's excluded from source control.
But this is not a satisfactory solution because:
a. The transformation is not run automatically when debugging (with F5). The developers need to remember to run it manually.
b. The result of the transformation ends up in the main "web.config" file which is, naturally, included in source control.
We had a very similar problem but only needed personalized versions of the <appSettings> section in Web.config.
In this situation the inclusion of an external file through configSource turned out to be problematic, as this attribute completely replaces the <appSettings>-node. So there remains no way to keep global key/values AND personal key/values for all developers. The whole section is completely replaced by the included private file.
What we need is both global and private <appSettings>. The solution we found was the file attribute. It allows to merge Web.config settings with settings from an additional file.
We ended up with a construct like this one:
<!-- Web.config with global appSettings) -->
...
<appSettings file="Web.PERSONAL.config">
<add key="BaseUrl" value="https://projectname.dev.local" />
...
</appSettings>
...
­
<!-- Web.PERSONAL.config with personal appSettings -->
<?xml version="1.0" encoding="utf-8"?>
<appSettings >
<add key="EmailSmtpUser" value="my.name#my.domain.com" />
<add key="EmailSmtpPwd" value="***" />
</appSettings >
If you put identical keys in both files, the Web.PERSONAL.config version will overwrite the Web.config version.
The file Web.PERSONAL.config must be excluded from Git through .gitignore .
Keep in mind:
While configSource works for ALL nodes in Web.config, the file attribute is restricted to <appSettings>.
Have web.config include an external file (via configSource) and add that file to .gitignore
The correct answer is to host your local development site in a separate location from your Visual Studio solution. You can then use publish profiles to publish changes to that location and web.config transforms to maintain a separate local config for each developer. Each developer would use a different publish profile which transforms the web.config with their own transform and deploys the transformed web.config to the publish location. You can then attach a debugger to the published site using Visual Studio's Debug > Attach To Process option.
I think there is a lot of value in standardising dev environments so that one can just download the solution and run it.
Custom, long term/permanent, developer specific configs will sooner or later lead to a subtle bug that will be tricky to find.
My solution to your problem would be to find out the reason(s) why permanent individual configs are needed and have a look if these environment specific differences can be eliminated.

ASP.NET: Securing Config Files in Github

In asp.net we can include file attribute in appsettings that can contain secret values:
Web.config
<appSettings file="HiddenSettings.config">
</appSettings>
HiddenSettings.config
<?xml version="1.0"?>
<appSettings>
<add key="DbConnectionString" value="VALUE_IN_TEMPLATE_FILE" />
</appSettings>
In git, we can simply keep the HiddenSettings.config in git-ignore, so that sensitive information will not be checked-in.
The problem with this approach is every time the developer takes the first copy of the code, he/she needs to fill the secret data manually.
What's the best practice to do that automatically (i.e. no manual action to fill secret information in local/target deployment environment)?
I've been pondering that recently myself. The best method I could come up with so far is to link to a separate config file as you did and put that file to a separate private repository. Then add that repository as a submodule to the actual project. For instance:
git submodule add git#github.com:someUser/private-config.git
and the config points to the relative path of the submodule, something like:
<appSettings file="../../../../private-config/The.Real.Deal.config">
<add key="someKey" value="SAMPLE VALUE" />
</appSettings>
So when a user checks out the project (with initializing submodules) the config in the private-repo will be available. If not than they can download the project without the actual values and will only have access to the sample values.
Compared to other methods this looked good to me but I'm always open to suggestions too.

ASP.NET 3.5 application with multiple web.config files (IIS 7)

We are working on a web application that creates more web applications.
Each web application will have to get a Url Rewrite rule (URL REWRITE MODULE 2.0).
As far as I know, there's no way to add such rules without modifying the web.config file (am I right??).
So my plan was to work with multiple web.config partial files. One main .config file, and lots of .config files per application (every file will contain it's web application url rewrite rules).
This way sounds a little bit messy, but I can't think of anything else, and suggestions will be welcomed.
So is it possible to use very-multiple web.config files for the root application?
Thanks in advance, Gal.
This following Tag will do the trick.
The absence of this tag was the main reason for my problem when i using with two web.config files for my two different application running in my website.
**<location path="." inheritInChildApplications="false">**
<system.web>
<!-- ... -->
</system.web>
**</location>**
Every application must have a full web.config and not partial, exept if you go with net 4
The trick is to use a lot the remove command on the other inside web.config and remove the parents setting that must not used on this.
For example if on the main root you have the a module that you do not won to use it on the other trees, you use the remove command on all other web.config to remove it. Especial the modules that are on one Bin and not on an other directory bin.
<httpModules>
<remove name="TheHttoModuleNotNeedHere" />
<remove name="AnonymousIdentification" />
... add here your other modules for that directory...
</httpModules>
The remove command is working for almost all sessions on config.
You can do make it work, I have done it, but its a lot of work to find all the conflicts/unnecessary configs and remove it.
For some other session there also the clear command. For example on role Manager you can clear all and add new.
<roleManager enabled="true" ...>
<providers>
<clear />
<add name="MyName" ... type="System.Web.Security.SqlRoleProvider" />
</providers>
Hope this help as tips to make it work.

msdeploy sync and web.config

I am using msdeploy to transfer my changes(via a nant script in Team City) that I make to a site and it is great!! I have just one question, I am using msdeploy with the sync feature to make my life easier.
I currently exclude the web.config in my msdeploy because I do not know how to change the web.config on the fly. How do I change the web.config on the destination site if I do a sync?
Suppose you have a source directory with a web.config file that looks like this:
<configuration>
<system.web>
<randomSection name="value" name2="value2" />
</system.web>
</configuration>
And you want to change the "name" attribute to "GoGermany"
msdeploy -verb:sync -source:dirpath=c:\source -dest:dirpath=c:\dest
-setParam:type=XmlFile,match=//randomSection/#name,scope=web.config$,value=GoGermany
This will sync the two directories, while converting web.configs to change the #name attribute. The "match" subparameter is an X-Path selecting the attribute to change.
You can also do the parameter using type="TextFile" in which case you can do a regex match/replace against the entire file. The example above uses XmlFile which means an XML attribute transform.
Hope that helps.

divide web.config

I am developing a asp.net project and I dont have very long web.config file yet(more then 400 lines). but with this nhibernate log4net and urlrewrites. its getting bigger and bigger. is there a proper way to divide web.config into pieces. like nhibernate.config and log4net.config ofcourse urlrewrite.config
system.webServer is a configuration section group - you cannot externalize that.
You can only put the configSource= on a configuration section - e.g.
<system.webServer>
<validation configSource="validation.config"/>
<modules configSource="modules.config" />
<handlers configSource="handlers.config" />
</system.webServer>
What is a configuration section group or a regular configuration section can only be determined by looking at the documentation for those things (and even then it's often not very easy to figure out whether it's a section or a section group :-( ).
This is possible by using the configSource attribute of root sections in the config file. This is actually a feature of the .NET configuration system so it can be done in any web or app config file.
Here is a blog post that describes this feature quite well.

Resources