Lluís Franco on Geeks.ms
  • Home

[HowTo] Modificar cadena de conexión, la eterna pregunta

  • By lfranco
  • Oct-20-2011
  • Sin categoría
  • 1 Comment.

Si no la he leído 200 veces en los foros MSDN no la he leído ninguna 🙂 vayan unos ejemplos:

Es posible modificar el App.config de una aplicación C# en tiempo de ejecución?

Cómo hago para cambiar los datos de conexión en tiempo de ejecución?

Cadena de conexión Dinámica, ¿cómo debo hacer esta modificación desde un windows form en el mismo aplicativo?

Y así unas cuantas. De hecho una búsqueda me ha arrojado más de 3.000 resultados :-S

De todos modos lo que me sorprende no es tanto el alto número de veces que se hace esta pregunta, sino que cada vez que la respondo me digo a mi mismo: Haz un post y publícalo para referenciar a la gente… y siempre se me olvida 😛

Bueno, pues de hoy no pasa. Y es que curiosamente me ha llegado la misma pregunta por dos medios distintos. Uhm… casualidad? No lo creo. Sin duda es una señal divina: El MEV me está hablando y yo -pobre mortal- debo obedecer.

App.config y Machine.config

A ver, el quid de la cuestión es que la primera vez que usamos una cadena de conexión (en un DataSource, Contexto de datos, etc.) el propio Visual Studio genera en el fichero app.config una entrada con nombre para nuestra aplicación. Esta entrada es parecida a esto:

<connectionStrings>

  <clear />

  <add name="YourApp.Properties.Settings.YourAppConnectionString"

    connectionString="Data Source=.sqlexpress;Initial Catalog=YourDataBase;Integrated Security=True"

    providerName="System.Data.SqlClient" />

</connectionStrings>

Y sirve para que si alguna vez deseamos cambiar el nombre del servidor, o la base de datos, o cualquier otro atributo, lo hagamos en un único sitio.

Antes de seguir un detalle: ¿Os habéis fijado si en vuestro app.config tenéis un clear antes de la cadena de conexión? Si no lo tenéis, os aconsejo añadirlo. Este clear lo que hace es no cargar las cadenas de conexión  del fichero machine.config, que es común a todas las aplicaciones.

Y es que cuando se inicia una aplicación de .NET, se cargan las secciones comunes del machine.config y a continuación se añaden las propias de la aplicación definidas en el app.config.

Como por defecto en el machine.config tenemos esto:

<connectionStrings>

    <add name="LocalSqlServer" connectionString="data source=.SQLEXPRESS;Integrated Security=SSPI;

    AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>

</connectionStrings>

Si no usamos el tag clear, al ejecutar nuestra aplicación tendremos dos cadenas de conexión, y la primera será la del machine.config… y eso no nos gusta 😛

Así que asumiendo que ya habéis agregado el tag clear, vamos al turrón.

System.Configuration

En este ensamblado encontraremos todo lo necesario para la gestión de nuestras cadenas de configuración (y muchas cosas más).

Lo primero es agregar una referencia a este ensamblado a nuestro proyecto:

References_system_configuration

Y a continuación crearemos una clase con un par de métodos para leer y guardar las cadenas de conexión en el app.config:

public class ConnectionStringManager

{

    public static string GetConnectionString(string connectionStringName)

    {

        Configuration appconfig =

            ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

        ConnectionStringSettings connStringSettings = appconfig.ConnectionStrings.ConnectionStrings[connectionStringName];

        return connStringSettings.ConnectionString;

    }

 

    public static void SaveConnectionString(string connectionStringName, string connectionString)

    {

        Configuration appconfig =

            ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

        appconfig.ConnectionStrings.ConnectionStrings[connectionStringName].ConnectionString = connectionString;

        appconfig.Save();

    }

}

Básicamente, al primero se le pasa el nombre de la cadena de conexión a recuperar (por si tenemos varias) y nos devuelve la cadena de conexión. Al segundo se le pasa el nombre de la cadena de conexión y la nueva cadena de conexión modificada.

Para hacerlo un poco más sencillo y no tener que recordar el nombre de las cadenas de conexión, vamos a crear algunos métodos más en la clase. Uno que retorne la lista de nombres de las cadenas de conexión del fichero de configuración, y otro que retorne sólo el nombre de la primera (muy útil si sólo tenemos una).

public static List<string> GetConnectionStringNames()

