Partilhar via


Configuração no ASP.NET Core

Por Rick Anderson e Kirk Larkin

Observação

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.

Advertência

Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.

Importante

Estas informações referem-se a um produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado comercialmente. A Microsoft não oferece garantias, expressas ou implícitas, em relação às informações fornecidas aqui.

Para a versão atual, consulte a versão .NET 9 deste artigo.

A configuração do aplicativo no ASP.NET Core é executada usando um ou mais provedores de configuração. Os provedores de configuração leem dados de configuração de pares chave-valor usando uma variedade de fontes de configuração:

  • Arquivos de configurações, como appsettings.json
  • Variáveis de ambiente
  • Azure Key Vault
  • Configuração da Aplicação Azure
  • Argumentos de linha de comando
  • Fornecedores personalizados, instalados ou criados
  • Arquivos de diretório
  • Objetos .NET na memória

Este artigo fornece informações sobre a configuração no ASP.NET Core. Para obter informações sobre como usar a configuração em aplicativos non-ASP.NET Core, consulte Configuração do .NET.

Para Blazor obter orientação de configuração, que adiciona ou substitui a orientação neste nó, consulte Configuração do ASP.NET CoreBlazor.

Configuração de aplicativos e hosts

ASP.NET aplicativos principais configuram e iniciam um host. O host é responsável pela inicialização do aplicativo e gerenciamento do tempo de vida. Os modelos ASP.NET Core criam um WebApplicationBuilder que contém o host. Embora alguma configuração possa ser feita no host e nos provedores de configuração do aplicativo, geralmente, apenas a configuração necessária para o host deve ser feita na configuração do host.

A configuração do aplicativo é a prioridade mais alta e é detalhada na próxima seção. A configuração do host segue a configuração do aplicativo e é descrita neste artigo.

Fontes de configuração de aplicativos padrão

ASP.NET principais aplicativos Web criados com dotnet new ou Visual Studio geram o seguinte código:

var builder = WebApplication.CreateBuilder(args);

WebApplication.CreateBuilder inicializa uma nova instância da classe WebApplicationBuilder com padrões pré-configurados. O WebApplicationBuilder inicializado (builder) fornece a configuração padrão para a aplicação na seguinte ordem, da mais alta para a mais baixa prioridade:

  1. Argumentos de linha de comando usando o provedor de configuração de linha de comando .
  2. Variáveis de ambiente não prefixadas usando o provedor de configuração de variáveis de ambiente não prefixadas.
  3. Segredos de usuário quando o aplicativo é executado no ambiente Development.
  4. appsettings.{Environment}.json usando o provedor de configuração JSON. Por exemplo, appsettings.Production.json e appsettings.Development.json.
  5. appsettings.json usando o provedor de configuração JSON .
  6. Um fallback para a configuração do host descrita na próxima seção.

Observação: WebApplication.CreateBuilder(args) só deve ser chamado uma vez em aplicativos que dependem da hospedagem em processo do IIS.

Fontes de configuração de host padrão

A lista a seguir contém as fontes de configuração de host padrão da prioridade mais alta para a mais baixa para WebApplicationBuilder:

  1. Argumentos de linha de comando usando o provedor de configuração de linha de comando
  2. DOTNET_-variáveis de ambiente prefixadas usando o provedor de configuração de variáveis de ambiente.
  3. ASPNETCORE_-variáveis de ambiente prefixadas usando o provedor de configuração de variáveis de ambiente.

Para o .NET Generic Host and Web Host, as fontes de configuração de host padrão da prioridade mais alta para a mais baixa é:

  1. ASPNETCORE_-variáveis de ambiente prefixadas usando o provedor de configuração de variáveis de ambiente.
  2. Argumentos de linha de comando usando o provedor de configuração de linha de comando
  3. DOTNET_-variáveis de ambiente prefixadas usando o provedor de configuração de variáveis de ambiente.

Quando um valor de configuração é definido na configuração do host e do aplicativo, a configuração do aplicativo é usada.

Variáveis do host

As seguintes variáveis são bloqueadas antecipadamente ao inicializar os construtores de host e não podem ser influenciadas pela configuração do aplicativo:

Todas as outras configurações de host são lidas a partir da configuração do aplicativo em vez da configuração do host.

URLS é uma das muitas configurações comuns de host que não é uma configuração de bootstrap. Como todas as outras configurações de host que não estão na lista anterior, URLS é lido mais tarde na configuração do aplicativo. A configuração do host é um fallback para a configuração do aplicativo, portanto, a configuração do host pode ser usada para definir URLS, mas ela será substituída por qualquer fonte de configuração na configuração do aplicativo, como appsettings.json.

Para obter mais informações, consulte Alterar a raiz do conteúdo, o nome do aplicativo e o ambiente e Alterar a raiz do conteúdo, o nome do aplicativo e o ambiente por variáveis de ambiente ou linha de comando

As seções restantes neste artigo referem-se à configuração do aplicativo.

Provedores de configuração de aplicativos

O código a seguir exibe os provedores de configuração habilitados na ordem em que foram adicionados:

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

A lista anterior de fontes de configuração padrão de prioridade mais alta a mais baixa mostra os provedores na ordem oposta em que são adicionados ao aplicativo gerado pelo modelo. Por exemplo, o provedor de configuração JSON é adicionado antes do provedor de configuração de linha de comando.

Os provedores de configuração que são adicionados posteriormente têm prioridade mais alta e substituem as configurações de chave anteriores. Por exemplo, se MyKey for definido em ambos appsettings.json e no ambiente, o valor do ambiente será usado. Usando os provedores de configuração padrão, o provedor de configuração de linha de comando substitui todos os outros provedores.

Para obter mais informações sobre CreateBuilder, consulte Configurações padrão do construtor.

appsettings.json

Considere o seguinte appsettings.json arquivo:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

O código a seguir do download de exemplo exibe várias das configurações anteriores:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

O padrão JsonConfigurationProvider carrega a configuração na seguinte ordem:

  1. appsettings.json
  2. appsettings.{Environment}.json : Por exemplo, os appsettings.Production.json e appsettings.Development.json arquivos. A versão de ambiente do arquivo é carregada com base no IHostingEnvironment.EnvironmentName. Para obter mais informações, consulte Usar vários ambientes no ASP.NET Core.

appsettings.{Environment}.json valores substituem as chaves em appsettings.json. Por exemplo, por padrão:

  • Durante o desenvolvimento, a configuração appsettings.Development.json substitui os valores encontrados no appsettings.json.
  • Na produção, a configuração de appsettings.Production.json substitui os valores encontrados em appsettings.json. Por exemplo, ao implantar o aplicativo no Azure.

Se um valor de configuração deve ser garantido, consulte GetValue. O exemplo anterior lê apenas cadeias de caracteres e não suporta um valor padrão.

Usando a configuração padrão, os arquivos appsettings.json e appsettings.{Environment}.json são habilitados com reloadOnChange: true. As alterações feitas no arquivo appsettings.json e appsettings.{Environment}.json são lidas pelo provedor de configuração JSONapós o aplicativo ser iniciado.

Comentários em appsettings.json

Comentários em appsettings.json e appsettings.{Environment}.json arquivos são suportados usando comentários no estilo JavaScript ou C#.

Alguns ambientes de desenvolvimento integrado (IDE) exibem erros ao editar um arquivo JSON que contém comentários. Geralmente, você pode ignorar erros e avisos de comentários, mas também pode desativá-los com uma configuração no IDE. No Visual Studio Code, por exemplo, adicione o seguinte ao settings.json arquivo para desabilitar os erros:

"files.associations": {
  "appsettings*.json": "jsonc"
}

Para outros IDEs, verifique a documentação da ferramenta e outros canais de suporte ao produto para determinar como silenciar os erros.

Vincular dados de configuração hierárquica usando o padrão de opções

A maneira preferida de ler os valores de configuração relacionados é usando o padrão de opções . Por exemplo, para ler os seguintes valores de configuração:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

Crie a seguinte PositionOptions classe:

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; } = String.Empty;
    public string Name { get; set; } = String.Empty;
}

Uma classe de opções:

  • Deve ser não abstrato e ter um construtor público sem parâmetros.
  • Todas as propriedades públicas de leitura-gravação do tipo são vinculadas.
  • Os campos não estão vinculados. No código anterior, Position não está vinculado. O Position campo é usado para que a cadeia de caracteres "Position" não precise ser codificada no aplicativo ao vincular a classe a um provedor de configuração.

O seguinte código:

  • Chama ConfigurationBinder.Bind para vincular a PositionOptions classe à Position seção.
  • Exibe os dados de Position configuração.
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

No código anterior, por padrão, as alterações no arquivo de configuração JSON após o início do aplicativo são lidas.

ConfigurationBinder.Get<T> Vincula e retorna o tipo especificado. ConfigurationBinder.Get<T> pode ser mais conveniente do que usar ConfigurationBinder.Bind. O código a seguir mostra como usar ConfigurationBinder.Get<T> com a PositionOptions classe:

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions? positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

No código anterior, por padrão, as alterações no arquivo de configuração JSON após o início do aplicativo são lidas.

Uma abordagem alternativa ao usar o padrão de opções é vincular a Position seção e adicioná-la ao contêiner do serviço de injeção de dependência. No código a seguir, PositionOptions é adicionado ao contêiner de serviço com Configure e vinculado à configuração:

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));

var app = builder.Build();

Usando o código anterior, o código a seguir lê as opções de posição:

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

No código anterior, as alterações no ficheiro de configuração JSON após o início da aplicação não são lidas. Para ler as alterações após o início do aplicativo, use IOptionsSnapshot.

Usando a configuração padrão, os arquivos appsettings.json e appsettings.{Environment}.json são habilitados com reloadOnChange: true. As alterações feitas no arquivo appsettings.json e appsettings.{Environment}.json são lidas pelo provedor de configuração JSONapós o aplicativo ser iniciado.

Consulte o provedor de configuração JSON neste documento para obter informações sobre como adicionar arquivos de configuração JSON adicionais.

Combinando a coleção de serviços

Considere o seguinte que registra serviços e configura opções:

using ConfigSample.Options;
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));
builder.Services.Configure<ColorOptions>(
    builder.Configuration.GetSection(ColorOptions.Color));

builder.Services.AddScoped<IMyDependency, MyDependency>();
builder.Services.AddScoped<IMyDependency2, MyDependency2>();

var app = builder.Build();

Grupos relacionados de registros podem ser movidos para um método de extensão para registrar serviços. Por exemplo, os serviços de configuração são adicionados à seguinte classe:

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }

        public static IServiceCollection AddMyDependencyGroup(
             this IServiceCollection services)
        {
            services.AddScoped<IMyDependency, MyDependency>();
            services.AddScoped<IMyDependency2, MyDependency2>();

            return services;
        }
    }
}

Os restantes serviços estão registados numa classe semelhante. O código a seguir usa os novos métodos de extensão para registrar os serviços:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddConfig(builder.Configuration)
    .AddMyDependencyGroup();

builder.Services.AddRazorPages();

var app = builder.Build();

Nota: Cada método de extensão services.Add{GROUP_NAME} adiciona e potencialmente configura serviços. Por exemplo, AddControllersWithViews adiciona os serviços que os controladores MVC com exibições exigem e AddRazorPages adiciona os serviços Razor o Pages requer.

Segurança e segredos do utilizador

Diretrizes de dados de configuração:

  • Nunca armazene senhas ou outros dados confidenciais no código do provedor de configuração ou em arquivos de configuração de texto simples. A ferramenta Secret Manager pode ser usada para armazenar segredos em desenvolvimento.
  • Não use segredos de produção em ambientes de desenvolvimento ou teste.
  • Especifique segredos fora do projeto para que eles não possam ser acidentalmente comprometidos em um repositório de código-fonte.
  • Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações, consulte Fluxos de autenticação seguros.

Por padrão, a fonte de configuração de segredos do usuário é registrada após as fontes de configuração JSON. Portanto, as chaves de segredo do usuário têm precedência sobre as chaves em appsettings.json e appsettings.{Environment}.json.

Para obter mais informações sobre como armazenar senhas ou outros dados confidenciais:

Variáveis de ambiente não prefixadas

As variáveis de ambiente não prefixadas são variáveis de ambiente diferentes daquelas prefixadas por ASPNETCORE_ ou DOTNET_. Por exemplo, os modelos de aplicação Web do ASP.NET Core estabelecem "ASPNETCORE_ENVIRONMENT": "Development" em launchSettings.json. Para obter mais informações sobre variáveis de ambiente ASPNETCORE_ e DOTNET_, consulte:

Usando a configuração padrão, o EnvironmentVariablesConfigurationProvider carrega a configuração dos pares chave-valor da variável de ambiente após a leitura de appsettings.json, appsettings.{Environment}.json e segredos do usuário. Portanto, os valores-chave lidos do ambiente substituem os valores lidos de appsettings.json, appsettings.{Environment}.json e segredos de utilizador.

O separador : não funciona com chaves hierárquicas de variáveis de ambiente em todas as plataformas. Por exemplo, o separador : não é suportado pelo Bash. O duplo sublinhado, __, é:

  • Suportado por todas as plataformas.
  • Substituído automaticamente por dois pontos, :.

Os seguintes comandos:

  • Defina as chaves de ambiente e os valores do exemplo anterior no Windows.
  • Teste as configurações ao usar o download de exemplo. O dotnet run comando deve ser executado no diretório do projeto.
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

As configurações de ambiente anteriores:

  • São definidos apenas em processos iniciados a partir da janela de comando em que foram configurados.
  • Não será lido por navegadores iniciados com o Visual Studio.

Os seguintes comandos setx podem ser usados para definir as chaves e valores de ambiente no Windows. set, ao contrário, setx as configurações são persistentes. /M Define a variável no ambiente do sistema. Se o /M switch não for usado, uma variável de ambiente do usuário será definida.

setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M

Para testar se os comandos anteriores substituem appsettings.json e appsettings.{Environment}.json:

  • Com o Visual Studio: saia e reinicie o Visual Studio.
  • Com a CLI: Inicie uma nova janela de comando e digite dotnet run.

Chame AddEnvironmentVariables com uma cadeia de caracteres para especificar um prefixo para variáveis de ambiente:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");

var app = builder.Build();

No código anterior:

O prefixo é removido quando os pares chave-valor de configuração são lidos.

Os comandos a seguir testam o prefixo personalizado:

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

A configuração padrão carrega variáveis de ambiente e argumentos de linha de comando prefixados com DOTNET_ e ASPNETCORE_. Os DOTNET_ prefixos e ASPNETCORE_ são usados pelo ASP.NET Core para configuração de host e aplicativo, mas não para configuração de usuário. Para obter mais informações sobre a configuração do host e do aplicativo, consulte .NET Generic Host.

No Serviço de Aplicativo do Azure, selecione Nova configuração de aplicativo na página Configuração de Definições>. As configurações do aplicativo do Serviço de Aplicativo do Azure são:

  • Encriptado em repouso e transmitido através de um canal encriptado.
  • Expostos como variáveis de ambiente.

Para obter mais informações, consulte Aplicativos do Azure: substituir a configuração do aplicativo usando o Portal do Azure.

Consulte Prefixos de cadeia de conexão para obter informações sobre cadeias de conexão de banco de dados do Azure.

Nomenclatura de variáveis de ambiente

Os nomes das variáveis de ambiente refletem a estrutura de um appsettings.json arquivo. Cada elemento na hierarquia é preferencialmente separado por um sublinhado duplo ou por dois pontos. Quando a estrutura do elemento inclui uma matriz, o índice da matriz deve ser tratado como um nome de elemento adicional nesse caminho. Considere o arquivo a seguir appsettings.json e seus valores equivalentes representados como variáveis de ambiente.

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "MySystem@example.com",
                "ToAddress": "SRE@example.com"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

variáveis de ambiente

setx SmtpServer smtp.example.com
setx Logging__0__Name ToEmail
setx Logging__0__Level Critical
setx Logging__0__Args__FromAddress MySystem@example.com
setx Logging__0__Args__ToAddress SRE@example.com
setx Logging__1__Name ToConsole
setx Logging__1__Level Information

