How to Override a Value in Web.config Programatically - c#

I am developing a web app with a group of people and we all have different connection strings to our database.
The connection string is stored in our web.config which is source controlled, and sometimes people check in their web.config with their connection string which messes up my environment.
I want to use an environment variable that if exists will override the connection string in my web.config. How can I do that?

As others have noted in your comments there is no easy way to stop people from changing any file that is under source-control. However, what you could do is change your web.config file to have:
<connectionStrings configSource="Configs\ConnectionStrings.config" > </connectionStrings>
Then have a folder called Configs and in there a file named ConnectionStrings.config with content like:
<connectionStrings>
<add name="YourVersionHere" ... />
</connectionStrings>
That way you can check the web.config file in / out without it altering your connection string (it is now held in a separate file). Of course, this doesn't get you out of jail because they can then overwrite the ConnectionStrings.config file but it does allow you to break your config out so you can always be up to date with all the settings but never do a GET on your ConnectionStrings.config file.
The same applies to AppConfig etc. Basically allows you to manage your config in smaller chunks rather than all in one place.
You can get more information here: http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.configsource.aspx

Is it possible for you to move your connection strings from your application-level web.config down to your system-level machine.config file?

Related

Which connection string is chosen when it is specified in web.config , in IIS Default web site and in IIS application?

There is an option to specify the Connection string in multiple places like In web.config, in IIS (Default web site and the application itself), if the connection string is specified in all these three places, which connection string is chosen by the App?
I did some testing with the connection strings in my application running using IIS 8.5.
It looks like there are only two places to add connection strings: the local web.config and global web.config. IIS gives an interface to update these files.
Duplicate keys in a web.config file or across the local and global web.config triggers is not allowed. So shouldn't have to worry about which connection is chosen. If your code calls for a key, it will find that value. If there are zero or multiple connection strings with the same key expect errors. :)
Local vs Global Web.Config - There are local web.configs for each app and a global web.config per server. The global web.config is at %systemroot%\Microsoft.NET\Framework64\v4.0.30319\CONFIG for me.
IIS Interface
IIS shows a 'Connection Strings' button (button and dialog are pictured below) that brings up a menu.
If I update a connection in the web.config file, the dialog updates. If I update from the dialog, the web.config updates. So it looks like they are kept in sync.
Connections from the local web.config show 'Entry Type' as Local. Global web.configs connections show as Inherited
I also tried to set the same key (eg LocalSqlServer) in both web.configs and IIS threw an error.
There is no order, there is a name property in the connection string.
<connectionStrings>
<add name="RealDB" providerName="System.Data.SqlClient" connectionString="" />
<add name="NorthWind" providerName="System.Data.SqlClient" connectionString="" />
</connectionStrings>
In your code which database you want to use, you can get it from web.config and you can send it or use it on your data access layer.
var realConnection = ConfigurationManager.ConnectionStrings["RealDB"].ConnectionString;
var NortWindConnection = ConfigurationManager.ConnectionStrings["NorthWind"].ConnectionString;

Getting a connection string

The program I'm writing accesses a database. So when I use the SqlConnection() class, I hard code the actual connection string as a parameter. Eventually I'd like o deploy this program to different users. So my question is:
When a user installs a program on their computer, how does the new connection string get created, where is it stored, and how can I access it?
Thanks for the help
You need to out it in a configuration file and load it from there. For an ASP.NET application it would be in the web.config file;
<connectionStrings>
<add name="MyConnection" connectionString="MyConnectionString" />
</connectionStrings>
and then use
string connectionString = ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString
in your application.
The for each installation it would be configured for the local requirements.
For a desktop application the details are different but the principle is the same.
See references in answer from Luis Sagasta
As explained in MSDN, you should save the connection string in the configuration file:
MSDN: Connection Strings and Configuration Files
In the same article you will find information about encrypting the configuration section:
MSDN:Encrypting Configuration File Sections Using Protected Configuration
Regards.

Updating Web.config file of various sites programatically

I am preparing a single tool(web application) using which i should be able to change web.config file of various web applications hosted on different web servers.
I tried using WebConfigurationManager.OpenWebConfiguration(strings), but it takes only relative path but if i put shared location of different web servers web.config files, it fails.
MSDN ref:
https://msdn.microsoft.com/en-us/library/ms151456(v=vs.110).aspx
I think, in my case i will not be able to use WebConfigurationManager.OpenWebConfiguration.
Only option is XDocument.
Please suggest.
In past projects, I have used base and transform files with success: https://msdn.microsoft.com/en-us/library/vstudio/dd465318(v=vs.100).aspx.
As an example, we have a connection string in our web.config.base file like:
...
<connectionStrings>
<!-- Connection String Changes will be lost when this file is
regenerated - Please edit your transform file instead -->
<add
name="MainConnectionString"
connectionString="(default connection string)" />
and an entry in a web.config.transform file that looks like:
<connectionStrings>
<add name="MainConnectionString"
connectionString="(system-specific connection string)"
xdt:Transform="Replace"
xdt:Locator="Match(name)"
/>
The the web.config file is recreated when the application builds, with whatever connection string is defined in the local transform file replacing the default string. The web.config.base file is committed to our versioning system, while the transform is not.
So devs can have one transform file to connect to their local db's, qa servers have a different transform file, and demo servers have a different set again, all with a minimum of fuss, because most settings are kept in the web.config.base file, which is passed around with the repository, and only the connection string changes have to be maintained from one environment to the next.

