Storing connection strings in web.config - asp.net

Why do we store connection strings in web.config file? What are the benefits of doing so?

The web config file is used so you can reference the connection anywhere in your app. It avoids having to deal with a fairly long connection string within your application.
Here is a good article which may give you detailed information: http://articles.sitepoint.com/article/web-config-file-demystified#
There is even a wiki page for it :) (surprisingly):
http://en.wikipedia.org/wiki/Web.config
If you ever move / change to a different database format the connection string setting inside of the web.config file can be changed in one place rather then digging through your entire application looking for it. This also avoids having to recompile or build an application to get the new connection string setting.
If you are wondering how to access the information from within a web.config file that can be found here:
http://msdn.microsoft.com/en-us/library/4c2kcht0(VS.85).aspx
There is also sample code right in there.

Imagine you have several classes which access your database; you can:
Place your connection string in every class
Create a constant to store that value
Place it inside your configuration file and to refer it
These have following characteristics:
Every time a connection string changes, for instance, migrating from development to production environment, you'll need to change everywhere;
By using a constant, you just need to change a single place. But in this case, when your string needs to be changed, you'll need to recompile it.
Same as above, without that recompile part. You can to develop your application and other people set that database connection to you
So, by storing a connection string into your web.config file you gain more flexibility to change that setting than other alternatives.

Reason #1
As everyone is mentioning, having the connection string in the web.config makes it easy to update/change as needed. It becomes a single source where the arguments can be easily be changed.
Reason #2
Beyond that though, IIS is configured not serve up web.config to users who request the file. If your website is,
www.mydomain.com
someone can't hit http://www.mydomain.com/web.config and scrape all your confidential settings, passwords, and so forth.
(As a side, note, IIS won't serve up files in the App_Code directory either to a user, so the web.config file isn't unique in this respect.)
Reason #3
ASP.NET automatically detects changes to configuration files and will immediately applies new settings.
More info..
MSDN has a discussion of the ASP.NET configuration system at,
http://msdn.microsoft.com/en-us/library/aa719558%28VS.71%29.aspx

What I like most about having the connection string in the web.config is when you have multiple environments that you test on. Say you have a Test server, Staging server and a Production server. Well you don't need to have code that checks which server you're on, or have to recompile different versions for each... just use the web.config to store your connection strings and that way you can have a different web.config on each server but the same web application with no hassles. You may want to Encrypt your Connection String Settings as well so they're not visible to everyone that has access to the folder.

You can reference them using the ConfigurationManager via the ConnectionStrings property.
http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.connectionstrings.aspx

It allows the connection string to be configured by someone maintaining the site.

You don't have to re-build the application if the connection string changes. An admin can make the change and the code remains the same.

Related

Moving ASP.net site to another server