Variáveis de ambiente definidas no launchSettings.json gerado

As variáveis de ambiente definidas em launchSettings.json substituem as definidas no ambiente do sistema. Por exemplo, os templates web do ASP.NET Core geram um arquivo launchSettings.json que define a configuração do endpoint como:

"applicationUrl": "https://localhost:5001;http://localhost:5000"

Configurar o applicationUrl configura a variável de ambiente ASPNETCORE_URLS e altera os valores definidos no ambiente.

Variáveis de ambiente de escape no Linux

No Linux, o valor das variáveis de ambiente de URL deve ser codificado para que systemd consiga analisá-lo. Use a ferramenta Linux systemd-escape que gera http:--localhost:5001

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

Exibir variáveis de ambiente

O código a seguir exibe as variáveis de ambiente e os valores na inicialização do aplicativo, o que pode ser útil ao depurar as configurações do ambiente:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

foreach (var c in builder.Configuration.AsEnumerable())
{
    Console.WriteLine(c.Key + " = " + c.Value);
}

Linha de comando

Usando a configuração padrão, o CommandLineConfigurationProvider carrega configuração dos pares chave-valor dos argumentos de linha de comando após as seguintes fontes de configuração:

  • appsettings.json e appsettings.{Environment}.json ficheiros.
  • Segredos do aplicativo no ambiente de desenvolvimento.
  • Variáveis de ambiente.

Por padrão, os valores de configuração definidos na linha de comandos têm precedência sobre os valores definidos por todos os outros provedores de configuração.

Argumentos de linha de comando

O comando a seguir define chaves e valores usando =:

dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick

O comando a seguir define chaves e valores usando /:

dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick

O comando a seguir define chaves e valores usando --:

dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick

O valor-chave:

  • Deve seguir =, ou a chave deve ter um prefixo de -- ou / quando o valor segue um espaço.
  • Não é necessário se = for usado. Por exemplo, MySetting=.

Dentro do mesmo comando, não misture pares de chave e valor de argumentos na linha de comando que usam = com pares de chave e valor que usam um espaço.

Mapeamentos de comutador

Os mapeamentos de switch permitem a lógica de substituição do nome da chave . Forneça um dicionário de substituições de switch para o AddCommandLine método.

Quando o dicionário de mapeamentos de interruptor é usado, o dicionário é verificado em busca de uma chave que corresponda à chave fornecida por um argumento de linha de comando. Se a chave de linha de comando for encontrada no dicionário, o valor do dicionário será passado de volta para definir o par chave-valor na configuração do aplicativo. Um mapeamento de switch é necessário para qualquer chave de linha de comando prefixada com um único traço (-).

Alternar regras de chave do dicionário de mapeamentos:

  • Os interruptores devem começar com - ou --.
  • O dicionário de mapeamentos de opção não deve conter chaves duplicadas.

Para usar um dicionário de mapeamentos de switch, passe-o para a invocação para AddCommandLine:


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

builder.Configuration.AddCommandLine(args, switchMappings);

var app = builder.Build();

Execute o seguinte comando funciona para testar a substituição de chave:

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

O código a seguir mostra os valores de chave para as chaves substituídas:

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

Para aplicativos que usam mapeamentos de comutação, a chamada para CreateDefaultBuilder não deve passar argumentos. A chamada do método CreateDefaultBuilder não inclui interruptores mapeados e não há maneira de passar o dicionário de mapeamento de comutadores para AddCommandLine. A solução não é passar os argumentos CreateDefaultBuilder , mas sim permitir que o ConfigurationBuilder método do AddCommandLine método processe os argumentos e o dicionário de mapeamento de switch.

Definir argumentos de ambiente e linha de comando com o Visual Studio

Os argumentos de ambiente e linha de comando podem ser definidos no Visual Studio a partir da caixa de diálogo de perfis de inicialização:

  • No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Propriedades.
  • Selecione a guia Debug > General e selecione Open debug launch profiles UI.

Dados de configuração hierárquica

A API de configuração lê os dados de configuração hierárquica nivelando os dados hierárquicos com o uso de um delimitador nas chaves de configuração.

O download de exemplo contém o seguinte appsettings.json arquivo:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

O seguinte código do download de exemplo exibe várias das configurações de configuração:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

A maneira preferida de ler dados de configuração hierárquica é usando o padrão de opções. Para obter mais informações, consulte Vincular dados de configuração hierárquica neste documento.

GetSection e GetChildren métodos estão disponíveis para isolar seções e subseções nos dados de configuração. Esses métodos são descritos posteriormente em GetSection, GetChildren e Exists.

Chaves e valores de configuração

Advertência

Este artigo mostra o uso de cadeias de conexão. Com um banco de dados local, o usuário não precisa ser autenticado, mas na produção, as cadeias de conexão às vezes incluem uma senha para autenticar. Uma credencial de senha de proprietário de recurso (ROPC) é um risco de segurança que deve ser evitado em bancos de dados de produção. Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações sobre autenticação para aplicativos implantados em ambientes de teste ou produção, consulte Fluxos de autenticação segura.

Chaves de configuração:

  • Não diferenciam maiúsculas de minúsculas. Por exemplo, ConnectionString e connectionstring são tratadas como chaves equivalentes.
  • Se uma chave e um valor forem definidos em mais de um provedor de configuração, o valor do último provedor adicionado será usado. Para obter mais informações, consulte Configuração padrão.
  • Chaves hierárquicas
    • Na API de configuração, o separador de dois pontos (:) funciona em todas as plataformas.
    • É possível que um separador de dois pontos não funcione em todas as plataformas para variáveis de ambiente. Um sublinhado duplo, __, é suportado por todas as plataformas e é convertido automaticamente em dois pontos :.
    • No Cofre de Chaves do Azure, as chaves hierárquicas são usadas -- como um separador. O provedor de configuração do Azure Key Vault substitui -- automaticamente por um : quando os segredos são carregados na configuração do aplicativo.
  • O ConfigurationBinder suporta a vinculação de matrizes a objetos usando índices de matriz em chaves de configuração. A vinculação de matriz é descrita na seção Vincular uma matriz a uma classe .

Valores de configuração:

  • São cadeias de caracteres.
  • Valores nulos não podem ser armazenados na configuração ou vinculados a objetos.

Provedores de configuração

A tabela a seguir mostra os provedores de configuração disponíveis para aplicativos ASP.NET Core.

Fornecedor Fornece configuração a partir de
provedor de configuração do Azure Key Vault Azure Key Vault
provedor de configuração do aplicativo Azure Configuração da Aplicação Azure
Provedor de configuração de linha de comando Parâmetros de linha de comando
Provedor de configuração personalizado Fonte personalizada
provedor de configuração de variáveis de ambiente Variáveis de ambiente
Provedor de configuração de arquivo Arquivos INI, JSON e XML
Provedor de configuração de chave por arquivo Arquivos de diretório
Provedor de configuração de memória Coleções na memória
Segredos do utilizador Arquivo no diretório de perfil de usuário

As fontes de configuração são lidas na ordem em que seus provedores de configuração são especificados. Organize os fornecedores de configuração no código para alinhar com as prioridades das fontes de configuração essenciais que o aplicativo necessita.

Uma sequência típica de provedores de configuração é:

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. Segredos do utilizador
  4. Variáveis de ambiente usando o provedor de configuração de Variáveis de Ambiente .
  5. Argumentos de linha de comando usando o provedor de configuração de linha de comando .

Uma prática comum é adicionar o provedor de configuração de linha de comando por último em uma série de provedores para permitir que os argumentos de linha de comando substituam a configuração definida pelos outros provedores.

A sequência anterior de provedores é usada na configuração padrão.

Prefixos de cadeia de conexão

Advertência

Este artigo mostra o uso de cadeias de conexão. Com um banco de dados local, o usuário não precisa ser autenticado, mas na produção, as cadeias de conexão às vezes incluem uma senha para autenticar. Uma credencial de senha de proprietário de recurso (ROPC) é um risco de segurança que deve ser evitado em bancos de dados de produção. Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações sobre autenticação para aplicativos implantados em ambientes de teste ou produção, consulte Fluxos de autenticação segura.

A API de configuração tem regras de processamento especiais para quatro variáveis de ambiente de cadeia de conexão. Essas cadeias de conexão estão envolvidas na configuração de cadeias de conexão do Azure para o ambiente do aplicativo. As variáveis de ambiente com os prefixos mostrados na tabela são carregadas no aplicativo com a configuração padrão ou quando nenhum prefixo é fornecido ao AddEnvironmentVariables.

Prefixo da cadeia de conexão Fornecedor
CUSTOMCONNSTR_ Provedor personalizado
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Banco de Dados SQL do Azure
SQLCONNSTR_ Servidor SQL

Quando uma variável de ambiente é descoberta e carregada na configuração com qualquer um dos quatro prefixos mostrados na tabela:

  • A chave de configuração é criada removendo o prefixo da variável de ambiente e adicionando uma seção de chave de configuração (ConnectionStrings).
  • É criado um novo par chave-valor de configuração que representa o provedor de conexão de banco de dados (exceto para CUSTOMCONNSTR_, que não tem nenhum provedor declarado).
Chave de variável de ambiente Chave de configuração convertida Entrada de configuração do provedor
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} Entrada de configuração não criada.
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} Chave: ConnectionStrings:{KEY}_ProviderName:
Valor: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} Chave: ConnectionStrings:{KEY}_ProviderName:
Valor: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} Chave: ConnectionStrings:{KEY}_ProviderName:
Valor: System.Data.SqlClient

Provedor de configuração de arquivos

FileConfigurationProvider é a classe base para carregar a configuração do sistema de arquivos. Os seguintes provedores de configuração derivam de FileConfigurationProvider:

Provedor de configuração INI

O IniConfigurationProvider carrega a configuração a partir de pares chave-valor do ficheiro INI em tempo de execução.

O código a seguir adiciona vários provedores de configuração:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
    .AddIniFile($"MyIniConfig.{builder.Environment.EnvironmentName}.ini",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

No código anterior, as configurações no MyIniConfig.ini e MyIniConfig.{Environment}.ini arquivos são substituídas por configurações no:

O download de exemplo contém o seguinte MyIniConfig.ini arquivo:

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

O código a seguir do download de exemplo exibe várias das configurações anteriores:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Provedor de configuração JSON

O JsonConfigurationProvider carrega a configuração a partir de pares chave-valor do ficheiro JSON.

As sobrecargas podem especificar:

  • Se o arquivo é opcional.
  • Se a configuração será recarregada se o arquivo for alterado.

Considere o seguinte código:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile("MyConfig.json",
        optional: true,
        reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

O código anterior:

Normalmente , você não deseja que um arquivo JSON personalizado substitua os valores definidos no provedor de configuração de variáveis de ambiente e no provedor de configuração de linha de comando.

Provedor de configuração XML

A XmlConfigurationProvider carrega a configuração a partir dos pares chave-valor do arquivo XML em tempo de execução.

O código a seguir adiciona vários provedores de configuração:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
    .AddXmlFile($"MyXMLFile.{builder.Environment.EnvironmentName}.xml",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

No código anterior, as configurações no MyXMLFile.xml e MyXMLFile.{Environment}.xml arquivos são substituídas por configurações no:

O download de exemplo contém o seguinte MyXMLFile.xml arquivo:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

O código a seguir do download de exemplo exibe várias das configurações anteriores:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Os elementos repetidos que usam o mesmo nome de elemento funcionam se o name atributo for usado para distinguir os elementos:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

O código a seguir lê o arquivo de configuração anterior e exibe as chaves e valores:

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

Os atributos podem ser usados para fornecer valores:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

O arquivo de configuração anterior carrega as seguintes chaves com value:

  • chave:atributo
  • seção:chave:atributo

Provedor de configuração de chave por arquivo

O KeyPerFileConfigurationProvider usa os arquivos de um diretório como pares chave-valor de configuração. A chave é o nome do arquivo. O valor contém o conteúdo do arquivo. O provedor de configuração de chave por arquivo é usado em cenários de hospedagem do Docker.

Para ativar a configuração de chave por arquivo, chame o AddKeyPerFile método de extensão em uma instância do ConfigurationBuilder. O directoryPath para os arquivos deve ser um caminho absoluto.

As sobrecargas permitem especificar:

  • Um Action<KeyPerFileConfigurationSource> delegado que configura a fonte.
  • Se o diretório é opcional e o caminho para o diretório.

O sublinhado duplo (__) é usado como um delimitador de chave de configuração em nomes de arquivo. Por exemplo, o nome Logging__LogLevel__System do arquivo produz a chave Logging:LogLevel:Systemde configuração .

Chame ConfigureAppConfiguration ao criar o host para especificar a configuração da aplicação:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

Provedor de configuração de memória

O MemoryConfigurationProvider usa uma coleção na memória como pares chave-valor de configuração.

O código a seguir adiciona uma coleção de memória ao sistema de configuração:

var builder = WebApplication.CreateBuilder(args);

var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

builder.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

O código a seguir do download de exemplo exibe as configurações anteriores:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

No código anterior, config.AddInMemoryCollection(Dict) é adicionado após os provedores de configuração padrão. Para obter um exemplo de como ordenar os provedores de configuração, consulte Provedor de configuração JSON.

Consulte Associar uma matriz para ver outro exemplo usando MemoryConfigurationProvider.

Kestrel Configuração do ponto final

Kestrel A configuração específica do ponto de extremidade substitui todas as configurações de ponto de extremidade interservidor. As configurações de endpoint entre servidores incluem:

Considere o seguinte appsettings.json arquivo usado em um aplicativo Web ASP.NET Core:

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

Quando a marcação realçada anterior é usada em um aplicativo Web ASP.NET Core e o aplicativo é iniciado na linha de comando com a seguinte configuração de ponto de extremidade entre servidores:

dotnet run --urls="https://localhost:7777"

Kestrel liga-se ao ponto de extremidade configurado especificamente para Kestrel no arquivo de appsettings.json (https://localhost:9999) e não https://localhost:7777.

Considere o Kestrel ponto de extremidade específico configurado como uma variável de ambiente:

set Kestrel__Endpoints__Https__Url=https://localhost:8888

Na variável de ambiente anterior, Https é o nome do Kestrel endpoint específico. O arquivo anterior appsettings.json também define um endpoint Kestrel específico chamado Https. Por padrão, as variáveis de ambiente que usam o provedor de configuração Variáveis de Ambiente são lidas após appsettings.{Environment}.json, portanto, a variável de ambiente anterior é usada para a extremidade de Https.

GetValue

ConfigurationBinder.GetValue extrai um único valor da configuração com uma chave especificada e o converte para o tipo especificado:

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

No código anterior, se NumberKey não for encontrado na configuração, o valor padrão de 99 é usado.

GetSection, GetChildren e Existe

Para os exemplos a seguir, considere o seguinte MySubsection.json arquivo:

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

O código a seguir adiciona MySubsection.json aos provedores de configuração:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MySubsection.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

GetSection

IConfiguration.GetSection Retorna uma subseção de configuração com a chave de subseção especificada.

O código a seguir retorna valores para section1:

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

O código a seguir retorna valores para section2:subsection0:

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSection nunca mais volta null. Se uma seção correspondente não for encontrada, um vazio IConfigurationSection será retornado.

Quando GetSection retorna uma seção correspondente, Value não é preenchida. Os Key e Path são devolvidos quando a seção existe.

GetChildren e existe

O código a seguir chama IConfiguration.GetChildren e retorna valores para section2:subsection0:

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = "";
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

O código anterior chama ConfigurationExtensions.Exists para verificar se a seção existe:

Vincular uma matriz

O ConfigurationBinder.Bind suporta a vinculação de matrizes a objetos usando índices de matriz em chaves de configuração. Qualquer formato de matriz que exponha um segmento de chave numérica é capaz de se associar a matrizes de classes POCO.

Considere MyArray.json a partir do download de exemplo:

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

O código a seguir adiciona MyArray.json aos provedores de configuração:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MyArray.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

O código a seguir lê a configuração e exibe os valores:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample? _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
       _array = Config.GetSection("array").Get<ArrayExample>();
        if (_array == null)
        {
            throw new ArgumentNullException(nameof(_array));
        }
        string s = String.Empty;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}
public class ArrayExample
{
    public string[]? Entries { get; set; } 
}

O código anterior retorna a seguinte saída:

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

Na saída anterior, o Índice 3 tem valor value40, correspondente a "4": "value40", em MyArray.json. Os índices de matriz acoplados são contínuos e não vinculados ao índice de chave de configuração. O fichário de configuração não é capaz de vincular valores nulos ou criar entradas nulas em objetos acoplados.

Provedor de configuração personalizada

O aplicativo de exemplo demonstra como criar um provedor de configuração básica que lê pares chave-valor de configuração de um banco de dados usando o Entity Framework (EF).

O provedor tem as seguintes características:

  • O banco de dados EF in-memory é usado para fins de demonstração. Para usar um banco de dados que exija uma cadeia de conexão, implemente um secundário ConfigurationBuilder para fornecer a cadeia de conexão de outro provedor de configuração.
  • O provedor lê uma tabela de banco de dados na configuração na inicialização. O provedor não consulta o banco de dados por chave.
  • A funcionalidade de recarregar ao alterar não está implementada, portanto, fazer alterações na base de dados após o início da aplicação não tem efeito na configuração da aplicação.

Defina uma EFConfigurationValue entidade para armazenar valores de configuração no banco de dados.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; } = String.Empty;
    public string Value { get; set; } = String.Empty;
}

Adicione um EFConfigurationContext para armazenar e acessar os valores configurados.

EFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}

