Is there any way to interpret (parser) a connection string for an object?

6

There is a particular library I am using where I need to separately pass the database connection values separately: Username, Password, Host, and Database.

I took this project and someone else, and I noticed that the programmer, in addition to the connectionString used for the default configuration of the database, separately set these same data through <appSettings> using <add key="Key" value="Value"> to implement specifically for that library cited above.

I do not think this is a good idea, since I would theoretically be repeating the same configuration I already have, but the difference is that it is written in connectionString .

I was wondering if there is any way to transform a connectionString into a key / value structure.

For example, I would like this string below to become an object or dictionary.

"Data Source=.\SQLEXPRESS;Initial Catalog=Target_Database;User Id=User; Password=MyPassword"

How can I do this?

    
asked by anonymous 06.07.2017 / 13:55

3 answers

6

How can you guarantee the format of string can do something like this:

var cs = ConfigurationManager.ConnectionStrings["connString"].ConnectionString;

var dicionario = cs.Split(';').ToDictionary(x => x.Split('=')[0], 
                                            x => x.Split('=')[1], 
                                            StringComparer.OrdinalIgnoreCase);

See working in .NET Fiddle.

This will return a dictionary with this structure

 
[Data Source, .\SQLEXPRESS]  
[Initial Catalog, Target_Database]  
[User Id, User]  
[Password, MyPassword]
    
06.07.2017 / 14:06
3

I would also like to give my two cents here.

After checking the English Stackoverflow , I learned that there is a specific class to do this work: System.Data.Common.DbConnectionStringBuilder .

I've done an example below just to demonstrate how it would be used.

using System;
using System.Data.Common;

public class Program
{
    public static void Main()
    {
        var builder = new DbConnectionStringBuilder();

        builder.ConnectionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=Target_Database;User Id=User; Password=MyPassword";

        Console.WriteLine(builder["data source"]);
    }
}

You can access the values of builder through the name of the option used in connectionString . There is no difference between uppercase and lowercase, so you could also use builder["Data Source"] to access the value of this property.

TIP : If you need to check, before using, if a property exists, just use the ContainsKey() method. It will return false if the last key does not exist.

    
06.07.2017 / 18:27
3

One suggestion is to use Regex with and add the results in a dictionary, the regex would look like this:

([^\s].*?)=([^;]+?)(;|$)

 ^     ^     ^        ^
 |     |     |        |
 |     |     |        |
 |     |     |        +---- Verifica se é o final da string
 |     |     |              ou se encontra um ponto virgula
 |     |     |        
 |     |     +------------- Busca o "valor" até encontrar um ;
 |     |             
 |     +------------------- Busca qualquer coisa que representa a chave
 |                  
 +------------------------- A chave não pode extrair o espaço que vier no prefixo

The code should look something like this

using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;

public class Test
{
    public static void Main()
    {
        Dictionary<string, string> configuracoes = new Dictionary<string, string>();

        string re = "([^\s].*?)=([^;]+?)(;|$)";

        string input = "Data Source=.\SQLEXPRESS;Initial Catalog=Target_Database;User Id=User; Password=MyPassword";

        foreach (Match m in Regex.Matches(input, re)) {
            //Salva o item
            configuracoes[m.Groups[1].Value] = m.Groups[2].Value;
        }

        //Pegando os itens do dicionário
        Console.WriteLine("Valor: {0}", configuracoes["Data Source"]); // Retorna .\SQLEXPRESS
        Console.WriteLine("Valor: {0}", configuracoes["Initial Catalog"]); // Retorna Target_Database
        Console.WriteLine("Valor: {0}", configuracoes["User Id"]); // Retorna User
        Console.WriteLine("Valor: {0}", configuracoes["Password"]); // Retorna MyPassword
    }
}

Notes:

  • The .Groups[1] takes what is inside the parentheses ([^\s].*?)
  • The .Groups[2] takes what is inside the parentheses ([^;]+?)
  

The .Groups[0] would get the whole match, and the .Groups[3] would get the (;|$) , but we will not use any of them

Example on IDEONE

    
06.07.2017 / 18:19