Modifying Root Web.config in code - asp.net

I would like to store some meta-information about a given site instance that can (a) be managed by that site instance and (b) persist clobbering of Web.config file.
The site will run in multiple environments (dev,testing,staging and production) and each environment can have different values for this metadata.
Note: All environments are running IIS 7.0+
The Root Web.config seems very appealing, as it is certainly outside of the website. Therefore, both files and databases can be changed while maintaining the metadata. I have seen how to modify the appSettings of the Web.config stored in the website, but is it possible to similarly modify the appSettings in the Root Web.config (Specifically within the proper directive)?
If you have other suggestions of approaching this problem, I would be very happy to hear them. Thank you!

would not use web.config for runtime modifications, that will cause the application to recycle, perhaps some other form of configuration file like app.config
if my assumption is incorrect and the web.config will not be edited after the application is started, then you can use WebConfigurationManager to access the file sections

Yes you can modufy the app settings within your web.config Just use the WebConfigurationManager class in the System.Web.Configuration namespace to create a Configuration object. This object could then be used to read and write changes to the web.config file.
You could then create your own "keys" or attributes that could be read as needed.
Depending upon what your attributes represent or if they need to be picked up by multiple environmnets from that server I would also look into making the modifications within the machine.config file as then those settings would apply to the enter machine and thereby picked up by multiple environments( if you are hosting multiple webapps from the server). This could save you time in modifying multiple web.config files and narrorw the storage or the metadata to one location vs. multiple config files in certain situations.

Related

Confused on what is the correct procedure on storing passwords in Web.config for Azure deployment

I've had a very frustrating experience on putting an MVC 5 app on Azure. I have been reading the following page: http://www.asp.net/identity/overview/features-api/best-practices-for-deploying-passwords-and-other-sensitive-data-to-aspnet-and-azure
But what I haven't managed to put in my head is the following:
Security Warning: Do not add your secrets .config file to your project or check it into source control. By default, Visual Studio sets the Build Action to Content, which means the file is deployed. For more information see Why don't all of the files in my project folder get deployed? Although you can use any extension for the secrets .config file, it's best to keep it .config, as config files are not served by IIS. Notice also that the AppSettingsSecrets.config file is two directory levels up from the web.config file, so it's completely out of the solution directory. By moving the file out of the solution directory, "git add *" won't add it to your repository.
And:
Security Warning: Unlike the AppSettingsSecrets.config file, the external connection strings file must be in the same directory as the root web.config file, so you'll have to take precautions to ensure you don't check it into your source repository.
The problem is the following: When I upload the Web.config file with the external files without being included I get hit by "The System cannot find the file specified", so for it to go away I must include the .config files defeating the purpose of Microsoft's post.
I really really really do not understand. I have added the connectionStrings and appSetting's keys in Azure's portal. What is the correct and secured way of putting my passwords and secrets online? What am I missing? Is it because I'm running in Debug mode?
According to this:
How can I secure passwords stored inside web.config?
There is nothing to worry about accessing the Web.config file...
But that just defies Microsoft's post.
Thanks.
I find the following technique to be the easiest way to do this.
Instead of putting the deployment values of these settings into the web.config, I keep the test values in there instead. I then put the deployment values into the Application Settings section of the Azure Website via the Azure Portal:
When the website runs, these settings will take precedence over what is in the web.config. This helps me avoid externalized files, allows me to keep sane development configuration that the team can share, and makes deployment very easy.
The best way is to set your secrets in the Connection Strings section of the portal. Any values set there will override values you specify in your web.config file.
This way they are only exposed to people who have admin access over the site itself. Having full access to the source won't even be enough to get the secret values.
More details here

customising web.config based on domain name