Assume I have asp.net websites on Server1 and need to move them to Server2, what is the best practice for this and how do I ensure that all relevant files, databases, etc are moved as well? Am I going to have to manually amend all the web.configs and other config files, plus find out what dependencies each site has, or is there a way to just export everything and import to the new server?
I have not found anything else on SO that has instructions for this.
Thanks
Edit: This is similar but not the same as the other question. The other question doesn't actually provide an answer, just some ideas about staging environments.
I'd like this to be as automated as possible due to having about 30 applications to move. The new server is pretty much identical but I noticed that when I moved one application using 'Web Deploy' as a test, it didn't bring over the dependencies and I had to manually find out which ones were missing and install them.
how do I ensure that all relevant files, databases, etc are moved as
well?
Typical asp.net sites have all data, and database under the one main directory. So you just copy/paste the full directory from the old to the new one server.
But we have some points to note here.
DataBase files are locked by the database, so you need to first remove them from the database.
In the new site you need to remount the database files and change the web.config according to the new server (eg, maybe new ip address, new names on database.
and finally the permissions on the new host must be correct and the same, if you have for example some directory that you need write permissions, you must add it also to the new server
You can also read: How to set correct file permissions for ASP.NET on IIS

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

How are parameters for ScriptResource.axd calls generated?

A client has custom firewall rules around their website to prevent any number of attacks. One of the custom rules blocks all requests (either GET or POST) including a double hyphen, in order to prevent SQL injection. While updating their website last night, we had an issue where on every page, one of the calls to the ScriptResource.axd included a double hyphen(--) resulting in access to the script being denied.
We had seen this issue previously and thought we had worked around it by using the ScriptReferenceProfiler in order to generate the list of scripts we'd need to combine in order to remove so many script references. That was working until the update last night when the issue reoccurred. (Interestingly, I reran the ScriptReferenceProfiler and all of the scripts it identified were already included in the CompositeScript listing so I don't know where this file came from.)
I finally created a new IIS virtual directory where the issue with the double dashes didn't occur, despite pointing to the same directory and codebase as the previous virtual directory. (I set the initial virtual directory to act as a redirect to the new one so the users wouldn't have to worry about updating links or bookmarks.) I can see from this post that the first parameter is generated via encrypting the assembly name and resourcename which explains the difference in the values between the two virtual directories.
But obviously, I'd like to avoid this situation in the future. Does anyone have any thoughts as to how to prevent double dashes from appearing in the ScriptResource requests?
For reference, this occurred in a VB.Net website running in .NET 4.0 on IIS 6/Windows Server 2003. Additionally, the script file being rejected was for an Infragistics control of some sort. (I turned off the firewall rule briefly in order to get the file and then re-enabled it. I wasn't able to tell from the script what role it played for Infragistics, though.)
Thanks.
The first parameter (d) is the assembly and the resource. For the assembly, this includes the name and version as well as the public key token if the assembly is strong named. If any of these change then the string for the resource will also change.
The second parameter (t) is just for the timestamp and this allows the resource to change if an assembly containing an embedded resource is updated without the assembly name or version changing even if caching is enabled on a site.
The encryption of the first parameter is based on the MachineKey so you could change the MachineKey to change the string that results from the encryption. This may help you to have a simple workaround for the issue when it does come up even if you don't control the names and versions of all of the assemblies that you use.
Related reading that may be of interest to you:
machineKey Element (ASP.NET Settings Schema)
How To: Configure MachineKey in ASP.NET 2.0
Debugging ASP.NET 2.0 Web Resources: Decrypting the URL and Getting the Resource Name

VB.Net Read 2 Connection Strings from external file

I have a situation where I have a vb.net program that uses two connection strings.
This program will be used on multiple web servers on multiple domains and the only difference for any of them is the two connection strings.
What would be the best solution to read in these connection strings from a file separate from my actual .vb code?
Ideally I want to be able to drop the .vb and the connection string file into its own folder on any number of asp.net websites and not update anything else (for example add any connections to the web.config or anything) than the external file containing the connection strings, I assume something like xml would suffice?
If possible could you give me code examples?
I would put them both in the same web.config. Give them two different names and dependent on which server you are on. You can use:
Request.ServerVariables("SERVER_NAME")
-OR-
Request.ServerVariables("LOCAL_ADDR")
Depending on your expected return you can condition the webconfigurationmanager to read one of the two connectionStrings property. Your best bet is to set a Session Variable from a basepage. Condition it to see if the Session has been populated and thus, you can read the variable throughout the application.
If you use two different .config files you are going to run into a problem where you are going to have to code your entire application on which one you want to ALWAYS use depending on which server you are on.
If you include a web.config file inside another web.config file it is the same as just adding the same two different connectionStrings in the same web.config file.
Use the built in .config support.
If you add an app.config file to your project, you can add a connectionStrings section to it, which you can access using the ConfigurationManager.ConnectionStrings property.
Please don't try to reinvent the wheel.

Using web.config to store and map info

I've been reading others questions regarding storing settings in the web.config. Most of you agree that's a good way to store settings.
I just have another doubt about that.
In my app, I need to map some ID's in the web.config. For example:
[Table = UserType]
1 - User
/2 - Admin
Is it a good idea to store these settings in the web.config so I know what is the right ID in my application? Do you have a better solution?
Thanks guys,
G
If that values doesn't change too often, it's better to create a enum to store that values. An enum sample could be:
enum UserType
{
User = 1,
Admin = 2
}
For more options, also take a look into [Flags] attribute: Enums, Flags, and C# — Oh my! (bad pun…)
Keep in mind every time you edit your web.config file, your IIS application pool get recycled.
I typically use the web.config to store things like connection strings, or key/value pairs that rarely [or never] change.
What you described would be ideal for an enum or perhaps a look up table in the database.
In my web application I have a number of "Configuration" settings that exceed the structure of the Web.Config file, and don't want the web site to restart after changing them.
I ended up creating a number of xml config files where the xml data maps to objects that get cached into collections. This allows us to change the config on the fly, while not restarting the web site. We have a filewatcher that triggers a reload of the cache objects from the Xml files when something in the configuration directory gets modified.
You can also use the database for this obviously, but in our case this was configuration data that is maintained by development and deployed with the build.

Resources