Crie uma classe que implemente o IConfigurationSource.

EFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) => _optionsAction = optionsAction;

    public IConfigurationProvider Build(IConfigurationBuilder builder) => new EFConfigurationProvider(_optionsAction);
}

Crie o provedor de configuração personalizada herdando do ConfigurationProvider. O provedor de configuração inicializa o banco de dados quando ele está vazio. Como as chaves de configuração não diferenciam maiúsculas de minúsculas, o dicionário usado para inicializar o banco de dados é criado com o comparador que não diferencia maiúsculas de minúsculas (StringComparer.OrdinalIgnoreCase).

EFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            if (dbContext == null || dbContext.Values == null)
            {
                throw new Exception("Null DB context");
            }
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues =
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                    { "quote1", "I aim to misbehave." },
                    { "quote2", "I swallowed a bug." },
                    { "quote3", "You can't stop the signal, Mal." }
            };

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue
            {
                Id = kvp.Key,
                Value = kvp.Value
            })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

Um AddEFConfiguration método de extensão permite adicionar a fonte de configuração a um ConfigurationBuilder.

Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
               this IConfigurationBuilder builder,
               Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

O código a seguir mostra como usar o personalizado EFConfigurationProvider em Program.cs:

//using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEFConfiguration(
    opt => opt.UseInMemoryDatabase("InMemoryDb"));

var app = builder.Build();

app.Run();

Configuração de acesso com injeção de dependência (DI)

Usando a Injeção de Dependência (DI), a configuração pode ser injetada em serviços ao resolver o IConfiguration serviço:

public class Service
{
    private readonly IConfiguration _config;

    public Service(IConfiguration config) =>
        _config = config;

    public void DoSomething()
    {
        var configSettingValue = _config["ConfigSetting"];

        // ...
    }
}

Para obter informações sobre como aceder a valores usando IConfiguration, consulte GetValue e GetSection, GetChildren e Exists neste artigo.

Configuração de acesso nas páginas Razor

O código a seguir exibe dados de configuração em uma Razor Página:

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

No código a seguir, MyOptions é adicionado ao contêiner de serviço com Configure e vinculado à configuração:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions"));

var app = builder.Build();

A marcação a seguir usa a @injectRazor diretiva para resolver e exibir os valores de opções:

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@using SampleApp.Models
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

Configuração de acesso em um arquivo de exibição MVC

O código a seguir exibe dados de configuração em uma exibição MVC:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

Configuração de acesso em Program.cs

O código seguinte acede à configuração no arquivo Program.cs.

var builder = WebApplication.CreateBuilder(args);

var key1 = builder.Configuration.GetValue<string>("KeyOne");

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

var key2 = app.Configuration.GetValue<int>("KeyTwo");
var key3 = app.Configuration.GetValue<bool>("KeyThree");

app.Logger.LogInformation("KeyOne: {KeyOne}", key1);
app.Logger.LogInformation("KeyTwo: {KeyTwo}", key2);
app.Logger.LogInformation("KeyThree: {KeyThree}", key3);

app.Run();

No appsettings.json exemplo anterior:

{
  ...
  "KeyOne": "Key One Value",
  "KeyTwo": 1999,
  "KeyThree": true
}

Configurar opções com um delegado

As opções configuradas num objeto delegado substituem os valores definidos nos provedores de configuração.

No código a seguir, um IConfigureOptions<TOptions> serviço é adicionado ao contêiner de serviço. Ele usa um delegado para configurar valores para MyOptions:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "Value configured in delegate";
    myOptions.Option2 = 500;
});

var app = builder.Build();

O código a seguir exibe os valores de opções:

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

No exemplo anterior, os valores de Option1 e Option2 são especificados em appsettings.json e depois substituídos pelo delegado configurado.

Configuração de host versus aplicativo

Antes de o aplicativo ser configurado e iniciado, um host é configurado e iniciado. O host é responsável pela inicialização do aplicativo e gerenciamento do tempo de vida. Tanto o aplicativo quanto o host são configurados usando os provedores de configuração descritos neste tópico. Os pares chave-valor de configuração do host também estão incluídos na configuração do aplicativo. Para obter mais informações sobre como os provedores de configuração são usados quando o host é criado e como as fontes de configuração afetam a configuração do host, consulte ASP.NET Visão geral dos fundamentos principais.

Configuração padrão do host

Para obter detalhes sobre a configuração padrão ao usar o host da Web, consulte a versão ASP.NET Core 2.2 deste tópico.

  • A configuração do host é fornecida a partir de:
    • Variáveis de ambiente prefixadas com DOTNET_ (por exemplo, DOTNET_ENVIRONMENT) usando o provedor de configuração de variáveis de ambiente. O prefixo (DOTNET_) é removido quando os pares chave-valor de configuração são carregados.
    • Argumentos de linha de comando usando o provedor de configuração de linha de comando .
  • A configuração padrão do host da Web é estabelecida (ConfigureWebHostDefaults):
    • Kestrel é usado como o servidor web e configurado usando os fornecedores de configuração da aplicação.
    • Adicione o Middleware de Filtragem de Host.
    • Adicione o Middleware de Cabeçalhos Encaminhados se a variável de ambiente ASPNETCORE_FORWARDEDHEADERS_ENABLED estiver definida como true.
    • Habilite a integração com o IIS.

Outra configuração

Este tópico refere-se apenas à configuração do aplicativo. Outros aspetos da execução e hospedagem de aplicativos ASP.NET Core são configurados usando arquivos de configuração não abordados neste tópico:

As variáveis de ambiente definidas em launchSettings.json substituem as definidas no ambiente do sistema.

Para obter mais informações sobre como migrar a configuração do aplicativo de versões anteriores do ASP.NET, consulte Migrar configuração para o ASP.NET Core.

Adicionar configuração a partir de um conjunto externo

Uma implementação IHostingStartup permite adicionar aprimoramentos a um aplicativo na inicialização a partir de um assembly externo fora da classe Startup do aplicativo. Para obter mais informações, consulte Usar assemblies de inicialização de hospedagem no ASP.NET Core.

Gerador de código-fonte de vinculação de configuração

O gerador de código fonte de associação de configuração fornece uma configuração compatível com AOT e otimização. Para obter mais informações, consulte Gerador de fontes para associação de configuração.

Recursos adicionais

A configuração do aplicativo no ASP.NET Core é executada usando um ou mais provedores de configuração. Os provedores de configuração leem dados de configuração de pares chave-valor usando uma variedade de fontes de configuração:

  • Arquivos de configurações, como appsettings.json
  • Variáveis de ambiente
  • Azure Key Vault
  • Configuração da Aplicação Azure
  • Argumentos de linha de comando
  • Fornecedores personalizados, instalados ou criados
  • Arquivos de diretório
  • Objetos .NET na memória

Este artigo fornece informações sobre a configuração no ASP.NET Core. Para obter informações sobre como usar a configuração em aplicativos de console, consulte Configuração do .NET.

Configuração de aplicativos e hosts

ASP.NET aplicativos principais configuram e iniciam um host. O host é responsável pela inicialização do aplicativo e gerenciamento do tempo de vida. Os modelos ASP.NET Core criam um WebApplicationBuilder que contém o host. Embora alguma configuração possa ser feita no host e nos provedores de configuração do aplicativo, geralmente, apenas a configuração necessária para o host deve ser feita na configuração do host.

A configuração do aplicativo é a prioridade mais alta e é detalhada na próxima seção. A configuração do host segue a configuração do aplicativo e é descrita neste artigo.

Fontes de configuração de aplicativos padrão

ASP.NET principais aplicativos Web criados com dotnet new ou Visual Studio geram o seguinte código:

var builder = WebApplication.CreateBuilder(args);

WebApplication.CreateBuilder inicializa uma nova instância da classe WebApplicationBuilder com padrões pré-configurados. O WebApplicationBuilder inicializado (builder) fornece a configuração padrão para a aplicação na seguinte ordem, da mais alta para a mais baixa prioridade:

  1. Argumentos de linha de comando usando o provedor de configuração de linha de comando .
  2. Variáveis de ambiente não prefixadas usando o provedor de configuração de variáveis de ambiente não prefixadas.
  3. Segredos de usuário quando o aplicativo é executado no ambiente Development.
  4. appsettings.{Environment}.json usando o provedor de configuração JSON. Por exemplo, appsettings.Production.json e appsettings.Development.json.
  5. appsettings.json usando o provedor de configuração JSON .
  6. Um fallback para a configuração do host descrita na próxima seção.

Fontes de configuração de host padrão

A lista a seguir contém as fontes de configuração de host padrão da prioridade mais alta para a mais baixa para WebApplicationBuilder:

  1. Argumentos de linha de comando usando o provedor de configuração de linha de comando
  2. DOTNET_-variáveis de ambiente prefixadas usando o provedor de configuração de variáveis de ambiente.
  3. ASPNETCORE_-variáveis de ambiente prefixadas usando o provedor de configuração de variáveis de ambiente.

Para o .NET Generic Host and Web Host, as fontes de configuração de host padrão da prioridade mais alta para a mais baixa é:

  1. ASPNETCORE_-variáveis de ambiente prefixadas usando o provedor de configuração de variáveis de ambiente.
  2. Argumentos de linha de comando usando o provedor de configuração de linha de comando
  3. DOTNET_-variáveis de ambiente prefixadas usando o provedor de configuração de variáveis de ambiente.

Quando um valor de configuração é definido na configuração do host e do aplicativo, a configuração do aplicativo é usada.

Variáveis do host

As seguintes variáveis são bloqueadas antecipadamente ao inicializar os construtores de host e não podem ser influenciadas pela configuração do aplicativo:

Todas as outras configurações de host são lidas a partir da configuração do aplicativo em vez da configuração do host.

URLS é uma das muitas configurações comuns de host que não é uma configuração de bootstrap. Como todas as outras configurações de host que não estão na lista anterior, URLS é lido mais tarde na configuração do aplicativo. A configuração do host é um fallback para a configuração do aplicativo, portanto, a configuração do host pode ser usada para definir URLS, mas ela será substituída por qualquer fonte de configuração na configuração do aplicativo, como appsettings.json.

Para obter mais informações, consulte Alterar a raiz do conteúdo, o nome do aplicativo e o ambiente e Alterar a raiz do conteúdo, o nome do aplicativo e o ambiente por variáveis de ambiente ou linha de comando

As seções restantes neste artigo referem-se à configuração do aplicativo.

Provedores de configuração de aplicativos

O código a seguir exibe os provedores de configuração habilitados na ordem em que foram adicionados:

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

A lista anterior de fontes de configuração padrão de prioridade mais alta a mais baixa mostra os provedores na ordem oposta em que são adicionados ao aplicativo gerado pelo modelo. Por exemplo, o provedor de configuração JSON é adicionado antes do provedor de configuração de linha de comando.

Os provedores de configuração que são adicionados posteriormente têm prioridade mais alta e substituem as configurações de chave anteriores. Por exemplo, se MyKey for definido em ambos appsettings.json e no ambiente, o valor do ambiente será usado. Usando os provedores de configuração padrão, o provedor de configuração de linha de comando substitui todos os outros provedores.

Para obter mais informações sobre CreateBuilder, consulte Configurações padrão do construtor.

appsettings.json

Considere o seguinte appsettings.json arquivo:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

O código a seguir do download de exemplo exibe várias das configurações anteriores:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

O padrão JsonConfigurationProvider carrega a configuração na seguinte ordem:

  1. appsettings.json
  2. appsettings.{Environment}.json : Por exemplo, os appsettings.Production.json e appsettings.Development.json arquivos. A versão de ambiente do arquivo é carregada com base no IHostingEnvironment.EnvironmentName. Para obter mais informações, consulte Usar vários ambientes no ASP.NET Core.

appsettings.{Environment}.json valores substituem as chaves em appsettings.json. Por exemplo, por padrão:

  • Durante o desenvolvimento, a configuração appsettings.Development.json substitui os valores encontrados no appsettings.json.
  • Na produção, a configuração de appsettings.Production.json substitui os valores encontrados em appsettings.json. Por exemplo, ao implantar o aplicativo no Azure.

Se um valor de configuração deve ser garantido, consulte GetValue. O exemplo anterior lê apenas cadeias de caracteres e não suporta um valor padrão.

Usando a configuração padrão, os arquivos appsettings.json e appsettings.{Environment}.json são habilitados com reloadOnChange: true. As alterações feitas no arquivo appsettings.json e appsettings.{Environment}.json são lidas pelo provedor de configuração JSONapós o aplicativo ser iniciado.

Comentários em appsettings.json

Comentários em arquivos appsettings.json e appsettings.{Environment}.json são suportados usando comentários ao estilo JavaScript ou C#.

Vincular dados de configuração hierárquica usando o padrão de opções

A maneira preferida de ler os valores de configuração relacionados é usando o padrão de opções . Por exemplo, para ler os seguintes valores de configuração:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

Crie a seguinte PositionOptions classe:

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; } = String.Empty;
    public string Name { get; set; } = String.Empty;
}

Uma classe de opções:

  • Deve ser não abstrato e ter um construtor público sem parâmetros.
  • Todas as propriedades públicas de leitura-gravação do tipo são vinculadas.
  • Os campos não estão vinculados. No código anterior, Position não está vinculado. O Position campo é usado para que a cadeia de caracteres "Position" não precise ser codificada no aplicativo ao vincular a classe a um provedor de configuração.

O seguinte código:

  • Chama ConfigurationBinder.Bind para vincular a PositionOptions classe à Position seção.
  • Exibe os dados de Position configuração.
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

No código anterior, por padrão, as alterações no arquivo de configuração JSON após o início do aplicativo são lidas.

ConfigurationBinder.Get<T> Vincula e retorna o tipo especificado. ConfigurationBinder.Get<T> pode ser mais conveniente do que usar ConfigurationBinder.Bind. O código a seguir mostra como usar ConfigurationBinder.Get<T> com a PositionOptions classe:

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions? positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

No código anterior, por padrão, as alterações no arquivo de configuração JSON após o início do aplicativo são lidas.

Uma abordagem alternativa ao usar o padrão de opções é vincular a Position seção e adicioná-la ao contêiner do serviço de injeção de dependência. No código a seguir, PositionOptions é adicionado ao contêiner de serviço com Configure e vinculado à configuração:

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));

var app = builder.Build();

Usando o código anterior, o código a seguir lê as opções de posição:

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

No código anterior, as alterações no ficheiro de configuração JSON após o início da aplicação não são lidas. Para ler as alterações após o início do aplicativo, use IOptionsSnapshot.

Usando a configuração padrão, os arquivos appsettings.json e appsettings.{Environment}.json são habilitados com reloadOnChange: true. As alterações feitas no arquivo appsettings.json e appsettings.{Environment}.json são lidas pelo provedor de configuração JSONapós o aplicativo ser iniciado.

