Correção: System.InvalidOperationException: No connection string named 'DefaultConnection' could be found
Se GetConnectionString retorna null no .NET 11, o seu appsettings.json não tem a chave, não está sendo copiado para a saída do build, ou o arquivo de ambiente errado está sendo selecionado. Três checagens resolvem 95% dos casos.
A correção: IConfiguration.GetConnectionString("DefaultConnection") retorna null, e o EF Core lança a exceção porque esperava uma string. Ou o seu appsettings.json não contém uma entrada ConnectionStrings:DefaultConnection, ou o arquivo não está sendo copiado para a saída do build, ou o ambiente errado está selecionado e a chave só existe num arquivo irmão. Verifique o JSON, configure Copy to Output Directory = Copy if newer e confirme que ASPNETCORE_ENVIRONMENT corresponde ao arquivo onde você escreveu a string.
Unhandled exception. System.InvalidOperationException: No connection string named 'DefaultConnection' could be found in the application configuration.
at Microsoft.EntityFrameworkCore.SqlServerDbContextOptionsExtensions.UseSqlServer(DbContextOptionsBuilder optionsBuilder, String connectionString, Action`1 sqlServerOptionsAction)
at Program.<Main>$(String[] args) in C:\src\Api\Program.cs:line 14
at Program.<Main>(String[] args)
O erro é levantado pelo UseSqlServer(string) do EF Core (e equivalentes em Npgsql, MySQL, SQLite) quando o parâmetro string é null. O texto da exceção vem da validação de parâmetros do EF Core, mas a causa raiz está sempre a montante, em Microsoft.Extensions.Configuration. Este guia foi escrito contra .NET 11 preview 4, EF Core 11.0.0-preview.4 e Microsoft.AspNetCore.App 11.0.0-preview.4. O mesmo conselho vale até o .NET Core 3.1.
Por que GetConnectionString retorna null
IConfiguration.GetConnectionString("X") é açúcar sintático para configuration["ConnectionStrings:X"]. O sistema de configuração percorre cada provedor registrado em ordem (arquivos JSON, user secrets, variáveis de ambiente, argumentos de linha de comando) e retorna o primeiro match. null significa que nenhum dos provedores tinha aquela chave. Existem seis razões comuns:
- A chave está faltando em
appsettings.json. - A chave está presente, mas o arquivo não é copiado para o diretório de saída, então o binário em execução nunca a vê.
- A chave está em
appsettings.Production.json, mas o app está rodando emDevelopment, onde sóappsettings.Development.jsoné carregado. - As ferramentas de tempo de design do EF Core (
dotnet ef migrations add) são invocadas a partir de uma pasta que não contém o arquivo JSON. - A chave mora em User Secrets, mas o
.csprojdo projeto está sem<UserSecretsId>. - A connection string está como variável de ambiente, mas o nome usa um underscore simples (
ConnectionStrings_DefaultConnection) em vez do underscore duplo obrigatório (ConnectionStrings__DefaultConnection).
Os casos 2 e 6 são os assassinos silenciosos, porque o código parece correto à inspeção.
Um repro mínimo
Uma Web API limpa criada com dotnet new webapi -n Api e uma ligação de EF Core. É o menor setup que reproduz o erro de forma confiável.
// .NET 11, C# 14, EF Core 11.0.0
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<AppDb>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
var app = builder.Build();
app.MapGet("/", () => "ok");
app.Run();
public class AppDb : DbContext
{
public AppDb(DbContextOptions<AppDb> options) : base(options) { }
}
// appsettings.json -- this file is what you THINK is being read
{
"Logging": { "LogLevel": { "Default": "Information" } },
"AllowedHosts": "*"
}
builder.Configuration.GetConnectionString("DefaultConnection") retorna null, o EF Core lança em UseSqlServer(null) e o host falha ao ser construído. A mensagem da exceção nomeia DefaultConnection, o que é enganoso: nada no EF Core obriga esse nome. Qualquer string que você passar para GetConnectionString(...) aparecerá lá.
A correção em três checagens
Execute na ordem. Cada uma já me pegou pelo menos uma vez.
1. Verifique se o JSON tem a chave
Abra o appsettings.json no projeto que hospeda o Program.cs (não o projeto que define o DbContext, se forem diferentes) e adicione a seção:
// appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=AppDb;Trusted_Connection=True;TrustServerCertificate=True"
}
}
O nome do provedor em UseSqlServer é independente do formato da connection string; SQL Server, PostgreSQL, MySQL e SQLite leem o mesmo formato ConnectionStrings:Name. Se o seu JSON tem a chave mas dentro de um objeto Settings aninhado, GetConnectionString não a encontrará. O caminho exato deve ser ConnectionStrings.<Name>.
2. Confirme que o arquivo está na saída do build
Isso pega bibliotecas de classes e worker services em que o template do projeto não inclui appsettings.json por padrão. Depois de dotnet build, verifique se o arquivo está junto da sua DLL:
dotnet build
ls bin/Debug/net11.0/appsettings.json
Se estiver faltando, adicione isso ao .csproj:
<!-- .NET 11 SDK-style csproj -->
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="appsettings.*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<DependentUpon>appsettings.json</DependentUpon>
</None>
</ItemGroup>
O Microsoft.NET.Sdk.Web inclui isso implicitamente, então um projeto criado com dotnet new webapi não precisa. Projetos worker (Microsoft.NET.Sdk.Worker) também incluem. O Microsoft.NET.Sdk puro não, e é onde a maioria desses bugs vive: um host de console reaproveitado para dotnet ef, ou uma biblioteca de classes que ganhou um Program.cs depois.
3. Faça o ambiente bater com o arquivo onde você escreveu
WebApplication.CreateBuilder carrega appsettings.json primeiro, depois appsettings.{Environment}.json, com o segundo sobrescrevendo o primeiro. O ambiente é lido de ASPNETCORE_ENVIRONMENT (Web) ou DOTNET_ENVIRONMENT (host genérico), com Production por padrão se nenhum estiver definido. Um modo de falha comum: você coloca a connection string só em appsettings.Development.json e depois roda o app em produção, onde só appsettings.json e appsettings.Production.json são carregados.
# powershell
$env:ASPNETCORE_ENVIRONMENT = "Development"
# bash
export ASPNETCORE_ENVIRONMENT=Development
dotnet run
Imprima o valor resolvido uma vez no startup para enxergá-lo nos logs:
// .NET 11, C# 14
var cs = builder.Configuration.GetConnectionString("DefaultConnection");
Console.WriteLine($"DefaultConnection length: {cs?.Length ?? 0}");
Nunca logue a connection string completa em produção, porque senhas costumam morar lá. Logar o tamanho é suficiente para distinguir null de “carregada mas vazia” de “carregada com conteúdo”.
Variantes que afetam diferentes audiências
dotnet ef migrations add a partir de uma biblioteca de classes
As ferramentas de tempo de design do EF Core resolvem o DbContext chamando o seu Program.Main ou encontrando um IDesignTimeDbContextFactory<T>. Se o DbContext mora numa biblioteca de classes, dotnet ef invoca o projeto de inicialização (a Web API) e lê a configuração dele. Rode da pasta certa:
# Bad: connection string is in Api/appsettings.json,
# but you ran this in Data/, where there is no JSON.
cd Data
dotnet ef migrations add Init
# Good: point at the startup project explicitly.
cd Data
dotnet ef migrations add Init --startup-project ../Api/Api.csproj
Se você precisa rodar migrations a partir do projeto de dados de forma autônoma (por exemplo, num pipeline de release), adicione um IDesignTimeDbContextFactory<AppDb>:
// .NET 11, EF Core 11.0.0
public class AppDbFactory : IDesignTimeDbContextFactory<AppDb>
{
public AppDb CreateDbContext(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false)
.AddEnvironmentVariables()
.Build();
var options = new DbContextOptionsBuilder<AppDb>()
.UseSqlServer(config.GetConnectionString("DefaultConnection"))
.Options;
return new AppDb(options);
}
}
Essa factory é apenas de tempo de design; ela não é registrada na DI nem roda em runtime.
Variáveis de ambiente em contêineres
Em Docker e Kubernetes, a convenção é achatar caminhos de configuração com underscore duplo. ConnectionStrings:DefaultConnection vira ConnectionStrings__DefaultConnection. Um underscore simples é apenas um nome comum, e o sistema de configuração não vai reconhecê-lo.
# docker-compose, .NET 11
services:
api:
image: api:11.0
environment:
ASPNETCORE_ENVIRONMENT: Production
ConnectionStrings__DefaultConnection: "Server=db;Database=App;User Id=sa;Password=..."
# Kubernetes secret reference
- name: ConnectionStrings__DefaultConnection
valueFrom:
secretKeyRef:
name: db
key: connection
Se a variável está correta mas continua sumida, confirme que AddEnvironmentVariables() está no pipeline de configuração. O WebApplication.CreateBuilder chama isso para você. Um ConfigurationBuilder customizado num projeto de console não chama, a não ser que você adicione explicitamente.
User Secrets em desenvolvimento
dotnet user-secrets set "ConnectionStrings:DefaultConnection" "..." só funciona quando o .csproj do projeto tem um elemento <UserSecretsId>:
<!-- .NET 11 SDK-style csproj -->
<PropertyGroup>
<TargetFramework>net11.0</TargetFramework>
<UserSecretsId>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</UserSecretsId>
</PropertyGroup>
dotnet user-secrets init adiciona isso para você. User secrets só são carregados quando IHostEnvironment.IsDevelopment() é true, o que é mais uma razão para a checagem 3 (a do ambiente) importar.
Azure Key Vault e outros provedores
Se você usa builder.Configuration.AddAzureKeyVault(...), o nome do secret precisa bater com o caminho de configuração, com -- como separador. Um secret do vault chamado ConnectionStrings--DefaultConnection aparece como ConnectionStrings:DefaultConnection. Um secret chamado DefaultConnection não.
O erro menciona um nome que você não reconhece
Se a mensagem diz No connection string named 'X' e X não é o nome que você digitou, provavelmente você está chamando UseSqlServer(connectionStringName: "X") numa sobrecarga antiga do EF Core que resolve nomes contra a tabela de connection strings da aplicação. O EF Core 11 ainda suporta isso por compatibilidade. A correção é a mesma: adicione uma entrada ConnectionStrings:X ou passe a connection string literal em vez de um nome.
Native AOT e trimming
Se você publica com Native AOT, o binding de configuração ainda funciona para GetConnectionString, que é uma busca de string simples. O erro que você está olhando não é um aviso de trim do AOT. Se você também ver IL3050, esse é o aviso de binding para o binding via reflexão do Configure<T>, não para connection strings.
Relacionado
Para o contexto mais amplo de EF Core que costuma cercar esse erro, veja o resumo sobre detecção de queries N+1 e o guia de queries compiladas em hot paths. Para amarrar testes contra a mesma connection string, o tutorial de Testcontainers mostra como subir um SQL Server real por fixture sem commitar credenciais. Para diagnosticar esse tipo de falha de startup num app rodando, o setup de Serilog e Seq deixa a configuração resolvida legível nos logs de produção.
Fontes
IConfiguration.GetConnectionStringextension, Microsoft Learn.- Configuration in ASP.NET Core, Microsoft Learn.
- Design-time DbContext Creation, EF Core docs.
- Safe storage of app secrets in development, Microsoft Learn.
- Environment variables configuration provider, Microsoft Learn, sobre o separador
__.
Comments
Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.