{

    List<string> cns = new List<string>();

    Configuration appconfig =

        ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

    foreach (ConnectionStringSettings cn in appconfig.ConnectionStrings.ConnectionStrings)

    {

        cns.Add(cn.Name);

    }

    return cns;

}

 

public static string GetFirstConnectionStringName()

{

    return GetConnectionStringNames().FirstOrDefault();

}

Incluso, basándonos en este último podemos crear otro que nos devuelva la primera cadena de conexión:

public static string GetFirstConnectionString()

{

    return GetConnectionString(GetFirstConnectionStringName());

}

Let’s play!

A partir de esta clase, trabajar con las cadenas de conexión es muy sencillo. Supongamos que tenemos un formulario similar a esto:

form_sqlserver_settings

Leer los valores de la cadena de conexión y mostrarlos es tan sencillo como esto:

private void showSavedConnectionSettings()

{

    SqlConnectionStringBuilder builder =

        new SqlConnectionStringBuilder(ConnectionStringManager.GetFirstConnectionString());

    connectionServerComboBox.EditValue = builder.DataSource.ToUpper();

    connectionDatabaseComboBox.EditValue = builder.InitialCatalog.ToUpper();

    if (builder.IntegratedSecurity)

    {

        connectionAuthenticationModeRadioGroup.EditValue = 0;

        connectionUsernameTextEdit.Text = string.Empty;

        connectionPasswordTextEdit.Text = string.Empty;

    }

    else

    {

        connectionAuthenticationModeRadioGroup.EditValue = 1;

        connectionUsernameTextEdit.Text = builder.UserID;

        connectionPasswordTextEdit.Text = builder.Password;

    }

}

Es decir, creamos un SqlConnectionStringBuilder a partir de la primera cadena de conexión del fichero de configuración y a partir de aquí, trabajamos por separado con cada una de las partes de la cadena, accediendo a las propiedades del builder (Datasource, InitialCatalog, IntegratedSecurity, etc.). De este modo las mostramos en el form, o dónde queramos…

Guardando que es gerundio

La siguiente pregunta lógica es: ¿Y para guardar sólo uno de los valores en el fichero de configuración? El típico ejemplo es modificar el nombre del servidor al instalar en el cliente final. Para ello vamos a usar también un builder, y vamos a ampliar la clase anterior con algunos métodos más. Para obtener los valores de las propiedades de la cadena de conexión y para guardarlos:

Obtener valores de propiedades de la cadena de conexión:

public static string GetSqlServerServerName()

{

    string cs = GetConnectionString(GetFirstConnectionStringName());

    if (cs != null)

    {

        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(cs);

        return builder.DataSource;

    }

    else

        return null;

}

 

public static string GetSqlServerDatabaseName()

{

    string cs = GetConnectionString(GetFirstConnectionStringName());

    if (cs != null)

    {

        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(cs);

        return builder.InitialCatalog;

    }

    else

        return null;

}

 

public static string GetSqlServerUserName()

{

    string cs = GetConnectionString(GetFirstConnectionStringName());

    if (cs != null)

    {

        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(cs);

        return builder.UserID;

    }

    else

        return null;

}

 

public static string GetSqlServerPassword()

{

    string cs = GetConnectionString(GetFirstConnectionStringName());

    if (cs != null)

    {

        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(cs);

        return builder.Password;

    }

    else

        return null;

}

 

public static bool? GetSqlServerIntegratedSecurity()

{

    string cs = GetConnectionString(GetFirstConnectionStringName());

    if (cs != null)

    {

        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(cs);

        return builder.IntegratedSecurity;

    }

    else

        return null;

}

Guardar valores de propiedades en la cadena de conexión:

public static string SetConnectionStringServerName(

    string connectionString, string serverName)

{

    SqlConnectionStringBuilder builder =

        new SqlConnectionStringBuilder(connectionString);

    builder.DataSource = serverName;

    return builder.ConnectionString;

}

 

public static string SetConnectionStringAutenticationIntegrated(

    string connectionString)

{

    SqlConnectionStringBuilder builder =

        new SqlConnectionStringBuilder(connectionString);

    builder.IntegratedSecurity = true;

    return builder.ConnectionString;

}

 

public static string SetConnectionStringAutenticationSQLServer(

    string connectionString, string username, string password)

{

    SqlConnectionStringBuilder builder =

        new SqlConnectionStringBuilder(connectionString);

    builder.IntegratedSecurity = false;

    builder.UserID = username;

    builder.Password = password;

    return builder.ConnectionString;

}

 