Consulte o provedor de configuração JSON neste documento para obter informações sobre como adicionar arquivos de configuração JSON adicionais.

Combinando a coleção de serviços

Considere o seguinte que registra serviços e configura opções:

using ConfigSample.Options;
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));
builder.Services.Configure<ColorOptions>(
    builder.Configuration.GetSection(ColorOptions.Color));

builder.Services.AddScoped<IMyDependency, MyDependency>();
builder.Services.AddScoped<IMyDependency2, MyDependency2>();

var app = builder.Build();

Grupos relacionados de registros podem ser movidos para um método de extensão para registrar serviços. Por exemplo, os serviços de configuração são adicionados à seguinte classe:

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }

        public static IServiceCollection AddMyDependencyGroup(
             this IServiceCollection services)
        {
            services.AddScoped<IMyDependency, MyDependency>();
            services.AddScoped<IMyDependency2, MyDependency2>();

            return services;
        }
    }
}

Os restantes serviços estão registados numa classe semelhante. O código a seguir usa os novos métodos de extensão para registrar os serviços:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddConfig(builder.Configuration)
    .AddMyDependencyGroup();

builder.Services.AddRazorPages();

var app = builder.Build();

Nota: Cada método de extensão services.Add{GROUP_NAME} adiciona e potencialmente configura serviços. Por exemplo, AddControllersWithViews adiciona os serviços que os controladores MVC com exibições exigem e AddRazorPages adiciona os serviços Razor o Pages requer.

Segurança e segredos do utilizador

Diretrizes de dados de configuração:

  • Nunca armazene senhas ou outros dados confidenciais no código do provedor de configuração ou em arquivos de configuração de texto simples. A ferramenta Secret Manager pode ser usada para armazenar segredos em desenvolvimento.
  • Não use segredos de produção em ambientes de desenvolvimento ou teste.
  • Especifique segredos fora do projeto para que eles não possam ser acidentalmente comprometidos em um repositório de código-fonte.
  • Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações, consulte Fluxos de autenticação seguros.

Por padrão, a fonte de configuração de segredos do usuário é registrada após as fontes de configuração JSON. Portanto, as chaves de segredo do usuário têm precedência sobre as chaves em appsettings.json e appsettings.{Environment}.json.

Para obter mais informações sobre como armazenar senhas ou outros dados confidenciais:

O Azure Key Vault armazena com segurança segredos de aplicativos para aplicativos ASP.NET Core. Para obter mais informações, consulte Provedor de configuração do Azure Key Vault no ASP.NET Core.

Variáveis de ambiente não prefixadas

As variáveis de ambiente não prefixadas são variáveis de ambiente diferentes daquelas prefixadas por ASPNETCORE_ ou DOTNET_. Por exemplo, os modelos de aplicação Web do ASP.NET Core estabelecem "ASPNETCORE_ENVIRONMENT": "Development" em launchSettings.json. Para obter mais informações sobre variáveis de ambiente ASPNETCORE_ e DOTNET_, consulte:

Usando a configuração padrão, o EnvironmentVariablesConfigurationProvider carrega a configuração dos pares chave-valor da variável de ambiente após a leitura de appsettings.json, appsettings.{Environment}.json e segredos do usuário. Portanto, os valores-chave lidos do ambiente substituem os valores lidos de appsettings.json, appsettings.{Environment}.json e segredos de utilizador.

O separador : não funciona com chaves hierárquicas de variáveis de ambiente em todas as plataformas. Por exemplo, o separador : não é suportado pelo Bash. O duplo sublinhado, __, é:

  • Suportado por todas as plataformas.
  • Substituído automaticamente por dois pontos, :.

Os seguintes set comandos:

  • Defina as chaves de ambiente e os valores do exemplo anterior no Windows.
  • Teste as configurações ao usar o download de exemplo. O dotnet run comando deve ser executado no diretório do projeto.
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

As configurações de ambiente anteriores:

  • São definidos apenas em processos iniciados a partir da janela de comando em que foram configurados.
  • Não será lido por navegadores iniciados com o Visual Studio.

Os seguintes comandos setx podem ser usados para definir as chaves e valores de ambiente no Windows. set, ao contrário, setx as configurações são persistentes. /M Define a variável no ambiente do sistema. Se o /M switch não for usado, uma variável de ambiente do usuário será definida.

setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M

Para testar se os comandos anteriores substituem appsettings.json e appsettings.{Environment}.json:

  • Com o Visual Studio: saia e reinicie o Visual Studio.
  • Com a CLI: Inicie uma nova janela de comando e digite dotnet run.

Chame AddEnvironmentVariables com uma cadeia de caracteres para especificar um prefixo para variáveis de ambiente:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");

var app = builder.Build();

No código anterior:

O prefixo é removido quando os pares chave-valor de configuração são lidos.

Os comandos a seguir testam o prefixo personalizado:

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

A configuração padrão carrega variáveis de ambiente e argumentos de linha de comando prefixados com DOTNET_ e ASPNETCORE_. Os DOTNET_ prefixos e ASPNETCORE_ são usados pelo ASP.NET Core para configuração de host e aplicativo, mas não para configuração de usuário. Para obter mais informações sobre a configuração do host e do aplicativo, consulte .NET Generic Host.

No Serviço de Aplicativo do Azure, selecione Nova configuração de aplicativo na página Configuração de Definições>. As configurações do aplicativo do Serviço de Aplicativo do Azure são:

  • Encriptado em repouso e transmitido através de um canal encriptado.
  • Expostos como variáveis de ambiente.

Para obter mais informações, consulte Aplicativos do Azure: substituir a configuração do aplicativo usando o Portal do Azure.

Consulte Prefixos de cadeia de conexão para obter informações sobre cadeias de conexão de banco de dados do Azure.

Nomenclatura de variáveis de ambiente

Os nomes das variáveis de ambiente refletem a estrutura de um appsettings.json arquivo. Cada elemento na hierarquia é preferencialmente separado por um sublinhado duplo ou por dois pontos. Quando a estrutura do elemento inclui uma matriz, o índice da matriz deve ser tratado como um nome de elemento adicional nesse caminho. Considere o arquivo a seguir appsettings.json e seus valores equivalentes representados como variáveis de ambiente.

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "MySystem@example.com",
                "ToAddress": "SRE@example.com"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

variáveis de ambiente

setx SmtpServer smtp.example.com
setx Logging__0__Name ToEmail
setx Logging__0__Level Critical
setx Logging__0__Args__FromAddress MySystem@example.com
setx Logging__0__Args__ToAddress SRE@example.com
setx Logging__1__Name ToConsole
setx Logging__1__Level Information

Variáveis de ambiente definidas no launchSettings.json gerado

As variáveis de ambiente definidas em launchSettings.json substituem as definidas no ambiente do sistema. Por exemplo, os templates web do ASP.NET Core geram um arquivo launchSettings.json que define a configuração do endpoint como:

"applicationUrl": "https://localhost:5001;http://localhost:5000"

Configurar o applicationUrl configura a variável de ambiente ASPNETCORE_URLS e altera os valores definidos no ambiente.

Variáveis de ambiente de escape no Linux

No Linux, o valor das variáveis de ambiente de URL deve ser codificado para que systemd consiga analisá-lo. Use a ferramenta Linux systemd-escape que gera http:--localhost:5001

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

Exibir variáveis de ambiente

O código a seguir exibe as variáveis de ambiente e os valores na inicialização do aplicativo, o que pode ser útil ao depurar as configurações do ambiente:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

foreach (var c in builder.Configuration.AsEnumerable())
{
    Console.WriteLine(c.Key + " = " + c.Value);
}

Linha de comando

Usando a configuração padrão, o CommandLineConfigurationProvider carrega configuração dos pares chave-valor dos argumentos de linha de comando após as seguintes fontes de configuração:

  • appsettings.json e appsettings.{Environment}.json ficheiros.
  • Segredos do aplicativo no ambiente de desenvolvimento.
  • Variáveis de ambiente.

Por padrão, os valores de configuração definidos na linha de comandos têm precedência sobre os valores definidos por todos os outros provedores de configuração.

Argumentos de linha de comando

O comando a seguir define chaves e valores usando =:

dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick

O comando a seguir define chaves e valores usando /:

dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick

O comando a seguir define chaves e valores usando --:

dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick

O valor-chave:

  • Deve seguir =, ou a chave deve ter um prefixo de -- ou / quando o valor segue um espaço.
  • Não é necessário se = for usado. Por exemplo, MySetting=.

Dentro do mesmo comando, não misture pares de chave e valor de argumentos na linha de comando que usam = com pares de chave e valor que usam um espaço.

Mapeamentos de comutador

Os mapeamentos de switch permitem a lógica de substituição do nome da chave . Forneça um dicionário de substituições de switch para o AddCommandLine método.

Quando o dicionário de mapeamentos de interruptor é usado, o dicionário é verificado em busca de uma chave que corresponda à chave fornecida por um argumento de linha de comando. Se a chave de linha de comando for encontrada no dicionário, o valor do dicionário será passado de volta para definir o par chave-valor na configuração do aplicativo. Um mapeamento de switch é necessário para qualquer chave de linha de comando prefixada com um único traço (-).

Alternar regras de chave do dicionário de mapeamentos:

  • Os interruptores devem começar com - ou --.
  • O dicionário de mapeamentos de opção não deve conter chaves duplicadas.

Para usar um dicionário de mapeamentos de switch, passe-o para a invocação para AddCommandLine:


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

builder.Configuration.AddCommandLine(args, switchMappings);

var app = builder.Build();

Execute o seguinte comando funciona para testar a substituição de chave:

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

O código a seguir mostra os valores de chave para as chaves substituídas:

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

Para aplicativos que usam mapeamentos de comutação, a chamada para CreateDefaultBuilder não deve passar argumentos. A chamada do método CreateDefaultBuilder não inclui interruptores mapeados e não há maneira de passar o dicionário de mapeamento de comutadores para AddCommandLine. A solução não é passar os argumentos CreateDefaultBuilder , mas sim permitir que o ConfigurationBuilder método do AddCommandLine método processe os argumentos e o dicionário de mapeamento de switch.

Definir argumentos de ambiente e linha de comando com o Visual Studio

Os argumentos de ambiente e linha de comando podem ser definidos no Visual Studio a partir da caixa de diálogo de perfis de inicialização:

  • No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Propriedades.
  • Selecione a guia Debug > General e selecione Open debug launch profiles UI.

Dados de configuração hierárquica

A API de configuração lê os dados de configuração hierárquica nivelando os dados hierárquicos com o uso de um delimitador nas chaves de configuração.

O download de exemplo contém o seguinte appsettings.json arquivo:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

O seguinte código do download de exemplo exibe várias das configurações de configuração:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

A maneira preferida de ler dados de configuração hierárquica é usando o padrão de opções. Para obter mais informações, consulte Vincular dados de configuração hierárquica neste documento.

GetSection e GetChildren métodos estão disponíveis para isolar seções e subseções nos dados de configuração. Esses métodos são descritos posteriormente em GetSection, GetChildren e Exists.

Chaves e valores de configuração

Advertência

Este artigo mostra o uso de cadeias de conexão. Com um banco de dados local, o usuário não precisa ser autenticado, mas na produção, as cadeias de conexão às vezes incluem uma senha para autenticar. Uma credencial de senha de proprietário de recurso (ROPC) é um risco de segurança que deve ser evitado em bancos de dados de produção. Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações sobre autenticação para aplicativos implantados em ambientes de teste ou produção, consulte Fluxos de autenticação segura.

Chaves de configuração:

  • Não diferenciam maiúsculas de minúsculas. Por exemplo, ConnectionString e connectionstring são tratadas como chaves equivalentes.
  • Se uma chave e um valor forem definidos em mais de um provedor de configuração, o valor do último provedor adicionado será usado. Para obter mais informações, consulte Configuração padrão.
  • Chaves hierárquicas
    • Na API de configuração, o separador de dois pontos (:) funciona em todas as plataformas.
    • É possível que um separador de dois pontos não funcione em todas as plataformas para variáveis de ambiente. Um sublinhado duplo, __, é suportado por todas as plataformas e é convertido automaticamente em dois pontos :.
    • No Cofre de Chaves do Azure, as chaves hierárquicas são usadas -- como um separador. O provedor de configuração do Azure Key Vault substitui -- automaticamente por um : quando os segredos são carregados na configuração do aplicativo.
  • O ConfigurationBinder suporta a vinculação de matrizes a objetos usando índices de matriz em chaves de configuração. A vinculação de matriz é descrita na seção Vincular uma matriz a uma classe .

Valores de configuração:

  • São cadeias de caracteres.
  • Valores nulos não podem ser armazenados na configuração ou vinculados a objetos.

Provedores de configuração

A tabela a seguir mostra os provedores de configuração disponíveis para aplicativos ASP.NET Core.

Fornecedor Fornece configuração a partir de
provedor de configuração do Azure Key Vault Azure Key Vault
provedor de configuração do aplicativo Azure Configuração da Aplicação Azure
Provedor de configuração de linha de comando Parâmetros de linha de comando
Provedor de configuração personalizado Fonte personalizada
provedor de configuração de variáveis de ambiente Variáveis de ambiente
Provedor de configuração de arquivo Arquivos INI, JSON e XML
Provedor de configuração de chave por arquivo Arquivos de diretório
Provedor de configuração de memória Coleções na memória
Segredos do utilizador Arquivo no diretório de perfil de usuário

As fontes de configuração são lidas na ordem em que seus provedores de configuração são especificados. Organize os fornecedores de configuração no código para alinhar com as prioridades das fontes de configuração essenciais que o aplicativo necessita.

Uma sequência típica de provedores de configuração é:

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. Segredos do utilizador
  4. Variáveis de ambiente usando o provedor de configuração de Variáveis de Ambiente .
  5. Argumentos de linha de comando usando o provedor de configuração de linha de comando .

Uma prática comum é adicionar o provedor de configuração de linha de comando por último em uma série de provedores para permitir que os argumentos de linha de comando substituam a configuração definida pelos outros provedores.

A sequência anterior de provedores é usada na configuração padrão.

Prefixos de cadeia de conexão

Advertência

Este artigo mostra o uso de cadeias de conexão. Com um banco de dados local, o usuário não precisa ser autenticado, mas na produção, as cadeias de conexão às vezes incluem uma senha para autenticar. Uma credencial de senha de proprietário de recurso (ROPC) é um risco de segurança que deve ser evitado em bancos de dados de produção. Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações sobre autenticação para aplicativos implantados em ambientes de teste ou produção, consulte Fluxos de autenticação segura.

A API de configuração tem regras de processamento especiais para quatro variáveis de ambiente de cadeia de conexão. Essas cadeias de conexão estão envolvidas na configuração de cadeias de conexão do Azure para o ambiente do aplicativo. As variáveis de ambiente com os prefixos mostrados na tabela são carregadas no aplicativo com a configuração padrão ou quando nenhum prefixo é fornecido ao AddEnvironmentVariables.

Prefixo da cadeia de conexão Fornecedor
CUSTOMCONNSTR_ Provedor personalizado
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Banco de Dados SQL do Azure
SQLCONNSTR_ Servidor SQL

Quando uma variável de ambiente é descoberta e carregada na configuração com qualquer um dos quatro prefixos mostrados na tabela:

  • A chave de configuração é criada removendo o prefixo da variável de ambiente e adicionando uma seção de chave de configuração (ConnectionStrings).
  • É criado um novo par chave-valor de configuração que representa o provedor de conexão de banco de dados (exceto para CUSTOMCONNSTR_, que não tem nenhum provedor declarado).
Chave de variável de ambiente Chave de configuração convertida Entrada de configuração do provedor
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} Entrada de configuração não criada.
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} Chave: ConnectionStrings:{KEY}_ProviderName:
Valor: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} Chave: ConnectionStrings:{KEY}_ProviderName:
Valor: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} Chave: ConnectionStrings:{KEY}_ProviderName:
Valor: System.Data.SqlClient

Provedor de configuração de arquivos

