可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Is there a way where I can add a connection string to the ConnectionStringCollection returned by the ConfigurationManager at runtime in an Asp.Net application?
I have tried the following but am told that the configuration file is readonly.
ConfigurationManager.ConnectionStrings.Add(new ConnectionStringSettings(params));
Is there another way to do this at runtime? I know at design time I can add a connection string to the web.config; however, I'm looking to add something to that collection at run time.
Thanks
EDIT:
One of the reasons why I'm attempting to do this is due to a security requirement that prevents me from placing ConnectionStrings in the web.config (even encrypted). I would like to use elements like Membership and Profiles on my project; however, I am looking into an alternative to doing such w/o writing a custom provider. Custom Provider's aren't all that bad, but if I can find an easier solution, I'm all for it.
回答1:
var cfg = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(@"/");
cfg.ConnectionStrings.ConnectionStrings.Add(new ConnectionStringSettings(params));
cfg.Save();
Be Advised this will cause your website to recycle since it modifies the config file. Check out http://msdn.microsoft.com/en-us/library/4c2kcht0(VS.80).aspx
回答2:
You can use reflection to disable the private bReadOnly field (bad idea, etc.):
typeof(ConfigurationElementCollection)
.GetField("bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(ConfigurationManager.ConnectionStrings, false);
ConfigurationManager.ConnectionStrings.Add(new ConnectionStringSettings());
This is similar to the technique required to modify an existing connection string, and added as a comment there by Brian Rodgers.
回答3:
Just to point out whoever gave you the "security requirement" that you can't place the connection string in the web.config is an idiot. The web.config can never be accessed by anything other than your application or remote access to the server.
This sounds entirely like a requirements problem and should be solved there.
回答4:
If you are trying to edit the connection strings in your web.config at runtime take a look at WebConfigurationManager.
If you are just trying to modify the configuration at runtime to inject a connection string then you are out of luck. The ConfigurationManager object tree is meant to be a direct reflection of the configuration files, if you were able to change that the state would then be inconsistent.
I would recommend creating a simple facade class that you could use to retrieve your connection strings. This way you could have the facade return a connection string from your on the fly collection or if one doesn't exist then it could grab it from the ConfigurationManager.
class ConnectionStringProvider
{
Dictionary<string, System.Configuration.ConnectionStringSettings> _localStrings = new Dictionary<string, System.Configuration.ConnectionStringSettings>();
public void AddLocalConnectionString(string name, string connstring)
{
System.Configuration.ConnectionStringSettings cs = new System.Configuration.ConnectionStringSettings(name, connstring);
_localStrings.Add(name, cs);
}
public void RemoveLocalConnectionString(string name)
{
_localStrings.Remove(name);
}
public System.Configuration.ConnectionStringSettings this[string name] {
get
{
return _localStrings.ContainsKey(name) ? _localStrings[name] : System.Configuration.ConfigurationManager.ConnectionStrings[name];
}
}
}
Or you could always go quite a bit heavier and use something like the Enterprise Library Configuration Block.
回答5:
Haven't tried it yet, but perhaps you can alter the value of an existing connection string at runtime? For example, instead of:
ConfigurationManager.ConnectionStrings.Add(new ConnectionStringSettings(params));
Maybe you could do something like:
ConfigurationManager.ConnectionStrings["myconnection"].ConnectionString = "something";
If so, you could specify the connection string "variables" in config, but set them to false or empty connection strings:
<add name="myconnection" connectionString="SET AT RUNTIME" ... />
回答6:
The configuration infrastructure supports very robust encryption through the Windows DataProtection API wich uses a machine specific key to encrypt the configuration sections. This way it would not be possible to read the encrypted data anywhere but on the machine where it was encrypted.
This is the same API that is used for the Government compliant drive/folder encryption in Windows. Would this stand up to your companies security requirements?
Either manually or through your deployment automation you can execute this command to encrypt the connectionStrings section of your web.config for a specific web application.
aspnet_regiis -pe "connectionStrings" -app "/MyCoolWebApplication" -prov "DataProtectionConfigurationProvider"
回答7:
If you are using MS SQL you can configure you web server to access the SQL Server via the windows authentication, so you never have to have any passwords at all in your webconfig, or even floating around in your application memory.
回答8:
No, you can't modify the config file at runtime, it isn't intended for that.
Maybe you could use the Enterprise Libraries Configuration to do that.