64 votes

Comment définir une configuration de chaîne de connexion par programme dans .net?

J'aimerais définir une chaîne de connexion par programmation, avec absolument aucun changement aux fichiers de configuration / clés de registre.

J'ai ce bout de code, mais malheureusement, il déclenche une exception avec "la configuration est en lecture seule".

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

Edit: Le problème est que j'ai un code existant qui lit la chaîne de connexion de la configuration. La chaîne de configuration manuellement, ou par l'intermédiaire d'une ressource, ne semble pas être valide les options. Ce que j'ai vraiment besoin d'une manière de modifier la configuration par programmation.

117voto

David Gardiner Points 4907

J'ai écrit à ce sujet dans un post sur mon blog . L'astuce consiste à utiliser la réflexion pour insérer des valeurs afin d'accéder aux champs (et méthodes) non publics.

par exemple.

 var settings = ConfigurationManager.ConnectionStrings[ 0 ];

var fi = typeof( ConfigurationElement ).GetField( "_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic );

fi.SetValue(settings, false);

settings.ConnectionString = "Data Source=Something";
 

9voto

NotNormal Points 11

Une autre façon de procéder serait d’opérer directement sur la collection:

 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);
 

8voto

Rupert Davis Points 61

Je cherchais la réponse à la même question à propos de permettre à l'utilisateur de modifier la chaîne de connexion en un clic une application en sélectionnant un serveur SQL local.

Le code ci-dessous affiche un formulaire utilisateur qui contacte tous les serveurs SQL disponibles localement et leur permet d'en sélectionner un. Il construit ensuite une chaîne de connexion pour ce serveur et la renvoie à partir d'une variable du formulaire. Le code modifie ensuite les fichiers de configuration et les enregistre.

 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))
}
 

7voto

Junto Points 5597

Je trouve que cela fonctionne pour moi:

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

Cela remplace une chaîne de connexion existante.

5voto

Jamal Hansen Points 814

Je suis actuellement en utilisant l'injection de dépendance pour gérer les différentes chaînes de connexion dans dev/prod vs environnements de test. J'en ai encore pour modifier manuellement le webconfig si je veux déplacer entre dev et de prod, mais pour le test, j'ai un IConnectionStringFactory interface avec un défaut de mise en œuvre qui ressemble à la configuration web et un autre test de configuration qui renvoie des valeurs statiques. De cette façon, quand je suis en essais j'ai tout simplement mis de l'usine à la mise en œuvre des tests et il sera de retour le test de la chaîne de connexion de la clé que je demande. Sinon, il va le chercher dans le webconfig.

J'ai pu étendre cette mesure à l'autre de la mise en œuvre de dev vs prod, mais je suis plus à l'aise d'avoir un seul de la mise en œuvre de IConnectionStringFactory dans ma production, l'assemblage et la mise en œuvre des tests lors de mes tests de l'assemblée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X