FileConfigurationProvider é a classe base para carregar a configuração do sistema de arquivos. Os seguintes provedores de configuração derivam de FileConfigurationProvider:

Provedor de configuração INI

O IniConfigurationProvider carrega a configuração a partir de pares chave-valor do ficheiro INI em tempo de execução.

O código a seguir adiciona vários provedores de configuração:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
    .AddIniFile($"MyIniConfig.{builder.Environment.EnvironmentName}.ini",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

No código anterior, as configurações no MyIniConfig.ini e MyIniConfig.{Environment}.ini arquivos são substituídas por configurações no:

O download de exemplo contém o seguinte MyIniConfig.ini arquivo:

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

O código a seguir do download de exemplo exibe várias das configurações anteriores:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Provedor de configuração JSON

O JsonConfigurationProvider carrega a configuração a partir de pares chave-valor do ficheiro JSON.

As sobrecargas podem especificar:

  • Se o arquivo é opcional.
  • Se a configuração será recarregada se o arquivo for alterado.

Considere o seguinte código:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile("MyConfig.json",
        optional: true,
        reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

O código anterior:

Normalmente , você não deseja que um arquivo JSON personalizado substitua os valores definidos no provedor de configuração de variáveis de ambiente e no provedor de configuração de linha de comando.

Provedor de configuração XML

A XmlConfigurationProvider carrega a configuração a partir dos pares chave-valor do arquivo XML em tempo de execução.

O código a seguir adiciona vários provedores de configuração:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
    .AddXmlFile($"MyXMLFile.{builder.Environment.EnvironmentName}.xml",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

No código anterior, as configurações no MyXMLFile.xml e MyXMLFile.{Environment}.xml arquivos são substituídas por configurações no:

O download de exemplo contém o seguinte MyXMLFile.xml arquivo:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

O código a seguir do download de exemplo exibe várias das configurações anteriores:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Os elementos repetidos que usam o mesmo nome de elemento funcionam se o name atributo for usado para distinguir os elementos:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

O código a seguir lê o arquivo de configuração anterior e exibe as chaves e valores:

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

Os atributos podem ser usados para fornecer valores:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

O arquivo de configuração anterior carrega as seguintes chaves com value:

  • chave:atributo
  • seção:chave:atributo

Provedor de configuração de chave por arquivo

O KeyPerFileConfigurationProvider usa os arquivos de um diretório como pares chave-valor de configuração. A chave é o nome do arquivo. O valor contém o conteúdo do arquivo. O provedor de configuração de chave por arquivo é usado em cenários de hospedagem do Docker.

Para ativar a configuração de chave por arquivo, chame o AddKeyPerFile método de extensão em uma instância do ConfigurationBuilder. O directoryPath para os arquivos deve ser um caminho absoluto.

As sobrecargas permitem especificar:

  • Um Action<KeyPerFileConfigurationSource> delegado que configura a fonte.
  • Se o diretório é opcional e o caminho para o diretório.

O sublinhado duplo (__) é usado como um delimitador de chave de configuração em nomes de arquivo. Por exemplo, o nome Logging__LogLevel__System do arquivo produz a chave Logging:LogLevel:Systemde configuração .

Chame ConfigureAppConfiguration ao criar o host para especificar a configuração da aplicação:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

Provedor de configuração de memória

O MemoryConfigurationProvider usa uma coleção na memória como pares chave-valor de configuração.

O código a seguir adiciona uma coleção de memória ao sistema de configuração:

var builder = WebApplication.CreateBuilder(args);

var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

builder.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

O código a seguir do download de exemplo exibe as configurações anteriores:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

No código anterior, config.AddInMemoryCollection(Dict) é adicionado após os provedores de configuração padrão. Para obter um exemplo de como ordenar os provedores de configuração, consulte Provedor de configuração JSON.

Consulte Associar uma matriz para ver outro exemplo usando MemoryConfigurationProvider.

Kestrel Configuração do ponto final

Kestrel A configuração específica do ponto de extremidade substitui todas as configurações de ponto de extremidade interservidor. As configurações de endpoint entre servidores incluem:

Considere o seguinte appsettings.json arquivo usado em um aplicativo Web ASP.NET Core:

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

Quando a marcação realçada anterior é usada em um aplicativo Web ASP.NET Core e o aplicativo é iniciado na linha de comando com a seguinte configuração de ponto de extremidade entre servidores:

dotnet run --urls="https://localhost:7777"

Kestrel liga-se ao ponto de extremidade configurado especificamente para Kestrel no arquivo de appsettings.json (https://localhost:9999) e não https://localhost:7777.

Considere o Kestrel ponto de extremidade específico configurado como uma variável de ambiente:

set Kestrel__Endpoints__Https__Url=https://localhost:8888

Na variável de ambiente anterior, Https é o nome do Kestrel endpoint específico. O arquivo anterior appsettings.json também define um endpoint Kestrel específico chamado Https. Por padrão, as variáveis de ambiente que usam o provedor de configuração Variáveis de Ambiente são lidas após appsettings.{Environment}.json, portanto, a variável de ambiente anterior é usada para a extremidade de Https.

GetValue

ConfigurationBinder.GetValue extrai um único valor da configuração com uma chave especificada e o converte para o tipo especificado:

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

No código anterior, se NumberKey não for encontrado na configuração, o valor padrão de 99 é usado.

GetSection, GetChildren e Existe

Para os exemplos a seguir, considere o seguinte MySubsection.json arquivo:

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

O código a seguir adiciona MySubsection.json aos provedores de configuração:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MySubsection.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

GetSection

IConfiguration.GetSection Retorna uma subseção de configuração com a chave de subseção especificada.

O código a seguir retorna valores para section1:

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

O código a seguir retorna valores para section2:subsection0:

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSection nunca mais volta null. Se uma seção correspondente não for encontrada, um vazio IConfigurationSection será retornado.

Quando GetSection retorna uma seção correspondente, Value não é preenchida. Os Key e Path são devolvidos quando a seção existe.

GetChildren e existe

O código a seguir chama IConfiguration.GetChildren e retorna valores para section2:subsection0:

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = "";
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

O código anterior chama ConfigurationExtensions.Exists para verificar se a seção existe:

Vincular uma matriz

O ConfigurationBinder.Bind suporta a vinculação de matrizes a objetos usando índices de matriz em chaves de configuração. Qualquer formato de matriz que exponha um segmento de chave numérica é capaz de se associar a matrizes de classes POCO.

Considere MyArray.json a partir do download de exemplo:

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

O código a seguir adiciona MyArray.json aos provedores de configuração:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MyArray.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

O código a seguir lê a configuração e exibe os valores:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample? _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
       _array = Config.GetSection("array").Get<ArrayExample>();
        if (_array == null)
        {
            throw new ArgumentNullException(nameof(_array));
        }
        string s = String.Empty;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}
public class ArrayExample
{
    public string[]? Entries { get; set; } 
}

O código anterior retorna a seguinte saída:

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

Na saída anterior, o Índice 3 tem valor value40, correspondente a "4": "value40", em MyArray.json. Os índices de matriz acoplados são contínuos e não vinculados ao índice de chave de configuração. O fichário de configuração não é capaz de vincular valores nulos ou criar entradas nulas em objetos acoplados.

Provedor de configuração personalizada

O aplicativo de exemplo demonstra como criar um provedor de configuração básica que lê pares chave-valor de configuração de um banco de dados usando o Entity Framework (EF).

O provedor tem as seguintes características:

  • O banco de dados EF in-memory é usado para fins de demonstração. Para usar um banco de dados que exija uma cadeia de conexão, implemente um secundário ConfigurationBuilder para fornecer a cadeia de conexão de outro provedor de configuração.
  • O provedor lê uma tabela de banco de dados na configuração na inicialização. O provedor não consulta o banco de dados por chave.
  • A funcionalidade de recarregar ao alterar não está implementada, portanto, fazer alterações na base de dados após o início da aplicação não tem efeito na configuração da aplicação.

Defina uma EFConfigurationValue entidade para armazenar valores de configuração no banco de dados.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; } = String.Empty;
    public string Value { get; set; } = String.Empty;
}

Adicione um EFConfigurationContext para armazenar e acessar os valores configurados.

EFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}

Crie uma classe que implemente o IConfigurationSource.

EFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) => _optionsAction = optionsAction;

    public IConfigurationProvider Build(IConfigurationBuilder builder) => new EFConfigurationProvider(_optionsAction);
}

Crie o provedor de configuração personalizada herdando do ConfigurationProvider. O provedor de configuração inicializa o banco de dados quando ele está vazio. Como as chaves de configuração não diferenciam maiúsculas de minúsculas, o dicionário usado para inicializar o banco de dados é criado com o comparador que não diferencia maiúsculas de minúsculas (StringComparer.OrdinalIgnoreCase).

EFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            if (dbContext == null || dbContext.Values == null)
            {
                throw new Exception("Null DB context");
            }
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues =
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                    { "quote1", "I aim to misbehave." },
                    { "quote2", "I swallowed a bug." },
                    { "quote3", "You can't stop the signal, Mal." }
            };

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue
            {
                Id = kvp.Key,
                Value = kvp.Value
            })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

Um AddEFConfiguration método de extensão permite adicionar a fonte de configuração a um ConfigurationBuilder.

Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
               this IConfigurationBuilder builder,
               Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

O código a seguir mostra como usar o personalizado EFConfigurationProvider em Program.cs:

//using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEFConfiguration(
    opt => opt.UseInMemoryDatabase("InMemoryDb"));

var app = builder.Build();

app.Run();

Configuração de acesso com injeção de dependência (DI)

Usando a Injeção de Dependência (DI), a configuração pode ser injetada em serviços ao resolver o IConfiguration serviço:

public class Service
{
    private readonly IConfiguration _config;

    public Service(IConfiguration config) =>
        _config = config;

    public void DoSomething()
    {
        var configSettingValue = _config["ConfigSetting"];

        // ...
    }
}

Para obter informações sobre como aceder a valores usando IConfiguration, consulte GetValue e GetSection, GetChildren e Exists neste artigo.

Configuração de acesso nas páginas Razor

O código a seguir exibe dados de configuração em uma Razor Página:

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

No código a seguir, MyOptions é adicionado ao contêiner de serviço com Configure e vinculado à configuração:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions"));

var app = builder.Build();

A marcação a seguir usa a @injectRazor diretiva para resolver e exibir os valores de opções:

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@using SampleApp.Models
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

Configuração de acesso em um arquivo de exibição MVC

O código a seguir exibe dados de configuração em uma exibição MVC:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

Configuração de acesso em Program.cs

O código seguinte acede à configuração no arquivo Program.cs.

var builder = WebApplication.CreateBuilder(args);

var key1 = builder.Configuration.GetValue<string>("KeyOne");

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

var key2 = app.Configuration.GetValue<int>("KeyTwo");
var key3 = app.Configuration.GetValue<bool>("KeyThree");

app.Logger.LogInformation("KeyOne: {KeyOne}", key1);
app.Logger.LogInformation("KeyTwo: {KeyTwo}", key2);
app.Logger.LogInformation("KeyThree: {KeyThree}", key3);

app.Run();

No appsettings.json exemplo anterior:

{
  ...
  "KeyOne": "Key One Value",
  "KeyTwo": 1999,
  "KeyThree": true
}

Configurar opções com um delegado

As opções configuradas num objeto delegado substituem os valores definidos nos provedores de configuração.

No código a seguir, um IConfigureOptions<TOptions> serviço é adicionado ao contêiner de serviço. Ele usa um delegado para configurar valores para MyOptions:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "Value configured in delegate";
    myOptions.Option2 = 500;
});

var app = builder.Build();

O código a seguir exibe os valores de opções:

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

No exemplo anterior, os valores de Option1 e Option2 são especificados em appsettings.json e depois substituídos pelo delegado configurado.

Configuração de host versus aplicativo

Antes de o aplicativo ser configurado e iniciado, um host é configurado e iniciado. O host é responsável pela inicialização do aplicativo e gerenciamento do tempo de vida. Tanto o aplicativo quanto o host são configurados usando os provedores de configuração descritos neste tópico. Os pares chave-valor de configuração do host também estão incluídos na configuração do aplicativo. Para obter mais informações sobre como os provedores de configuração são usados quando o host é criado e como as fontes de configuração afetam a configuração do host, consulte ASP.NET Visão geral dos fundamentos principais.

Configuração padrão do host

Para obter detalhes sobre a configuração padrão ao usar o host da Web, consulte a versão ASP.NET Core 2.2 deste tópico.

  • A configuração do host é fornecida a partir de:
    • Variáveis de ambiente prefixadas com DOTNET_ (por exemplo, DOTNET_ENVIRONMENT) usando o provedor de configuração de variáveis de ambiente. O prefixo (DOTNET_) é removido quando os pares chave-valor de configuração são carregados.
    • Argumentos de linha de comando usando o provedor de configuração de linha de comando .
  • A configuração padrão do host da Web é estabelecida (ConfigureWebHostDefaults):
    • Kestrel é usado como o servidor web e configurado usando os fornecedores de configuração da aplicação.
    • Adicione o Middleware de Filtragem de Host.
    • Adicione o Middleware de Cabeçalhos Encaminhados se a variável de ambiente ASPNETCORE_FORWARDEDHEADERS_ENABLED estiver definida como true.
    • Habilite a integração com o IIS.

Outra configuração

Este tópico refere-se apenas à configuração do aplicativo. Outros aspetos da execução e hospedagem de aplicativos ASP.NET Core são configurados usando arquivos de configuração não abordados neste tópico:

As variáveis de ambiente definidas em launchSettings.json substituem as definidas no ambiente do sistema.

Para obter mais informações sobre como migrar a configuração do aplicativo de versões anteriores do ASP.NET, consulte Migrar configuração para o ASP.NET Core.

Adicionar configuração a partir de um conjunto externo

Uma implementação IHostingStartup permite adicionar aprimoramentos a um aplicativo na inicialização a partir de um assembly externo fora da classe Startup do aplicativo. Para obter mais informações, consulte Usar assemblies de inicialização de hospedagem no ASP.NET Core.

Recursos adicionais

A configuração do aplicativo no ASP.NET Core é executada usando um ou mais provedores de configuração. Os provedores de configuração leem dados de configuração de pares chave-valor usando uma variedade de fontes de configuração:

  • Arquivos de configurações, como appsettings.json
  • Variáveis de ambiente
  • Azure Key Vault
  • Configuração da Aplicação Azure
  • Argumentos de linha de comando
  • Fornecedores personalizados, instalados ou criados
  • Arquivos de diretório
  • Objetos .NET na memória

Este artigo fornece informações sobre a configuração no ASP.NET Core. Para obter informações sobre como usar a configuração em aplicativos de console, consulte Configuração do .NET.

Configuração de aplicativos e hosts

ASP.NET aplicativos principais configuram e iniciam um host. O host é responsável pela inicialização do aplicativo e gerenciamento do tempo de vida. Os modelos ASP.NET Core criam um WebApplicationBuilder que contém o host. Embora alguma configuração possa ser feita no host e nos provedores de configuração do aplicativo, geralmente, apenas a configuração necessária para o host deve ser feita na configuração do host.

A configuração do aplicativo é a prioridade mais alta e é detalhada na próxima seção. A configuração do host segue a configuração do aplicativo e é descrita neste artigo.

Fontes de configuração de aplicativos padrão

ASP.NET principais aplicativos Web criados com dotnet new ou Visual Studio geram o seguinte código:

var builder = WebApplication.CreateBuilder(args);

WebApplication.CreateBuilder inicializa uma nova instância da classe WebApplicationBuilder com padrões pré-configurados. O WebApplicationBuilder inicializado (builder) fornece a configuração padrão para a aplicação na seguinte ordem, da mais alta para a mais baixa prioridade:

  1. Argumentos de linha de comando usando o provedor de configuração de linha de comando .
  2. Variáveis de ambiente não prefixadas usando o provedor de configuração de variáveis de ambiente não prefixadas.
  3. Segredos de usuário quando o aplicativo é executado no ambiente Development.
  4. appsettings.{Environment}.json usando o provedor de configuração JSON. Por exemplo, appsettings.Production.json e appsettings.Development.json.
  5. appsettings.json usando o provedor de configuração JSON .
  6. Um fallback para a configuração do host descrita na próxima seção.

