Configurazione in ASP.NET Core
Di Rick Anderson e Kirk Larkin
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere i criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Importante
Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Per la versione corrente, vedere la versione .NET 9 di questo articolo.
La configurazione dell'applicazione in ASP.NET Core viene eseguita usando uno o più provider di configurazione. I provider di configurazione leggono i dati di configurazione da coppie chiave-valore usando diverse origini di configurazione:
- File di impostazioni, ad esempio
appsettings.json
- Variabili di ambiente
- Azure Key Vault
- Configurazione app di Azure
- Argomenti della riga di comando
- Provider personalizzati, installati o creati
- File della directory
- Oggetti .NET in memoria
Questo articolo offre informazioni sulla configurazione in ASP.NET Core. Per informazioni sull'uso della configurazione nelle app console, vedere Configurazione di .NET.
Per Blazor indicazioni sulla configurazione, che aggiunge o sostituisce le linee guida in questo nodo, vedere ASP.NET Configurazione coreBlazor.
Configurazione dell'applicazione e dell'host
Le app ASP.NET Core configurano e avviano un host. L'host è responsabile della gestione dell'avvio e della durata delle app. I modelli di ASP.NET Core creano un WebApplicationBuilder che contiene l'host. Sebbene parte della configurazione possa essere eseguita sia nel provider di configurazione dell'host che nel provider di configurazione dell'applicazione, in generale solo la configurazione necessaria all'host deve essere eseguita nella configurazione dell'host.
La configurazione dell'applicazione è la priorità più alta ed è descritta nel dettaglio nella sezione successiva. La configurazione dell'host segue la configurazione dell'applicazione ed è descritta in questo articolo.
Origini della configurazione dell'applicazione predefinite
Le app Web ASP.NET Core create con dotnet new o Visual Studio generano il codice seguente:
var builder = WebApplication.CreateBuilder(args);
WebApplication.CreateBuilder inizializza una nuova istanza della classe WebApplicationBuilder con valori predefiniti preconfigurati. Il WebApplicationBuilder
(builder
) inizializzato offre la configurazione predefinita per l'app nell'ordine seguente, dalla priorità più alta a quella più bassa:
- Argomenti della riga di comando che usano il provider di configurazione della riga di comando.
- Variabili di ambiente senza prefisso che usano il provider di configurazione delle variabili di ambiente senza prefisso.
- Segreti dell'utente quando l'app viene eseguita nell'ambiente
Development
. appsettings.{Environment}.json
usando il provider di configurazione JSON. Ad esempio,appsettings.Production.json
eappsettings.Development.json
.- appsettings.json usando il provider di configurazione JSON.
- Un fallback alla configurazione dell'host descritto nella sezione successiva.
Origini della configurazione dell'host predefinite
L'elenco seguente contiene le origini di configurazione host predefinite dalla priorità più alta alla più bassa per WebApplicationBuilder:
- Argomenti della riga di comando che usano il provider di configurazione della riga di comando
- Variabili di ambiente con prefisso
DOTNET_
che usano il provider di configurazione delle variabili di ambiente. - Variabili di ambiente con prefisso
ASPNETCORE_
che usano il provider di configurazione delle variabili di ambiente.
Per l'host generico .NET e l'host Web, le origini di configurazione host predefinite dalla priorità più alta alla più bassa sono:
- Variabili di ambiente con prefisso
ASPNETCORE_
che usano il provider di configurazione delle variabili di ambiente. - Argomenti della riga di comando che usano il provider di configurazione della riga di comando
- Variabili di ambiente con prefisso
DOTNET_
che usano il provider di configurazione delle variabili di ambiente.
Quando un valore di configurazione viene impostato nella configurazione dell'host e dell'applicazione, viene usata la configurazione dell'applicazione.
Variabili dell'host
Le variabili seguenti vengono bloccate in anticipo durante l'inizializzazione dei generatori di host e non possono essere influenzate dalla configurazione dell'applicazione:
- Nome applicazione
- Nome dell'ambiente, ad esempio
Development
,Production
eStaging
- Radice del contenuto
- Radice Web
- Se cercare gli assembly di avvio di hosting e quali assembly cercare.
- Variabili lette dal codice dell'app e della libreria da hostBuilderContext.Configuration nei callback IHostBuilder.ConfigureAppConfiguration.
Ogni altra impostazione dell'host viene letta dalla configurazione dell'applicazione anziché dalla configurazione dell'host.
URLS
è una delle numerose impostazioni dell'host comuni che non è un'impostazione bootstrap. Come tutte le altre impostazioni dell'host non presenti nell'elenco precedente, URLS
viene letta successivamente dalla configurazione dell'applicazione. Poiché la configurazione dell'host è un fallback per la configurazione dell'applicazione, la configurazione dell'host può essere usata per impostare URLS
, ma verrà sostituita da qualsiasi origine di configurazione nella configurazione dell'applicazione, come appsettings.json
.
Per altre informazioni, vedere Modificare la radice del contenuto, il nome dell'app e l'ambiente e Modificare la radice del contenuto, il nome dell'app e l'ambiente in base alle variabili di ambiente o alla riga di comando
Le sezioni rimanenti di questo articolo fanno riferimento alla configurazione dell'applicazione.
Provider di configurazione dell'applicazione
Il codice seguente visualizza i provider di configurazione abilitati nell'ordine in cui sono stati aggiunti:
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);
}
}
L'elenco precedente delle origini di configurazione predefinite dalla priorità più alta alla priorità più bassa mostra i provider nell'ordine opposto in cui vengono aggiunti all'applicazione generata dal modello. Ad esempio, il provider di configurazione JSON viene aggiunto prima del provider di configurazione della riga di comando.
I provider di configurazione aggiunti successivamente hanno priorità più alta e sostituiscono le impostazioni delle chiavi precedenti. Ad esempio, se MyKey
è impostato sia in appsettings.json
che nell'ambiente, viene usato il valore dell'ambiente. Quando si usano i provider di configurazione predefiniti, il provider di configurazione della riga di comando sostituisce tutti gli altri provider.
Per altre informazioni su CreateBuilder
, vedere Impostazioni predefinite del generatore.
appsettings.json
Considerare il file appsettings.json
seguente:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Il codice seguente del download di esempio visualizza diverse impostazioni delle configurazioni precedenti:
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}");
}
}
Il JsonConfigurationProvider predefinito carica la configurazione nell'ordine seguente:
appsettings.json
appsettings.{Environment}.json
: ad esempio, i fileappsettings.Production.json
eappsettings.Development.json
. La versione dell'ambiente del file viene caricata in base a IHostingEnvironment.EnvironmentName. Per altre informazioni, vedere Usare più ambienti in ASP.NET Core.
I valori appsettings.{Environment}.json
sostituiscono le chiavi in appsettings.json
. Ad esempio, per impostazione predefinita:
- Nello sviluppo la configurazione
appsettings.Development.json
sovrascrive i valori trovati inappsettings.json
. - Nella produzione la configurazione
appsettings.Production.json
sovrascrive i valori trovati inappsettings.json
. Ad esempio, durante la distribuzione dell'app in Azure.
Se è necessario garantire un valore di configurazione, vedere GetValue. L'esempio precedente legge solo le stringhe e non supporta un valore predefinito.
Quando si usa la configurazione predefinita, i file appsettings.json
e appsettings.{Environment}.json
sono abilitati con reloadOnChange: true. Le modifiche apportate al appsettings.json
file e appsettings.{Environment}.json
dopo l'avvio dell'app vengono lette dal provider di configurazione JSON.
Commenti in appsettings.json
I commenti in appsettings.json
e appsettings.{Environment}.json
i file sono supportati usando commenti in stile JavaScript o C#.
Associare dati di configurazione gerarchici usando il modello di opzioni
Il modo preferito per leggere i valori di configurazione correlati prevede l'uso del modello di opzioni. Ad esempio, per leggere i valori di configurazione seguenti:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Creare la classe PositionOptions
seguente:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
}
Una classe di opzioni:
- Deve essere non astratta con un costruttore pubblico senza parametri.
- Tutte le proprietà di lettura/scrittura pubbliche del tipo sono associate.
- I campi non sono associati. Nel codice precedente
Position
non è associato. Il campoPosition
viene usato in modo che la stringa"Position"
non debba essere hardcoded nell'app quando la classe viene associata a un provider di configurazione.
Il codice seguente:
- Chiama ConfigurationBinder.Bind per associare la classe
PositionOptions
alla sezionePosition
. - Visualizza i dati di configurazione di
Position
.
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}");
}
}
Nel codice precedente, per impostazione predefinita, le modifiche apportate al file di configurazione JSON dopo l'avvio dell'app vengono lette.
ConfigurationBinder.Get<T>
associa e restituisce il tipo specificato. ConfigurationBinder.Get<T>
può risultare più utile rispetto all'uso di ConfigurationBinder.Bind
. Il codice seguente mostra come usare ConfigurationBinder.Get<T>
con la classe PositionOptions
:
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}");
}
}
Nel codice precedente, per impostazione predefinita, le modifiche apportate al file di configurazione JSON dopo l'avvio dell'app vengono lette.
Un approccio alternativo quando si usa il modello opzioni consiste nell'associare la sezione Position
e aggiungerla al contenitore del servizio di inserimento di dipendenze. Nel codice seguente PositionOptions
viene aggiunta al contenitore del servizio con Configure e associata alla configurazione:
using ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<PositionOptions>(
builder.Configuration.GetSection(PositionOptions.Position));
var app = builder.Build();
Quando si usa il codice precedente, il codice seguente legge le opzioni di posizione:
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}");
}
}
Nel codice precedente le modifiche al file di configurazione JSON dopo l'avvio dell'app non vengono lette. Per leggere le modifiche dopo l'avvio dell'app, usare IOptionsSnapshot.
Quando si usa la configurazione predefinita, i file appsettings.json
e appsettings.{Environment}.json
sono abilitati con reloadOnChange: true. Le modifiche apportate al appsettings.json
file e appsettings.{Environment}.json
dopo l'avvio dell'app vengono lette dal provider di configurazione JSON.
Per informazioni sull'aggiunta di file di configurazione JSON aggiuntivi, vedere Provider di configurazione JSON in questo documento.
Combinazione della raccolta di servizi
Considerare il codice seguente che registra i servizi e configura le opzioni:
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();
I gruppi correlati di registrazioni possono essere spostati in un metodo di estensione per registrare i servizi. Ad esempio, i servizi di configurazione vengono aggiunti alla classe seguente:
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;
}
}
}
I servizi rimanenti vengono registrati in una classe simile. Il codice seguente usa i nuovi metodi di estensione per registrare i servizi:
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: ogni metodo di estensione services.Add{GROUP_NAME}
aggiunge e configura potenzialmente i servizi. Ad esempio, AddControllersWithViews aggiunge i controller MVC dei servizi con visualizzazioni richiesti e AddRazorPages aggiunge le pagina Razor dei servizi richieste.
Sicurezza e segreti dell'utente
Linee guida per i dati di configurazione:
- Non archiviare mai la password o altri dati sensibili nel codice del provider di configurazione o in file di configurazione di testo normale. Per l'archiviazione di segreti per lo sviluppo, è possibile usare lo strumento Secret Manager.
- Non usare i segreti di produzione in ambienti di sviluppo o di test.
- Specificare i segreti all'esterno del progetto in modo che non possano essere inavvertitamente inviati a un repository del codice sorgente.
- Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni, vedere Proteggere i flussi di autenticazione.
Per impostazione predefinita, l'origine di configurazione dei segreti utente viene registrata dopo le origini di configurazione JSON. Pertanto, le chiavi dei segreti dell'utente hanno la precedenza sulle chiavi in appsettings.json
e appsettings.{Environment}.json
.
Per altre informazioni sull'archiviazione di password o altri dati sensibili:
- Usare più ambienti in ASP.NET Core
- Archiviazione sicura di segreti dell'app durante lo sviluppo in ASP.NET Core: include consigli sull'uso delle variabili di ambiente per l'archiviazione dei dati sensibili. Lo strumento Secret Manager usa il provider di configurazione file per archiviare i segreti utente in un file JSON nel sistema locale.
- Azure Key Vault archivia in modo sicuro i segreti delle app ASP.NET Core. Per altre informazioni, vedere Provider di configurazione di Azure Key Vault in ASP.NET Core.
Variabili di ambiente senza prefisso
Le variabili di ambiente senza prefisso sono variabili di ambiente diverse da quelle precedute da ASPNETCORE_
o DOTNET_
. Ad esempio, i modelli di applicazione Web ASP.NET Core impostano "ASPNETCORE_ENVIRONMENT": "Development"
in launchSettings.json
. Per altre informazioni sulle variabili di ambiente ASPNETCORE_
e DOTNET_
, vedere:
- Elenco delle origini di configurazione predefinite dalla priorità più alta alla priorità più bassa incluse le variabili di ambiente senza prefisso, con prefisso
ASPNETCORE_
e con prefissoDOTNETCORE_
. - Variabili di ambiente
DOTNET_
usate all'esterno di Microsoft.Extensions.Hosting.
Quando si usa la configurazione predefinita, EnvironmentVariablesConfigurationProvider carica la configurazione dalle coppie chiave-valore delle variabili di ambiente dopo la lettura di appsettings.json
, appsettings.{Environment}.json
e dei segreti dell'utente. Therefore, i valori di chiave letti dall'ambiente sostituiscono i valori letti da appsettings.json
, appsettings.{Environment}.json
e dai segreti dell'utente.
Il separatore :
non funziona con le chiavi gerarchiche delle variabili di ambiente in tutte le piattaforme. Ad esempio, il :
separatore non è supportato da Bash. Il doppio carattere di sottolineatura, __
, è:
- Supportato da tutte le piattaforme.
- Sostituito automaticamente da due punti,
:
.
I comandi seguenti:
- Impostano le chiavi e i valori di ambiente dell'esempio precedente in Windows.
- Testano le impostazioni quando viene usato il download di esempio. Il comando
dotnet run
deve essere eseguito nella directory del progetto.
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run
Le impostazioni dell'ambiente precedenti:
- Sono impostate solo nei processi avviati dalla finestra di comando in cui sono stati impostate.
- Non verranno lette dai browser avviati con Visual Studio.
I comandi setx seguenti possono essere usati per impostare le chiavi e i valori di ambiente in Windows. A differenza di set
, le impostazioni setx
vengono mantenute. /M
imposta la variabile nell'ambiente di sistema. Se non viene usata l'opzione /M
, viene impostata una variabile di ambiente dell'utente.
setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M
Per verificare che i comandi precedenti sostituiscano appsettings.json
e appsettings.{Environment}.json
:
- Con Visual Studio: uscire e riavviare Visual Studio.
- Con l'interfaccia della riga di comando: avviare una nuova finestra di comando e immettere
dotnet run
.
Chiamare AddEnvironmentVariables con una stringa per specificare un prefisso per le variabili di ambiente:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
var app = builder.Build();
Nel codice precedente:
builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_")
viene aggiunto dopo i provider di configurazione predefiniti. Per un esempio di ordinamento dei provider di configurazione, vedere Provider di configurazione JSON.- Le variabili di ambiente impostate con il prefisso
MyCustomPrefix_
sostituiscono i provider di configurazione predefiniti. Sono incluse le variabili di ambiente senza il prefisso.
Il prefisso viene rimosso quando vengono lette le coppie chiave-valore della configurazione.
I comandi seguenti testano il prefisso personalizzato:
set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run
La configurazione predefinita carica le variabili di ambiente e gli argomenti della riga di comando con prefisso DOTNET_
e ASPNETCORE_
. I prefissi DOTNET_
e ASPNETCORE_
vengono usati da ASP.NET Core per la configurazione dell'host e dell'app, ma non per la configurazione dell'utente. Per altre informazioni sulla configurazione dell'host e dell'app, vedere Host generico .NET.
In Servizio app di Azure selezionare Nuova impostazione applicazione nella pagina Impostazioni > Configurazione. Le impostazioni applicazione del Servizio app di Azure sono:
- Crittografato in e rest trasmesso tramite un canale crittografato.
- Esposte come variabili di ambiente.
Per altre informazioni, vedere App di Azure: Eseguire l'override della configurazione delle app usando il portale di Azure.
Per informazioni sulle stringhe di connessione del database di Azure, vedere Prefissi della stringa di connessione.
Denominazione delle variabili di ambiente
I nomi delle variabili di ambiente riflettono la struttura di un file appsettings.json
. Ogni elemento nella gerarchia è separato da un doppio carattere di sottolineatura (preferibile) o due punti. Quando la struttura dell'elemento include una matrice, l'indice della matrice deve essere considerato come un nome di elemento aggiuntivo in questo percorso. Si consideri il file appsettings.json
seguente e i relativi valori equivalenti rappresentati come variabili di 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"
}
]
}
variabili di 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
Variabili di ambiente impostate nel file launchSettings.json generato
Variabili di ambiente impostate in launchSettings.json
sostituiscono quelle impostate nell'ambiente di sistema. Ad esempio, i modelli Web ASP.NET Core generano un file launchSettings.json
che imposta la configurazione dell'endpoint su:
"applicationUrl": "https://localhost:5001;http://localhost:5000"
La configurazione di applicationUrl
imposta la variabile di ambiente ASPNETCORE_URLS
e sostituisce i valori impostati nell'ambiente.
Carattere di escape per le variabili di ambiente in Linux
In Linux il valore delle variabili di ambiente degli URL deve essere preceduto da un carattere di escape in modo che systemd
possa analizzarle. Usare lo strumento linux systemd-escape
che restituisce http:--localhost:5001
groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001
Visualizzare le variabili di ambiente
Il codice seguente visualizza le variabili di ambiente e i valori all'avvio dell'applicazione, utile durante il debug delle impostazioni di ambiente:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
foreach (var c in builder.Configuration.AsEnumerable())
{
Console.WriteLine(c.Key + " = " + c.Value);
}
Riga di comando
Quando si usa la configurazione predefinita, CommandLineConfigurationProvider carica la configurazione dalle coppie chiave-valore degli argomenti della riga di comando dopo le origini di configurazione seguenti:
- File
appsettings.json
eappsettings.{Environment}.json
. - Segreti dell'app nell'ambiente di sviluppo.
- variabili di ambiente.
Per impostazione predefinita, i valori di configurazione impostati nella riga di comando sostituiscono i valori di configurazione impostati con tutti gli altri provider di configurazione.
Argomenti della riga di comando
Il comando seguente imposta chiavi e valori usando =
:
dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick
Il comando seguente imposta chiavi e valori usando /
:
dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick
Il comando seguente imposta chiavi e valori usando --
:
dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick
Il valore di chiave:
- Deve seguire
=
o la chiave deve avere un prefisso--
o/
quando il valore segue uno spazio. - Non è richiesto se viene usato
=
. Ad esempio:MySetting=
.
Nello stesso comando, non mischiare coppie chiave-valore di argomenti della riga di comando che usano =
con coppie chiave-valore che usano uno spazio.
Mapping di sostituzione
I mapping di sostituzione consentono di usare la logica di sostituzione del nome della chiave. Specificare un dizionario delle sostituzioni al metodo AddCommandLine.
Quando viene utilizzato il dizionario dei mapping di sostituzione, nel dizionario viene controllata la presenza di una chiave corrispondente alla chiave fornita da un argomento della riga di comando. Se la chiave della riga di comando viene trovata nel dizionario, il valore del dizionario viene passato nuovamente per impostare la coppia chiave-valore nella configurazione dell'app. Un mapping di sostituzione è necessario per le chiavi della riga di comando con un trattino singolo (-
) come prefisso.
Regole principali del dizionario dei mapping di sostituzione:
- Le sostituzioni devono iniziare con
-
o--
. - Il dizionario dei mapping di sostituzione non deve contenere chiavi duplicate.
Per usare un dizionario dei mapping di sostituzione, passarlo nella chiamata a 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();
Per testare la sostituzione delle chiavi è possibile eseguire il comando seguente:
dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6
Il codice seguente mostra i valori di chiave per le chiavi sostituite:
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"]}'");
}
}
Per le app che usano i mapping di sostituzione, la chiamata a CreateDefaultBuilder
non deve passare argomenti. La chiamata AddCommandLine
del metodo CreateDefaultBuilder
non include sostituzioni mappate e non è possibile passare il dizionario dei mapping di sostituzione a CreateDefaultBuilder
. La soluzione non consiste nel passare gli argomenti a CreateDefaultBuilder
ma nel consentire al metodo AddCommandLine
del metodo ConfigurationBuilder
di elaborare entrambi gli argomenti e il dizionario dei mapping di sostituzione.
Impostare gli argomenti dell'ambiente e della riga di comando con Visual Studio
Gli argomenti dell'ambiente e della riga di comando possono essere impostati in Visual Studio dalla finestra dei profili di avvio:
- In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e selezionare Proprietà.
- Selezionare la scheda Debug > Generale e selezionare Aprire interfaccia utente profili di avvio debug.
Dati di configurazione gerarchici
L'API di configurazione legge i dati di configurazione gerarchici rendendoli flat grazie all'uso di un delimitatore nelle chiavi di configurazione.
Il download di esempio contiene il file appsettings.json
seguente:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Il codice seguente del download di esempio visualizza diverse impostazioni delle configurazioni:
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}");
}
}
Il modo preferito per leggere i dati di configurazione gerarchici prevede l'uso del modello di opzioni. Per altre informazioni, vedere Associare dati di configurazione gerarchici in questo documento.
I metodi GetSection e GetChildren sono disponibili per isolare le sezioni e gli elementi figlio di una sezione nei dati di configurazione. Questi metodi sono descritti più avanti in GetSection, GetChildren ed Exists.
Chiavi e valori di configurazione
Avviso
Questo articolo illustra l'uso di stringa di connessione. Con un database locale l'utente non deve essere autenticato, ma nell'ambiente di produzione stringa di connessione talvolta include una password per l'autenticazione. Una credenziale della password del proprietario della risorsa (ROPC) è un rischio per la sicurezza che deve essere evitato nei database di produzione. Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni sull'autenticazione per le app distribuite in ambienti di test o di produzione, vedere Proteggere i flussi di autenticazione.
Chiavi di configurazione:
- non viene fatta distinzione tra maiuscole e minuscole. Ad esempio,
ConnectionString
econnectionstring
vengono considerate chiavi equivalenti. - Se una chiave e un valore sono impostati in più provider di configurazione, viene usato il valore dell'ultimo provider aggiunto. Per altre informazioni, vedere Configurazione predefinita.
- Chiavi gerarchica
- Nell'ambito dell'API di configurazione, il separatore due punti (
:
) funziona in tutte le piattaforme. - Nelle variabili di ambiente, un separatore due punti potrebbe non funzionare in tutte le piattaforme. Il doppio carattere di sottolineatura,
__
, è supportato da tutte le piattaforme e viene convertito automaticamente nei due punti:
. - In Azure Key Vault le chiavi gerarchiche usano
--
come separatore. Il provider di configurazione di Azure Key Vault sostituisce automaticamente--
con:
quando i segreti vengono caricati nella configurazione dell'app.
- Nell'ambito dell'API di configurazione, il separatore due punti (
- Il ConfigurationBinder supporta l'associazione di matrici agli oggetti usando gli indici delle matrici nelle chiavi di configurazione. L'associazione di matrici è descritta nella sezione Associare una matrice a una classe.
Valori di configurazione:
- sono stringhe.
- I valori null non possono essere archiviati nella configurazione o associati a oggetti.
Provider di configurazione
La tabella seguente mostra i provider di configurazione disponibili per le app ASP.NET Core.
Provider | Fornisce la configurazione da |
---|---|
Azure Key Vault configuration provider (Provider di configurazione di Azure Key Vault) | Azure Key Vault |
Provider di configurazione app di Azure | Configurazione app di Azure |
Provider di configurazione della riga di comando | Parametri della riga di comando |
Provider di configurazione personalizzato | Origine personalizzata |
Provider di configurazione delle variabili di ambiente | Variabili di ambiente |
Provider di configurazione file | File INI, JSON e XML |
Provider di configurazione chiave-per-file | File della directory |
Provider di configurazione della memoria | Raccolte in memoria |
Segreti utente | File nella directory dei profili utente |
Le origini di configurazione vengono lette nell'ordine in cui vengono specificati i rispetti provider di configurazione. Ordinare i provider di configurazione nel codice in base alle priorità per le origini di configurazione sottostanti richieste dall'app.
Una sequenza tipica di provider di configurazione è:
appsettings.json
appsettings.{Environment}.json
- Segreti utente
- Variabili di ambiente che usano il provider di configurazione delle variabili di ambiente.
- Argomenti della riga di comando che usano il provider di configurazione della riga di comando.
È pratica comune aggiungere il provider di configurazione della riga di comando per ultimo in una serie di provider per consentire agli argomenti della riga di comando di sostituire la configurazione impostata da altri provider.
La sequenza di provider precedente è usata nella configurazione predefinita.
Prefissi della stringa di connessione
Avviso
Questo articolo illustra l'uso di stringa di connessione. Con un database locale l'utente non deve essere autenticato, ma nell'ambiente di produzione stringa di connessione talvolta include una password per l'autenticazione. Una credenziale della password del proprietario della risorsa (ROPC) è un rischio per la sicurezza che deve essere evitato nei database di produzione. Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni sull'autenticazione per le app distribuite in ambienti di test o di produzione, vedere Proteggere i flussi di autenticazione.
L'API di configurazione ha regole di elaborazione speciali per quattro variabili di ambiente della stringa di connessione. Queste stringhe di connessione sono coinvolte nella configurazione delle stringhe di connessione di Azure per l'ambiente dell'app. Le variabili di ambiente con i prefissi indicati nella tabella vengono caricate nell'app con la configurazione predefinita o quando non viene specificato alcun prefisso per AddEnvironmentVariables
.
Prefisso della stringa di connessione | Provider |
---|---|
CUSTOMCONNSTR_ |
Provider personalizzato |
MYSQLCONNSTR_ |
MySQL |
SQLAZURECONNSTR_ |
Database SQL di Azure |
SQLCONNSTR_ |
SQL Server |
Quando una variabile di ambiente viene individuata e caricata nella configurazione con uno qualsiasi dei quattro prefissi indicati nella tabella:
- La chiave di configurazione viene creata rimuovendo il prefisso della variabile di ambiente e aggiungendo una sezione per la chiave di configurazione (
ConnectionStrings
). - Viene creata una nuova coppia chiave-valore della configurazione che rappresenta il provider di connessione al database (ad eccezione di
CUSTOMCONNSTR_
, che non ha un provider dichiarato).
Chiave della variabile di ambiente | Chiave di configurazione convertita | Voce di configurazione del provider |
---|---|---|
CUSTOMCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Voce di configurazione non creata. |
MYSQLCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Chiave: ConnectionStrings:{KEY}_ProviderName :Valore: MySql.Data.MySqlClient |
SQLAZURECONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Chiave: ConnectionStrings:{KEY}_ProviderName :Valore: System.Data.SqlClient |
SQLCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Chiave: ConnectionStrings:{KEY}_ProviderName :Valore: System.Data.SqlClient |
Provider di configurazione file
FileConfigurationProvider è la classe base per il caricamento della configurazione dal file system. I provider di configurazione seguenti derivano da FileConfigurationProvider
:
Provider di configurazione INI
IniConfigurationProvider carica la configurazione da coppie chiave-valore di file INI in fase di esecuzione.
Il codice seguente aggiunge diversi provider di configurazione:
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();
Nel codice precedente le impostazioni nei file MyIniConfig.ini
e MyIniConfig.{Environment}.ini
sono sostituite dalle impostazioni in:
- Provider di configurazione delle variabili di ambiente
- Provider di configurazione della riga di comando.
Il download di esempio contiene il file MyIniConfig.ini
seguente:
MyKey="MyIniConfig.ini Value"
[Position]
Title="My INI Config title"
Name="My INI Config name"
[Logging:LogLevel]
Default=Information
Microsoft=Warning
Il codice seguente del download di esempio visualizza diverse impostazioni delle configurazioni precedenti:
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}");
}
}
Provider di configurazione JSON
Carica JsonConfigurationProvider la configurazione dalle coppie chiave-valore del file JSON.
Gli overload possono specificare:
- Se il file è facoltativo.
- Se la configurazione viene ricaricata se viene modificato il file.
Osservare il codice seguente:
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();
Il codice precedente:
- Configura il provider di configurazione JSON per caricare il
MyConfig.json
file con le opzioni seguenti:optional: true
: il file è facoltativo.reloadOnChange: true
: il file viene ricaricato quando vengono salvate le modifiche.
- Legge i provider di configurazione predefiniti prima del file
MyConfig.json
. Le impostazioni nel fileMyConfig.json
sostituiscono le impostazioni nei provider di configurazione predefiniti, incluso il provider di configurazione delle variabili di ambiente e il provider di configurazione della riga di comando.
In genere non si vuole che un file JSON personalizzato sostituisci i valori impostati nel provider di configurazione delle variabili di ambiente e nel provider di configurazione della riga di comando.
Provider di configurazione XML
Il XmlConfigurationProvider carica la configurazione da coppie chiave-valore di file XML in fase di esecuzione.
Il codice seguente aggiunge diversi provider di configurazione:
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();
Nel codice precedente le impostazioni nei file MyXMLFile.xml
e MyXMLFile.{Environment}.xml
sono sostituite dalle impostazioni in:
- Provider di configurazione delle variabili di ambiente
- Provider di configurazione della riga di comando.
Il download di esempio contiene il file MyXMLFile.xml
seguente:
<?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>
Il codice seguente del download di esempio visualizza diverse impostazioni delle configurazioni precedenti:
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}");
}
}
La ripetizione di elementi che usano lo stesso nome di elemento funziona se si usa l'attributo name
per distinguere gli elementi:
<?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>
Il codice seguente legge il file di configurazione precedente e visualizza le chiavi e i valori:
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"
);
}
}
È possibile usare attributi per fornire valori:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<key attribute="value" />
<section>
<key attribute="value" />
</section>
</configuration>
Il file di configurazione precedente carica le chiavi seguenti con value
:
- key:attribute
- section:key:attribute
Provider di configurazione chiave-per-file
Il KeyPerFileConfigurationProvider usa i file di una directory come coppie chiave-valore della configurazione. La chiave è il nome del file. Il valore contiene il contenuto del file. Il provider di configurazione chiave-per-file viene usato negli scenari di hosting di Docker.
Per attivare la configurazione chiave-per-file, chiamare il metodo di estensione AddKeyPerFile su un'istanza di ConfigurationBuilder. Il directoryPath
per i file deve essere un percorso assoluto.
Gli overload consentono di specificare:
- Un delegato
Action<KeyPerFileConfigurationSource>
che configura l'origine. - Se la directory è facoltativa e il percorso della directory.
Il doppio carattere di sottolineatura (__
) viene usato come delimitatore per le chiavi di configurazione nei nomi dei file. Ad esempio, il nome di file Logging__LogLevel__System
produce la chiave di configurazione Logging:LogLevel:System
.
Chiamare ConfigureAppConfiguration
quando si crea l'host per specificare la configurazione dell'app:
.ConfigureAppConfiguration((hostingContext, config) =>
{
var path = Path.Combine(
Directory.GetCurrentDirectory(), "path/to/files");
config.AddKeyPerFile(directoryPath: path, optional: true);
})
Provider di configurazione della memoria
Il MemoryConfigurationProvider usa una raccolta in memoria come coppie chiave-valore della configurazione.
Il codice seguente aggiunge una raccolta di memoria al sistema di configurazione:
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();
Il codice seguente del download di esempio visualizza le impostazioni delle configurazioni precedenti:
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}");
}
}
Nel codice precedente config.AddInMemoryCollection(Dict)
viene aggiunto dopo i provider di configurazione predefiniti. Per un esempio di ordinamento dei provider di configurazione, vedere Provider di configurazione JSON.
Vedere Associare una matrice per un altro esempio che usa MemoryConfigurationProvider
.
Configurazione di endpoint Kestrel
La configurazione di endpoint specifica di Kestrel sostituisce tutte le configurazioni di endpoint tra server. Le configurazioni di endpoint tra server includono:
- UseUrls
--urls
nella riga di comando- Variabile di ambiente
ASPNETCORE_URLS
Si consideri il file appsettings.json
seguente usato in un'app Web ASP.NET Core:
{
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://localhost:9999"
}
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Quando il markup evidenziato precedente viene usato in un'app Web ASP.NET Core e l'app viene avviata dalla riga di comando con la configurazione dell'endpoint tra server seguente:
dotnet run --urls="https://localhost:7777"
Kestrel si associa all'endpoint configurato specificatamente per Kestrel nel file appsettings.json
(https://localhost:9999
) e non in https://localhost:7777
.
Si consideri l'endpoint specifico di Kestrel configurato come variabile di ambiente:
set Kestrel__Endpoints__Https__Url=https://localhost:8888
nella variabile di ambiente precedente Https
è il nome dell'endpoint specifico di Kestrel. Il file appsettings.json
precedente definisce anche un endpoint specifico di Kestrel denominato Https
. Per impostazione predefinita, le variabili di ambiente che usano il provider di configurazione delle variabili di ambiente vengono lette dopo appsettings.{Environment}.json
, di conseguenza la variabile di ambiente precedente viene usata per l'endpoint Https
.
GetValue
ConfigurationBinder.GetValue estrae un valore dalla configurazione con una chiave specificata e lo converte nel tipo specificato:
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}");
}
}
Nel codice precedente, se NumberKey
non viene trovato nella configurazione, viene usato il valore predefinito di 99
.
GetSection, GetChildren ed Exists
Per gli esempi che seguono, prendere in considerazione il file MySubsection.json
seguente:
{
"section0": {
"key0": "value00",
"key1": "value01"
},
"section1": {
"key0": "value10",
"key1": "value11"
},
"section2": {
"subsection0": {
"key0": "value200",
"key1": "value201"
},
"subsection1": {
"key0": "value210",
"key1": "value211"
}
}
}
Il codice seguente aggiunge MySubsection.json
ai provider di configurazione:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.AddJsonFile("MySubsection.json",
optional: true,
reloadOnChange: true);
builder.Services.AddRazorPages();
var app = builder.Build();
GetSection
IConfiguration.GetSection restituisce una sottosezione della configurazione con la chiave di sottosezione specificata.
Il codice seguente restituisce i valori per 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"]}'");
}
}
Il codice seguente restituisce i valori per 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
non restituisce mai null
. Se non viene trovata una sezione corrispondente, viene restituita una IConfigurationSection
vuota.
Quando GetSection
restituisce una sezione corrispondente, Value non viene compilata. Quando la sezione esiste, vengono restituiti Key e Path.
GetChildren ed Exists
Il codice seguente chiama IConfiguration.GetChildren e restituisce i valori per 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);
}
}
Il codice precedente chiama ConfigurationExtensions.Exists per verificare che la sezione esista:
Associare una matrice
Il ConfigurationBinder.Bind supporta l'associazione di matrici agli oggetti usando gli indici delle matrici nelle chiavi di configurazione. Qualsiasi formato di matrice che espone un segmento chiave numerico supporta l'associazione di matrici a una matrice di classi POCO.
Si consideri MyArray.json
del download di esempio:
{
"array": {
"entries": {
"0": "value00",
"1": "value10",
"2": "value20",
"4": "value40",
"5": "value50"
}
}
}
Il codice seguente aggiunge MyArray.json
ai provider di configurazione:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.AddJsonFile("MyArray.json",
optional: true,
reloadOnChange: true);
builder.Services.AddRazorPages();
var app = builder.Build();
Il codice seguente legge la configurazione e visualizza i valori:
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; }
}
Il codice precedente restituisce l'output seguente:
Index: 0 Value: value00
Index: 1 Value: value10
Index: 2 Value: value20
Index: 3 Value: value40
Index: 4 Value: value50
Nell'output precedente Index 3 ha il valore value40
, corrispondente a "4": "value40",
in MyArray.json
. Gli indici di matrice associati sono continui e non associati all'indice delle chiavi di configurazione. Il binder di configurazione non supporta l'associazione di valori Null o la creazione di voci Null negli oggetti associati.
Provider di configurazione personalizzato
L'app di esempio dimostra come creare un provider di configurazione di base che legge le coppie chiave-valore di configurazione da un database usando Entity Framework (EF).
Il provider ha le caratteristiche seguenti:
- Il database in memoria di Entity Framework viene usato a scopo dimostrativo. Per usare un database che richiede una stringa di connessione, implementare un
ConfigurationBuilder
secondario per fornire la stringa di connessione da un altro provider di configurazione. - Il provider legge una tabella di database in una configurazione all'avvio. Il provider non esegue una query sul database per ogni chiave.
- Il ricaricamento in caso di modifica non è implementato, quindi l'aggiornamento del database dopo l'avvio dell'app non ha alcun effetto sulla configurazione dell'app.
Definire un'entità EFConfigurationValue
per l'archiviazione dei valori di configurazione nel database.
Models/EFConfigurationValue.cs
:
public class EFConfigurationValue
{
public string Id { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
}
Aggiungere EFConfigurationContext
per archiviare i valori configurati e accedervi.
EFConfigurationProvider/EFConfigurationContext.cs
:
public class EFConfigurationContext : DbContext
{
public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
{
}
public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}
Creare una classe che implementi 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);
}
Creare il provider di configurazione personalizzato ereditando da ConfigurationProvider. Il provider di configurazione inizializza il database quando è vuoto. Poiché nelle chiavi di configurazione non viene fatta distinzione tra maiuscole e minuscole, il dizionario usato per inizializzare il database viene creato con l'operatore di confronto senza distinzione tra maiuscole e minuscole (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;
}
}
Un metodo di estensione AddEFConfiguration
consente di aggiungere l'origine di configurazione a un ConfigurationBuilder
.
Extensions/EntityFrameworkExtensions.cs
:
public static class EntityFrameworkExtensions
{
public static IConfigurationBuilder AddEFConfiguration(
this IConfigurationBuilder builder,
Action<DbContextOptionsBuilder> optionsAction)
{
return builder.Add(new EFConfigurationSource(optionsAction));
}
}
Il codice seguente mostra come usare EFConfigurationProvider
personalizzato in Program.cs
:
//using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddEFConfiguration(
opt => opt.UseInMemoryDatabase("InMemoryDb"));
var app = builder.Build();
app.Run();
Configurazione dell'accesso con inserimento delle dipendenze
La configurazione può essere inserita nei servizi usando l'inserimento delle dipendenze attraverso la risoluzione del servizio IConfiguration:
public class Service
{
private readonly IConfiguration _config;
public Service(IConfiguration config) =>
_config = config;
public void DoSomething()
{
var configSettingValue = _config["ConfigSetting"];
// ...
}
}
Per informazioni su come accedere ai valori usando IConfiguration
, vedere GetValue e GetSection, GetChildren ed Exists in questo articolo.
Accedere alla configurazione nelle pagine Razor
Il codice seguente visualizza i dati di configurazione in una pagina Razor:
@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
Nel codice seguente MyOptions
viene aggiunta al contenitore del servizio con Configure e associata alla configurazione:
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
Il markup seguente usa la direttiva @inject
Razor per risolvere e visualizzare i valori delle opzioni:
@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>
Accedere alla configurazione in un file di visualizzazione MVC
Il codice seguente visualizza i dati di configurazione in una visualizzazione MVC:
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
Accedere alla configurazione in Program.cs
Il codice seguente accede alla configurazione nel file 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();
In appsettings.json
per l'esempio precedente:
{
...
"KeyOne": "Key One Value",
"KeyTwo": 1999,
"KeyThree": true
}
Configurare opzioni con un delegato
Le opzioni configurate in un delegato sostituiscono i valori impostati nei provider di configurazione.
Nel codice seguente viene aggiunto un servizio IConfigureOptions<TOptions> al contenitore di servizi. Viene usato un delegato per configurare i valori per 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();
Il codice seguente visualizza i valori delle opzioni:
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}");
}
}
Nell'esempio precedente i valori di Option1
e Option2
sono specificati in appsettings.json
e quindi sostituiti dal delegato configurato.
Host e configurazione delle app
Prima che l'app venga configurata e avviata, viene configurato e avviato un host. L'host è responsabile della gestione dell'avvio e della durata delle app. Sia l'app che l'host vengono configurati tramite i provider di configurazione descritti in questo argomento. Anche le coppie chiave-valore di configurazione dell'host sono incluse nella configurazione dell'app. Per altre informazioni su come vengono usati i provider di configurazione per la creazione dell'host e sugli effetti delle origini di configurazione sulla configurazione dell'host, vedere Panoramica delle nozioni di base su ASP.NET Core.
Configurazione dell'host predefinita
Per informazioni dettagliate sulla configurazione predefinita quando viene usato l'host Web, vedere la versione di questo argomento per ASP.NET Core 2.2.
- La configurazione dell'host viene fornita da:
- Variabili di ambiente con prefisso
DOTNET_
(ad esempio,DOTNET_ENVIRONMENT
) che usano il provider di configurazione delle variabili di ambiente. Il prefisso (DOTNET_
) viene rimosso al caricamento delle coppie chiave-valore della configurazione. - Argomenti della riga di comando che usano il provider di configurazione della riga di comando.
- Variabili di ambiente con prefisso
- Viene stabilita la configurazione predefinita dell'host Web (
ConfigureWebHostDefaults
):- Kestrel viene usato come server Web e configurato con i provider di configurazione dell'app.
- Aggiungere il middleware di filtro host.
- Aggiungere il middleware delle intestazioni inoltrate se la variabile di ambiente
ASPNETCORE_FORWARDEDHEADERS_ENABLED
è impostata sutrue
. - Abilitare l'integrazione di IIS.
Altra configurazione
Questo argomento riguarda solo la configurazione dell'app. Altri aspetti dell'esecuzione e dell'hosting delle app ASP.NET Core vengono configurati usando i file di configurazione non descritti in questo argomento:
launch.json
/launchSettings.json
sono file di configurazione degli strumenti per l'ambiente di sviluppo, descritto:- In Usare più ambienti in ASP.NET Core.
- Nel set di documentazione in cui i file vengono usati per configurare le app ASP.NET Core per gli scenari di sviluppo.
web.config
è un file di configurazione del server, descritto negli argomenti seguenti:
Variabili di ambiente impostate in launchSettings.json
sostituiscono quelle impostate nell'ambiente di sistema.
Per altre informazioni sulla migrazione della configurazione dell'app da versioni precedenti di ASP.NET, vedere Eseguire l'aggiornamento da ASP.NET a ASP.NET Core.
Aggiungere la configurazione da un assembly esterno
Un'implementazione IHostingStartup consente l'aggiunta di miglioramenti a un'app all'avvio, da un assembly esterno alla classe Startup
dell'app. Per altre informazioni, vedere Usare assembly di avvio dell'hosting in ASP.NET Core.
Generatore di origini con associazione della configurazione
Il generatore di origine dell'associazione di configurazione fornisce la configurazione AOT e trim-friendly. Per altre informazioni, vedere Generatore di origine dell'associazione di configurazione.
Risorse aggiuntive
La configurazione dell'applicazione in ASP.NET Core viene eseguita usando uno o più provider di configurazione. I provider di configurazione leggono i dati di configurazione da coppie chiave-valore usando diverse origini di configurazione:
- File di impostazioni, ad esempio
appsettings.json
- Variabili di ambiente
- Azure Key Vault
- Configurazione app di Azure
- Argomenti della riga di comando
- Provider personalizzati, installati o creati
- File della directory
- Oggetti .NET in memoria
Questo articolo offre informazioni sulla configurazione in ASP.NET Core. Per informazioni sull'uso della configurazione nelle app console, vedere Configurazione di .NET.
Configurazione dell'applicazione e dell'host
Le app ASP.NET Core configurano e avviano un host. L'host è responsabile della gestione dell'avvio e della durata delle app. I modelli di ASP.NET Core creano un WebApplicationBuilder che contiene l'host. Sebbene parte della configurazione possa essere eseguita sia nel provider di configurazione dell'host che nel provider di configurazione dell'applicazione, in generale solo la configurazione necessaria all'host deve essere eseguita nella configurazione dell'host.
La configurazione dell'applicazione è la priorità più alta ed è descritta nel dettaglio nella sezione successiva. La configurazione dell'host segue la configurazione dell'applicazione ed è descritta in questo articolo.
Origini della configurazione dell'applicazione predefinite
Le app Web ASP.NET Core create con dotnet new o Visual Studio generano il codice seguente:
var builder = WebApplication.CreateBuilder(args);
WebApplication.CreateBuilder inizializza una nuova istanza della classe WebApplicationBuilder con valori predefiniti preconfigurati. Il WebApplicationBuilder
(builder
) inizializzato offre la configurazione predefinita per l'app nell'ordine seguente, dalla priorità più alta a quella più bassa:
- Argomenti della riga di comando che usano il provider di configurazione della riga di comando.
- Variabili di ambiente senza prefisso che usano il provider di configurazione delle variabili di ambiente senza prefisso.
- Segreti dell'utente quando l'app viene eseguita nell'ambiente
Development
. appsettings.{Environment}.json
usando il provider di configurazione JSON. Ad esempio,appsettings.Production.json
eappsettings.Development.json
.- appsettings.json usando il provider di configurazione JSON.
- Un fallback alla configurazione dell'host descritto nella sezione successiva.
Origini della configurazione dell'host predefinite
L'elenco seguente contiene le origini di configurazione host predefinite dalla priorità più alta alla più bassa per WebApplicationBuilder:
- Argomenti della riga di comando che usano il provider di configurazione della riga di comando
- Variabili di ambiente con prefisso
DOTNET_
che usano il provider di configurazione delle variabili di ambiente. - Variabili di ambiente con prefisso
ASPNETCORE_
che usano il provider di configurazione delle variabili di ambiente.
Per l'host generico .NET e l'host Web, le origini di configurazione host predefinite dalla priorità più alta alla più bassa sono:
- Variabili di ambiente con prefisso
ASPNETCORE_
che usano il provider di configurazione delle variabili di ambiente. - Argomenti della riga di comando che usano il provider di configurazione della riga di comando
- Variabili di ambiente con prefisso
DOTNET_
che usano il provider di configurazione delle variabili di ambiente.
Quando un valore di configurazione viene impostato nella configurazione dell'host e dell'applicazione, viene usata la configurazione dell'applicazione.
Variabili dell'host
Le variabili seguenti vengono bloccate in anticipo durante l'inizializzazione dei generatori di host e non possono essere influenzate dalla configurazione dell'applicazione:
- Nome applicazione
- Nome dell'ambiente, ad esempio
Development
,Production
eStaging
- Radice del contenuto
- Radice Web
- Se cercare gli assembly di avvio di hosting e quali assembly cercare.
- Variabili lette dal codice dell'app e della libreria da hostBuilderContext.Configuration nei callback IHostBuilder.ConfigureAppConfiguration.
Ogni altra impostazione dell'host viene letta dalla configurazione dell'applicazione anziché dalla configurazione dell'host.
URLS
è una delle numerose impostazioni dell'host comuni che non è un'impostazione bootstrap. Come tutte le altre impostazioni dell'host non presenti nell'elenco precedente, URLS
viene letta successivamente dalla configurazione dell'applicazione. Poiché la configurazione dell'host è un fallback per la configurazione dell'applicazione, la configurazione dell'host può essere usata per impostare URLS
, ma verrà sostituita da qualsiasi origine di configurazione nella configurazione dell'applicazione, come appsettings.json
.
Per altre informazioni, vedere Modificare la radice del contenuto, il nome dell'app e l'ambiente e Modificare la radice del contenuto, il nome dell'app e l'ambiente in base alle variabili di ambiente o alla riga di comando
Le sezioni rimanenti di questo articolo fanno riferimento alla configurazione dell'applicazione.
Provider di configurazione dell'applicazione
Il codice seguente visualizza i provider di configurazione abilitati nell'ordine in cui sono stati aggiunti:
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);
}
}
L'elenco precedente delle origini di configurazione predefinite dalla priorità più alta alla priorità più bassa mostra i provider nell'ordine opposto in cui vengono aggiunti all'applicazione generata dal modello. Ad esempio, il provider di configurazione JSON viene aggiunto prima del provider di configurazione della riga di comando.
I provider di configurazione aggiunti successivamente hanno priorità più alta e sostituiscono le impostazioni delle chiavi precedenti. Ad esempio, se MyKey
è impostato sia in appsettings.json
che nell'ambiente, viene usato il valore dell'ambiente. Quando si usano i provider di configurazione predefiniti, il provider di configurazione della riga di comando sostituisce tutti gli altri provider.
Per altre informazioni su CreateBuilder
, vedere Impostazioni predefinite del generatore.
appsettings.json
Considerare il file appsettings.json
seguente:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Il codice seguente del download di esempio visualizza diverse impostazioni delle configurazioni precedenti:
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}");
}
}
Il JsonConfigurationProvider predefinito carica la configurazione nell'ordine seguente:
appsettings.json
appsettings.{Environment}.json
: ad esempio, i fileappsettings.Production.json
eappsettings.Development.json
. La versione dell'ambiente del file viene caricata in base a IHostingEnvironment.EnvironmentName. Per altre informazioni, vedere Usare più ambienti in ASP.NET Core.
I valori appsettings.{Environment}.json
sostituiscono le chiavi in appsettings.json
. Ad esempio, per impostazione predefinita:
- Nello sviluppo la configurazione
appsettings.Development.json
sovrascrive i valori trovati inappsettings.json
. - Nella produzione la configurazione
appsettings.Production.json
sovrascrive i valori trovati inappsettings.json
. Ad esempio, durante la distribuzione dell'app in Azure.
Se è necessario garantire un valore di configurazione, vedere GetValue. L'esempio precedente legge solo le stringhe e non supporta un valore predefinito.
Quando si usa la configurazione predefinita, i file appsettings.json
e appsettings.{Environment}.json
sono abilitati con reloadOnChange: true. Le modifiche apportate al appsettings.json
file e appsettings.{Environment}.json
dopo l'avvio dell'app vengono lette dal provider di configurazione JSON.
Commenti in appsettings.json
I commenti in appsettings.json
e appsettings.{Environment}.json
i file sono supportati usando commenti in stile JavaScript o C#.
Associare dati di configurazione gerarchici usando il modello di opzioni
Il modo preferito per leggere i valori di configurazione correlati prevede l'uso del modello di opzioni. Ad esempio, per leggere i valori di configurazione seguenti:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Creare la classe PositionOptions
seguente:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
}
Una classe di opzioni:
- Deve essere non astratta con un costruttore pubblico senza parametri.
- Tutte le proprietà di lettura/scrittura pubbliche del tipo sono associate.
- I campi non sono associati. Nel codice precedente
Position
non è associato. Il campoPosition
viene usato in modo che la stringa"Position"
non debba essere hardcoded nell'app quando la classe viene associata a un provider di configurazione.
Il codice seguente:
- Chiama ConfigurationBinder.Bind per associare la classe
PositionOptions
alla sezionePosition
. - Visualizza i dati di configurazione di
Position
.
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}");
}
}
Nel codice precedente, per impostazione predefinita, le modifiche apportate al file di configurazione JSON dopo l'avvio dell'app vengono lette.
ConfigurationBinder.Get<T>
associa e restituisce il tipo specificato. ConfigurationBinder.Get<T>
può risultare più utile rispetto all'uso di ConfigurationBinder.Bind
. Il codice seguente mostra come usare ConfigurationBinder.Get<T>
con la classe PositionOptions
:
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}");
}
}
Nel codice precedente, per impostazione predefinita, le modifiche apportate al file di configurazione JSON dopo l'avvio dell'app vengono lette.
Un approccio alternativo quando si usa il modello opzioni consiste nell'associare la sezione Position
e aggiungerla al contenitore del servizio di inserimento di dipendenze. Nel codice seguente PositionOptions
viene aggiunta al contenitore del servizio con Configure e associata alla configurazione:
using ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<PositionOptions>(
builder.Configuration.GetSection(PositionOptions.Position));
var app = builder.Build();
Quando si usa il codice precedente, il codice seguente legge le opzioni di posizione:
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}");
}
}
Nel codice precedente le modifiche al file di configurazione JSON dopo l'avvio dell'app non vengono lette. Per leggere le modifiche dopo l'avvio dell'app, usare IOptionsSnapshot.
Quando si usa la configurazione predefinita, i file appsettings.json
e appsettings.{Environment}.json
sono abilitati con reloadOnChange: true. Le modifiche apportate al appsettings.json
file e appsettings.{Environment}.json
dopo l'avvio dell'app vengono lette dal provider di configurazione JSON.
Per informazioni sull'aggiunta di file di configurazione JSON aggiuntivi, vedere Provider di configurazione JSON in questo documento.
Combinazione della raccolta di servizi
Considerare il codice seguente che registra i servizi e configura le opzioni:
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();
I gruppi correlati di registrazioni possono essere spostati in un metodo di estensione per registrare i servizi. Ad esempio, i servizi di configurazione vengono aggiunti alla classe seguente:
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;
}
}
}
I servizi rimanenti vengono registrati in una classe simile. Il codice seguente usa i nuovi metodi di estensione per registrare i servizi:
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: ogni metodo di estensione services.Add{GROUP_NAME}
aggiunge e configura potenzialmente i servizi. Ad esempio, AddControllersWithViews aggiunge i controller MVC dei servizi con visualizzazioni richiesti e AddRazorPages aggiunge le pagina Razor dei servizi richieste.
Sicurezza e segreti dell'utente
Linee guida per i dati di configurazione:
- Non archiviare mai la password o altri dati sensibili nel codice del provider di configurazione o in file di configurazione di testo normale. Per l'archiviazione di segreti per lo sviluppo, è possibile usare lo strumento Secret Manager.
- Non usare i segreti di produzione in ambienti di sviluppo o di test.
- Specificare i segreti all'esterno del progetto in modo che non possano essere inavvertitamente inviati a un repository del codice sorgente.
- Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni, vedere Proteggere i flussi di autenticazione.
Per impostazione predefinita, l'origine di configurazione dei segreti utente viene registrata dopo le origini di configurazione JSON. Pertanto, le chiavi dei segreti dell'utente hanno la precedenza sulle chiavi in appsettings.json
e appsettings.{Environment}.json
.
Per altre informazioni sull'archiviazione di password o altri dati sensibili:
- Usare più ambienti in ASP.NET Core
- Archiviazione sicura di segreti dell'app durante lo sviluppo in ASP.NET Core: include consigli sull'uso delle variabili di ambiente per l'archiviazione dei dati sensibili. Lo strumento Secret Manager usa il provider di configurazione file per archiviare i segreti utente in un file JSON nel sistema locale.
Azure Key Vault archivia in modo sicuro i segreti delle app ASP.NET Core. Per altre informazioni, vedere Provider di configurazione di Azure Key Vault in ASP.NET Core.
Variabili di ambiente senza prefisso
Le variabili di ambiente senza prefisso sono variabili di ambiente diverse da quelle precedute da ASPNETCORE_
o DOTNET_
. Ad esempio, i modelli di applicazione Web ASP.NET Core impostano "ASPNETCORE_ENVIRONMENT": "Development"
in launchSettings.json
. Per altre informazioni sulle variabili di ambiente ASPNETCORE_
e DOTNET_
, vedere:
- Elenco delle origini di configurazione predefinite dalla priorità più alta alla priorità più bassa incluse le variabili di ambiente senza prefisso, con prefisso
ASPNETCORE_
e con prefissoDOTNETCORE_
. - Variabili di ambiente
DOTNET_
usate all'esterno di Microsoft.Extensions.Hosting.
Quando si usa la configurazione predefinita, EnvironmentVariablesConfigurationProvider carica la configurazione dalle coppie chiave-valore delle variabili di ambiente dopo la lettura di appsettings.json
, appsettings.{Environment}.json
e dei segreti dell'utente. Therefore, i valori di chiave letti dall'ambiente sostituiscono i valori letti da appsettings.json
, appsettings.{Environment}.json
e dai segreti dell'utente.
Il separatore :
non funziona con le chiavi gerarchiche delle variabili di ambiente in tutte le piattaforme. Ad esempio, il :
separatore non è supportato da Bash. Il doppio carattere di sottolineatura, __
, è:
- Supportato da tutte le piattaforme.
- Sostituito automaticamente da due punti,
:
.
I comandi set
seguenti:
- Impostano le chiavi e i valori di ambiente dell'esempio precedente in Windows.
- Testano le impostazioni quando viene usato il download di esempio. Il comando
dotnet run
deve essere eseguito nella directory del progetto.
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run
Le impostazioni dell'ambiente precedenti:
- Sono impostate solo nei processi avviati dalla finestra di comando in cui sono stati impostate.
- Non verranno lette dai browser avviati con Visual Studio.
I comandi setx seguenti possono essere usati per impostare le chiavi e i valori di ambiente in Windows. A differenza di set
, le impostazioni setx
vengono mantenute. /M
imposta la variabile nell'ambiente di sistema. Se non viene usata l'opzione /M
, viene impostata una variabile di ambiente dell'utente.
setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M
Per verificare che i comandi precedenti sostituiscano appsettings.json
e appsettings.{Environment}.json
:
- Con Visual Studio: uscire e riavviare Visual Studio.
- Con l'interfaccia della riga di comando: avviare una nuova finestra di comando e immettere
dotnet run
.
Chiamare AddEnvironmentVariables con una stringa per specificare un prefisso per le variabili di ambiente:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
var app = builder.Build();
Nel codice precedente:
builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_")
viene aggiunto dopo i provider di configurazione predefiniti. Per un esempio di ordinamento dei provider di configurazione, vedere Provider di configurazione JSON.- Le variabili di ambiente impostate con il prefisso
MyCustomPrefix_
sostituiscono i provider di configurazione predefiniti. Sono incluse le variabili di ambiente senza il prefisso.
Il prefisso viene rimosso quando vengono lette le coppie chiave-valore della configurazione.
I comandi seguenti testano il prefisso personalizzato:
set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run
La configurazione predefinita carica le variabili di ambiente e gli argomenti della riga di comando con prefisso DOTNET_
e ASPNETCORE_
. I prefissi DOTNET_
e ASPNETCORE_
vengono usati da ASP.NET Core per la configurazione dell'host e dell'app, ma non per la configurazione dell'utente. Per altre informazioni sulla configurazione dell'host e dell'app, vedere Host generico .NET.
In Servizio app di Azure selezionare Nuova impostazione applicazione nella pagina Impostazioni > Configurazione. Le impostazioni applicazione del Servizio app di Azure sono:
- Crittografato in e rest trasmesso tramite un canale crittografato.
- Esposte come variabili di ambiente.
Per altre informazioni, vedere App di Azure: Eseguire l'override della configurazione delle app usando il portale di Azure.
Per informazioni sulle stringhe di connessione del database di Azure, vedere Prefissi della stringa di connessione.
Denominazione delle variabili di ambiente
I nomi delle variabili di ambiente riflettono la struttura di un file appsettings.json
. Ogni elemento nella gerarchia è separato da un doppio carattere di sottolineatura (preferibile) o due punti. Quando la struttura dell'elemento include una matrice, l'indice della matrice deve essere considerato come un nome di elemento aggiuntivo in questo percorso. Si consideri il file appsettings.json
seguente e i relativi valori equivalenti rappresentati come variabili di 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"
}
]
}
variabili di 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
Variabili di ambiente impostate nel file launchSettings.json generato
Variabili di ambiente impostate in launchSettings.json
sostituiscono quelle impostate nell'ambiente di sistema. Ad esempio, i modelli Web ASP.NET Core generano un file launchSettings.json
che imposta la configurazione dell'endpoint su:
"applicationUrl": "https://localhost:5001;http://localhost:5000"
La configurazione di applicationUrl
imposta la variabile di ambiente ASPNETCORE_URLS
e sostituisce i valori impostati nell'ambiente.
Carattere di escape per le variabili di ambiente in Linux
In Linux il valore delle variabili di ambiente degli URL deve essere preceduto da un carattere di escape in modo che systemd
possa analizzarle. Usare lo strumento linux systemd-escape
che restituisce http:--localhost:5001
groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001
Visualizzare le variabili di ambiente
Il codice seguente visualizza le variabili di ambiente e i valori all'avvio dell'applicazione, utile durante il debug delle impostazioni di ambiente:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
foreach (var c in builder.Configuration.AsEnumerable())
{
Console.WriteLine(c.Key + " = " + c.Value);
}
Riga di comando
Quando si usa la configurazione predefinita, CommandLineConfigurationProvider carica la configurazione dalle coppie chiave-valore degli argomenti della riga di comando dopo le origini di configurazione seguenti:
- File
appsettings.json
eappsettings.{Environment}.json
. - Segreti dell'app nell'ambiente di sviluppo.
- variabili di ambiente.
Per impostazione predefinita, i valori di configurazione impostati nella riga di comando sostituiscono i valori di configurazione impostati con tutti gli altri provider di configurazione.
Argomenti della riga di comando
Il comando seguente imposta chiavi e valori usando =
:
dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick
Il comando seguente imposta chiavi e valori usando /
:
dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick
Il comando seguente imposta chiavi e valori usando --
:
dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick
Il valore di chiave:
- Deve seguire
=
o la chiave deve avere un prefisso--
o/
quando il valore segue uno spazio. - Non è richiesto se viene usato
=
. Ad esempio:MySetting=
.
Nello stesso comando, non mischiare coppie chiave-valore di argomenti della riga di comando che usano =
con coppie chiave-valore che usano uno spazio.
Mapping di sostituzione
I mapping di sostituzione consentono di usare la logica di sostituzione del nome della chiave. Specificare un dizionario delle sostituzioni al metodo AddCommandLine.
Quando viene utilizzato il dizionario dei mapping di sostituzione, nel dizionario viene controllata la presenza di una chiave corrispondente alla chiave fornita da un argomento della riga di comando. Se la chiave della riga di comando viene trovata nel dizionario, il valore del dizionario viene passato nuovamente per impostare la coppia chiave-valore nella configurazione dell'app. Un mapping di sostituzione è necessario per le chiavi della riga di comando con un trattino singolo (-
) come prefisso.
Regole principali del dizionario dei mapping di sostituzione:
- Le sostituzioni devono iniziare con
-
o--
. - Il dizionario dei mapping di sostituzione non deve contenere chiavi duplicate.
Per usare un dizionario dei mapping di sostituzione, passarlo nella chiamata a 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();
Per testare la sostituzione delle chiavi è possibile eseguire il comando seguente:
dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6
Il codice seguente mostra i valori di chiave per le chiavi sostituite:
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"]}'");
}
}
Per le app che usano i mapping di sostituzione, la chiamata a CreateDefaultBuilder
non deve passare argomenti. La chiamata AddCommandLine
del metodo CreateDefaultBuilder
non include sostituzioni mappate e non è possibile passare il dizionario dei mapping di sostituzione a CreateDefaultBuilder
. La soluzione non consiste nel passare gli argomenti a CreateDefaultBuilder
ma nel consentire al metodo AddCommandLine
del metodo ConfigurationBuilder
di elaborare entrambi gli argomenti e il dizionario dei mapping di sostituzione.
Impostare gli argomenti dell'ambiente e della riga di comando con Visual Studio
Gli argomenti dell'ambiente e della riga di comando possono essere impostati in Visual Studio dalla finestra dei profili di avvio:
- In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e selezionare Proprietà.
- Selezionare la scheda Debug > Generale e selezionare Aprire interfaccia utente profili di avvio debug.
Dati di configurazione gerarchici
L'API di configurazione legge i dati di configurazione gerarchici rendendoli flat grazie all'uso di un delimitatore nelle chiavi di configurazione.
Il download di esempio contiene il file appsettings.json
seguente:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Il codice seguente del download di esempio visualizza diverse impostazioni delle configurazioni:
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}");
}
}
Il modo preferito per leggere i dati di configurazione gerarchici prevede l'uso del modello di opzioni. Per altre informazioni, vedere Associare dati di configurazione gerarchici in questo documento.
I metodi GetSection e GetChildren sono disponibili per isolare le sezioni e gli elementi figlio di una sezione nei dati di configurazione. Questi metodi sono descritti più avanti in GetSection, GetChildren ed Exists.
Chiavi e valori di configurazione
Avviso
Questo articolo illustra l'uso di stringa di connessione. Con un database locale l'utente non deve essere autenticato, ma nell'ambiente di produzione stringa di connessione talvolta include una password per l'autenticazione. Una credenziale della password del proprietario della risorsa (ROPC) è un rischio per la sicurezza che deve essere evitato nei database di produzione. Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni sull'autenticazione per le app distribuite in ambienti di test o di produzione, vedere Proteggere i flussi di autenticazione.
Chiavi di configurazione:
- non viene fatta distinzione tra maiuscole e minuscole. Ad esempio,
ConnectionString
econnectionstring
vengono considerate chiavi equivalenti. - Se una chiave e un valore sono impostati in più provider di configurazione, viene usato il valore dell'ultimo provider aggiunto. Per altre informazioni, vedere Configurazione predefinita.
- Chiavi gerarchica
- Nell'ambito dell'API di configurazione, il separatore due punti (
:
) funziona in tutte le piattaforme. - Nelle variabili di ambiente, un separatore due punti potrebbe non funzionare in tutte le piattaforme. Il doppio carattere di sottolineatura,
__
, è supportato da tutte le piattaforme e viene convertito automaticamente nei due punti:
. - In Azure Key Vault le chiavi gerarchiche usano
--
come separatore. Il provider di configurazione di Azure Key Vault sostituisce automaticamente--
con:
quando i segreti vengono caricati nella configurazione dell'app.
- Nell'ambito dell'API di configurazione, il separatore due punti (
- Il ConfigurationBinder supporta l'associazione di matrici agli oggetti usando gli indici delle matrici nelle chiavi di configurazione. L'associazione di matrici è descritta nella sezione Associare una matrice a una classe.
Valori di configurazione:
- sono stringhe.
- I valori null non possono essere archiviati nella configurazione o associati a oggetti.
Provider di configurazione
La tabella seguente mostra i provider di configurazione disponibili per le app ASP.NET Core.
Provider | Fornisce la configurazione da |
---|---|
Azure Key Vault configuration provider (Provider di configurazione di Azure Key Vault) | Azure Key Vault |
Provider di configurazione app di Azure | Configurazione app di Azure |
Provider di configurazione della riga di comando | Parametri della riga di comando |
Provider di configurazione personalizzato | Origine personalizzata |
Provider di configurazione delle variabili di ambiente | Variabili di ambiente |
Provider di configurazione file | File INI, JSON e XML |
Provider di configurazione chiave-per-file | File della directory |
Provider di configurazione della memoria | Raccolte in memoria |
Segreti utente | File nella directory dei profili utente |
Le origini di configurazione vengono lette nell'ordine in cui vengono specificati i rispetti provider di configurazione. Ordinare i provider di configurazione nel codice in base alle priorità per le origini di configurazione sottostanti richieste dall'app.
Una sequenza tipica di provider di configurazione è:
appsettings.json
appsettings.{Environment}.json
- Segreti utente
- Variabili di ambiente che usano il provider di configurazione delle variabili di ambiente.
- Argomenti della riga di comando che usano il provider di configurazione della riga di comando.
È pratica comune aggiungere il provider di configurazione della riga di comando per ultimo in una serie di provider per consentire agli argomenti della riga di comando di sostituire la configurazione impostata da altri provider.
La sequenza di provider precedente è usata nella configurazione predefinita.
Prefissi della stringa di connessione
Avviso
Questo articolo illustra l'uso di stringa di connessione. Con un database locale l'utente non deve essere autenticato, ma nell'ambiente di produzione stringa di connessione talvolta include una password per l'autenticazione. Una credenziale della password del proprietario della risorsa (ROPC) è un rischio per la sicurezza che deve essere evitato nei database di produzione. Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni sull'autenticazione per le app distribuite in ambienti di test o di produzione, vedere Proteggere i flussi di autenticazione.
L'API di configurazione ha regole di elaborazione speciali per quattro variabili di ambiente della stringa di connessione. Queste stringhe di connessione sono coinvolte nella configurazione delle stringhe di connessione di Azure per l'ambiente dell'app. Le variabili di ambiente con i prefissi indicati nella tabella vengono caricate nell'app con la configurazione predefinita o quando non viene specificato alcun prefisso per AddEnvironmentVariables
.
Prefisso della stringa di connessione | Provider |
---|---|
CUSTOMCONNSTR_ |
Provider personalizzato |
MYSQLCONNSTR_ |
MySQL |
SQLAZURECONNSTR_ |
Database SQL di Azure |
SQLCONNSTR_ |
SQL Server |
Quando una variabile di ambiente viene individuata e caricata nella configurazione con uno qualsiasi dei quattro prefissi indicati nella tabella:
- La chiave di configurazione viene creata rimuovendo il prefisso della variabile di ambiente e aggiungendo una sezione per la chiave di configurazione (
ConnectionStrings
). - Viene creata una nuova coppia chiave-valore della configurazione che rappresenta il provider di connessione al database (ad eccezione di
CUSTOMCONNSTR_
, che non ha un provider dichiarato).
Chiave della variabile di ambiente | Chiave di configurazione convertita | Voce di configurazione del provider |
---|---|---|
CUSTOMCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Voce di configurazione non creata. |
MYSQLCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Chiave: ConnectionStrings:{KEY}_ProviderName :Valore: MySql.Data.MySqlClient |
SQLAZURECONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Chiave: ConnectionStrings:{KEY}_ProviderName :Valore: System.Data.SqlClient |
SQLCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Chiave: ConnectionStrings:{KEY}_ProviderName :Valore: System.Data.SqlClient |
Provider di configurazione file
FileConfigurationProvider è la classe base per il caricamento della configurazione dal file system. I provider di configurazione seguenti derivano da FileConfigurationProvider
:
Provider di configurazione INI
IniConfigurationProvider carica la configurazione da coppie chiave-valore di file INI in fase di esecuzione.
Il codice seguente aggiunge diversi provider di configurazione:
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();
Nel codice precedente le impostazioni nei file MyIniConfig.ini
e MyIniConfig.{Environment}.ini
sono sostituite dalle impostazioni in:
- Provider di configurazione delle variabili di ambiente
- Provider di configurazione della riga di comando.
Il download di esempio contiene il file MyIniConfig.ini
seguente:
MyKey="MyIniConfig.ini Value"
[Position]
Title="My INI Config title"
Name="My INI Config name"
[Logging:LogLevel]
Default=Information
Microsoft=Warning
Il codice seguente del download di esempio visualizza diverse impostazioni delle configurazioni precedenti:
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}");
}
}
Provider di configurazione JSON
Carica JsonConfigurationProvider la configurazione dalle coppie chiave-valore del file JSON.
Gli overload possono specificare:
- Se il file è facoltativo.
- Se la configurazione viene ricaricata se viene modificato il file.
Osservare il codice seguente:
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();
Il codice precedente:
- Configura il provider di configurazione JSON per caricare il
MyConfig.json
file con le opzioni seguenti:optional: true
: il file è facoltativo.reloadOnChange: true
: il file viene ricaricato quando vengono salvate le modifiche.
- Legge i provider di configurazione predefiniti prima del file
MyConfig.json
. Le impostazioni nel fileMyConfig.json
sostituiscono le impostazioni nei provider di configurazione predefiniti, incluso il provider di configurazione delle variabili di ambiente e il provider di configurazione della riga di comando.
In genere non si vuole che un file JSON personalizzato sostituisci i valori impostati nel provider di configurazione delle variabili di ambiente e nel provider di configurazione della riga di comando.
Provider di configurazione XML
Il XmlConfigurationProvider carica la configurazione da coppie chiave-valore di file XML in fase di esecuzione.
Il codice seguente aggiunge diversi provider di configurazione:
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();
Nel codice precedente le impostazioni nei file MyXMLFile.xml
e MyXMLFile.{Environment}.xml
sono sostituite dalle impostazioni in:
- Provider di configurazione delle variabili di ambiente
- Provider di configurazione della riga di comando.
Il download di esempio contiene il file MyXMLFile.xml
seguente:
<?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>
Il codice seguente del download di esempio visualizza diverse impostazioni delle configurazioni precedenti:
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}");
}
}
La ripetizione di elementi che usano lo stesso nome di elemento funziona se si usa l'attributo name
per distinguere gli elementi:
<?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>
Il codice seguente legge il file di configurazione precedente e visualizza le chiavi e i valori:
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"
);
}
}
È possibile usare attributi per fornire valori:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<key attribute="value" />
<section>
<key attribute="value" />
</section>
</configuration>
Il file di configurazione precedente carica le chiavi seguenti con value
:
- key:attribute
- section:key:attribute
Provider di configurazione chiave-per-file
Il KeyPerFileConfigurationProvider usa i file di una directory come coppie chiave-valore della configurazione. La chiave è il nome del file. Il valore contiene il contenuto del file. Il provider di configurazione chiave-per-file viene usato negli scenari di hosting di Docker.
Per attivare la configurazione chiave-per-file, chiamare il metodo di estensione AddKeyPerFile su un'istanza di ConfigurationBuilder. Il directoryPath
per i file deve essere un percorso assoluto.
Gli overload consentono di specificare:
- Un delegato
Action<KeyPerFileConfigurationSource>
che configura l'origine. - Se la directory è facoltativa e il percorso della directory.
Il doppio carattere di sottolineatura (__
) viene usato come delimitatore per le chiavi di configurazione nei nomi dei file. Ad esempio, il nome di file Logging__LogLevel__System
produce la chiave di configurazione Logging:LogLevel:System
.
Chiamare ConfigureAppConfiguration
quando si crea l'host per specificare la configurazione dell'app:
.ConfigureAppConfiguration((hostingContext, config) =>
{
var path = Path.Combine(
Directory.GetCurrentDirectory(), "path/to/files");
config.AddKeyPerFile(directoryPath: path, optional: true);
})
Provider di configurazione della memoria
Il MemoryConfigurationProvider usa una raccolta in memoria come coppie chiave-valore della configurazione.
Il codice seguente aggiunge una raccolta di memoria al sistema di configurazione:
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();
Il codice seguente del download di esempio visualizza le impostazioni delle configurazioni precedenti:
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}");
}
}
Nel codice precedente config.AddInMemoryCollection(Dict)
viene aggiunto dopo i provider di configurazione predefiniti. Per un esempio di ordinamento dei provider di configurazione, vedere Provider di configurazione JSON.
Vedere Associare una matrice per un altro esempio che usa MemoryConfigurationProvider
.
Configurazione di endpoint Kestrel
La configurazione di endpoint specifica di Kestrel sostituisce tutte le configurazioni di endpoint tra server. Le configurazioni di endpoint tra server includono:
- UseUrls
--urls
nella riga di comando- Variabile di ambiente
ASPNETCORE_URLS
Si consideri il file appsettings.json
seguente usato in un'app Web ASP.NET Core:
{
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://localhost:9999"
}
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Quando il markup evidenziato precedente viene usato in un'app Web ASP.NET Core e l'app viene avviata dalla riga di comando con la configurazione dell'endpoint tra server seguente:
dotnet run --urls="https://localhost:7777"
Kestrel si associa all'endpoint configurato specificatamente per Kestrel nel file appsettings.json
(https://localhost:9999
) e non in https://localhost:7777
.
Si consideri l'endpoint specifico di Kestrel configurato come variabile di ambiente:
set Kestrel__Endpoints__Https__Url=https://localhost:8888
nella variabile di ambiente precedente Https
è il nome dell'endpoint specifico di Kestrel. Il file appsettings.json
precedente definisce anche un endpoint specifico di Kestrel denominato Https
. Per impostazione predefinita, le variabili di ambiente che usano il provider di configurazione delle variabili di ambiente vengono lette dopo appsettings.{Environment}.json
, di conseguenza la variabile di ambiente precedente viene usata per l'endpoint Https
.
GetValue
ConfigurationBinder.GetValue estrae un valore dalla configurazione con una chiave specificata e lo converte nel tipo specificato:
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}");
}
}
Nel codice precedente, se NumberKey
non viene trovato nella configurazione, viene usato il valore predefinito di 99
.
GetSection, GetChildren ed Exists
Per gli esempi che seguono, prendere in considerazione il file MySubsection.json
seguente:
{
"section0": {
"key0": "value00",
"key1": "value01"
},
"section1": {
"key0": "value10",
"key1": "value11"
},
"section2": {
"subsection0": {
"key0": "value200",
"key1": "value201"
},
"subsection1": {
"key0": "value210",
"key1": "value211"
}
}
}
Il codice seguente aggiunge MySubsection.json
ai provider di configurazione:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.AddJsonFile("MySubsection.json",
optional: true,
reloadOnChange: true);
builder.Services.AddRazorPages();
var app = builder.Build();
GetSection
IConfiguration.GetSection restituisce una sottosezione della configurazione con la chiave di sottosezione specificata.
Il codice seguente restituisce i valori per 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"]}'");
}
}
Il codice seguente restituisce i valori per 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
non restituisce mai null
. Se non viene trovata una sezione corrispondente, viene restituita una IConfigurationSection
vuota.
Quando GetSection
restituisce una sezione corrispondente, Value non viene compilata. Quando la sezione esiste, vengono restituiti Key e Path.
GetChildren ed Exists
Il codice seguente chiama IConfiguration.GetChildren e restituisce i valori per 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);
}
}
Il codice precedente chiama ConfigurationExtensions.Exists per verificare che la sezione esista:
Associare una matrice
Il ConfigurationBinder.Bind supporta l'associazione di matrici agli oggetti usando gli indici delle matrici nelle chiavi di configurazione. Qualsiasi formato di matrice che espone un segmento chiave numerico supporta l'associazione di matrici a una matrice di classi POCO.
Si consideri MyArray.json
del download di esempio:
{
"array": {
"entries": {
"0": "value00",
"1": "value10",
"2": "value20",
"4": "value40",
"5": "value50"
}
}
}
Il codice seguente aggiunge MyArray.json
ai provider di configurazione:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.AddJsonFile("MyArray.json",
optional: true,
reloadOnChange: true);
builder.Services.AddRazorPages();
var app = builder.Build();
Il codice seguente legge la configurazione e visualizza i valori:
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; }
}
Il codice precedente restituisce l'output seguente:
Index: 0 Value: value00
Index: 1 Value: value10
Index: 2 Value: value20
Index: 3 Value: value40
Index: 4 Value: value50
Nell'output precedente Index 3 ha il valore value40
, corrispondente a "4": "value40",
in MyArray.json
. Gli indici di matrice associati sono continui e non associati all'indice delle chiavi di configurazione. Il binder di configurazione non supporta l'associazione di valori Null o la creazione di voci Null negli oggetti associati.
Provider di configurazione personalizzato
L'app di esempio dimostra come creare un provider di configurazione di base che legge le coppie chiave-valore di configurazione da un database usando Entity Framework (EF).
Il provider ha le caratteristiche seguenti:
- Il database in memoria di Entity Framework viene usato a scopo dimostrativo. Per usare un database che richiede una stringa di connessione, implementare un
ConfigurationBuilder
secondario per fornire la stringa di connessione da un altro provider di configurazione. - Il provider legge una tabella di database in una configurazione all'avvio. Il provider non esegue una query sul database per ogni chiave.
- Il ricaricamento in caso di modifica non è implementato, quindi l'aggiornamento del database dopo l'avvio dell'app non ha alcun effetto sulla configurazione dell'app.
Definire un'entità EFConfigurationValue
per l'archiviazione dei valori di configurazione nel database.
Models/EFConfigurationValue.cs
:
public class EFConfigurationValue
{
public string Id { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
}
Aggiungere EFConfigurationContext
per archiviare i valori configurati e accedervi.
EFConfigurationProvider/EFConfigurationContext.cs
:
public class EFConfigurationContext : DbContext
{
public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
{
}
public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}
Creare una classe che implementi 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);
}
Creare il provider di configurazione personalizzato ereditando da ConfigurationProvider. Il provider di configurazione inizializza il database quando è vuoto. Poiché nelle chiavi di configurazione non viene fatta distinzione tra maiuscole e minuscole, il dizionario usato per inizializzare il database viene creato con l'operatore di confronto senza distinzione tra maiuscole e minuscole (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;
}
}
Un metodo di estensione AddEFConfiguration
consente di aggiungere l'origine di configurazione a un ConfigurationBuilder
.
Extensions/EntityFrameworkExtensions.cs
:
public static class EntityFrameworkExtensions
{
public static IConfigurationBuilder AddEFConfiguration(
this IConfigurationBuilder builder,
Action<DbContextOptionsBuilder> optionsAction)
{
return builder.Add(new EFConfigurationSource(optionsAction));
}
}
Il codice seguente mostra come usare EFConfigurationProvider
personalizzato in Program.cs
:
//using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddEFConfiguration(
opt => opt.UseInMemoryDatabase("InMemoryDb"));
var app = builder.Build();
app.Run();
Configurazione dell'accesso con inserimento delle dipendenze
La configurazione può essere inserita nei servizi usando l'inserimento delle dipendenze attraverso la risoluzione del servizio IConfiguration:
public class Service
{
private readonly IConfiguration _config;
public Service(IConfiguration config) =>
_config = config;
public void DoSomething()
{
var configSettingValue = _config["ConfigSetting"];
// ...
}
}
Per informazioni su come accedere ai valori usando IConfiguration
, vedere GetValue e GetSection, GetChildren ed Exists in questo articolo.
Accedere alla configurazione nelle pagine Razor
Il codice seguente visualizza i dati di configurazione in una pagina Razor:
@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
Nel codice seguente MyOptions
viene aggiunta al contenitore del servizio con Configure e associata alla configurazione:
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
Il markup seguente usa la direttiva @inject
Razor per risolvere e visualizzare i valori delle opzioni:
@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>
Accedere alla configurazione in un file di visualizzazione MVC
Il codice seguente visualizza i dati di configurazione in una visualizzazione MVC:
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
Accedere alla configurazione in Program.cs
Il codice seguente accede alla configurazione nel file 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();
In appsettings.json
per l'esempio precedente:
{
...
"KeyOne": "Key One Value",
"KeyTwo": 1999,
"KeyThree": true
}
Configurare opzioni con un delegato
Le opzioni configurate in un delegato sostituiscono i valori impostati nei provider di configurazione.
Nel codice seguente viene aggiunto un servizio IConfigureOptions<TOptions> al contenitore di servizi. Viene usato un delegato per configurare i valori per 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();
Il codice seguente visualizza i valori delle opzioni:
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}");
}
}
Nell'esempio precedente i valori di Option1
e Option2
sono specificati in appsettings.json
e quindi sostituiti dal delegato configurato.
Host e configurazione delle app
Prima che l'app venga configurata e avviata, viene configurato e avviato un host. L'host è responsabile della gestione dell'avvio e della durata delle app. Sia l'app che l'host vengono configurati tramite i provider di configurazione descritti in questo argomento. Anche le coppie chiave-valore di configurazione dell'host sono incluse nella configurazione dell'app. Per altre informazioni su come vengono usati i provider di configurazione per la creazione dell'host e sugli effetti delle origini di configurazione sulla configurazione dell'host, vedere Panoramica delle nozioni di base su ASP.NET Core.
Configurazione dell'host predefinita
Per informazioni dettagliate sulla configurazione predefinita quando viene usato l'host Web, vedere la versione di questo argomento per ASP.NET Core 2.2.
- La configurazione dell'host viene fornita da:
- Variabili di ambiente con prefisso
DOTNET_
(ad esempio,DOTNET_ENVIRONMENT
) che usano il provider di configurazione delle variabili di ambiente. Il prefisso (DOTNET_
) viene rimosso al caricamento delle coppie chiave-valore della configurazione. - Argomenti della riga di comando che usano il provider di configurazione della riga di comando.
- Variabili di ambiente con prefisso
- Viene stabilita la configurazione predefinita dell'host Web (
ConfigureWebHostDefaults
):- Kestrel viene usato come server Web e configurato con i provider di configurazione dell'app.
- Aggiungere il middleware di filtro host.
- Aggiungere il middleware delle intestazioni inoltrate se la variabile di ambiente
ASPNETCORE_FORWARDEDHEADERS_ENABLED
è impostata sutrue
. - Abilitare l'integrazione di IIS.
Altra configurazione
Questo argomento riguarda solo la configurazione dell'app. Altri aspetti dell'esecuzione e dell'hosting delle app ASP.NET Core vengono configurati usando i file di configurazione non descritti in questo argomento:
launch.json
/launchSettings.json
sono file di configurazione degli strumenti per l'ambiente di sviluppo, descritto:- In Usare più ambienti in ASP.NET Core.
- Nel set di documentazione in cui i file vengono usati per configurare le app ASP.NET Core per gli scenari di sviluppo.
web.config
è un file di configurazione del server, descritto negli argomenti seguenti:
Variabili di ambiente impostate in launchSettings.json
sostituiscono quelle impostate nell'ambiente di sistema.
Per altre informazioni sulla migrazione della configurazione dell'app da versioni precedenti di ASP.NET, vedere Eseguire l'aggiornamento da ASP.NET a ASP.NET Core.
Aggiungere la configurazione da un assembly esterno
Un'implementazione IHostingStartup consente l'aggiunta di miglioramenti a un'app all'avvio, da un assembly esterno alla classe Startup
dell'app. Per altre informazioni, vedere Usare assembly di avvio dell'hosting in ASP.NET Core.
Risorse aggiuntive
La configurazione dell'applicazione in ASP.NET Core viene eseguita usando uno o più provider di configurazione. I provider di configurazione leggono i dati di configurazione da coppie chiave-valore usando diverse origini di configurazione:
- File di impostazioni, ad esempio
appsettings.json
- Variabili di ambiente
- Azure Key Vault
- Configurazione app di Azure
- Argomenti della riga di comando
- Provider personalizzati, installati o creati
- File della directory
- Oggetti .NET in memoria
Questo articolo offre informazioni sulla configurazione in ASP.NET Core. Per informazioni sull'uso della configurazione nelle app console, vedere Configurazione di .NET.
Configurazione dell'applicazione e dell'host
Le app ASP.NET Core configurano e avviano un host. L'host è responsabile della gestione dell'avvio e della durata delle app. I modelli di ASP.NET Core creano un WebApplicationBuilder che contiene l'host. Sebbene parte della configurazione possa essere eseguita sia nel provider di configurazione dell'host che nel provider di configurazione dell'applicazione, in generale solo la configurazione necessaria all'host deve essere eseguita nella configurazione dell'host.
La configurazione dell'applicazione è la priorità più alta ed è descritta nel dettaglio nella sezione successiva. La configurazione dell'host segue la configurazione dell'applicazione ed è descritta in questo articolo.
Origini della configurazione dell'applicazione predefinite
Le app Web ASP.NET Core create con dotnet new o Visual Studio generano il codice seguente:
var builder = WebApplication.CreateBuilder(args);
WebApplication.CreateBuilder inizializza una nuova istanza della classe WebApplicationBuilder con valori predefiniti preconfigurati. Il WebApplicationBuilder
(builder
) inizializzato offre la configurazione predefinita per l'app nell'ordine seguente, dalla priorità più alta a quella più bassa:
- Argomenti della riga di comando che usano il provider di configurazione della riga di comando.
- Variabili di ambiente senza prefisso che usano il provider di configurazione delle variabili di ambiente senza prefisso.
- Segreti dell'utente quando l'app viene eseguita nell'ambiente
Development
. appsettings.{Environment}.json
usando il provider di configurazione JSON. Ad esempio,appsettings.Production.json
eappsettings.Development.json
.- appsettings.json usando il provider di configurazione JSON.
- Un fallback alla configurazione dell'host descritto nella sezione successiva.
Origini della configurazione dell'host predefinite
L'elenco seguente contiene le origini della configurazione dell'host predefinite, dalla priorità più alta a quella più bassa:
- Variabili di ambiente con prefisso
ASPNETCORE_
che usano il provider di configurazione delle variabili di ambiente. - Argomenti della riga di comando che usano il provider di configurazione della riga di comando
- Variabili di ambiente con prefisso
DOTNET_
che usano il provider di configurazione delle variabili di ambiente.
Quando un valore di configurazione viene impostato nella configurazione dell'host e dell'applicazione, viene usata la configurazione dell'applicazione.
Vedere Spiegazione in questo commento di GitHub per una spiegazione del perché nella configurazione dell'host, le variabili di ambiente con prefisso ASPNETCORE_
hanno una priorità più alta degli argomenti della riga di comando.
Variabili dell'host
Le variabili seguenti vengono bloccate in anticipo durante l'inizializzazione dei generatori di host e non possono essere influenzate dalla configurazione dell'applicazione:
- Nome applicazione
- Nome dell'ambiente, ad esempio
Development
,Production
eStaging
- Radice del contenuto
- Radice Web
- Se cercare gli assembly di avvio di hosting e quali assembly cercare.
- Variabili lette dal codice dell'app e della libreria da hostBuilderContext.Configuration nei callback IHostBuilder.ConfigureAppConfiguration.
Ogni altra impostazione dell'host viene letta dalla configurazione dell'applicazione anziché dalla configurazione dell'host.
URLS
è una delle numerose impostazioni dell'host comuni che non è un'impostazione bootstrap. Come tutte le altre impostazioni dell'host non presenti nell'elenco precedente, URLS
viene letta successivamente dalla configurazione dell'applicazione. Poiché la configurazione dell'host è un fallback per la configurazione dell'applicazione, la configurazione dell'host può essere usata per impostare URLS
, ma verrà sostituita da qualsiasi origine di configurazione nella configurazione dell'applicazione, come appsettings.json
.
Per altre informazioni, vedere Modificare la radice del contenuto, il nome dell'app e l'ambiente e Modificare la radice del contenuto, il nome dell'app e l'ambiente in base alle variabili di ambiente o alla riga di comando
Le sezioni rimanenti di questo articolo fanno riferimento alla configurazione dell'applicazione.
Provider di configurazione dell'applicazione
Il codice seguente visualizza i provider di configurazione abilitati nell'ordine in cui sono stati aggiunti:
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);
}
}
L'elenco precedente delle origini di configurazione predefinite dalla priorità più alta alla priorità più bassa mostra i provider nell'ordine opposto in cui vengono aggiunti all'applicazione generata dal modello. Ad esempio, il provider di configurazione JSON viene aggiunto prima del provider di configurazione della riga di comando.
I provider di configurazione aggiunti successivamente hanno priorità più alta e sostituiscono le impostazioni delle chiavi precedenti. Ad esempio, se MyKey
è impostato sia in appsettings.json
che nell'ambiente, viene usato il valore dell'ambiente. Quando si usano i provider di configurazione predefiniti, il provider di configurazione della riga di comando sostituisce tutti gli altri provider.
Per altre informazioni su CreateBuilder
, vedere Impostazioni predefinite del generatore.
appsettings.json
Considerare il file appsettings.json
seguente:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Il codice seguente del download di esempio visualizza diverse impostazioni delle configurazioni precedenti:
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}");
}
}
Il JsonConfigurationProvider predefinito carica la configurazione nell'ordine seguente:
appsettings.json
appsettings.{Environment}.json
: ad esempio, i fileappsettings.Production.json
eappsettings.Development.json
. La versione dell'ambiente del file viene caricata in base a IHostingEnvironment.EnvironmentName. Per altre informazioni, vedere Usare più ambienti in ASP.NET Core.
I valori appsettings.{Environment}.json
sostituiscono le chiavi in appsettings.json
. Ad esempio, per impostazione predefinita:
- Nello sviluppo la configurazione
appsettings.Development.json
sovrascrive i valori trovati inappsettings.json
. - Nella produzione la configurazione
appsettings.Production.json
sovrascrive i valori trovati inappsettings.json
. Ad esempio, durante la distribuzione dell'app in Azure.
Se è necessario garantire un valore di configurazione, vedere GetValue. L'esempio precedente legge solo le stringhe e non supporta un valore predefinito.
Quando si usa la configurazione predefinita, i file appsettings.json
e appsettings.{Environment}.json
sono abilitati con reloadOnChange: true. Le modifiche apportate al appsettings.json
file e appsettings.{Environment}.json
dopo l'avvio dell'app vengono lette dal provider di configurazione JSON.
Associare dati di configurazione gerarchici usando il modello di opzioni
Il modo preferito per leggere i valori di configurazione correlati prevede l'uso del modello di opzioni. Ad esempio, per leggere i valori di configurazione seguenti:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Creare la classe PositionOptions
seguente:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
}
Una classe di opzioni:
- Deve essere non astratta con un costruttore pubblico senza parametri.
- Tutte le proprietà di lettura/scrittura pubbliche del tipo sono associate.
- I campi non sono associati. Nel codice precedente
Position
non è associato. Il campoPosition
viene usato in modo che la stringa"Position"
non debba essere hardcoded nell'app quando la classe viene associata a un provider di configurazione.
Il codice seguente:
- Chiama ConfigurationBinder.Bind per associare la classe
PositionOptions
alla sezionePosition
. - Visualizza i dati di configurazione di
Position
.
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}");
}
}
Nel codice precedente, per impostazione predefinita, le modifiche apportate al file di configurazione JSON dopo l'avvio dell'app vengono lette.
ConfigurationBinder.Get<T>
associa e restituisce il tipo specificato. ConfigurationBinder.Get<T>
può risultare più utile rispetto all'uso di ConfigurationBinder.Bind
. Il codice seguente mostra come usare ConfigurationBinder.Get<T>
con la classe PositionOptions
:
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}");
}
}
Nel codice precedente, per impostazione predefinita, le modifiche apportate al file di configurazione JSON dopo l'avvio dell'app vengono lette.
Un approccio alternativo quando si usa il modello opzioni consiste nell'associare la sezione Position
e aggiungerla al contenitore del servizio di inserimento di dipendenze. Nel codice seguente PositionOptions
viene aggiunta al contenitore del servizio con Configure e associata alla configurazione:
using ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<PositionOptions>(
builder.Configuration.GetSection(PositionOptions.Position));
var app = builder.Build();
Quando si usa il codice precedente, il codice seguente legge le opzioni di posizione:
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}");
}
}
Nel codice precedente le modifiche al file di configurazione JSON dopo l'avvio dell'app non vengono lette. Per leggere le modifiche dopo l'avvio dell'app, usare IOptionsSnapshot.
Quando si usa la configurazione predefinita, i file appsettings.json
e appsettings.{Environment}.json
sono abilitati con reloadOnChange: true. Le modifiche apportate al appsettings.json
file e appsettings.{Environment}.json
dopo l'avvio dell'app vengono lette dal provider di configurazione JSON.
Per informazioni sull'aggiunta di file di configurazione JSON aggiuntivi, vedere Provider di configurazione JSON in questo documento.
Combinazione della raccolta di servizi
Considerare il codice seguente che registra i servizi e configura le opzioni:
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();
I gruppi correlati di registrazioni possono essere spostati in un metodo di estensione per registrare i servizi. Ad esempio, i servizi di configurazione vengono aggiunti alla classe seguente:
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;
}
}
}
I servizi rimanenti vengono registrati in una classe simile. Il codice seguente usa i nuovi metodi di estensione per registrare i servizi:
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: ogni metodo di estensione services.Add{GROUP_NAME}
aggiunge e configura potenzialmente i servizi. Ad esempio, AddControllersWithViews aggiunge i controller MVC dei servizi con visualizzazioni richiesti e AddRazorPages aggiunge le pagina Razor dei servizi richieste.
Sicurezza e segreti dell'utente
Linee guida per i dati di configurazione:
- Non archiviare mai la password o altri dati sensibili nel codice del provider di configurazione o in file di configurazione di testo normale. Per l'archiviazione di segreti per lo sviluppo, è possibile usare lo strumento Secret Manager.
- Non usare i segreti di produzione in ambienti di sviluppo o di test.
- Specificare i segreti all'esterno del progetto in modo che non possano essere inavvertitamente inviati a un repository del codice sorgente.
- Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni, vedere Proteggere i flussi di autenticazione.
Per impostazione predefinita, l'origine di configurazione dei segreti utente viene registrata dopo le origini di configurazione JSON. Pertanto, le chiavi dei segreti dell'utente hanno la precedenza sulle chiavi in appsettings.json
e appsettings.{Environment}.json
.
Per altre informazioni sull'archiviazione di password o altri dati sensibili:
- Usare più ambienti in ASP.NET Core
- Archiviazione sicura di segreti dell'app durante lo sviluppo in ASP.NET Core: include consigli sull'uso delle variabili di ambiente per l'archiviazione dei dati sensibili. Lo strumento Secret Manager usa il provider di configurazione file per archiviare i segreti utente in un file JSON nel sistema locale.
Azure Key Vault archivia in modo sicuro i segreti delle app ASP.NET Core. Per altre informazioni, vedere Provider di configurazione di Azure Key Vault in ASP.NET Core.
Variabili di ambiente senza prefisso
Le variabili di ambiente senza prefisso sono variabili di ambiente diverse da quelle precedute da ASPNETCORE_
o DOTNET_
. Ad esempio, i modelli di applicazione Web ASP.NET Core impostano "ASPNETCORE_ENVIRONMENT": "Development"
in launchSettings.json
. Per altre informazioni sulle variabili di ambiente ASPNETCORE_
e DOTNET_
, vedere:
- Elenco delle origini di configurazione predefinite dalla priorità più alta alla priorità più bassa incluse le variabili di ambiente senza prefisso, con prefisso
ASPNETCORE_
e con prefissoDOTNETCORE_
. - Variabili di ambiente
DOTNET_
usate all'esterno di Microsoft.Extensions.Hosting.
Quando si usa la configurazione predefinita, EnvironmentVariablesConfigurationProvider carica la configurazione dalle coppie chiave-valore delle variabili di ambiente dopo la lettura di appsettings.json
, appsettings.{Environment}.json
e dei segreti dell'utente. Therefore, i valori di chiave letti dall'ambiente sostituiscono i valori letti da appsettings.json
, appsettings.{Environment}.json
e dai segreti dell'utente.
Il separatore :
non funziona con le chiavi gerarchiche delle variabili di ambiente in tutte le piattaforme. Ad esempio, il :
separatore non è supportato da Bash. Il doppio carattere di sottolineatura, __
, è:
- Supportato da tutte le piattaforme.
- Sostituito automaticamente da due punti,
:
.
I comandi set
seguenti:
- Impostano le chiavi e i valori di ambiente dell'esempio precedente in Windows.
- Testano le impostazioni quando viene usato il download di esempio. Il comando
dotnet run
deve essere eseguito nella directory del progetto.
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run
Le impostazioni dell'ambiente precedenti:
- Sono impostate solo nei processi avviati dalla finestra di comando in cui sono stati impostate.
- Non verranno lette dai browser avviati con Visual Studio.
I comandi setx seguenti possono essere usati per impostare le chiavi e i valori di ambiente in Windows. A differenza di set
, le impostazioni setx
vengono mantenute. /M
imposta la variabile nell'ambiente di sistema. Se non viene usata l'opzione /M
, viene impostata una variabile di ambiente dell'utente.
setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M
Per verificare che i comandi precedenti sostituiscano appsettings.json
e appsettings.{Environment}.json
:
- Con Visual Studio: uscire e riavviare Visual Studio.
- Con l'interfaccia della riga di comando: avviare una nuova finestra di comando e immettere
dotnet run
.
Chiamare AddEnvironmentVariables con una stringa per specificare un prefisso per le variabili di ambiente:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
var app = builder.Build();
Nel codice precedente:
builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_")
viene aggiunto dopo i provider di configurazione predefiniti. Per un esempio di ordinamento dei provider di configurazione, vedere Provider di configurazione JSON.- Le variabili di ambiente impostate con il prefisso
MyCustomPrefix_
sostituiscono i provider di configurazione predefiniti. Sono incluse le variabili di ambiente senza il prefisso.
Il prefisso viene rimosso quando vengono lette le coppie chiave-valore della configurazione.
I comandi seguenti testano il prefisso personalizzato:
set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run
La configurazione predefinita carica le variabili di ambiente e gli argomenti della riga di comando con prefisso DOTNET_
e ASPNETCORE_
. I prefissi DOTNET_
e ASPNETCORE_
vengono usati da ASP.NET Core per la configurazione dell'host e dell'app, ma non per la configurazione dell'utente. Per altre informazioni sulla configurazione dell'host e dell'app, vedere Host generico .NET.
In Servizio app di Azure selezionare Nuova impostazione applicazione nella pagina Impostazioni > Configurazione. Le impostazioni applicazione del Servizio app di Azure sono:
- Crittografato in e rest trasmesso tramite un canale crittografato.
- Esposte come variabili di ambiente.
Per altre informazioni, vedere App di Azure: Eseguire l'override della configurazione delle app usando il portale di Azure.
Per informazioni sulle stringhe di connessione del database di Azure, vedere Prefissi della stringa di connessione.
Denominazione delle variabili di ambiente
I nomi delle variabili di ambiente riflettono la struttura di un file appsettings.json
. Ogni elemento nella gerarchia è separato da un doppio carattere di sottolineatura (preferibile) o due punti. Quando la struttura dell'elemento include una matrice, l'indice della matrice deve essere considerato come un nome di elemento aggiuntivo in questo percorso. Si consideri il file appsettings.json
seguente e i relativi valori equivalenti rappresentati come variabili di 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"
}
]
}
variabili di 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
Variabili di ambiente impostate nel file launchSettings.json generato
Variabili di ambiente impostate in launchSettings.json
sostituiscono quelle impostate nell'ambiente di sistema. Ad esempio, i modelli Web ASP.NET Core generano un file launchSettings.json
che imposta la configurazione dell'endpoint su:
"applicationUrl": "https://localhost:5001;http://localhost:5000"
La configurazione di applicationUrl
imposta la variabile di ambiente ASPNETCORE_URLS
e sostituisce i valori impostati nell'ambiente.
Carattere di escape per le variabili di ambiente in Linux
In Linux il valore delle variabili di ambiente degli URL deve essere preceduto da un carattere di escape in modo che systemd
possa analizzarle. Usare lo strumento linux systemd-escape
che restituisce http:--localhost:5001
groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001
Visualizzare le variabili di ambiente
Il codice seguente visualizza le variabili di ambiente e i valori all'avvio dell'applicazione, utile durante il debug delle impostazioni di ambiente:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
foreach (var c in builder.Configuration.AsEnumerable())
{
Console.WriteLine(c.Key + " = " + c.Value);
}
Riga di comando
Quando si usa la configurazione predefinita, CommandLineConfigurationProvider carica la configurazione dalle coppie chiave-valore degli argomenti della riga di comando dopo le origini di configurazione seguenti:
- File
appsettings.json
eappsettings.{Environment}.json
. - Segreti dell'app nell'ambiente di sviluppo.
- variabili di ambiente.
Per impostazione predefinita, i valori di configurazione impostati nella riga di comando sostituiscono i valori di configurazione impostati con tutti gli altri provider di configurazione.
Argomenti della riga di comando
Il comando seguente imposta chiavi e valori usando =
:
dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick
Il comando seguente imposta chiavi e valori usando /
:
dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick
Il comando seguente imposta chiavi e valori usando --
:
dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick
Il valore di chiave:
- Deve seguire
=
o la chiave deve avere un prefisso--
o/
quando il valore segue uno spazio. - Non è richiesto se viene usato
=
. Ad esempio:MySetting=
.
Nello stesso comando, non mischiare coppie chiave-valore di argomenti della riga di comando che usano =
con coppie chiave-valore che usano uno spazio.
Mapping di sostituzione
I mapping di sostituzione consentono di usare la logica di sostituzione del nome della chiave. Specificare un dizionario delle sostituzioni al metodo AddCommandLine.
Quando viene utilizzato il dizionario dei mapping di sostituzione, nel dizionario viene controllata la presenza di una chiave corrispondente alla chiave fornita da un argomento della riga di comando. Se la chiave della riga di comando viene trovata nel dizionario, il valore del dizionario viene passato nuovamente per impostare la coppia chiave-valore nella configurazione dell'app. Un mapping di sostituzione è necessario per le chiavi della riga di comando con un trattino singolo (-
) come prefisso.
Regole principali del dizionario dei mapping di sostituzione:
- Le sostituzioni devono iniziare con
-
o--
. - Il dizionario dei mapping di sostituzione non deve contenere chiavi duplicate.
Per usare un dizionario dei mapping di sostituzione, passarlo nella chiamata a 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();
Per testare la sostituzione delle chiavi è possibile eseguire il comando seguente:
dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6
Il codice seguente mostra i valori di chiave per le chiavi sostituite:
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"]}'");
}
}
Per le app che usano i mapping di sostituzione, la chiamata a CreateDefaultBuilder
non deve passare argomenti. La chiamata AddCommandLine
del metodo CreateDefaultBuilder
non include sostituzioni mappate e non è possibile passare il dizionario dei mapping di sostituzione a CreateDefaultBuilder
. La soluzione non consiste nel passare gli argomenti a CreateDefaultBuilder
ma nel consentire al metodo AddCommandLine
del metodo ConfigurationBuilder
di elaborare entrambi gli argomenti e il dizionario dei mapping di sostituzione.
Impostare gli argomenti dell'ambiente e della riga di comando con Visual Studio
Gli argomenti dell'ambiente e della riga di comando possono essere impostati in Visual Studio dalla finestra dei profili di avvio:
- In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e selezionare Proprietà.
- Selezionare la scheda Debug > Generale e selezionare Aprire interfaccia utente profili di avvio debug.
Dati di configurazione gerarchici
L'API di configurazione legge i dati di configurazione gerarchici rendendoli flat grazie all'uso di un delimitatore nelle chiavi di configurazione.
Il download di esempio contiene il file appsettings.json
seguente:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Il codice seguente del download di esempio visualizza diverse impostazioni delle configurazioni:
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}");
}
}
Il modo preferito per leggere i dati di configurazione gerarchici prevede l'uso del modello di opzioni. Per altre informazioni, vedere Associare dati di configurazione gerarchici in questo documento.
I metodi GetSection e GetChildren sono disponibili per isolare le sezioni e gli elementi figlio di una sezione nei dati di configurazione. Questi metodi sono descritti più avanti in GetSection, GetChildren ed Exists.
Chiavi e valori di configurazione
Avviso
Questo articolo illustra l'uso di stringa di connessione. Con un database locale l'utente non deve essere autenticato, ma nell'ambiente di produzione stringa di connessione talvolta include una password per l'autenticazione. Una credenziale della password del proprietario della risorsa (ROPC) è un rischio per la sicurezza che deve essere evitato nei database di produzione. Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni sull'autenticazione per le app distribuite in ambienti di test o di produzione, vedere Proteggere i flussi di autenticazione.
Chiavi di configurazione:
- non viene fatta distinzione tra maiuscole e minuscole. Ad esempio,
ConnectionString
econnectionstring
vengono considerate chiavi equivalenti. - Se una chiave e un valore vengono impostati in più di un provider di configurazione, viene usato il valore dell'ultimo provider aggiunto. Per altre informazioni, vedere Configurazione predefinita.
- Chiavi gerarchica
- Nell'ambito dell'API di configurazione, il separatore due punti (
:
) funziona in tutte le piattaforme. - Nelle variabili di ambiente, un separatore due punti potrebbe non funzionare in tutte le piattaforme. Il doppio carattere di sottolineatura,
__
, è supportato da tutte le piattaforme e viene convertito automaticamente nei due punti:
. - In Azure Key Vault le chiavi gerarchiche usano
--
come separatore. Il provider di configurazione di Azure Key Vault sostituisce automaticamente--
con:
quando i segreti vengono caricati nella configurazione dell'app.
- Nell'ambito dell'API di configurazione, il separatore due punti (
- Il ConfigurationBinder supporta l'associazione di matrici agli oggetti usando gli indici delle matrici nelle chiavi di configurazione. L'associazione di matrici è descritta nella sezione Associare una matrice a una classe.
Valori di configurazione:
- sono stringhe.
- I valori null non possono essere archiviati nella configurazione o associati a oggetti.
Provider di configurazione
La tabella seguente mostra i provider di configurazione disponibili per le app ASP.NET Core.
Provider | Fornisce la configurazione da |
---|---|
Azure Key Vault configuration provider (Provider di configurazione di Azure Key Vault) | Azure Key Vault |
Provider di configurazione app di Azure | Configurazione app di Azure |
Provider di configurazione della riga di comando | Parametri della riga di comando |
Provider di configurazione personalizzato | Origine personalizzata |
Provider di configurazione delle variabili di ambiente | Variabili di ambiente |
Provider di configurazione file | File INI, JSON e XML |
Provider di configurazione chiave-per-file | File della directory |
Provider di configurazione della memoria | Raccolte in memoria |
Segreti utente | File nella directory dei profili utente |
Le origini di configurazione vengono lette nell'ordine in cui vengono specificati i rispetti provider di configurazione. Ordinare i provider di configurazione nel codice in base alle priorità per le origini di configurazione sottostanti richieste dall'app.
Una sequenza tipica di provider di configurazione è:
appsettings.json
appsettings.{Environment}.json
- Segreti utente
- Variabili di ambiente che usano il provider di configurazione delle variabili di ambiente.
- Argomenti della riga di comando che usano il provider di configurazione della riga di comando.
È pratica comune aggiungere il provider di configurazione della riga di comando per ultimo in una serie di provider per consentire agli argomenti della riga di comando di sostituire la configurazione impostata da altri provider.
La sequenza di provider precedente è usata nella configurazione predefinita.
Prefissi della stringa di connessione
Avviso
Questo articolo illustra l'uso di stringa di connessione. Con un database locale l'utente non deve essere autenticato, ma nell'ambiente di produzione stringa di connessione talvolta include una password per l'autenticazione. Una credenziale della password del proprietario della risorsa (ROPC) è un rischio per la sicurezza che deve essere evitato nei database di produzione. Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni sull'autenticazione per le app distribuite in ambienti di test o di produzione, vedere Proteggere i flussi di autenticazione.
L'API di configurazione ha regole di elaborazione speciali per quattro variabili di ambiente della stringa di connessione. Queste stringhe di connessione sono coinvolte nella configurazione delle stringhe di connessione di Azure per l'ambiente dell'app. Le variabili di ambiente con i prefissi indicati nella tabella vengono caricate nell'app con la configurazione predefinita o quando non viene specificato alcun prefisso per AddEnvironmentVariables
.
Prefisso della stringa di connessione | Provider |
---|---|
CUSTOMCONNSTR_ |
Provider personalizzato |
MYSQLCONNSTR_ |
MySQL |
SQLAZURECONNSTR_ |
Database SQL di Azure |
SQLCONNSTR_ |
SQL Server |
Quando una variabile di ambiente viene individuata e caricata nella configurazione con uno qualsiasi dei quattro prefissi indicati nella tabella:
- La chiave di configurazione viene creata rimuovendo il prefisso della variabile di ambiente e aggiungendo una sezione per la chiave di configurazione (
ConnectionStrings
). - Viene creata una nuova coppia chiave-valore della configurazione che rappresenta il provider di connessione al database (ad eccezione di
CUSTOMCONNSTR_
, che non ha un provider dichiarato).
Chiave della variabile di ambiente | Chiave di configurazione convertita | Voce di configurazione del provider |
---|---|---|
CUSTOMCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Voce di configurazione non creata. |
MYSQLCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Chiave: ConnectionStrings:{KEY}_ProviderName :Valore: MySql.Data.MySqlClient |
SQLAZURECONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Chiave: ConnectionStrings:{KEY}_ProviderName :Valore: System.Data.SqlClient |
SQLCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Chiave: ConnectionStrings:{KEY}_ProviderName :Valore: System.Data.SqlClient |
Provider di configurazione file
FileConfigurationProvider è la classe base per il caricamento della configurazione dal file system. I provider di configurazione seguenti derivano da FileConfigurationProvider
:
Provider di configurazione INI
IniConfigurationProvider carica la configurazione da coppie chiave-valore di file INI in fase di esecuzione.
Il codice seguente aggiunge diversi provider di configurazione:
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();
Nel codice precedente le impostazioni nei file MyIniConfig.ini
e MyIniConfig.{Environment}.ini
sono sostituite dalle impostazioni in:
- Provider di configurazione delle variabili di ambiente
- Provider di configurazione della riga di comando.
Il download di esempio contiene il file MyIniConfig.ini
seguente:
MyKey="MyIniConfig.ini Value"
[Position]
Title="My INI Config title"
Name="My INI Config name"
[Logging:LogLevel]
Default=Information
Microsoft=Warning
Il codice seguente del download di esempio visualizza diverse impostazioni delle configurazioni precedenti:
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}");
}
}
Provider di configurazione JSON
Carica JsonConfigurationProvider la configurazione dalle coppie chiave-valore del file JSON.
Gli overload possono specificare:
- Se il file è facoltativo.
- Se la configurazione viene ricaricata se viene modificato il file.
Osservare il codice seguente:
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();
Il codice precedente:
- Configura il provider di configurazione JSON per caricare il
MyConfig.json
file con le opzioni seguenti:optional: true
: il file è facoltativo.reloadOnChange: true
: il file viene ricaricato quando vengono salvate le modifiche.
- Legge i provider di configurazione predefiniti prima del file
MyConfig.json
. Le impostazioni nel fileMyConfig.json
sostituiscono le impostazioni nei provider di configurazione predefiniti, incluso il provider di configurazione delle variabili di ambiente e il provider di configurazione della riga di comando.
In genere non si vuole che un file JSON personalizzato sostituisci i valori impostati nel provider di configurazione delle variabili di ambiente e nel provider di configurazione della riga di comando.
Provider di configurazione XML
Il XmlConfigurationProvider carica la configurazione da coppie chiave-valore di file XML in fase di esecuzione.
Il codice seguente aggiunge diversi provider di configurazione:
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();
Nel codice precedente le impostazioni nei file MyXMLFile.xml
e MyXMLFile.{Environment}.xml
sono sostituite dalle impostazioni in:
- Provider di configurazione delle variabili di ambiente
- Provider di configurazione della riga di comando.
Il download di esempio contiene il file MyXMLFile.xml
seguente:
<?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>
Il codice seguente del download di esempio visualizza diverse impostazioni delle configurazioni precedenti:
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}");
}
}
La ripetizione di elementi che usano lo stesso nome di elemento funziona se si usa l'attributo name
per distinguere gli elementi:
<?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>
Il codice seguente legge il file di configurazione precedente e visualizza le chiavi e i valori:
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"
);
}
}
È possibile usare attributi per fornire valori:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<key attribute="value" />
<section>
<key attribute="value" />
</section>
</configuration>
Il file di configurazione precedente carica le chiavi seguenti con value
:
- key:attribute
- section:key:attribute
Provider di configurazione chiave-per-file
Il KeyPerFileConfigurationProvider usa i file di una directory come coppie chiave-valore della configurazione. La chiave è il nome del file. Il valore contiene il contenuto del file. Il provider di configurazione chiave-per-file viene usato negli scenari di hosting di Docker.
Per attivare la configurazione chiave-per-file, chiamare il metodo di estensione AddKeyPerFile su un'istanza di ConfigurationBuilder. Il directoryPath
per i file deve essere un percorso assoluto.
Gli overload consentono di specificare:
- Un delegato
Action<KeyPerFileConfigurationSource>
che configura l'origine. - Se la directory è facoltativa e il percorso della directory.
Il doppio carattere di sottolineatura (__
) viene usato come delimitatore per le chiavi di configurazione nei nomi dei file. Ad esempio, il nome di file Logging__LogLevel__System
produce la chiave di configurazione Logging:LogLevel:System
.
Chiamare ConfigureAppConfiguration
quando si crea l'host per specificare la configurazione dell'app:
.ConfigureAppConfiguration((hostingContext, config) =>
{
var path = Path.Combine(
Directory.GetCurrentDirectory(), "path/to/files");
config.AddKeyPerFile(directoryPath: path, optional: true);
})
Provider di configurazione della memoria
Il MemoryConfigurationProvider usa una raccolta in memoria come coppie chiave-valore della configurazione.
Il codice seguente aggiunge una raccolta di memoria al sistema di configurazione:
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();
Il codice seguente del download di esempio visualizza le impostazioni delle configurazioni precedenti:
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}");
}
}
Nel codice precedente config.AddInMemoryCollection(Dict)
viene aggiunto dopo i provider di configurazione predefiniti. Per un esempio di ordinamento dei provider di configurazione, vedere Provider di configurazione JSON.
Vedere Associare una matrice per un altro esempio che usa MemoryConfigurationProvider
.
Configurazione di endpoint Kestrel
La configurazione di endpoint specifica di Kestrel sostituisce tutte le configurazioni di endpoint tra server. Le configurazioni di endpoint tra server includono:
- UseUrls
--urls
nella riga di comando- Variabile di ambiente
ASPNETCORE_URLS
Si consideri il file appsettings.json
seguente usato in un'app Web ASP.NET Core:
{
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://localhost:9999"
}
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Quando il markup evidenziato precedente viene usato in un'app Web ASP.NET Core e l'app viene avviata dalla riga di comando con la configurazione dell'endpoint tra server seguente:
dotnet run --urls="https://localhost:7777"
Kestrel si associa all'endpoint configurato specificatamente per Kestrel nel file appsettings.json
(https://localhost:9999
) e non in https://localhost:7777
.
Si consideri l'endpoint specifico di Kestrel configurato come variabile di ambiente:
set Kestrel__Endpoints__Https__Url=https://localhost:8888
nella variabile di ambiente precedente Https
è il nome dell'endpoint specifico di Kestrel. Il file appsettings.json
precedente definisce anche un endpoint specifico di Kestrel denominato Https
. Per impostazione predefinita, le variabili di ambiente che usano il provider di configurazione delle variabili di ambiente vengono lette dopo appsettings.{Environment}.json
, di conseguenza la variabile di ambiente precedente viene usata per l'endpoint Https
.
GetValue
ConfigurationBinder.GetValue estrae un valore dalla configurazione con una chiave specificata e lo converte nel tipo specificato:
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}");
}
}
Nel codice precedente, se NumberKey
non viene trovato nella configurazione, viene usato il valore predefinito di 99
.
GetSection, GetChildren ed Exists
Per gli esempi che seguono, prendere in considerazione il file MySubsection.json
seguente:
{
"section0": {
"key0": "value00",
"key1": "value01"
},
"section1": {
"key0": "value10",
"key1": "value11"
},
"section2": {
"subsection0": {
"key0": "value200",
"key1": "value201"
},
"subsection1": {
"key0": "value210",
"key1": "value211"
}
}
}
Il codice seguente aggiunge MySubsection.json
ai provider di configurazione:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.AddJsonFile("MySubsection.json",
optional: true,
reloadOnChange: true);
builder.Services.AddRazorPages();
var app = builder.Build();
GetSection
IConfiguration.GetSection restituisce una sottosezione della configurazione con la chiave di sottosezione specificata.
Il codice seguente restituisce i valori per 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"]}'");
}
}
Il codice seguente restituisce i valori per 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
non restituisce mai null
. Se non viene trovata una sezione corrispondente, viene restituita una IConfigurationSection
vuota.
Quando GetSection
restituisce una sezione corrispondente, Value non viene compilata. Quando la sezione esiste, vengono restituiti Key e Path.
GetChildren ed Exists
Il codice seguente chiama IConfiguration.GetChildren e restituisce i valori per 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);
}
}
Il codice precedente chiama ConfigurationExtensions.Exists per verificare che la sezione esista:
Associare una matrice
Il ConfigurationBinder.Bind supporta l'associazione di matrici agli oggetti usando gli indici delle matrici nelle chiavi di configurazione. Qualsiasi formato di matrice che espone un segmento chiave numerico supporta l'associazione di matrici a una matrice di classi POCO.
Si consideri MyArray.json
del download di esempio:
{
"array": {
"entries": {
"0": "value00",
"1": "value10",
"2": "value20",
"4": "value40",
"5": "value50"
}
}
}
Il codice seguente aggiunge MyArray.json
ai provider di configurazione:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.AddJsonFile("MyArray.json",
optional: true,
reloadOnChange: true);
builder.Services.AddRazorPages();
var app = builder.Build();
Il codice seguente legge la configurazione e visualizza i valori:
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; }
}
Il codice precedente restituisce l'output seguente:
Index: 0 Value: value00
Index: 1 Value: value10
Index: 2 Value: value20
Index: 3 Value: value40
Index: 4 Value: value50
Nell'output precedente Index 3 ha il valore value40
, corrispondente a "4": "value40",
in MyArray.json
. Gli indici di matrice associati sono continui e non associati all'indice delle chiavi di configurazione. Il binder di configurazione non supporta l'associazione di valori Null o la creazione di voci Null negli oggetti associati.
Provider di configurazione personalizzato
L'app di esempio dimostra come creare un provider di configurazione di base che legge le coppie chiave-valore di configurazione da un database usando Entity Framework (EF).
Il provider ha le caratteristiche seguenti:
- Il database in memoria di Entity Framework viene usato a scopo dimostrativo. Per usare un database che richiede una stringa di connessione, implementare un
ConfigurationBuilder
secondario per fornire la stringa di connessione da un altro provider di configurazione. - Il provider legge una tabella di database in una configurazione all'avvio. Il provider non esegue una query sul database per ogni chiave.
- Il ricaricamento in caso di modifica non è implementato, quindi l'aggiornamento del database dopo l'avvio dell'app non ha alcun effetto sulla configurazione dell'app.
Definire un'entità EFConfigurationValue
per l'archiviazione dei valori di configurazione nel database.
Models/EFConfigurationValue.cs
:
public class EFConfigurationValue
{
public string Id { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
}
Aggiungere EFConfigurationContext
per archiviare i valori configurati e accedervi.
EFConfigurationProvider/EFConfigurationContext.cs
:
public class EFConfigurationContext : DbContext
{
public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
{
}
public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}
Creare una classe che implementi 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);
}
Creare il provider di configurazione personalizzato ereditando da ConfigurationProvider. Il provider di configurazione inizializza il database quando è vuoto. Poiché nelle chiavi di configurazione non viene fatta distinzione tra maiuscole e minuscole, il dizionario usato per inizializzare il database viene creato con l'operatore di confronto senza distinzione tra maiuscole e minuscole (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;
}
}
Un metodo di estensione AddEFConfiguration
consente di aggiungere l'origine di configurazione a un ConfigurationBuilder
.
Extensions/EntityFrameworkExtensions.cs
:
public static class EntityFrameworkExtensions
{
public static IConfigurationBuilder AddEFConfiguration(
this IConfigurationBuilder builder,
Action<DbContextOptionsBuilder> optionsAction)
{
return builder.Add(new EFConfigurationSource(optionsAction));
}
}
Il codice seguente mostra come usare EFConfigurationProvider
personalizzato in Program.cs
:
//using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddEFConfiguration(
opt => opt.UseInMemoryDatabase("InMemoryDb"));
var app = builder.Build();
app.Run();
Configurazione dell'accesso con inserimento delle dipendenze
La configurazione può essere inserita nei servizi usando l'inserimento delle dipendenze attraverso la risoluzione del servizio IConfiguration:
public class Service
{
private readonly IConfiguration _config;
public Service(IConfiguration config) =>
_config = config;
public void DoSomething()
{
var configSettingValue = _config["ConfigSetting"];
// ...
}
}
Per informazioni su come accedere ai valori usando IConfiguration
, vedere GetValue e GetSection, GetChildren ed Exists in questo articolo.
Accedere alla configurazione nelle pagine Razor
Il codice seguente visualizza i dati di configurazione in una pagina Razor:
@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
Nel codice seguente MyOptions
viene aggiunta al contenitore del servizio con Configure e associata alla configurazione:
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
Il markup seguente usa la direttiva @inject
Razor per risolvere e visualizzare i valori delle opzioni:
@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>
Accedere alla configurazione in un file di visualizzazione MVC
Il codice seguente visualizza i dati di configurazione in una visualizzazione MVC:
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
Accedere alla configurazione in Program.cs
Il codice seguente accede alla configurazione nel file 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();
In appsettings.json
per l'esempio precedente:
{
...
"KeyOne": "Key One Value",
"KeyTwo": 1999,
"KeyThree": true
}
Configurare opzioni con un delegato
Le opzioni configurate in un delegato sostituiscono i valori impostati nei provider di configurazione.
Nel codice seguente viene aggiunto un servizio IConfigureOptions<TOptions> al contenitore di servizi. Viene usato un delegato per configurare i valori per 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();
Il codice seguente visualizza i valori delle opzioni:
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}");
}
}
Nell'esempio precedente i valori di Option1
e Option2
sono specificati in appsettings.json
e quindi sostituiti dal delegato configurato.
Host e configurazione delle app
Prima che l'app venga configurata e avviata, viene configurato e avviato un host. L'host è responsabile della gestione dell'avvio e della durata delle app. Sia l'app che l'host vengono configurati tramite i provider di configurazione descritti in questo argomento. Anche le coppie chiave-valore di configurazione dell'host sono incluse nella configurazione dell'app. Per altre informazioni su come vengono usati i provider di configurazione per la creazione dell'host e sugli effetti delle origini di configurazione sulla configurazione dell'host, vedere Panoramica delle nozioni di base su ASP.NET Core.
Configurazione dell'host predefinita
Per informazioni dettagliate sulla configurazione predefinita quando viene usato l'host Web, vedere la versione di questo argomento per ASP.NET Core 2.2.
- La configurazione dell'host viene fornita da:
- Variabili di ambiente con prefisso
DOTNET_
(ad esempio,DOTNET_ENVIRONMENT
) che usano il provider di configurazione delle variabili di ambiente. Il prefisso (DOTNET_
) viene rimosso al caricamento delle coppie chiave-valore della configurazione. - Argomenti della riga di comando che usano il provider di configurazione della riga di comando.
- Variabili di ambiente con prefisso
- Viene stabilita la configurazione predefinita dell'host Web (
ConfigureWebHostDefaults
):- Kestrel viene usato come server Web e configurato con i provider di configurazione dell'app.
- Aggiungere il middleware di filtro host.
- Aggiungere il middleware delle intestazioni inoltrate se la variabile di ambiente
ASPNETCORE_FORWARDEDHEADERS_ENABLED
è impostata sutrue
. - Abilitare l'integrazione di IIS.
Altra configurazione
Questo argomento riguarda solo la configurazione dell'app. Altri aspetti dell'esecuzione e dell'hosting delle app ASP.NET Core vengono configurati usando i file di configurazione non descritti in questo argomento:
launch.json
/launchSettings.json
sono file di configurazione degli strumenti per l'ambiente di sviluppo, descritto:- In Usare più ambienti in ASP.NET Core.
- Nel set di documentazione in cui i file vengono usati per configurare le app ASP.NET Core per gli scenari di sviluppo.
web.config
è un file di configurazione del server, descritto negli argomenti seguenti:
Variabili di ambiente impostate in launchSettings.json
sostituiscono quelle impostate nell'ambiente di sistema.
Per altre informazioni sulla migrazione della configurazione dell'app da versioni precedenti di ASP.NET, vedere Eseguire l'aggiornamento da ASP.NET a ASP.NET Core.
Aggiungere la configurazione da un assembly esterno
Un'implementazione IHostingStartup consente l'aggiunta di miglioramenti a un'app all'avvio, da un assembly esterno alla classe Startup
dell'app. Per altre informazioni, vedere Usare assembly di avvio dell'hosting in ASP.NET Core.
Risorse aggiuntive
Configurazione di endpoint Kestrel
La configurazione di endpoint specifica di Kestrel sostituisce tutte le configurazioni di endpoint tra server. Le configurazioni di endpoint tra server includono:
- UseUrls
--urls
nella riga di comando- Variabile di ambiente
ASPNETCORE_URLS
Si consideri il file appsettings.json
seguente usato in un'app Web ASP.NET Core:
{
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://localhost:9999"
}
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Quando il markup evidenziato precedente viene usato in un'app Web ASP.NET Core e l'app viene avviata dalla riga di comando con la configurazione dell'endpoint tra server seguente:
dotnet run --urls="https://localhost:7777"
Kestrel si associa all'endpoint configurato specificatamente per Kestrel nel file appsettings.json
(https://localhost:9999
) e non in https://localhost:7777
.
Si consideri l'endpoint specifico di Kestrel configurato come variabile di ambiente:
set Kestrel__Endpoints__Https__Url=https://localhost:8888
nella variabile di ambiente precedente Https
è il nome dell'endpoint specifico di Kestrel. Il file appsettings.json
precedente definisce anche un endpoint specifico di Kestrel denominato Https
. Per impostazione predefinita, le variabili di ambiente che usano il provider di configurazione delle variabili di ambiente vengono lette dopo appsettings.{Environment}.json
, di conseguenza la variabile di ambiente precedente viene usata per l'endpoint Https
.
GetValue
ConfigurationBinder.GetValue estrae un singolo valore dalla configurazione con una chiave specificata e lo converte nel tipo specificato. Questo metodo è un metodo di estensione per 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}");
}
}
Nel codice precedente, se NumberKey
non viene trovato nella configurazione, viene usato il valore predefinito di 99
.
GetSection, GetChildren ed Exists
Per gli esempi che seguono, prendere in considerazione il file MySubsection.json
seguente:
{
"section0": {
"key0": "value00",
"key1": "value01"
},
"section1": {
"key0": "value10",
"key1": "value11"
},
"section2": {
"subsection0": {
"key0": "value200",
"key1": "value201"
},
"subsection1": {
"key0": "value210",
"key1": "value211"
}
}
}
Il codice seguente aggiunge MySubsection.json
ai provider di configurazione:
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 restituisce una sottosezione della configurazione con la chiave di sottosezione specificata.
Il codice seguente restituisce i valori per 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"]}'");
}
}
Il codice seguente restituisce i valori per 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
non restituisce mai null
. Se non viene trovata una sezione corrispondente, viene restituita una IConfigurationSection
vuota.
Quando GetSection
restituisce una sezione corrispondente, Value non viene compilata. Quando la sezione esiste, vengono restituiti Key e Path.
GetChildren ed Exists
Il codice seguente chiama IConfiguration.GetChildren e restituisce i valori per 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);
}
}
Il codice precedente chiama ConfigurationExtensions.Exists per verificare che la sezione esista:
Associare una matrice
Il ConfigurationBinder.Bind supporta l'associazione di matrici agli oggetti usando gli indici delle matrici nelle chiavi di configurazione. Qualsiasi formato di matrice che espone un segmento chiave numerico supporta l'associazione di matrici a una matrice di classi POCO.
Si consideri MyArray.json
del download di esempio:
{
"array": {
"entries": {
"0": "value00",
"1": "value10",
"2": "value20",
"4": "value40",
"5": "value50"
}
}
}
Il codice seguente aggiunge MyArray.json
ai provider di configurazione:
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>();
});
}
Il codice seguente legge la configurazione e visualizza i valori:
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);
}
}
Il codice precedente restituisce l'output seguente:
Index: 0 Value: value00
Index: 1 Value: value10
Index: 2 Value: value20
Index: 3 Value: value40
Index: 4 Value: value50
Nell'output precedente Index 3 ha il valore value40
, corrispondente a "4": "value40",
in MyArray.json
. Gli indici di matrice associati sono continui e non associati all'indice delle chiavi di configurazione. Il binder di configurazione non supporta l'associazione di valori Null o la creazione di voci Null negli oggetti associati
Il codice seguente carica la configurazione array:entries
con il metodo di estensione 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>();
});
}
}
Il codice seguente legge la configurazione in arrayDict
Dictionary
e visualizza i valori:
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);
}
}
Il codice precedente restituisce l'output seguente:
Index: 0 Value: value0
Index: 1 Value: value1
Index: 2 Value: value2
Index: 3 Value: value4
Index: 4 Value: value5
L'indice #3 nell'oggetto associato contiene i dati di configurazione per la chiave di configurazione array:4
e il relativo valore di value4
. Quando i dati di configurazione contenenti una matrice vengono associati, gli indici di matrice nelle chiavi di configurazione vengono usati per scorrere i dati di configurazione quando si crea l'oggetto. Un valore null non può essere mantenuto nei dati di configurazione e una voce con valore null non viene creata in un oggetto associato quando una matrice nelle chiavi di configurazione ignora uno o più indici.
L'elemento di configurazione mancante per l'indice #3 può essere fornito prima dell'associazione all'istanza ArrayExample
da qualsiasi provider di configurazione che legge la coppia chiave-valore dell'indice #3. Si consideri il file Value3.json
seguente del download di esempio:
{
"array:entries:3": "value3"
}
Il codice seguente include la configurazione per Value3.json
e :arrayDict
Dictionary
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>();
});
}
}
Il codice seguente legge la configurazione precedente e visualizza i valori:
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);
}
}
Il codice precedente restituisce l'output seguente:
Index: 0 Value: value0
Index: 1 Value: value1
Index: 2 Value: value2
Index: 3 Value: value3
Index: 4 Value: value4
Index: 5 Value: value5
I provider di configurazione personalizzati non devono implementare l'associazione di matrici.
Provider di configurazione personalizzato
Avviso
Questo articolo illustra l'uso di stringa di connessione. Con un database locale l'utente non deve essere autenticato, ma nell'ambiente di produzione stringa di connessione talvolta include una password per l'autenticazione. Una credenziale della password del proprietario della risorsa (ROPC) è un rischio per la sicurezza che deve essere evitato nei database di produzione. Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni sull'autenticazione per le app distribuite in ambienti di test o di produzione, vedere Proteggere i flussi di autenticazione.
L'app di esempio dimostra come creare un provider di configurazione di base che legge le coppie chiave-valore di configurazione da un database usando Entity Framework (EF).
Il provider ha le caratteristiche seguenti:
- Il database in memoria di Entity Framework viene usato a scopo dimostrativo. Per usare un database che richiede una stringa di connessione, implementare un
ConfigurationBuilder
secondario per fornire la stringa di connessione da un altro provider di configurazione. - Il provider legge una tabella di database in una configurazione all'avvio. Il provider non esegue una query sul database per ogni chiave.
- Il ricaricamento in caso di modifica non è implementato, quindi l'aggiornamento del database dopo l'avvio dell'app non ha alcun effetto sulla configurazione dell'app.
Definire un'entità EFConfigurationValue
per l'archiviazione dei valori di configurazione nel database.
Models/EFConfigurationValue.cs
:
public class EFConfigurationValue
{
public string Id { get; set; }
public string Value { get; set; }
}
Aggiungere EFConfigurationContext
per archiviare i valori configurati e accedervi.
EFConfigurationProvider/EFConfigurationContext.cs
:
// using Microsoft.EntityFrameworkCore;
public class EFConfigurationContext : DbContext
{
public EFConfigurationContext(DbContextOptions options) : base(options)
{
}
public DbSet<EFConfigurationValue> Values { get; set; }
}
Creare una classe che implementi 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);
}
}
Creare il provider di configurazione personalizzato ereditando da ConfigurationProvider. Il provider di configurazione inizializza il database quando è vuoto. Poiché nelle chiavi di configurazione non viene fatta distinzione tra maiuscole e minuscole, il dizionario usato per inizializzare il database viene creato con l'operatore di confronto senza distinzione tra maiuscole e minuscole (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;
}
}
Un metodo di estensione AddEFConfiguration
consente di aggiungere l'origine di configurazione a un 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));
}
}
Il codice seguente mostra come usare EFConfigurationProvider
personalizzato in Program.cs
:
// using Microsoft.EntityFrameworkCore;
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddEFConfiguration(
options => options.UseInMemoryDatabase("InMemoryDb"));
})
Accedere alla configurazione in Avvio
Il codice seguente visualizza i dati di configurazione nei metodi Startup
:
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();
});
}
}
Per un esempio di accesso alla configurazione usando metodi di servizio di avvio, vedere Avvio dell'applicazione: Metodi pratici.
Accedere alla configurazione nelle pagine Razor
Il codice seguente visualizza i dati di configurazione in una pagina Razor:
@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
Nel codice seguente MyOptions
viene aggiunta al contenitore del servizio con Configure e associata alla configurazione:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
services.AddRazorPages();
}
Il markup seguente usa la direttiva @inject
Razor per risolvere e visualizzare i valori delle opzioni:
@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>
Accedere alla configurazione in un file di visualizzazione MVC
Il codice seguente visualizza i dati di configurazione in una visualizzazione MVC:
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
Configurare opzioni con un delegato
Le opzioni configurate in un delegato sostituiscono i valori impostati nei provider di configurazione.
La configurazione di opzioni con un delegato è illustrata nell'Esempio 2 nell'app di esempio.
Nel codice seguente viene aggiunto un servizio IConfigureOptions<TOptions> al contenitore di servizi. Viene usato un delegato per configurare i valori per MyOptions
:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(myOptions =>
{
myOptions.Option1 = "Value configured in delegate";
myOptions.Option2 = 500;
});
services.AddRazorPages();
}
Il codice seguente visualizza i valori delle opzioni:
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}");
}
}
Nell'esempio precedente i valori di Option1
e Option2
sono specificati in appsettings.json
e quindi sostituiti dal delegato configurato.
Host e configurazione delle app
Prima che l'app venga configurata e avviata, viene configurato e avviato un host. L'host è responsabile della gestione dell'avvio e della durata delle app. Sia l'app che l'host vengono configurati tramite i provider di configurazione descritti in questo argomento. Anche le coppie chiave-valore di configurazione dell'host sono incluse nella configurazione dell'app. Per altre informazioni su come vengono usati i provider di configurazione per la creazione dell'host e sugli effetti delle origini di configurazione sulla configurazione dell'host, vedere Panoramica delle nozioni di base su ASP.NET Core.
Configurazione dell'host predefinita
Per informazioni dettagliate sulla configurazione predefinita quando viene usato l'host Web, vedere la versione di questo argomento per ASP.NET Core 2.2.
- La configurazione dell'host viene fornita da:
- Variabili di ambiente con prefisso
DOTNET_
(ad esempio,DOTNET_ENVIRONMENT
) che usano il provider di configurazione delle variabili di ambiente. Il prefisso (DOTNET_
) viene rimosso al caricamento delle coppie chiave-valore della configurazione. - Argomenti della riga di comando che usano il provider di configurazione della riga di comando.
- Variabili di ambiente con prefisso
- Viene stabilita la configurazione predefinita dell'host Web (
ConfigureWebHostDefaults
):- Kestrel viene usato come server Web e configurato con i provider di configurazione dell'app.
- Aggiungere il middleware di filtro host.
- Aggiungere il middleware delle intestazioni inoltrate se la variabile di ambiente
ASPNETCORE_FORWARDEDHEADERS_ENABLED
è impostata sutrue
. - Abilitare l'integrazione di IIS.
Altra configurazione
Questo argomento riguarda solo la configurazione dell'app. Altri aspetti dell'esecuzione e dell'hosting delle app ASP.NET Core vengono configurati usando i file di configurazione non descritti in questo argomento:
launch.json
/launchSettings.json
sono file di configurazione degli strumenti per l'ambiente di sviluppo, descritto:- In Usare più ambienti in ASP.NET Core.
- Nel set di documentazione in cui i file vengono usati per configurare le app ASP.NET Core per gli scenari di sviluppo.
web.config
è un file di configurazione del server, descritto negli argomenti seguenti:
Variabili di ambiente impostate in launchSettings.json
sostituiscono quelle impostate nell'ambiente di sistema.
Per altre informazioni sulla migrazione della configurazione dell'app da versioni precedenti di ASP.NET, vedere Eseguire l'aggiornamento da ASP.NET a ASP.NET Core.
Aggiungere la configurazione da un assembly esterno
Un'implementazione IHostingStartup consente l'aggiunta di miglioramenti a un'app all'avvio, da un assembly esterno alla classe Startup
dell'app. Per altre informazioni, vedere Usare assembly di avvio dell'hosting in ASP.NET Core.