56

When I change the connection string using this code, it does not reload app.config at runtime. I expected it to reload similarly to how we reload app.config.

config.ConnectionStrings.ConnectionStrings["JVVNL_NEW.Properties.Settings.JVVNL_NEWConnectionString1"].ConnectionString = ConString;
config.ConnectionStrings.ConnectionStrings["CMS_NEW.Properties.Settings.JVVNL_NEWConnectionString1"].ConnectionString = ConString;
config.Save(ConfigurationSaveMode.Modified,true);
ConfigurationManager.RefreshSection(config.ConnectionStrings.SectionInformation.SectionName);
anishpatel
  • 1,472
  • 1
  • 16
  • 23

8 Answers8

102

Had to do this exact thing. This is the code that worked for me:

var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var connectionStringsSection = (ConnectionStringsSection)config.GetSection("connectionStrings");
connectionStringsSection.ConnectionStrings["Blah"].ConnectionString = "Data Source=blah;Initial Catalog=blah;UID=blah;password=blah";
config.Save();
ConfigurationManager.RefreshSection("connectionStrings");
Bradley Mountford
  • 8,195
  • 4
  • 41
  • 41
  • 1
    @Bradley :I am trying do the same thing but i am getting UAC rights issues... because app.config is in programfiles. Is there a way can i change the location of app.config. I have tried `AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\app.config");` in `Main()` but it did work. – prasy Jan 16 '15 at 15:10
  • 1
    @Bradley This throws a NullReferenceException for me so I changed it to `config.ConnectionStrings.ConnectionStrings.Add(new ConnectionStringSettings())` but the rest of the code works. Thanks! – knguyen Apr 22 '15 at 17:30
  • @knguyen Sounds like you either did not have a config section named "connectionStrings" or did not have a connection string defined in that section with the name you specified in line 3 (which I named "Blah") of the example. – Bradley Mountford Apr 27 '15 at 18:56
  • 6
    Actually, I just tested and this *does* change the on-disk file for me. – Josh Jan 13 '17 at 18:35
  • https://learn.microsoft.com/en-ca/dotnet/api/system.configuration.configuration.save does indeed confirm that the configuration file is updated by calling the `save` method – jmlane Dec 18 '17 at 14:57
  • it was not working for me, after this change it worked for me `OpenExeConfiguration(Application.ExecutablePath)` Note: to see the effect open file your_app_name.exe.config with notepad – sairfan Jun 05 '18 at 18:08
7

IIRC, the ConfigurationManager.RefreshSection requires a string parameter specifying the name of the Section to refresh :

ConfigurationManager.RefreshSection("connectionStrings");

I think that the ASP.NET application should automatically reload when the ConnectionStrings element is modified and the configuration does not need to be manually reloaded.

Cerebrus
  • 25,615
  • 8
  • 56
  • 70
4
//You can apply the logic in "Program.cs"

//Logic for getting new connection string
//****
//

MyDBName="mydb";

//
//****

//Assign new connection string to a variable
string newCnnStr = a="Data Source=.\SQLExpress;Initial Catalog=" + MyDBName + ";Persist Security Info=True;User ID=sa;Password=mypwd";

//And Finally replace the value of setting
Properties.Settings.Default["Nameof_ConnectionString_inSettingFile"] = newCnnStr;

//This method replaces the value at run time and also don't needs app.config for the same setting. It will have the va;ue till the application runs.

//It worked for me.
Romesh
  • 2,291
  • 3
  • 24
  • 47
2

Yeah, when ASP.NET web.config gets updated, the whole application gets restarted which means the web.config gets reloaded.

ajma
  • 12,106
  • 12
  • 71
  • 90
2

You can also refresh the configuration in it's entirety:

ConnectionStringSettings importToConnectionString = currentConfiguration.ConnectionStrings.ConnectionStrings[newName];

if (importToConnectionString == null)
{
    importToConnectionString = new ConnectionStringSettings();
    importToConnectionString.ConnectionString = importFromConnectionString.ConnectionString;
    importToConnectionString.ProviderName = importFromConnectionString.ProviderName;
    importToConnectionString.Name = newName;
    currentConfiguration.ConnectionStrings.ConnectionStrings.Add(importToConnectionString);
}
else
{
    importToConnectionString.ConnectionString = importFromConnectionString.ConnectionString;
    importToConnectionString.ProviderName = importFromConnectionString.ProviderName;
}

Properties.Settings.Default.Reload();
Neil Barnwell
  • 41,080
  • 29
  • 148
  • 220
  • Hi Neil, could you maybe expand on your answer? I am a noob. How do I set currentConfiguration and importFromConnectionString ? – robnardo Jul 03 '09 at 15:16
  • @neil-barnwell: Please elborate the implementation of the line "Properties.Settings.Default.Reload(); ". Right now it is too cryptic to understand – Sudhanshu Mishra Jul 11 '12 at 05:25
  • @mishrsud Well it does what it says - it loads into memory the settings you've just saved to the file. – Neil Barnwell Jul 11 '12 at 08:28