Fontes de configuração de host padrão

A lista a seguir contém as fontes de configuração de host padrão da prioridade mais alta para a mais baixa:

  1. ASPNETCORE_-variáveis de ambiente prefixadas usando o provedor de configuração de variáveis de ambiente.
  2. Argumentos de linha de comando usando o provedor de configuração de linha de comando
  3. DOTNET_-variáveis de ambiente prefixadas usando o provedor de configuração de variáveis de ambiente.

Quando um valor de configuração é definido na configuração do host e do aplicativo, a configuração do aplicativo é usada.

Consulte Explicação neste comentário do GitHub para obter uma explicação de por que, na configuração do host, ASPNETCORE_ as variáveis de ambiente prefixadas têm prioridade maior do que os argumentos de linha de comando.

Variáveis do host

As seguintes variáveis são bloqueadas antecipadamente ao inicializar os construtores de host e não podem ser influenciadas pela configuração do aplicativo:

Todas as outras configurações de host são lidas a partir da configuração do aplicativo em vez da configuração do host.

URLS é uma das muitas configurações comuns de host que não é uma configuração de bootstrap. Como todas as outras configurações de host que não estão na lista anterior, URLS é lido mais tarde na configuração do aplicativo. A configuração do host é um fallback para a configuração do aplicativo, portanto, a configuração do host pode ser usada para definir URLS, mas ela será substituída por qualquer fonte de configuração na configuração do aplicativo, como appsettings.json.

Para obter mais informações, consulte Alterar a raiz do conteúdo, o nome do aplicativo e o ambiente e Alterar a raiz do conteúdo, o nome do aplicativo e o ambiente por variáveis de ambiente ou linha de comando

As seções restantes neste artigo referem-se à configuração do aplicativo.

Provedores de configuração de aplicativos

O código a seguir exibe os provedores de configuração habilitados na ordem em que foram adicionados:

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

A lista anterior de fontes de configuração padrão de prioridade mais alta a mais baixa mostra os provedores na ordem oposta em que são adicionados ao aplicativo gerado pelo modelo. Por exemplo, o provedor de configuração JSON é adicionado antes do provedor de configuração de linha de comando.

Os provedores de configuração que são adicionados posteriormente têm prioridade mais alta e substituem as configurações de chave anteriores. Por exemplo, se MyKey for definido em ambos appsettings.json e no ambiente, o valor do ambiente será usado. Usando os provedores de configuração padrão, o provedor de configuração de linha de comando substitui todos os outros provedores.

Para obter mais informações sobre CreateBuilder, consulte Configurações padrão do construtor.

appsettings.json

Considere o seguinte appsettings.json arquivo:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

O código a seguir do download de exemplo exibe várias das configurações anteriores:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

O padrão JsonConfigurationProvider carrega a configuração na seguinte ordem:

  1. appsettings.json
  2. appsettings.{Environment}.json : Por exemplo, os appsettings.Production.json e appsettings.Development.json arquivos. A versão de ambiente do arquivo é carregada com base no IHostingEnvironment.EnvironmentName. Para obter mais informações, consulte Usar vários ambientes no ASP.NET Core.

appsettings.{Environment}.json valores substituem as chaves em appsettings.json. Por exemplo, por padrão:

  • Durante o desenvolvimento, a configuração appsettings.Development.json substitui os valores encontrados no appsettings.json.
  • Na produção, a configuração de appsettings.Production.json substitui os valores encontrados em appsettings.json. Por exemplo, ao implantar o aplicativo no Azure.

Se um valor de configuração deve ser garantido, consulte GetValue. O exemplo anterior lê apenas cadeias de caracteres e não suporta um valor padrão.

Usando a configuração padrão, os arquivos appsettings.json e appsettings.{Environment}.json são habilitados com reloadOnChange: true. As alterações feitas no arquivo appsettings.json e appsettings.{Environment}.json são lidas pelo provedor de configuração JSONapós o aplicativo ser iniciado.

Vincular dados de configuração hierárquica usando o padrão de opções

A maneira preferida de ler os valores de configuração relacionados é usando o padrão de opções . Por exemplo, para ler os seguintes valores de configuração:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

Crie a seguinte PositionOptions classe:

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; } = String.Empty;
    public string Name { get; set; } = String.Empty;
}

Uma classe de opções:

  • Deve ser não abstrato e ter um construtor público sem parâmetros.
  • Todas as propriedades públicas de leitura-gravação do tipo são vinculadas.
  • Os campos não estão vinculados. No código anterior, Position não está vinculado. O Position campo é usado para que a cadeia de caracteres "Position" não precise ser codificada no aplicativo ao vincular a classe a um provedor de configuração.

O seguinte código:

  • Chama ConfigurationBinder.Bind para vincular a PositionOptions classe à Position seção.
  • Exibe os dados de Position configuração.
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

No código anterior, por padrão, as alterações no arquivo de configuração JSON após o início do aplicativo são lidas.

ConfigurationBinder.Get<T> Vincula e retorna o tipo especificado. ConfigurationBinder.Get<T> pode ser mais conveniente do que usar ConfigurationBinder.Bind. O código a seguir mostra como usar ConfigurationBinder.Get<T> com a PositionOptions classe:

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions? positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

No código anterior, por padrão, as alterações no arquivo de configuração JSON após o início do aplicativo são lidas.

Uma abordagem alternativa ao usar o padrão de opções é vincular a Position seção e adicioná-la ao contêiner do serviço de injeção de dependência. No código a seguir, PositionOptions é adicionado ao contêiner de serviço com Configure e vinculado à configuração:

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));

var app = builder.Build();

Usando o código anterior, o código a seguir lê as opções de posição:

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

No código anterior, as alterações no ficheiro de configuração JSON após o início da aplicação não são lidas. Para ler as alterações após o início do aplicativo, use IOptionsSnapshot.

Usando a configuração padrão, os arquivos appsettings.json e appsettings.{Environment}.json são habilitados com reloadOnChange: true. As alterações feitas no arquivo appsettings.json e appsettings.{Environment}.json são lidas pelo provedor de configuração JSONapós o aplicativo ser iniciado.

Consulte o provedor de configuração JSON neste documento para obter informações sobre como adicionar arquivos de configuração JSON adicionais.

Combinando a coleção de serviços

Considere o seguinte que registra serviços e configura opções:

using ConfigSample.Options;
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));
builder.Services.Configure<ColorOptions>(
    builder.Configuration.GetSection(ColorOptions.Color));

builder.Services.AddScoped<IMyDependency, MyDependency>();
builder.Services.AddScoped<IMyDependency2, MyDependency2>();

var app = builder.Build();

Grupos relacionados de registros podem ser movidos para um método de extensão para registrar serviços. Por exemplo, os serviços de configuração são adicionados à seguinte classe:

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }

        public static IServiceCollection AddMyDependencyGroup(
             this IServiceCollection services)
        {
            services.AddScoped<IMyDependency, MyDependency>();
            services.AddScoped<IMyDependency2, MyDependency2>();

            return services;
        }
    }
}

Os restantes serviços estão registados numa classe semelhante. O código a seguir usa os novos métodos de extensão para registrar os serviços:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddConfig(builder.Configuration)
    .AddMyDependencyGroup();

builder.Services.AddRazorPages();

var app = builder.Build();

Nota: Cada método de extensão services.Add{GROUP_NAME} adiciona e potencialmente configura serviços. Por exemplo, AddControllersWithViews adiciona os serviços que os controladores MVC com exibições exigem e AddRazorPages adiciona os serviços Razor o Pages requer.

Segurança e segredos do utilizador

Diretrizes de dados de configuração:

  • Nunca armazene senhas ou outros dados confidenciais no código do provedor de configuração ou em arquivos de configuração de texto simples. A ferramenta Secret Manager pode ser usada para armazenar segredos em desenvolvimento.
  • Não use segredos de produção em ambientes de desenvolvimento ou teste.
  • Especifique segredos fora do projeto para que eles não possam ser acidentalmente comprometidos em um repositório de código-fonte.
  • Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações, consulte Fluxos de autenticação seguros.

Por padrão, a fonte de configuração de segredos do usuário é registrada após as fontes de configuração JSON. Portanto, as chaves de segredo do usuário têm precedência sobre as chaves em appsettings.json e appsettings.{Environment}.json.

Para obter mais informações sobre como armazenar senhas ou outros dados confidenciais:

O Azure Key Vault armazena com segurança segredos de aplicativos para aplicativos ASP.NET Core. Para obter mais informações, consulte Provedor de configuração do Azure Key Vault no ASP.NET Core.

Variáveis de ambiente não prefixadas

As variáveis de ambiente não prefixadas são variáveis de ambiente diferentes daquelas prefixadas por ASPNETCORE_ ou DOTNET_. Por exemplo, os modelos de aplicação Web do ASP.NET Core estabelecem "ASPNETCORE_ENVIRONMENT": "Development" em launchSettings.json. Para obter mais informações sobre variáveis de ambiente ASPNETCORE_ e DOTNET_, consulte:

Usando a configuração padrão, o EnvironmentVariablesConfigurationProvider carrega a configuração dos pares chave-valor da variável de ambiente após a leitura de appsettings.json, appsettings.{Environment}.json e segredos do usuário. Portanto, os valores-chave lidos do ambiente substituem os valores lidos de appsettings.json, appsettings.{Environment}.json e segredos de utilizador.

O separador : não funciona com chaves hierárquicas de variáveis de ambiente em todas as plataformas. Por exemplo, o separador : não é suportado pelo Bash. O duplo sublinhado, __, é:

  • Suportado por todas as plataformas.
  • Substituído automaticamente por dois pontos, :.

Os seguintes set comandos:

  • Defina as chaves de ambiente e os valores do exemplo anterior no Windows.
  • Teste as configurações ao usar o download de exemplo. O dotnet run comando deve ser executado no diretório do projeto.
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

As configurações de ambiente anteriores:

  • São definidos apenas em processos iniciados a partir da janela de comando em que foram configurados.
  • Não será lido por navegadores iniciados com o Visual Studio.

Os seguintes comandos setx podem ser usados para definir as chaves e valores de ambiente no Windows. set, ao contrário, setx as configurações são persistentes. /M Define a variável no ambiente do sistema. Se o /M switch não for usado, uma variável de ambiente do usuário será definida.

setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M

Para testar se os comandos anteriores substituem appsettings.json e appsettings.{Environment}.json:

  • Com o Visual Studio: saia e reinicie o Visual Studio.
  • Com a CLI: Inicie uma nova janela de comando e digite dotnet run.

Chame AddEnvironmentVariables com uma cadeia de caracteres para especificar um prefixo para variáveis de ambiente:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");

var app = builder.Build();

No código anterior:

O prefixo é removido quando os pares chave-valor de configuração são lidos.

Os comandos a seguir testam o prefixo personalizado:

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

A configuração padrão carrega variáveis de ambiente e argumentos de linha de comando prefixados com DOTNET_ e ASPNETCORE_. Os DOTNET_ prefixos e ASPNETCORE_ são usados pelo ASP.NET Core para configuração de host e aplicativo, mas não para configuração de usuário. Para obter mais informações sobre a configuração do host e do aplicativo, consulte .NET Generic Host.

No Serviço de Aplicativo do Azure, selecione Nova configuração de aplicativo na página Configuração de Definições>. As configurações do aplicativo do Serviço de Aplicativo do Azure são:

  • Encriptado em repouso e transmitido através de um canal encriptado.
  • Expostos como variáveis de ambiente.

Para obter mais informações, consulte Aplicativos do Azure: substituir a configuração do aplicativo usando o Portal do Azure.

Consulte Prefixos de cadeia de conexão para obter informações sobre cadeias de conexão de banco de dados do Azure.

Nomenclatura de variáveis de ambiente

Os nomes das variáveis de ambiente refletem a estrutura de um appsettings.json arquivo. Cada elemento na hierarquia é preferencialmente separado por um sublinhado duplo ou por dois pontos. Quando a estrutura do elemento inclui uma matriz, o índice da matriz deve ser tratado como um nome de elemento adicional nesse caminho. Considere o arquivo a seguir appsettings.json e seus valores equivalentes representados como variáveis de ambiente.

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "MySystem@example.com",
                "ToAddress": "SRE@example.com"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

variáveis de ambiente

setx SmtpServer smtp.example.com
setx Logging__0__Name ToEmail
setx Logging__0__Level Critical
setx Logging__0__Args__FromAddress MySystem@example.com
setx Logging__0__Args__ToAddress SRE@example.com
setx Logging__1__Name ToConsole
setx Logging__1__Level Information

Variáveis de ambiente definidas no launchSettings.json gerado

As variáveis de ambiente definidas em launchSettings.json substituem as definidas no ambiente do sistema. Por exemplo, os templates web do ASP.NET Core geram um arquivo launchSettings.json que define a configuração do endpoint como:

"applicationUrl": "https://localhost:5001;http://localhost:5000"

Configurar o applicationUrl configura a variável de ambiente ASPNETCORE_URLS e altera os valores definidos no ambiente.

Variáveis de ambiente de escape no Linux

No Linux, o valor das variáveis de ambiente de URL deve ser codificado para que systemd consiga analisá-lo. Use a ferramenta Linux systemd-escape que gera http:--localhost:5001

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

Exibir variáveis de ambiente

O código a seguir exibe as variáveis de ambiente e os valores na inicialização do aplicativo, o que pode ser útil ao depurar as configurações do ambiente:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

foreach (var c in builder.Configuration.AsEnumerable())
{
    Console.WriteLine(c.Key + " = " + c.Value);
}

Linha de comando

Usando a configuração padrão, o CommandLineConfigurationProvider carrega configuração dos pares chave-valor dos argumentos de linha de comando após as seguintes fontes de configuração:

  • appsettings.json e appsettings.{Environment}.json ficheiros.
  • Segredos do aplicativo no ambiente de desenvolvimento.
  • Variáveis de ambiente.

Por padrão, os valores de configuração definidos na linha de comandos têm precedência sobre os valores definidos por todos os outros provedores de configuração.

Argumentos de linha de comando

O comando a seguir define chaves e valores usando =:

dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick

O comando a seguir define chaves e valores usando /:

dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick

O comando a seguir define chaves e valores usando --:

dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick

O valor-chave:

  • Deve seguir =, ou a chave deve ter um prefixo de -- ou / quando o valor segue um espaço.
  • Não é necessário se = for usado. Por exemplo, MySetting=.

Dentro do mesmo comando, não misture pares de chave e valor de argumentos na linha de comando que usam = com pares de chave e valor que usam um espaço.

Mapeamentos de comutador

Os mapeamentos de switch permitem a lógica de substituição do nome da chave . Forneça um dicionário de substituições de switch para o AddCommandLine método.

Quando o dicionário de mapeamentos de interruptor é usado, o dicionário é verificado em busca de uma chave que corresponda à chave fornecida por um argumento de linha de comando. Se a chave de linha de comando for encontrada no dicionário, o valor do dicionário será passado de volta para definir o par chave-valor na configuração do aplicativo. Um mapeamento de switch é necessário para qualquer chave de linha de comando prefixada com um único traço (-).

Alternar regras de chave do dicionário de mapeamentos:

  • Os interruptores devem começar com - ou --.
  • O dicionário de mapeamentos de opção não deve conter chaves duplicadas.

Para usar um dicionário de mapeamentos de switch, passe-o para a invocação para AddCommandLine:


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

builder.Configuration.AddCommandLine(args, switchMappings);

var app = builder.Build();

Execute o seguinte comando funciona para testar a substituição de chave:

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

O código a seguir mostra os valores de chave para as chaves substituídas:

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

Para aplicativos que usam mapeamentos de comutação, a chamada para CreateDefaultBuilder não deve passar argumentos. A chamada do método CreateDefaultBuilder não inclui interruptores mapeados e não há maneira de passar o dicionário de mapeamento de comutadores para AddCommandLine. A solução não é passar os argumentos CreateDefaultBuilder , mas sim permitir que o ConfigurationBuilder método do AddCommandLine método processe os argumentos e o dicionário de mapeamento de switch.

