如何在.net中以编程方式设置连接stringconfiguration?

我想以编程方式设置连接string,绝对不会更改任何configuration文件/registry项。

我有这段代码,但不幸的是它引发一个exception,“configuration是只读的”。

ConfigurationManager.ConnectionStrings.Clear(); string connectionString = "Server=myserver;Port=8080;Database=my_db;..."; ConnectionStringSettings connectionStringSettings = new ConnectionStringSettings("MyConnectionStringKey", connectionString); ConfigurationManager.ConnectionStrings.Add(connectionStringSettings); 

编辑:问题是我有现有的代码,从configuration读取连接string。 所以手动设置configurationstring,或通过资源,似乎不是有效的选项。 我真正需要的是以编程方式修改configuration的方法。

我在博客上写了一篇文章 。 诀窍是使用reflection来戳入值作为访问非公共字段(和方法)的方式。

例如。

 var settings = ConfigurationManager.ConnectionStrings[ 0 ]; var fi = typeof( ConfigurationElement ).GetField( "_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic ); fi.SetValue(settings, false); settings.ConnectionString = "Data Source=Something"; 

我正在寻找答案,允许用户通过select一个本地SQL Server来修改连接string在一次点击应用程序相同的问题。

下面的代码显示一个联系所有本地可用的SQL Server的用户表单,并允许他们select一个。 然后它为该服务器构造一个连接string,并从窗体上的一个variables返回它。 代码然后修改configuration文件并保存它。

 string NewConnection = ""; // get the user to supply connection details frmSetSQLConnection frm = new frmSetSQLConnection(); frm.ShowDialog(); if (frm.DialogResult == DialogResult.OK) { // here we set the users connection string for the database // Get the application configuration file. System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); // Get the connection strings section. ConnectionStringsSection csSection = config.ConnectionStrings; foreach (ConnectionStringSettings connection3 in csSection.ConnectionStrings) { // Here we check for the preset string - this could be done by item no as well if (connection3.ConnectionString == "Data Source=SQL204\\SQL2008;Initial Catalog=Transition;Integrated Security=True") { // amend the details and save connection3.ConnectionString = frm.Connection; NewConnection = frm.Connection; break; } } config.Save(ConfigurationSaveMode.Modified); // reload the config file so the new values are available ConfigurationManager.RefreshSection(csSection.SectionInformation.Name); return clsDBMaintenance.UpdateDatabase(NewConnection)) } 

我发现这对我有用:

 Configuration config = WebConfigurationManager.OpenWebConfiguration("~"); ConnectionStringsSection section = config.GetSection("connectionStrings") as ConnectionStringsSection; if (section != null) { section.ConnectionStrings["MyConnectionString"].ConnectionString = connectionString; config.Save(); } 

这将覆盖现有的连接string。

解决这个问题的另一种方法是直接在集合上进行操作:

 var settings = ConfigurationManager.ConnectionStrings; var element = typeof(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); var collection = typeof(ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); element.SetValue(settings, false); collection.SetValue(settings, false); settings.Add(new ConnectionStringSettings("ConnectionStringName", connectionString)); // Repeat above line as necessary collection.SetValue(settings, true); element.SetValue(settings, true); 

我正在使用dependency injection来处理dev / prod与testing环境中的不同连接string。 如果我想要移到dev和prod之间,我仍然需要手动更改webconfig,但是为了testing,我有一个IConnectionStringFactory接口,它具有一个默认实现,它查看Webconfiguration和一个返回静态值的替代testingconfiguration。 这样,当我testing时,我只是将工厂设置为testing实现,它将返回我要求的密钥的testing连接string。 否则,它会在webconfig中查找。

我可以扩展到另一个实现dev或prod,但我更容易有一个IConnectionStringFactory实现在我的生产组装和testing实现在我的testing大会。

你可以把它放在资源文件中。 它不会具有ConfigurationManager类的内置function,但它将起作用。

假设Resources.resx:

Resources.Default.ConnectionString = "Server=myserver;" // etc

然后在你的代码中:

conn.ConnectionString = Resources.Default.ConnectionString

这是一个黑客,我知道。

除了给出的其他答案外,假设连接string不是简单的另一个configurationvariables或常量,可以考虑使用SqlConnectionStringBuilder类,而不是直接将string连接在一起。

编辑:UPS,对不起,只是看到你基本上想从另一个来源读取您的连接string(完成我猜)。

ConfigurationManager用于从configuration文件读取

您的解决scheme是简单地将conn.ConnectionString设置为您需要的连接string。