Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Use SqlConnectionStringBuilder para criar e editar strings de conexão por meio de propriedades tipadas. Herda de DbConnectionStringBuilder. Use-o sempre que seu código adicionar ou alterar um valor, em vez de juntar cadeias de caracteres.
O construtor:
- Expõe cada palavra-chave como uma propriedade tipada. Por exemplo,
ConnectTimeoutcomo um int eEncryptcomo umSqlConnectionEncryptOption. - Rejeita palavras-chave desconhecidas e muitos valores fora da faixa com ArgumentException ao configurá-los.
- Mapeia sinônimos como
Servereuidpara palavras-chave canônicas comoData SourceeUser ID. - Coloca entre aspas os valores que contêm pontos e vírgulas, aspas ou espaços à frente ou ao fim.
Para a lista de palavras-chave, veja Opções de Conexão. Para o formato de texto, veja Regras de parsing.
Cada amostra é um programa completo. As abas do .NET Framework usam C# 7.3. Para criar um projeto que execute as amostras, veja Criar o projeto.
Prevenir a injeção de cadeia de conexão
Quando seu código insere texto não confiável em uma cadeia de conexão, um ponto e vírgula nesse texto pode adicionar uma palavra-chave ou substituir uma anterior, porque o último valor vence. O construtor armazena o valor inteiro em uma propriedade e o coloca entre aspas, para que o texto não possa se tornar outra palavra-chave.
Este programa define InitialCatalog para um valor que tenta desligar o pooling:
using Microsoft.Data.SqlClient;
// Simulates a value that came from a user or another untrusted source.
string databaseFromUser = "Orders;Pooling=false";
var builder = new SqlConnectionStringBuilder
{
DataSource = "tcp:sql.example.com,1433",
InitialCatalog = databaseFromUser,
IntegratedSecurity = true,
Encrypt = SqlConnectionEncryptOption.Strict,
};
Console.WriteLine(builder.ConnectionString);
Console.WriteLine($"Pooling: {builder.Pooling}");
A saída é:
Data Source=tcp:sql.example.com,1433;Initial Catalog="Orders;Pooling=false";Integrated Security=True;Encrypt=Strict
Pooling: True
O gerador coloca o valor entre aspas, e Pooling permanece True. O driver envia Orders;Pooling=false para o servidor como o nome do banco de dados.
Usar aspas impede a injeção de palavras-chave. Não decide se um valor é permitido. Verifique a entrada não confiável em relação a uma lista de servidores ou bancos de dados permitidos antes de usá-la.
Complete uma string de conexão base
Armazene as partes de uma cadeia de conexão que não mudam, como o servidor e o banco de dados, na configuração. Adicione o segredo e os valores específicos da carga de trabalho em tempo de execução. Passe a string base para o construtor e então defina as propriedades.
Esse programa lê uma string base e uma senha de variáveis de ambiente separadas, conecta-se com autenticação SQL e confirma que a senha não fica visível após a abertura da conexão.
using Microsoft.Data.SqlClient;
// The base string holds no secret. The password comes from a separate secret source.
string baseConnectionString =
Environment.GetEnvironmentVariable("SQL_BASE_CONNECTION_STRING")
?? throw new InvalidOperationException(
"Set the SQL_BASE_CONNECTION_STRING environment variable.");
string password =
Environment.GetEnvironmentVariable("SQL_PASSWORD")
?? throw new InvalidOperationException(
"Set the SQL_PASSWORD environment variable.");
var builder = new SqlConnectionStringBuilder(baseConnectionString)
{
Password = password,
ApplicationName = "Orders.Worker",
};
await using var connection = new SqlConnection(builder.ConnectionString);
await connection.OpenAsync();
await using var command = new SqlCommand("SELECT APP_NAME();", connection);
Console.WriteLine($"APP_NAME(): {await command.ExecuteScalarAsync()}");
var opened = new SqlConnectionStringBuilder(connection.ConnectionString);
Console.WriteLine($"Password visible after open: {opened.ContainsKey("Password") && opened.Password.Length > 0}");
Defina SQL_BASE_CONNECTION_STRING para um valor como Server=tcp:<server>,1433;Database=<database>;User ID=<user>;Encrypt=true. A saída é:
APP_NAME(): Orders.Worker
Password visible after open: False
Persist Security Info tem como padrão false, então o driver remove a senha de SqlConnection.ConnectionString após a abertura da conexão. Mantenha essa configuração padrão.
Prefira um método de autenticação que não precise de senha, como autenticação integrada no Windows ou uma identidade gerenciada pelo Microsoft Entra ID. Para mais informações, veja autenticação do Microsoft Entra ID e Proteger informações de conexão.
Leitura e alteração de valores
O construtor também funciona como dicionário. O indexador, ContainsKey, Remove e TryGetValue aceitam uma palavra-chave ou qualquer um dos sinônimos.
using Microsoft.Data.SqlClient;
var b = new SqlConnectionStringBuilder("Server=sql.example.com;Database=Orders;uid=app_user;pwd=x");
b["server"] = "tcp:sql2.example.com,1433";
Console.WriteLine($"DataSource: {b.DataSource}");
Console.WriteLine($"ContainsKey(\"uid\"): {b.ContainsKey("uid")}");
Console.WriteLine($"Remove(\"pwd\"): {b.Remove("pwd")}");
Console.WriteLine($"TryGetValue: {b.TryGetValue("Database", out object? db)} {db}");
Console.WriteLine($"ShouldSerialize(\"Pooling\"): {b.ShouldSerialize("Pooling")}");
Console.WriteLine(b.ConnectionString);
try { b["Bogus"] = 1; } catch (Exception e) { Console.WriteLine($"{e.GetType().Name}: {e.Message}"); }
try { b.ConnectTimeout = -1; } catch (Exception e) { Console.WriteLine($"{e.GetType().Name}: {e.Message}"); }
A saída é:
DataSource: tcp:sql2.example.com,1433
ContainsKey("uid"): True
Remove("pwd"): True
TryGetValue: True Orders
ShouldSerialize("Pooling"): False
Data Source=tcp:sql2.example.com,1433;Initial Catalog=Orders;User ID=app_user
ArgumentException: Keyword not supported: 'Bogus'.
ArgumentException: Invalid value for key 'Connect Timeout'.
ShouldSerialize retorna false para uma palavra-chave que não está na string.
ContainsKey retorna true para cada palavra-chave suportada, independentemente de a string a definir ou não. A propriedade ConnectionString inclui apenas as palavras-chave que você definiu.
Entenda o que o builder não verifica
O construtor rejeita palavras-chave desconhecidas e muitos valores inválidos, mas não verifica todos os valores. Por exemplo, ele aceita qualquer texto para Type System Version e Transaction Binding, e não verifica o comprimento das strings. Também não verifica combinações de palavras-chave, então aceita Authentication=Active Directory Default junto com Integrated Security=true.
SqlConnection rejeita essa combinação com ArgumentException quando você passa a string. Para a lista completa de regras, veja Regras de validação.
O construtor escreve Authentication valores sem espaços, como Authentication=ActiveDirectoryDefault. O driver aceita ambas as formas.
O construtor também não protege uma senha depois que ela entra na memória do processo, e não decide se uma configuração de servidor, identidade ou certificado é segura.
Mantenha uma cadeia de conexão canônica
Cada cadeia de conexão distinta tem seu próprio pool de conexão. Duas cadeias manuscritas que diferem apenas na ordem das keywords ou sinônimos criam dois pools. O construtor escreve palavras-chave canônicas em uma ordem consistente, então Server=a;Database=d e Database=d;Server=a tornam-se ambos Data Source=a;Initial Catalog=d. Construa a cadeia de conexão uma vez na inicialização e reutilize builder.ConnectionString. Não adicione valores por requisição, como nomes de usuário ou IDs de requisição. Para mais orientações sobre pooling, veja Usar pool de conexões.