public static string SetConnectionStringDatabaseName(

    string connectionString, string databaseName)

{

    SqlConnectionStringBuilder builder =

        new SqlConnectionStringBuilder(connectionString);

    builder.InitialCatalog = databaseName;

    return builder.ConnectionString;

}

Así pues, para cambiar el nombre del servidor en el app.config bastaría con:

  1. Leer la cadena de conexión actual
  2. Cambiar el nombre del server
  3. Volver a guardar la cadena de conexión
string cs = ConnectionStringManager.GetFirstConnectionString();

string newConStr = ConnectionStringManager.SetConnectionStringServerName(cs, "MyNewServer");

ConnectionStringManager.SaveConnectionString(

    ConnectionStringManager.GetFirstConnectionStringName(), newConStr);

Me han quedado bastantes cosas en el tintero (recuperar los servidores SQL Server de nuestra red local, mostrar las bases de datos de un server, o crear un formulario para el usuario final). Si hay tiempo y pensáis que es un tema de interés lo veremos en futuros posts.

Nos vemos! 😀

Comments

One Responseso far

  1. kiquenet dice:
    24 octubre, 2011 a las 5:20 pm

    Sería interesante ver ese diálogo de Sql Server 🙂

    Respecto a cuadros de diálogos así, éstas son buenas referencias:

    http://stackoverflow.com/questions/2205993/winforms-connection-properties-dialog-for-configuration-string

    Data Connection Dialog
    http://archive.msdn.microsoft.com/Connection

    Saludos

    Responder

Deja un comentario Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

← Previous Post Next Post →

Tags

async Back best practices

Entradas recientes

  • Video de mi charla en la #dotNetSpain2016
  • I’m back. Miss me?
  • Office365 actualizado a 2013 para nuevas suscripciones
  • Serializar listas genéricas en aplicaciones WinRT
  • [TPL] Problemas de concurrencia

Comentarios recientes

  • Darling Chavez en Tip: Mostrar objetos relacionados en DevExpress GridControl
  • Alexander en [TPL] Problemas de concurrencia
  • cristinakity en Funciones escalares en TSQL, JOINS, CROSS APPLY, y la madre que parió al topo.
  • cristinakity en Funciones escalares en TSQL, JOINS, CROSS APPLY, y la madre que parió al topo.
  • anonymous en HowTo: Crear una pantalla de inicio (splash screen)

Archivos

  • marzo 2016
  • marzo 2013
  • octubre 2012
  • septiembre 2012
  • agosto 2012
  • febrero 2012
  • diciembre 2011
  • noviembre 2011
  • octubre 2011
  • septiembre 2011
  • agosto 2011
  • junio 2011
  • mayo 2011
  • abril 2011
  • febrero 2011
  • enero 2011
  • diciembre 2010
  • noviembre 2010
  • octubre 2010
  • agosto 2010
  • julio 2010
  • marzo 2010
  • febrero 2010
  • enero 2010
  • diciembre 2009
  • noviembre 2009
  • octubre 2009
  • septiembre 2009
  • agosto 2009
  • julio 2009
  • junio 2009
  • mayo 2009
  • abril 2009
  • marzo 2009
  • febrero 2009
  • enero 2009
  • diciembre 2008
  • noviembre 2008
  • octubre 2008
  • septiembre 2008
  • agosto 2008
  • julio 2008
  • junio 2008
  • mayo 2008
  • abril 2008
  • marzo 2008
  • febrero 2008
  • enero 2008
  • diciembre 2007
  • noviembre 2007
  • octubre 2007
  • septiembre 2007
  • agosto 2007
  • abril 2007
  • febrero 2007
  • enero 2007

Categorías

  • .NET
  • C#
  • Channel9
  • Evento
  • Personal
  • Videos

Meta

  • Acceder
  • RSS de las entradas
  • RSS de los comentarios
  • WordPress.org
About This Site

A cras tincidunt, ut tellus et. Gravida scel ipsum sed iaculis, nunc non nam. Placerat sed phase llus, purus purus elit.

Archives Widget
  • January 2010
  • December 2009
  • November 2009
  • October 2009
Categories
  • Entertainment
  • Technology
  • Sports & Recreation
  • Jobs & Lifestyle
Search
  • facebook
  • twitter
  • rss

Powered by WordPress  |  Business Directory by InkThemes.

This site uses cookies: Find out more.