Most of my websites include one LIVE (production) and two TEST environments which are accessible via three different domain names e.g.
www.mysite.com
test1.mysite.com
test2.mysite.com
Each of the above are IIS Websites which point to the same physical versioned folder when they are all running the same version of the website.
What I typically do when releasing a new version is to place the new version into a new physical folder e.g. /inetpub/wwwroot/mywebsite/v41/ and point one of the TEST sites to that version of the site and test it. Once passed, the LIVE (and other TEST) websites are also repointed to the new version (e.g. v41).
Now my problem is this. Each website has its own database (TESTs have a copy of LIVE which can be refreshed via a couple of SQL BACKUP/RESTORE commands) however, the three sites are all "looking" at the same web.config file and therefore the same Database Connection Strings (either a System.Data.SqlClient or System.Data.EntityClient provider).
Is there any way that I can configure web.config to provide different connectionStrings based on the domain name/IIS website of the incoming request?
Maybe a tag or an attribute that qualifies a given tag?
I've looked all over for a solution but not yet found one.
Thanks in advance,
BloodBaz
there are two ways to manage multiple environment Specific Web.config file....
using t4 template,below is the link for that
http://ilearnable.net/2010/08/02/t4-for-complex-configuration/
VS Configuration Manager and create new "LIVE", "test1", "test2" build configurations for your project,check out the link
http://weblogs.asp.net/scottgu/archive/2007/09/21/tip-trick-automating-dev-qa-staging-and-production-web-config-settings-with-vs-2005.aspx
hope this helps..
why not split your config file up so connectionStrings.config is its own file. Then you can deploy everything and not overwrite that connectionString file.
where you normally would put the connectionString do this
<connectionStrings configSource="connectionStrings.config" />
Then create a file named connectionString.config
<?xml version="1.0"?>
<connectionStrings>
</connectionStrings>
Alternatively you can create another build option other than just release/debug. You can have web.config transforms that output a different config file depending on which one is selected.
I had a similar problem; I solved it by setting up all the database connection info in the same web config file, and then writing a handler that decides on the fly, based on the request and context, which environment it's in and uses that database.

ASP.NET - Have settings in the Web.config (and access them using ConfigurationSection) or in a separate XML file

I have few settings which I could place in a separate XML file and have them accessed in the Web app. Then I thought (thinking of one additional file to deploy), why not have them in the web.config itself. However, just because I need to have custom nodes, I can not have the settings under . So, I am thinking of creating a custom config handler following this. Would that be better than having a separate XML file? Is It going to be an overkill or performance wise? Is there a better way to go?
From performance standpoint putting custom settings in web.config and creating a configuration handler will be OK because the config values are cached and read only once when the application starts. Putting the values in a separate XML file you will need to handle the caching your self if you want to avoid parsing it every time you need to access those values.

Application Variable Vs Web.Config Variable

Which is better from a performance perspective?
Accessing a Global Application Variable (Application["foo"])
versus
Accessing an AppSetting variable from the web.config
Does .NET Cache the AppSetting variables so that it is not accessing the web.config file with every use?
These two things are not comparable. appSettings, or any other configuration settings, are for configuration settings. Application variables are for quantities that might change during the course of the application, or are for things like tables of domain data values. These latter are things which you would not place into a configuration file, because they change rarely, and do not need to be configured.
appSettings and everything else in a config file, is cached. The file is only read once per AppDomain, in general. In fact, when you change your web.config, it causes an AppDomain restart, mainly so that the new configuration settings can be read in.
appSettings are apparently not cached
EDIT: Seems both appSettings and Application variables would be the same speed then. After the initial load of course.

ASP.NET: external custom config file in a virtual directory - how to?

I know that there at least two approaches to leverage the web.config file:
using the configSource attribute which was introduced in .NET 2.0 - here is a good blog entry about it.
The file attribute of the appSettings tag which lets you point to an external file with a relative path. Described in the MSDN documentation on the appSettings element.
Now, my problem is that both approaches work well only for physical paths. But I need to address a config file which is in a virtual directory.
Which other method could I use to put my config resources in a virtual directory?
Note: I want to do it this way, because I have multiple instances of my web application on the same server (and that on many servers). To keep deployment easy and clean, I want to keep one directory for all the files (aspx, ascx, images, css, js etc.) and point the web apps in IIS for different customers (=domains, https etc.) to this single directory. In every IIS web I would have a virtual directory called "custom" which points to a different folder for each web.
Update: I'd like to point out that this virtual directory "custom" is not suited to contain an inherited web.config - that web.config would be valid only for the custom folder which doesn't contain aspx/ascx files.
I have the same scenario and after reading you post I realised that asp.net won't let you do this for various security reasons.
Therefore I turned to the OS to find an equivalent to the Linux soft link function which in turn led me to the Junction utility from sysinternals. This can create a directory that is actually any other directory on that volume and asp.net can't tell the difference and so happy loads the config sections that are not actually in a subdirectory of you website. Works for me :)
Virtual Directories can be set as applications, and you can just place another web.config there.
It will inherit any changes from the parent config, and you can add custom settings in it.
I was looking to do the same thing but it did not work, so I decided to do the opposite, as you know the web.config can be inherited, so I pointed IIS to a folder containing the client config (connection string, file path etc) files and the website files i put them on a virtual directory with the rest of the webconfig (where it load dll and other application files needed)
So basically i can use the website files to multple clients and the clients with their own Database connection string and other specific client settings.

Resources