Definir argumentos de ambiente e linha de comando com o Visual Studio

Os argumentos de ambiente e linha de comando podem ser definidos no Visual Studio a partir da caixa de diálogo de perfis de inicialização:

  • No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Propriedades.
  • Selecione a guia Debug > General e selecione Open debug launch profiles UI.

Dados de configuração hierárquica

A API de configuração lê os dados de configuração hierárquica nivelando os dados hierárquicos com o uso de um delimitador nas chaves de configuração.

O download de exemplo contém o seguinte appsettings.json arquivo:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

O seguinte código do download de exemplo exibe várias das configurações de configuração:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

A maneira preferida de ler dados de configuração hierárquica é usando o padrão de opções. Para obter mais informações, consulte Vincular dados de configuração hierárquica neste documento.

GetSection e GetChildren métodos estão disponíveis para isolar seções e subseções nos dados de configuração. Esses métodos são descritos posteriormente em GetSection, GetChildren e Exists.

Chaves e valores de configuração

Advertência

Este artigo mostra o uso de cadeias de conexão. Com um banco de dados local, o usuário não precisa ser autenticado, mas na produção, as cadeias de conexão às vezes incluem uma senha para autenticar. Uma credencial de senha de proprietário de recurso (ROPC) é um risco de segurança que deve ser evitado em bancos de dados de produção. Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações sobre autenticação para aplicativos implantados em ambientes de teste ou produção, consulte Fluxos de autenticação segura.

Chaves de configuração:

  • Não diferenciam maiúsculas de minúsculas. Por exemplo, ConnectionString e connectionstring são tratadas como chaves equivalentes.
  • Se uma chave e um valor forem definidos em mais de um provedor de configuração, o valor do último provedor adicionado será usado. Para obter mais informações, consulte Configuração padrão.
  • Chaves hierárquicas
    • Na API de configuração, o separador de dois pontos (:) funciona em todas as plataformas.
    • É possível que um separador de dois pontos não funcione em todas as plataformas para variáveis de ambiente. Um sublinhado duplo, __, é suportado por todas as plataformas e é convertido automaticamente em dois pontos :.
    • No Cofre de Chaves do Azure, as chaves hierárquicas são usadas -- como um separador. O provedor de configuração do Azure Key Vault substitui -- automaticamente por um : quando os segredos são carregados na configuração do aplicativo.
  • O ConfigurationBinder suporta a vinculação de matrizes a objetos usando índices de matriz em chaves de configuração. A vinculação de matriz é descrita na seção Vincular uma matriz a uma classe .

Valores de configuração:

  • São cadeias de caracteres.
  • Valores nulos não podem ser armazenados na configuração ou vinculados a objetos.

Provedores de configuração

A tabela a seguir mostra os provedores de configuração disponíveis para aplicativos ASP.NET Core.

Fornecedor Fornece configuração a partir de
provedor de configuração do Azure Key Vault Azure Key Vault
provedor de configuração do aplicativo Azure Configuração da Aplicação Azure
Provedor de configuração de linha de comando Parâmetros de linha de comando
Provedor de configuração personalizado Fonte personalizada
provedor de configuração de variáveis de ambiente Variáveis de ambiente
Provedor de configuração de arquivo Arquivos INI, JSON e XML
Provedor de configuração de chave por arquivo Arquivos de diretório
Provedor de configuração de memória Coleções na memória
Segredos do utilizador Arquivo no diretório de perfil de usuário

As fontes de configuração são lidas na ordem em que seus provedores de configuração são especificados. Organize os fornecedores de configuração no código para alinhar com as prioridades das fontes de configuração essenciais que o aplicativo necessita.

Uma sequência típica de provedores de configuração é:

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. Segredos do utilizador
  4. Variáveis de ambiente usando o provedor de configuração de Variáveis de Ambiente .
  5. Argumentos de linha de comando usando o provedor de configuração de linha de comando .

Uma prática comum é adicionar o provedor de configuração de linha de comando por último em uma série de provedores para permitir que os argumentos de linha de comando substituam a configuração definida pelos outros provedores.

A sequência anterior de provedores é usada na configuração padrão.

Prefixos de cadeia de conexão

Advertência

Este artigo mostra o uso de cadeias de conexão. Com um banco de dados local, o usuário não precisa ser autenticado, mas na produção, as cadeias de conexão às vezes incluem uma senha para autenticar. Uma credencial de senha de proprietário de recurso (ROPC) é um risco de segurança que deve ser evitado em bancos de dados de produção. Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações sobre autenticação para aplicativos implantados em ambientes de teste ou produção, consulte Fluxos de autenticação segura.

A API de configuração tem regras de processamento especiais para quatro variáveis de ambiente de cadeia de conexão. Essas cadeias de conexão estão envolvidas na configuração de cadeias de conexão do Azure para o ambiente do aplicativo. As variáveis de ambiente com os prefixos mostrados na tabela são carregadas no aplicativo com a configuração padrão ou quando nenhum prefixo é fornecido ao AddEnvironmentVariables.

Prefixo da cadeia de conexão Fornecedor
CUSTOMCONNSTR_ Provedor personalizado
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Banco de Dados SQL do Azure
SQLCONNSTR_ Servidor SQL

Quando uma variável de ambiente é descoberta e carregada na configuração com qualquer um dos quatro prefixos mostrados na tabela:

  • A chave de configuração é criada removendo o prefixo da variável de ambiente e adicionando uma seção de chave de configuração (ConnectionStrings).
  • É criado um novo par chave-valor de configuração que representa o provedor de conexão de banco de dados (exceto para CUSTOMCONNSTR_, que não tem nenhum provedor declarado).
Chave de variável de ambiente Chave de configuração convertida Entrada de configuração do provedor
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} Entrada de configuração não criada.
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} Chave: ConnectionStrings:{KEY}_ProviderName:
Valor: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} Chave: ConnectionStrings:{KEY}_ProviderName:
Valor: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} Chave: ConnectionStrings:{KEY}_ProviderName:
Valor: System.Data.SqlClient

Provedor de configuração de arquivos

FileConfigurationProvider é a classe base para carregar a configuração do sistema de arquivos. Os seguintes provedores de configuração derivam de FileConfigurationProvider:

Provedor de configuração INI

O IniConfigurationProvider carrega a configuração a partir de pares chave-valor do ficheiro INI em tempo de execução.

O código a seguir adiciona vários provedores de configuração:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
    .AddIniFile($"MyIniConfig.{builder.Environment.EnvironmentName}.ini",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

No código anterior, as configurações no MyIniConfig.ini e MyIniConfig.{Environment}.ini arquivos são substituídas por configurações no:

O download de exemplo contém o seguinte MyIniConfig.ini arquivo:

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

O código a seguir do download de exemplo exibe várias das configurações anteriores:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Provedor de configuração JSON

O JsonConfigurationProvider carrega a configuração a partir de pares chave-valor do ficheiro JSON.

As sobrecargas podem especificar:

  • Se o arquivo é opcional.
  • Se a configuração será recarregada se o arquivo for alterado.

Considere o seguinte código:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile("MyConfig.json",
        optional: true,
        reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

O código anterior:

Normalmente , você não deseja que um arquivo JSON personalizado substitua os valores definidos no provedor de configuração de variáveis de ambiente e no provedor de configuração de linha de comando.

Provedor de configuração XML

A XmlConfigurationProvider carrega a configuração a partir dos pares chave-valor do arquivo XML em tempo de execução.

O código a seguir adiciona vários provedores de configuração:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
    .AddXmlFile($"MyXMLFile.{builder.Environment.EnvironmentName}.xml",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

No código anterior, as configurações no MyXMLFile.xml e MyXMLFile.{Environment}.xml arquivos são substituídas por configurações no:

O download de exemplo contém o seguinte MyXMLFile.xml arquivo:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

O código a seguir do download de exemplo exibe várias das configurações anteriores:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Os elementos repetidos que usam o mesmo nome de elemento funcionam se o name atributo for usado para distinguir os elementos:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

O código a seguir lê o arquivo de configuração anterior e exibe as chaves e valores:

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

Os atributos podem ser usados para fornecer valores:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

O arquivo de configuração anterior carrega as seguintes chaves com value:

  • chave:atributo
  • seção:chave:atributo

Provedor de configuração de chave por arquivo

O KeyPerFileConfigurationProvider usa os arquivos de um diretório como pares chave-valor de configuração. A chave é o nome do arquivo. O valor contém o conteúdo do arquivo. O provedor de configuração de chave por arquivo é usado em cenários de hospedagem do Docker.

Para ativar a configuração de chave por arquivo, chame o AddKeyPerFile método de extensão em uma instância do ConfigurationBuilder. O directoryPath para os arquivos deve ser um caminho absoluto.

As sobrecargas permitem especificar:

  • Um Action<KeyPerFileConfigurationSource> delegado que configura a fonte.
  • Se o diretório é opcional e o caminho para o diretório.

O sublinhado duplo (__) é usado como um delimitador de chave de configuração em nomes de arquivo. Por exemplo, o nome Logging__LogLevel__System do arquivo produz a chave Logging:LogLevel:Systemde configuração .

Chame ConfigureAppConfiguration ao criar o host para especificar a configuração da aplicação:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

Provedor de configuração de memória

O MemoryConfigurationProvider usa uma coleção na memória como pares chave-valor de configuração.

O código a seguir adiciona uma coleção de memória ao sistema de configuração:

var builder = WebApplication.CreateBuilder(args);

var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

builder.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

O código a seguir do download de exemplo exibe as configurações anteriores:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

No código anterior, config.AddInMemoryCollection(Dict) é adicionado após os provedores de configuração padrão. Para obter um exemplo de como ordenar os provedores de configuração, consulte Provedor de configuração JSON.

Consulte Associar uma matriz para ver outro exemplo usando MemoryConfigurationProvider.

Kestrel Configuração do ponto final

Kestrel A configuração específica do ponto de extremidade substitui todas as configurações de ponto de extremidade interservidor. As configurações de endpoint entre servidores incluem:

Considere o seguinte appsettings.json arquivo usado em um aplicativo Web ASP.NET Core:

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

Quando a marcação realçada anterior é usada em um aplicativo Web ASP.NET Core e o aplicativo é iniciado na linha de comando com a seguinte configuração de ponto de extremidade entre servidores:

dotnet run --urls="https://localhost:7777"

Kestrel liga-se ao ponto de extremidade configurado especificamente para Kestrel no arquivo de appsettings.json (https://localhost:9999) e não https://localhost:7777.

Considere o Kestrel ponto de extremidade específico configurado como uma variável de ambiente:

set Kestrel__Endpoints__Https__Url=https://localhost:8888

Na variável de ambiente anterior, Https é o nome do Kestrel endpoint específico. O arquivo anterior appsettings.json também define um endpoint Kestrel específico chamado Https. Por padrão, as variáveis de ambiente que usam o provedor de configuração Variáveis de Ambiente são lidas após appsettings.{Environment}.json, portanto, a variável de ambiente anterior é usada para a extremidade de Https.

GetValue

ConfigurationBinder.GetValue extrai um único valor da configuração com uma chave especificada e o converte para o tipo especificado:

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

No código anterior, se NumberKey não for encontrado na configuração, o valor padrão de 99 é usado.

GetSection, GetChildren e Existe

Para os exemplos a seguir, considere o seguinte MySubsection.json arquivo:

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

O código a seguir adiciona MySubsection.json aos provedores de configuração:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MySubsection.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

GetSection

IConfiguration.GetSection Retorna uma subseção de configuração com a chave de subseção especificada.

O código a seguir retorna valores para section1:

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

O código a seguir retorna valores para section2:subsection0:

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSection nunca mais volta null. Se uma seção correspondente não for encontrada, um vazio IConfigurationSection será retornado.

Quando GetSection retorna uma seção correspondente, Value não é preenchida. Os Key e Path são devolvidos quando a seção existe.

GetChildren e existe

O código a seguir chama IConfiguration.GetChildren e retorna valores para section2:subsection0:

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = "";
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

O código anterior chama ConfigurationExtensions.Exists para verificar se a seção existe:

Vincular uma matriz

O ConfigurationBinder.Bind suporta a vinculação de matrizes a objetos usando índices de matriz em chaves de configuração. Qualquer formato de matriz que exponha um segmento de chave numérica é capaz de se associar a matrizes de classes POCO.

Considere MyArray.json a partir do download de exemplo:

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

O código a seguir adiciona MyArray.json aos provedores de configuração:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MyArray.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

O código a seguir lê a configuração e exibe os valores:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample? _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
       _array = Config.GetSection("array").Get<ArrayExample>();
        if (_array == null)
        {
            throw new ArgumentNullException(nameof(_array));
        }
        string s = String.Empty;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}
public class ArrayExample
{
    public string[]? Entries { get; set; } 
}

O código anterior retorna a seguinte saída:

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

Na saída anterior, o Índice 3 tem valor value40, correspondente a "4": "value40", em MyArray.json. Os índices de matriz acoplados são contínuos e não vinculados ao índice de chave de configuração. O fichário de configuração não é capaz de vincular valores nulos ou criar entradas nulas em objetos acoplados.

Provedor de configuração personalizada

O aplicativo de exemplo demonstra como criar um provedor de configuração básica que lê pares chave-valor de configuração de um banco de dados usando o Entity Framework (EF).

O provedor tem as seguintes características:

  • O banco de dados EF in-memory é usado para fins de demonstração. Para usar um banco de dados que exija uma cadeia de conexão, implemente um secundário ConfigurationBuilder para fornecer a cadeia de conexão de outro provedor de configuração.
  • O provedor lê uma tabela de banco de dados na configuração na inicialização. O provedor não consulta o banco de dados por chave.
  • A funcionalidade de recarregar ao alterar não está implementada, portanto, fazer alterações na base de dados após o início da aplicação não tem efeito na configuração da aplicação.

Defina uma EFConfigurationValue entidade para armazenar valores de configuração no banco de dados.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; } = String.Empty;
    public string Value { get; set; } = String.Empty;
}

Adicione um EFConfigurationContext para armazenar e acessar os valores configurados.

EFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}

Crie uma classe que implemente o IConfigurationSource.

EFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) => _optionsAction = optionsAction;

    public IConfigurationProvider Build(IConfigurationBuilder builder) => new EFConfigurationProvider(_optionsAction);
}

Crie o provedor de configuração personalizada herdando do ConfigurationProvider. O provedor de configuração inicializa o banco de dados quando ele está vazio. Como as chaves de configuração não diferenciam maiúsculas de minúsculas, o dicionário usado para inicializar o banco de dados é criado com o comparador que não diferencia maiúsculas de minúsculas (StringComparer.OrdinalIgnoreCase).

EFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            if (dbContext == null || dbContext.Values == null)
            {
                throw new Exception("Null DB context");
            }
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues =
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                    { "quote1", "I aim to misbehave." },
                    { "quote2", "I swallowed a bug." },
                    { "quote3", "You can't stop the signal, Mal." }
            };

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue
            {
                Id = kvp.Key,
                Value = kvp.Value
            })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

Um AddEFConfiguration método de extensão permite adicionar a fonte de configuração a um ConfigurationBuilder.

Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
               this IConfigurationBuilder builder,
               Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

O código a seguir mostra como usar o personalizado EFConfigurationProvider em Program.cs:

//using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEFConfiguration(
    opt => opt.UseInMemoryDatabase("InMemoryDb"));

var app = builder.Build();

app.Run();

Configuração de acesso com injeção de dependência (DI)

Usando a Injeção de Dependência (DI), a configuração pode ser injetada em serviços ao resolver o IConfiguration serviço:

public class Service
{
    private readonly IConfiguration _config;

    public Service(IConfiguration config) =>
        _config = config;

    public void DoSomething()
    {
        var configSettingValue = _config["ConfigSetting"];

        // ...
    }
}

Para obter informações sobre como aceder a valores usando IConfiguration, consulte GetValue e GetSection, GetChildren e Exists neste artigo.

Configuração de acesso nas páginas Razor

O código a seguir exibe dados de configuração em uma Razor Página:

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