connectionstring declare in iis without declaring in web.config

I want to declare my connection string in IIS and get it from there. I don't want to declare it in web.config page. Rather I need to know if is it possible to get the string from iis in web.config or read it from code file. I am using asp.net 4.0.,coding in c# and server is IIS7.5
According to this article you can use the IIS UI, or the command line to modify your connection string, but this will just write into the <connectionString> element in the web.config file any way (unless you've set it up to save elsewhere).
Also, you can store it in another .config file if you wish, and pull it into your web.config like so
<appSettings file="../VirtualDirectory/config/Env.config">
</appSettings>
You could then call it like so in your code:
System.Configuration.ConfigurationManager.AppSettings["DefaultConn"]
This can be quite useful if you want the location of your connection string to not be under your site (i.e. in a virtual directory).
You should put your connection string in the web.config. Putting your connection string elsewhere might not be portable, like moving from machine to machine. You also have the machine.config
In all, put in the web.config and you can encrypt it if you care about the secrecy
You can also have a separate config file e.g. db.config referenced from your web.config using the configSource attribute.
<connectionStringss configSource="Configuration\db.config" />

Need changable App.config file in WPF

I have a desktop WPF application which uses Entity Framework 4.1 Code First approach to manage data.
EF adds a connection string to the App.config file and I wan't to be able to change this connection string at runtime.
Scenario is like this:
When I deploy the application it has a default connection string in the App.config file. The user runs the application and since the connection string will probably be invalid for the user (because of server name, user id and password) I will display a server configuration window.
Here user will enter the valid information about his connection and press OK. I will then be able to change the App.config file and save the user's new valid information to the file.
Problems:
If I change it using ConfigurationManager, the changes will be temporary meaning that the file is not saved, changes are made in memory.
If I read the App.config file into a stream, make required changes in the memory, delete physical file and save the in memory stream as App.config again, Windows will not let me make changes to files under ProgramFiles folder.
What is would be the best approach here?
EDIT: Problem Again!
After I modify the App.config file with this method:
private void ApplyChangesToConnectionString()
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var connectionStringsSection = (ConnectionStringsSection)config.GetSection("connectionStrings");
connectionStringsSection.ConnectionStrings["SomeUniqueName"].ConnectionString = GetChangesAppliedConnectionString(connectionStringsSection.ConnectionStrings["SomeUniqueName"].ConnectionString);
config.Save(); // This line throws an exception
ConfigurationManager.RefreshSection("connectionStrings");
}
config.Save(); method call throws an error saying
"Access to "C:\Program Files (x86)\MyCompany\MyApp\MyApp.exe.config"
is denied."
I know that files under "Program files" are immutable, so how can I handle this?
I couldn't modify ConfigurationManager.ConnectionStrings["key"] object, because it is readonly.
So I decided to add a new connection string to my App.config file so it looks like this:
<connectionStrings>
<add name="SomeUniqueName" connectionString="Data Source=(local)\SQLExpress;Initial Catalog=MyDb;User Id=sa;Password=password; MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
and then changed my DbContext constructor to take newly added connection string like this:
public MyContext()
: base("name=SomeUniqueName")
{
}
Here, the value of name attribute at connection string and constructor must match.
Then to change this newly added connection string at runtime I used a method like this:
private void ApplyChangesToConnectionString()
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var connectionStringsSection = (ConnectionStringsSection)config.GetSection("connectionStrings");
connectionStringsSection.ConnectionStrings["SomeUniqueName"].ConnectionString = GetChangesAppliedConnectionString(connectionStringsSection.ConnectionStrings["SomeUniqueName"].ConnectionString);
config.Save();
ConfigurationManager.RefreshSection("connectionStrings");
}
App.config is not the proper place to do this since it's a global configuration used by the application.
I recommend you to save the settings per user. See this related question : c# - approach for saving user settings in a WPF application?
App.config is the correct approach in my opinion, however I wouldn't rely on writing the file physically yourself. Instead, allow the framework to do the heavy lifting for you.
Check out the sample here.
EDIT: Glad Sandeep's comment above has helped you. Feel free to check out that link too if you want a bit more information!

Categories