1

First you might want to add

using System.Configuration;

To your .cs file. If it not available add it through the Project References as it is not included by default in a new project.

This is my solution to this problem. First I made the ConnectionProperties Class that saves the items I need to change in the original connection string. The _name variable in the ConnectionProperties class is important to be the name of the connectionString The first method takes a connection string and changes the option you want with the new value.

private String changeConnStringItem(string connString,string option, string value)
    {
        String[] conItems = connString.Split(';');
        String result = "";
        foreach (String item in conItems)
        {
            if (item.StartsWith(option))
            {
                result += option + "=" + value + ";";
            }
            else
            {
                result += item + ";";
            }
        }
        return result;
    }

You can change this method to accomodate your own needs. I have both mysql and mssql connections so I needed both of them. Of course you can refine this draft code for yourself.

private void changeConnectionSettings(ConnectionProperties cp)
{
     var cnSection = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
     String connString = cnSection.ConnectionStrings.ConnectionStrings[cp.Name].ConnectionString;
     connString = changeConnStringItem(connString, "provider connection string=\"data source", cp.DataSource);
     connString = changeConnStringItem(connString, "provider connection string=\"server", cp.DataSource);
     connString = changeConnStringItem(connString, "user id", cp.Username);
     connString = changeConnStringItem(connString, "password", cp.Password);
     connString = changeConnStringItem(connString, "initial catalog", cp.InitCatalogue);
     connString = changeConnStringItem(connString, "database", cp.InitCatalogue);
           cnSection.ConnectionStrings.ConnectionStrings[cp.Name].ConnectionString = connString;
     cnSection.Save();
     ConfigurationManager.RefreshSection("connectionStrings");
}

As I didn't want to add trivial information I ommited the Properties region of my code. Please add it if you want this to work.

class ConnectionProperties
{
    private String _name;
    private String _dataSource;
    private String _username;
    private String _password;
    private String _initCatalogue;

    /// <summary>
    /// Basic Connection Properties constructor
    /// </summary>
    public ConnectionProperties()
    {

    }

    /// <summary>
    /// Constructor with the needed settings
    /// </summary>
    /// <param name="name">The name identifier of the connection</param>
    /// <param name="dataSource">The url where we connect</param>
    /// <param name="username">Username for connection</param>
    /// <param name="password">Password for connection</param>
    /// <param name="initCat">Initial catalogue</param>
    public ConnectionProperties(String name,String dataSource, String username, String password, String initCat)
    {
        _name = name;
        _dataSource = dataSource;
        _username = username;
        _password = password;
        _initCatalogue = initCat;
    }
// Enter corresponding Properties here for access to private variables
}
Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61
0

//here is how to do it in Windows App.Config

public static bool ChangeConnectionString(string Name, string value, string providerName, string AppName)
    {
        bool retVal = false;
        try
        {

            string FILE_NAME = string.Concat(Application.StartupPath, "\\", AppName.Trim(), ".exe.Config"); //the application configuration file name
            XmlTextReader reader = new XmlTextReader(FILE_NAME);
            XmlDocument doc = new XmlDocument();
            doc.Load(reader);
            reader.Close();
            string nodeRoute = string.Concat("connectionStrings/add");

            XmlNode cnnStr = null;
            XmlElement root = doc.DocumentElement;
            XmlNodeList Settings = root.SelectNodes(nodeRoute);

            for (int i = 0; i < Settings.Count; i++)
            {
                cnnStr = Settings[i];
                if (cnnStr.Attributes["name"].Value.Equals(Name))
                    break;
                cnnStr = null;
            }

            cnnStr.Attributes["connectionString"].Value = value;
            cnnStr.Attributes["providerName"].Value = providerName;
            doc.Save(FILE_NAME);
            retVal = true;
        }
        catch (Exception ex)
        {
            retVal = false;
            //Handle the Exception as you like
        }
        return retVal;
    }
Matt Cain
  • 5,638
  • 3
  • 36
  • 45
Joselo
  • 1
  • 2
0

Here's the method I use:

public void AddOrUpdateAppConnectionStrings(string key, string value)
{
    try
    {
        var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        var settings = configFile.ConnectionStrings.ConnectionStrings;
        if (settings[key] == null)
        {
            settings.Add(new ConnectionStringSettings(key,value));
        }
        else
        {
            settings[key].ConnectionString = value;
        }
        configFile.Save(ConfigurationSaveMode.Modified);
        ConfigurationManager.RefreshSection(configFile.ConnectionStrings.SectionInformation.Name);
        Properties.Settings.Default.Reload();
    }
    catch (ConfigurationErrorsException)
    {
        Console.WriteLine("Error writing app settings");
    }
}
Joe Mayo
  • 7,501
  • 7
  • 41
  • 60