No código a seguir, MyOptions é adicionado ao contêiner de serviço com Configure e vinculado à configuração:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions"));

var app = builder.Build();

A marcação a seguir usa a @injectRazor diretiva para resolver e exibir os valores de opções:

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@using SampleApp.Models
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

Configuração de acesso em um arquivo de exibição MVC

O código a seguir exibe dados de configuração em uma exibição MVC:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

Configuração de acesso em Program.cs

O código seguinte acede à configuração no arquivo Program.cs.

var builder = WebApplication.CreateBuilder(args);

var key1 = builder.Configuration.GetValue<string>("KeyOne");

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

var key2 = app.Configuration.GetValue<int>("KeyTwo");
var key3 = app.Configuration.GetValue<bool>("KeyThree");

app.Logger.LogInformation("KeyOne: {KeyOne}", key1);
app.Logger.LogInformation("KeyTwo: {KeyTwo}", key2);
app.Logger.LogInformation("KeyThree: {KeyThree}", key3);

app.Run();

No appsettings.json exemplo anterior:

{
  ...
  "KeyOne": "Key One Value",
  "KeyTwo": 1999,
  "KeyThree": true
}

Configurar opções com um delegado

As opções configuradas num objeto delegado substituem os valores definidos nos provedores de configuração.

No código a seguir, um IConfigureOptions<TOptions> serviço é adicionado ao contêiner de serviço. Ele usa um delegado para configurar valores para MyOptions:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "Value configured in delegate";
    myOptions.Option2 = 500;
});

var app = builder.Build();

O código a seguir exibe os valores de opções:

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

No exemplo anterior, os valores de Option1 e Option2 são especificados em appsettings.json e depois substituídos pelo delegado configurado.

Configuração de host versus aplicativo

Antes de o aplicativo ser configurado e iniciado, um host é configurado e iniciado. O host é responsável pela inicialização do aplicativo e gerenciamento do tempo de vida. Tanto o aplicativo quanto o host são configurados usando os provedores de configuração descritos neste tópico. Os pares chave-valor de configuração do host também estão incluídos na configuração do aplicativo. Para obter mais informações sobre como os provedores de configuração são usados quando o host é criado e como as fontes de configuração afetam a configuração do host, consulte ASP.NET Visão geral dos fundamentos principais.

Configuração padrão do host

Para obter detalhes sobre a configuração padrão ao usar o host da Web, consulte a versão ASP.NET Core 2.2 deste tópico.

  • A configuração do host é fornecida a partir de:
    • Variáveis de ambiente prefixadas com DOTNET_ (por exemplo, DOTNET_ENVIRONMENT) usando o provedor de configuração de variáveis de ambiente. O prefixo (DOTNET_) é removido quando os pares chave-valor de configuração são carregados.
    • Argumentos de linha de comando usando o provedor de configuração de linha de comando .
  • A configuração padrão do host da Web é estabelecida (ConfigureWebHostDefaults):
    • Kestrel é usado como o servidor web e configurado usando os fornecedores de configuração da aplicação.
    • Adicione o Middleware de Filtragem de Host.
    • Adicione o Middleware de Cabeçalhos Encaminhados se a variável de ambiente ASPNETCORE_FORWARDEDHEADERS_ENABLED estiver definida como true.
    • Habilite a integração com o IIS.

Outra configuração

Este tópico refere-se apenas à configuração do aplicativo. Outros aspetos da execução e hospedagem de aplicativos ASP.NET Core são configurados usando arquivos de configuração não abordados neste tópico:

As variáveis de ambiente definidas em launchSettings.json substituem as definidas no ambiente do sistema.

Para obter mais informações sobre como migrar a configuração do aplicativo de versões anteriores do ASP.NET, consulte Migrar configuração para o ASP.NET Core.

Adicionar configuração a partir de um conjunto externo

Uma implementação IHostingStartup permite adicionar aprimoramentos a um aplicativo na inicialização a partir de um assembly externo fora da classe Startup do aplicativo. Para obter mais informações, consulte Usar assemblies de inicialização de hospedagem no ASP.NET Core.

Recursos adicionais

Kestrel Configuração do ponto final

Kestrel A configuração específica do ponto de extremidade substitui todas as configurações de ponto de extremidade interservidor. As configurações de endpoint entre servidores incluem:

Considere o seguinte appsettings.json arquivo usado em um aplicativo Web ASP.NET Core:

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

Quando a marcação realçada anterior é usada em um aplicativo Web ASP.NET Core e o aplicativo é iniciado na linha de comando com a seguinte configuração de ponto de extremidade entre servidores:

dotnet run --urls="https://localhost:7777"

Kestrel liga-se ao ponto de extremidade configurado especificamente para Kestrel no arquivo de appsettings.json (https://localhost:9999) e não https://localhost:7777.

Considere o Kestrel ponto de extremidade específico configurado como uma variável de ambiente:

set Kestrel__Endpoints__Https__Url=https://localhost:8888

Na variável de ambiente anterior, Https é o nome do Kestrel endpoint específico. O arquivo anterior appsettings.json também define um endpoint Kestrel específico chamado Https. Por padrão, as variáveis de ambiente que usam o provedor de configuração Variáveis de Ambiente são lidas após appsettings.{Environment}.json, portanto, a variável de ambiente anterior é usada para a extremidade de Https.

GetValue

ConfigurationBinder.GetValue Extrai um único valor da configuração com uma chave especificada e o converte para o tipo especificado. Este método é um método de extensão para IConfiguration:

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

No código anterior, se NumberKey não for encontrado na configuração, o valor padrão de 99 é usado.

GetSection, GetChildren e Existe

Para os exemplos a seguir, considere o seguinte MySubsection.json arquivo:

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

O código a seguir adiciona MySubsection.json aos provedores de configuração:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("MySubsection.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

GetSection

IConfiguration.GetSection Retorna uma subseção de configuração com a chave de subseção especificada.

O código a seguir retorna valores para section1:

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

O código a seguir retorna valores para section2:subsection0:

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSection nunca mais volta null. Se uma seção correspondente não for encontrada, um vazio IConfigurationSection será retornado.

Quando GetSection retorna uma seção correspondente, Value não é preenchida. Os Key e Path são devolvidos quando a seção existe.

GetChildren e existe

O código a seguir chama IConfiguration.GetChildren e retorna valores para section2:subsection0:

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = null;
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new System.Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

O código anterior chama ConfigurationExtensions.Exists para verificar se a seção existe:

Vincular uma matriz

O ConfigurationBinder.Bind suporta a vinculação de matrizes a objetos usando índices de matriz em chaves de configuração. Qualquer formato de matriz que exponha um segmento de chave numérica é capaz de se associar a matrizes de classes POCO.

Considere MyArray.json a partir do download de exemplo:

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

O código a seguir adiciona MyArray.json aos provedores de configuração:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("MyArray.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

O código a seguir lê a configuração e exibe os valores:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = null;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}

O código anterior retorna a seguinte saída:

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

Na saída anterior, o Índice 3 tem valor value40, correspondente a "4": "value40", em MyArray.json. Os índices de matriz acoplados são contínuos e não vinculados ao índice de chave de configuração. O fichário de configuração não é capaz de vincular valores nulos ou criar entradas nulas em objetos acoplados

O código a seguir carrega a configuração array:entries com o método de extensão AddInMemoryCollection:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var arrayDict = new Dictionary<string, string>
        {
            {"array:entries:0", "value0"},
            {"array:entries:1", "value1"},
            {"array:entries:2", "value2"},
            //              3   Skipped
            {"array:entries:4", "value4"},
            {"array:entries:5", "value5"}
        };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(arrayDict);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

O código a arrayDictDictionary seguir lê a configuração no e exibe os valores:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = null;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}

O código anterior retorna a seguinte saída:

Index: 0  Value: value0
Index: 1  Value: value1
Index: 2  Value: value2
Index: 3  Value: value4
Index: 4  Value: value5

O índice #3 no objeto acoplado contém os dados de configuração para a array:4 chave de configuração e seu valor de value4. Quando os dados de configuração que contêm uma matriz são vinculados, os índices de matriz nas chaves de configuração são usados para iterar os dados de configuração ao criar o objeto. Um valor nulo não pode ser retido nos dados de configuração e uma entrada com valor nulo não é criada em um objeto acoplado quando uma matriz em chaves de configuração ignora um ou mais índices.

O item de configuração ausente para o índice #3 pode ser fornecido antes da ArrayExample vinculação à instância por qualquer provedor de configuração que leia o par chave/valor do índice #3. Considere o seguinte Value3.json arquivo do download de exemplo:

{
  "array:entries:3": "value3"
}

O código a seguir inclui a configuração para Value3.json e o arrayDictDictionary:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var arrayDict = new Dictionary<string, string>
        {
            {"array:entries:0", "value0"},
            {"array:entries:1", "value1"},
            {"array:entries:2", "value2"},
            //              3   Skipped
            {"array:entries:4", "value4"},
            {"array:entries:5", "value5"}
        };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(arrayDict);
                config.AddJsonFile("Value3.json",
                                    optional: false, reloadOnChange: false);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

O código a seguir lê a configuração anterior e exibe os valores:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = null;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}

O código anterior retorna a seguinte saída:

Index: 0  Value: value0
Index: 1  Value: value1
Index: 2  Value: value2
Index: 3  Value: value3
Index: 4  Value: value4
Index: 5  Value: value5

Provedores de configuração personalizados não são necessários para implementar a vinculação de matriz.

Provedor de configuração personalizada

Advertência

Este artigo mostra o uso de cadeias de conexão. Com um banco de dados local, o usuário não precisa ser autenticado, mas na produção, as cadeias de conexão às vezes incluem uma senha para autenticar. Uma credencial de senha de proprietário de recurso (ROPC) é um risco de segurança que deve ser evitado em bancos de dados de produção. Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações sobre autenticação para aplicativos implantados em ambientes de teste ou produção, consulte Fluxos de autenticação segura.

O aplicativo de exemplo demonstra como criar um provedor de configuração básica que lê pares chave-valor de configuração de um banco de dados usando o Entity Framework (EF).

O provedor tem as seguintes características:

  • O banco de dados EF in-memory é usado para fins de demonstração. Para usar um banco de dados que exija uma cadeia de conexão, implemente um secundário ConfigurationBuilder para fornecer a cadeia de conexão de outro provedor de configuração.
  • O provedor lê uma tabela de banco de dados na configuração na inicialização. O provedor não consulta o banco de dados por chave.
  • A funcionalidade de recarregar ao alterar não está implementada, portanto, fazer alterações na base de dados após o início da aplicação não tem efeito na configuração da aplicação.

Defina uma EFConfigurationValue entidade para armazenar valores de configuração no banco de dados.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; }
    public string Value { get; set; }
}

Adicione um EFConfigurationContext para armazenar e acessar os valores configurados.

EFConfigurationProvider/EFConfigurationContext.cs:

// using Microsoft.EntityFrameworkCore;

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values { get; set; }
}

Crie uma classe que implemente o IConfigurationSource.

EFConfigurationProvider/EFConfigurationSource.cs:

// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction)
    {
        _optionsAction = optionsAction;
    }

    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new EFConfigurationProvider(_optionsAction);
    }
}

Crie o provedor de configuração personalizada herdando do ConfigurationProvider. O provedor de configuração inicializa o banco de dados quando ele está vazio. Como as chaves de configuração não diferenciam maiúsculas de minúsculas, o dicionário usado para inicializar o banco de dados é criado com o comparador que não diferencia maiúsculas de minúsculas (StringComparer.OrdinalIgnoreCase).

EFConfigurationProvider/EFConfigurationProvider.cs:

// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues = 
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                { "quote1", "I aim to misbehave." },
                { "quote2", "I swallowed a bug." },
                { "quote3", "You can't stop the signal, Mal." }
            };

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue 
                {
                    Id = kvp.Key,
                    Value = kvp.Value
                })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

Um AddEFConfiguration método de extensão permite adicionar a fonte de configuração a um ConfigurationBuilder.

Extensions/EntityFrameworkExtensions.cs:

// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
        this IConfigurationBuilder builder, 
        Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

O código a seguir mostra como usar o personalizado EFConfigurationProvider em Program.cs:

// using Microsoft.EntityFrameworkCore;

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddEFConfiguration(
                options => options.UseInMemoryDatabase("InMemoryDb"));
        })

Configuração de acesso na inicialização

O código a seguir exibe dados de configuração nos Startup métodos.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
        Console.WriteLine($"MyKey : {Configuration["MyKey"]}");
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        Console.WriteLine($"Position:Title : {Configuration["Position:Title"]}");

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

Para obter um exemplo de acesso à configuração usando métodos de conveniência de inicialização, consulte Inicialização do aplicativo: métodos de conveniência.

Configuração de acesso nas páginas Razor

O código a seguir exibe dados de configuração em uma Razor Página:

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

No código a seguir, MyOptions é adicionado ao contêiner de serviço com Configure e vinculado à configuração:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));

    services.AddRazorPages();
}

A marcação a seguir usa a @injectRazor diretiva para resolver e exibir os valores de opções:

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

Configuração de acesso em um arquivo de exibição MVC

O código a seguir exibe dados de configuração em uma exibição MVC:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

Configurar opções com um delegado

As opções configuradas num objeto delegado substituem os valores definidos nos provedores de configuração.

A configuração de opções com um delegado é demonstrada como Exemplo 2 no aplicativo de exemplo.

No código a seguir, um IConfigureOptions<TOptions> serviço é adicionado ao contêiner de serviço. Ele usa um delegado para configurar valores para MyOptions:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(myOptions =>
    {
        myOptions.Option1 = "Value configured in delegate";
        myOptions.Option2 = 500;
    });

    services.AddRazorPages();
}

O código a seguir exibe os valores de opções:

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

No exemplo anterior, os valores de Option1 e Option2 são especificados em appsettings.json e depois substituídos pelo delegado configurado.

Configuração de host versus aplicativo

Antes de o aplicativo ser configurado e iniciado, um host é configurado e iniciado. O host é responsável pela inicialização do aplicativo e gerenciamento do tempo de vida. Tanto o aplicativo quanto o host são configurados usando os provedores de configuração descritos neste tópico. Os pares chave-valor de configuração do host também estão incluídos na configuração do aplicativo. Para obter mais informações sobre como os provedores de configuração são usados quando o host é criado e como as fontes de configuração afetam a configuração do host, consulte ASP.NET Visão geral dos fundamentos principais.

Configuração padrão do host

Para obter detalhes sobre a configuração padrão ao usar o host da Web, consulte a versão ASP.NET Core 2.2 deste tópico.

  • A configuração do host é fornecida a partir de:
    • Variáveis de ambiente prefixadas com DOTNET_ (por exemplo, DOTNET_ENVIRONMENT) usando o provedor de configuração de variáveis de ambiente. O prefixo (DOTNET_) é removido quando os pares chave-valor de configuração são carregados.
    • Argumentos de linha de comando usando o provedor de configuração de linha de comando.
  • A configuração padrão do host da Web é estabelecida (ConfigureWebHostDefaults):
    • Kestrel é usado como o servidor web e configurado usando os fornecedores de configuração da aplicação.
    • Adicione o Middleware de Filtragem de Host.
    • Adicione o Middleware de Cabeçalhos Encaminhados se a variável de ambiente ASPNETCORE_FORWARDEDHEADERS_ENABLED estiver definida como true.
    • Habilite a integração com o IIS.

Outra configuração

Este tópico refere-se apenas à configuração do aplicativo. Outros aspetos da execução e hospedagem de aplicativos ASP.NET Core são configurados usando arquivos de configuração não abordados neste tópico:

As variáveis de ambiente definidas em launchSettings.json substituem as definidas no ambiente do sistema.

Para obter mais informações sobre como migrar a configuração do aplicativo de versões anteriores do ASP.NET, consulte Migrar configuração para o ASP.NET Core.

Adicionar configuração a partir de um conjunto externo

Uma implementação IHostingStartup permite adicionar aprimoramentos a um aplicativo na inicialização a partir de um assembly externo fora da classe Startup do aplicativo. Para obter mais informações, consulte Usar assemblies de inicialização de hospedagem no ASP.NET Core.

Recursos adicionais