Configuración en ASP.NET Core
Por Rick Anderson y Kirk Larkin
Nota
Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión de .NET 9 de este artículo.
Advertencia
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulte la directiva de compatibilidad de .NET y .NET Core. Para la versión actual, consulte la versión de .NET 9 de este artículo.
Importante
Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Para la versión actual, consulte la versión de .NET 9 de este artículo.
La configuración de aplicaciones en ASP.NET Core se realiza mediante uno o varios proveedores de configuración. Los proveedores de configuración leen los datos sobre los ajustes de los pares clave-valor mediante distintos orígenes de configuración:
- Archivos de configuración, como
appsettings.json
- Variables de entorno
- Azure Key Vault
- Azure App Configuration
- Argumentos de la línea de comandos
- Proveedores personalizados (instalados o creados)
- Archivos de directorio
- Objetos de .NET en memoria
En este artículo se proporciona información sobre la configuración en ASP.NET Core. Para más información sobre el uso de la configuración en las aplicaciones de consola, consulte Configuración de .NET.
Para obtener una guía sobre la configuración de Blazor, que se agregue o reemplace la guía en este nodo, consulta Configuración de Blazor en ASP.NET Core.
Configuración de host y de aplicación
Las aplicaciones de ASP.NET Core configuran e inician un host. El host es responsable de la administración del inicio y la duración de la aplicación. Las plantillas de ASP.NET Core crean un objeto WebApplicationBuilder que contiene el host. Aunque parte de la configuración se puede realizar tanto en los proveedores de configuración tanto del host como de la aplicación, por lo general la configuración necesaria para el host solo se debe realizar en la configuración del host.
La configuración de la aplicación tiene la máxima prioridad y se detalla en la sección siguiente. La configuración del host sigue a la configuración de la aplicación y se describe en este artículo.
Orígenes de configuración de aplicación predeterminados
Las aplicaciones web de ASP.NET Core creadas con dotnet new o con Visual Studio generan el código siguiente:
var builder = WebApplication.CreateBuilder(args);
WebApplication.CreateBuilder inicializa una nueva instancia de la clase WebApplicationBuilder con valores predeterminados preconfigurados. El objeto WebApplicationBuilder
(builder
) inicializado proporciona la configuración predeterminada de la aplicación en el orden siguiente, de la prioridad más alta a la más baja:
- Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos.
- Variables de entorno sin prefijo que usan el proveedor de configuración de variables de entorno sin prefijo
- Secretos del usuario cuando la aplicación se ejecuta en el entorno
Development
. appsettings.{Environment}.json
con el proveedor de configuración JSON. Por ejemplo,appsettings.Production.json
yappsettings.Development.json
.- appsettings.json con el proveedor de configuración JSON.
- Una reserva a la configuración del host (se describe en la siguiente sección)
Orígenes de configuración de host predeterminados
La siguiente lista contiene los orígenes de configuración de host predeterminados, de la prioridad más alta a la más baja para WebApplicationBuilder:
- Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos
- Variables de entorno con el prefijo
DOTNET_
que usan el proveedor de configuración de variables de entorno - Variables de entorno con el prefijo
ASPNETCORE_
que usan el proveedor de configuración de variables de entorno
En el caso del host genérico de .NET y el host web, los orígenes de configuración de host predeterminados de la prioridad más alta a la más baja son los siguientes:
- Variables de entorno con el prefijo
ASPNETCORE_
que usan el proveedor de configuración de variables de entorno - Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos
- Variables de entorno con el prefijo
DOTNET_
que usan el proveedor de configuración de variables de entorno
Si se establece un valor de configuración en la configuración del host y de la aplicación, se usa la configuración de la aplicación.
Variables de host
Las siguientes variables se bloquean pronto al inicializar los generadores de hosts y no se ven influidas por la configuración de la aplicación:
- Nombre de la aplicación
- Nombre del entorno, por ejemplo,
Development
,Production
yStaging
- Raíz del contenido
- Raíz web
- Si se van a buscar ensamblados de inicio de hospedaje y qué ensamblados se van a buscar
- Variables que el código de aplicación y biblioteca lee de HostBuilderContext.Configuration en las devoluciones de llamada IHostBuilder.ConfigureAppConfiguration
Cualquier otra configuración de host se lee de la configuración de la aplicación en lugar de la configuración del host.
URLS
es una de las muchas configuraciones de host comunes que no es una configuración de arranque. Como cualquier otra configuración de host que no figura en la lista anterior, URLS
se lee más adelante desde la configuración de la aplicación. La configuración del host es una reserva de la configuración de la aplicación, con lo cual se puede usar para establecer URLS
, pero quedará invalidada por cualquier origen de configuración de la aplicación, como appsettings.json
.
Para obtener más información, consulte Cambio de la raíz del contenido, el nombre de la aplicación y el entorno y Cambio de la raíz del contenido, el nombre de la aplicación y el entorno por variables de entorno o línea de comandos.
El resto de secciones de este artículo se centran en la configuración de la aplicación.
Proveedores de configuración de la aplicación
El código siguiente muestra los proveedores de configuración habilitados en el orden en el que se han agregado:
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);
}
}
La lista anterior de orígenes de configuración predeterminados ordenados de prioridad más alta a más baja muestra los proveedores en orden opuesto al que se agregan a la aplicación generada por la plantilla. Así, por ejemplo, el proveedor de configuración JSON se agrega antes que el proveedor de configuración de línea de comandos.
Los proveedores de configuración que se agreguen posteriormente tienen mayor prioridad e invalidan los ajustes de configuración de clave anteriores. Por ejemplo, si MyKey
se establece tanto en appsettings.json
como en el entorno, se usará el valor del entorno. Con los proveedores de configuración predeterminados, el proveedor de configuración de línea de comandos reemplaza al resto de proveedores.
Para obtener más información sobre CreateBuilder
, consulte el artículo Configuración predeterminada del generador.
appsettings.json
Fíjese en el siguiente archivo appsettings.json
:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
El siguiente código de la descarga de ejemplo muestra algunas de las configuraciones anteriores:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
El elemento JsonConfigurationProvider predeterminado carga la configuración en el siguiente orden:
appsettings.json
appsettings.{Environment}.json
: por ejemplo, los archivosappsettings.Production.json
yappsettings.Development.json
. La versión del entorno del archivo se carga en función de IHostingEnvironment.EnvironmentName. Para obtener más información, consulte Usar varios entornos en ASP.NET Core.
Los valores de appsettings.{Environment}.json
invalidan las claves en appsettings.json
. Por ejemplo, de forma predeterminada:
- En la fase de desarrollo, la configuración
appsettings.Development.json
sobrescribe los valores encontrados enappsettings.json
. - En la fase de producción, la configuración
appsettings.Production.json
sobrescribe los valores encontrados enappsettings.json
. Por ejemplo, al implementar la aplicación en Azure.
Si se debe garantizar un valor de configuración, consulte GetValue. En el ejemplo anterior solo se leen cadenas y no se admite un valor predeterminado.
Si usa la configuración predeterminada, los archivosappsettings.json
y appsettings.{Environment}.json
están habilitados con reloadOnChange: true. Los cambios realizados en appsettings.json
y el archivo appsettings.{Environment}.json
después de iniciar la aplicación los lee el proveedor de configuración JSON.
Comentarios en appsettings.json
Los comentarios en los archivos appsettings.json
y appsettings.{Environment}.json
se admiten mediante comentarios de estilo C# o JavaScript.
Enlace de datos de configuración jerárquica mediante el patrón de opciones
La mejor manera de leer valores de configuración relacionados es usar el patrón de opciones. Por ejemplo, para leer los siguientes valores de configuración:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Crea la siguiente clase PositionOptions
:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
}
Una clase de opciones:
- Debe ser no abstracta con un constructor público sin parámetros.
- Todas las propiedades de lectura y escritura públicas del tipo están enlazadas.
- Los campos no se enlazan. En el código anterior,
Position
no está enlazado. El campoPosition
se usa para que la cadena"Position"
no se tenga que codificar de forma rígida en la aplicación al enlazar la clase a un proveedor de configuración.
El código siguiente:
- Llama a ConfigurationBinder.Bind para enlazar la clase
PositionOptions
a la secciónPosition
. - Muestra los datos de configuración de
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}");
}
}
En el código anterior, de forma predeterminada, los cambios en el archivo de configuración de JSON producidos una vez iniciada la aplicación se leen.
ConfigurationBinder.Get<T>
enlaza y devuelve el tipo especificado. Puede ser más conveniente usar ConfigurationBinder.Get<T>
que ConfigurationBinder.Bind
. En el código siguiente se muestra cómo puede usar ConfigurationBinder.Get<T>
con la clase 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}");
}
}
En el código anterior, de forma predeterminada, los cambios en el archivo de configuración de JSON producidos una vez iniciada la aplicación se leen.
Un enfoque alternativo a la hora de usar el patrón de opciones consiste en enlazar la sección Position
y agregarla al contenedor del servicio de inserción de dependencias. En el siguiente código se agrega PositionOptions
al contenedor de servicios con Configure y se enlaza a la configuración:
using ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<PositionOptions>(
builder.Configuration.GetSection(PositionOptions.Position));
var app = builder.Build();
A partir del código anterior, el siguiente código lee las opciones de posición:
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}");
}
}
En el código anterior, los cambios en el archivo de configuración de JSON producidos una vez iniciada la aplicación no se leen. Para leer los cambios una vez iniciada la aplicación, usa IOptionsSnapshot.
Si usa la configuración predeterminada, los archivosappsettings.json
y appsettings.{Environment}.json
están habilitados con reloadOnChange: true. Los cambios realizados en appsettings.json
y el archivo appsettings.{Environment}.json
después de iniciar la aplicación los lee el proveedor de configuración JSON.
Consulte la sección Proveedor de configuración JSON en este artículo para obtener información sobre cómo agregar archivos de configuración JSON adicionales.
Combinación de colecciones de servicios
Tenga en cuenta el siguiente método que registra los servicios y configura las opciones:
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();
Los grupos de registros relacionados pueden moverse a un método de extensión para registrar los servicios. Por ejemplo, los servicios de configuración se agregan a la siguiente clase:
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;
}
}
}
Los servicios restantes se registran en una clase similar. El siguiente código usa los nuevos métodos de extensión para registrar los servicios:
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddConfig(builder.Configuration)
.AddMyDependencyGroup();
builder.Services.AddRazorPages();
var app = builder.Build();
Nota: Cada método de extensión services.Add{GROUP_NAME}
agrega servicios y potencialmente los configura. Por ejemplo, AddControllersWithViews agrega los controladores MVC de servicios con las vistas que se requieren y AddRazorPages agrega los servicios que Razor Pages requiere.
Seguridad y secretos de usuario
Directrices para los datos de configuración:
- Nunca almacene contraseñas u otros datos confidenciales en el código del proveedor de configuración o en archivos de configuración de texto sin formato. Se puede usar la herramienta Administrador de secretos para almacenar secretos en desarrollo.
- No use secretos de producción en los entornos de desarrollo o pruebas.
- Especifique los secretos fuera del proyecto para que no se confirmen en un repositorio de código fuente de manera accidental.
- Las aplicaciones de producción deben usar el flujo de autenticación más seguro disponible. Para más información, consulte Flujos de autenticación seguros.
De forma predeterminada, el origen de configuración de los secretos de usuario se registra después de los orígenes de configuración de JSON. Por lo tanto, las claves de secretos de usuario tienen prioridad sobre las claves de appsettings.json
y appsettings.{Environment}.json
.
Para obtener más información sobre cómo almacenar contraseñas u otros datos confidenciales consulte:
- Usar varios entornos en ASP.NET Core
- Caja fuerte almacenamiento de secretos de aplicaciones en el ASP.NET Core: incluye consejos sobre el uso de variables de entorno para almacenar datos confidenciales. La herramienta Administrador de secretos usa el proveedor de configuración de archivo para almacenar secretos de usuario en un archivo JSON en el sistema local.
- Azure Key Vault almacena de forma segura secretos de aplicación para aplicaciones de ASP.NET Core. Para obtener más información, vea Proveedor de configuración de Azure Key Vault en ASP.NET Core.
Variables de entorno sin prefijo
Las variables de entorno sin prefijo son variables de entorno distintas de las que exhiben los prefijos ASPNETCORE_
o DOTNET_
. Por ejemplo, las plantillas de aplicación web de ASP.NET Core establecen "ASPNETCORE_ENVIRONMENT": "Development"
en launchSettings.json
. Para obtener más información sobre las variables de entorno ASPNETCORE_
y DOTNET_
, consulte:
- Lista de orígenes de configuración predeterminados ordenados de prioridad más alta a más baja, incluidas las variables de entorno sin prefijo y con los prefijos
ASPNETCORE_
yDOTNETCORE_
- Variables de entorno
DOTNET_
usadas fuera de Microsoft.Extensions.Hosting
Al usar la configuración predeterminada, EnvironmentVariablesConfigurationProvider carga la configuración de los pares clave-valor de la variable de entorno después de leer appsettings.json
, appsettings.{Environment}.json
y los secretos de usuario. Por lo tanto, los valores de clave que se leen del entorno reemplazan los valores que se leen de appsettings.json
, appsettings.{Environment}.json
y los secretos de usuario.
El separador :
no funciona con claves jerárquicas de variables de entorno en todas las plataformas. Por ejemplo, el separador :
no es compatible con Bash. El carácter de subrayado doble, __
, tiene las siguientes características:
- Es compatible con todas las plataformas.
- Se reemplaza automáticamente por dos puntos,
:
.
Los siguientes comandos :
- Establecen las claves de entorno y los valores del ejemplo anterior en Windows.
- Prueban la configuración al usar la descarga de ejemplo. El comando
dotnet run
debe ejecutarse en el directorio del proyecto.
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run
Los ajustes de configuración del entorno anteriores:
- Solo se establecen en procesos iniciados desde la ventana de comandos en la que se establecieron.
- No los podrán leer los exploradores que se inician con Visual Studio.
Los siguientes comandos setx se pueden usar para establecer las claves de entorno y los valores en Windows. A diferencia de set
, la configuración de setx
se conserva. /M
establece la variable en el entorno del sistema. Si no se usa el modificador /M
, se establece una variable de entorno de usuario.
setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M
Para comprobar que los comandos anteriores invalidan appsettings.json
y appsettings.{Environment}.json
:
- Con Visual Studio: salga y reinicie Visual Studio.
- Con la CLI: abra una nueva ventana de comandos y escriba
dotnet run
.
Llame a AddEnvironmentVariables con una cadena para especificar un prefijo para las variables de entorno:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
var app = builder.Build();
En el código anterior:
builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_")
se agrega después de los proveedores de configuración predeterminados. Para obtener un ejemplo de ordenación de los proveedores de configuración, consulte la sección Proveedor de configuración JSON.- Las variables de entorno establecidas con el prefijo
MyCustomPrefix_
invalidan los proveedores de configuración predeterminados. Esto incluye las variables de entorno sin el prefijo.
El prefijo se quita cuando se leen los pares clave-valor de configuración.
Los siguientes comandos prueban el prefijo personalizado:
set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run
La configuración predeterminada carga las variables de entorno y los argumentos de la línea de comandos con los prefijos DOTNET_
y ASPNETCORE_
. ASP.NET Core usa los prefijos DOTNET_
y ASPNETCORE_
para la configuración del host y la aplicación, pero no para la del usuario. Para obtener más información sobre la configuración del host y de la aplicación, consulte el artículo Host genérico de .NET.
En Azure App Service, seleccione Nueva configuración de la aplicación en la página Configuración > Configuración. Los ajustes de configuración de Azure App Service:
- Se cifran en rest y se transmiten a través de un canal cifrado.
- Se exponen como variables de entorno.
Para más información, consulte Aplicaciones de Azure: Invalidación de la configuración de la aplicación mediante Azure Portal.
Consulte la sección Prefijos de cadena de conexión para obtener información sobre las cadenas de conexión de base de datos de Azure.
Nomenclatura de variables de entorno
Los nombres de las variables de entorno reflejan la estructura de un archivo appsettings.json
. Cada elemento de la jerarquía está separado por un carácter de subrayado doble (preferible) o un signo de dos puntos. Cuando la estructura del elemento incluye una matriz, el índice de la matriz se debe tratar como un nombre de elemento adicional en esta ruta de acceso. Considere el siguiente archivo appsettings.json
y sus valores equivalentes representados como variables de entorno.
appsettings.json
{
"SmtpServer": "smtp.example.com",
"Logging": [
{
"Name": "ToEmail",
"Level": "Critical",
"Args": {
"FromAddress": "MySystem@example.com",
"ToAddress": "SRE@example.com"
}
},
{
"Name": "ToConsole",
"Level": "Information"
}
]
}
variables de entorno
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
Variables de entorno configuradas en el archivo launchSettings.json generado
Las variables de entorno configuradas en launchSettings.json
invalidan aquellas configuradas en el entorno del sistema. Por ejemplo, las plantillas web ASP.NET Core generan un archivo launchSettings.json
que establece la configuración del punto de conexión en:
"applicationUrl": "https://localhost:5001;http://localhost:5000"
Al configurar applicationUrl
, se establece la variable de entorno ASPNETCORE_URLS
y se invalidan los valores establecidos en el entorno.
Variables de entorno de escape en Linux
En Linux, el valor de las variables de entorno de URL debe ser de escape, para que systemd
pueda analizarlas. Uso de la herramienta de Linux systemd-escape
que produce http:--localhost:5001
groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001
Visualización de las variables de entorno
En el código siguiente se muestran las variables de entorno y los valores en el inicio de la aplicación, lo que puede resultar útil al depurar la configuración del entorno:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
foreach (var c in builder.Configuration.AsEnumerable())
{
Console.WriteLine(c.Key + " = " + c.Value);
}
Línea de comandos
Si se usa la configuración predeterminada, CommandLineConfigurationProvider carga la configuración de los pares de clave-valor de argumento de la línea de comandos después de los siguientes orígenes de configuración:
- archivos
appsettings.json
yappsettings.{Environment}.json
. - Secretos de aplicaciones en el entorno de desarrollo.
- Variables de entorno.
De forma predeterminada, los valores de configuración establecidos en la línea de comandos reemplazan los valores de configuración establecidos con el resto de proveedores de configuración.
Argumentos de la línea de comandos
El comando siguiente establece las claves y los valores mediante =
:
dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick
El comando siguiente establece las claves y los valores mediante /
:
dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick
El comando siguiente establece las claves y los valores mediante --
:
dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick
El valor de la clave:
- Debe seguir a un signo
=
, o bien la clave debe tener un prefijo--
o/
cuando el valor sigue a un espacio. - No es necesario si se usa
=
. Por ejemplo:MySetting=
.
Dentro del mismo comando, no mezcle pares clave-valor de argumento de la línea de comandos que usan =
con pares de clave-valor que usan un espacio.
Asignaciones de modificador
Las asignaciones de modificador admiten la lógica de sustitución de nombres de clave. Proporcione un diccionario de reemplazos de modificador al método AddCommandLine.
Cuando se usa el diccionario de asignaciones de modificador, se comprueba en el diccionario si una clave coincide con la clave proporcionada por un argumento de línea de comandos. Si la clave de la línea de comandos se encuentra en el diccionario, se devuelve el valor del diccionario para establecer el par clave-valor en la configuración de la aplicación. Se requiere una asignación de conmutador para cualquier clave de línea de comandos precedida por un solo guion (-
).
Reglas de clave del diccionario de asignaciones de modificador:
- Los modificadores deben comenzar con
-
o--
. - El diccionario de asignaciones de modificador no debe contener claves duplicadas.
Para usar un diccionario de asignaciones de modificador, páselo a la llamada 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();
La ejecución del siguiente comando sirve para probar el reemplazo de claves:
dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6
El código siguiente muestra los valores de clave para las claves reemplazadas:
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"]}'");
}
}
En el caso de las aplicaciones que usen las asignaciones de modificador, la llamada a CreateDefaultBuilder
no tiene que pasar argumentos. En la llamada de AddCommandLine
al método CreateDefaultBuilder
, no se incluyen modificadores asignados y no hay forma de pasar el diccionario de asignación de modificador a CreateDefaultBuilder
. La solución no es pasar los argumentos de CreateDefaultBuilder
, sino permitir que el método AddCommandLine
del método ConfigurationBuilder
procese tanto los argumentos como el diccionario de asignación de modificador.
Configuración del entorno y de los argumentos de la línea de comandos con Visual Studio
Los argumentos de entorno y de línea de comandos se pueden establecer en Visual Studio desde el cuadro de diálogo de perfiles de inicio:
- En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Propiedades.
- Seleccione la pestaña Depurar > General y luego Abrir la interfaz de usuario de perfiles de inicio de depuración.
Datos de configuración jerárquica
La API de configuración lee los datos de configuración jerárquica al disminuir los datos jerárquicos mediante el uso de un delimitador en las claves de configuración.
La descarga de ejemplo contiene el siguiente archivo appsettings.json
:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
El siguiente código de la descarga de ejemplo muestra algunas de las opciones de configuración:
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 mejor manera de leer datos de configuración jerárquica es usar el patrón de opciones. Para obtener más información, vea la sección Enlace de datos de configuración jerárquica en este documento.
Los métodos GetSection y GetChildren están disponibles para aislar las secciones y los elementos secundarios de una sección en los datos de configuración. Estos métodos se describen más adelante en la sección GetSection, GetChildren y Exists.
Claves y valores de configuración
Advertencia
En este artículo se muestra el uso de cadena de conexión. Con una base de datos local, el usuario no tiene que autenticarse, pero en producción, cadena de conexión a veces incluye una contraseña para autenticarse. Una credencial de contraseña de propietario de recursos (ROPC) es un riesgo de seguridad que se debe evitar en las bases de datos de producción. Las aplicaciones de producción deben usar el flujo de autenticación más seguro disponible. Para obtener más información sobre la autenticación de aplicaciones implementadas para probar o entornos de producción, consulte Flujos de autenticación seguros.
Las claves de configuración:
- No distinguen mayúsculas de minúsculas. Por ejemplo,
ConnectionString
yconnectionstring
se consideran claves equivalente. - Si se establece una clave y un valor en más de un proveedor de configuración, se usa el valor del último proveedor agregado. Para obtener más información, vea la sección Configuración predeterminada.
- Claves jerárquicas
- Dentro de la API de configuración, un separador de dos puntos (
:
) funciona en todas las plataformas. - En las variables de entorno, puede que un separador de dos puntos no funcione en todas las plataformas. Todas las plataformas admiten un carácter de subrayado doble,
__
, que se convierte automáticamente en un signo de dos puntos:
. - En Azure Key Vault, las claves jerárquicas usan
--
como separador. El proveedor de configuración de Azure Key Vault reemplaza automáticamente--
con:
cuando los secretos se cargan en la configuración de la aplicación.
- Dentro de la API de configuración, un separador de dos puntos (
- ConfigurationBinder admite enlazar matrices a objetos con los índices de matriz en las claves de configuración. El enlace de matriz se describe en la sección Enlace de una matriz a una clase.
Los valores de configuración:
- Son cadenas.
- Los valores NULL no se pueden almacenar en la configuración ni enlazar a los objetos.
Proveedores de configuración
La siguiente tabla muestra los proveedores de configuración disponibles para las aplicaciones de ASP.NET Core.
Proveedor | Proporciona la configuración de |
---|---|
Proveedor de configuración de Azure Key Vault | Azure Key Vault |
Proveedor de configuración de aplicaciones de Azure | Configuración de aplicaciones de Azure |
Proveedor de configuración de línea de comandos | Parámetros de la línea de comandos |
Proveedor de configuración personalizada | Origen personalizado |
Proveedor de configuración de variables de entorno | Variables de entorno |
Proveedor de configuración de archivo | Archivos INI, JSON y XML |
Proveedor de configuración de clave por archivo | Archivos de directorio |
Proveedor de configuración de memoria | Colecciones en memoria |
Secretos de usuario | Archivo en el directorio del perfil de usuario |
Los orígenes de configuración se leen en el orden en que se especifican sus proveedores de configuración. Ordene los proveedores de configuración en el código para cumplir con las prioridades relacionadas con los orígenes de configuración subyacentes que la aplicación necesita.
Esta es una secuencia típica de proveedores de configuración:
appsettings.json
appsettings.{Environment}.json
- Secretos de usuario
- Variables de entorno con el proveedor de configuración de variables de entorno.
- Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos.
Una práctica común es agregar el proveedor de configuración de línea de comandos al final en una serie de proveedores para permitir que los argumentos de la línea de comandos reemplacen la configuración establecida por el resto de los proveedores.
La secuencia de proveedores anterior se usa en la configuración predeterminada.
Prefijos de cadena de conexión
Advertencia
En este artículo se muestra el uso de cadena de conexión. Con una base de datos local, el usuario no tiene que autenticarse, pero en producción, cadena de conexión a veces incluye una contraseña para autenticarse. Una credencial de contraseña de propietario de recursos (ROPC) es un riesgo de seguridad que se debe evitar en las bases de datos de producción. Las aplicaciones de producción deben usar el flujo de autenticación más seguro disponible. Para obtener más información sobre la autenticación de aplicaciones implementadas para probar o entornos de producción, consulte Flujos de autenticación seguros.
La API de configuración tiene reglas de procesamiento especiales para cuatro variables de entorno de cadena de conexión. Estas cadenas de conexión están implicadas en la configuración de las cadenas de conexión de Azure para el entorno de la aplicación. Las variables de entorno con los prefijos que se muestran en la tabla se cargan en la aplicación con la configuración predeterminada o cuando no se proporciona ningún prefijo a AddEnvironmentVariables
.
Prefijo de cadena de conexión | Proveedor |
---|---|
CUSTOMCONNSTR_ |
Proveedor personalizado |
MYSQLCONNSTR_ |
MySQL |
SQLAZURECONNSTR_ |
Azure SQL Database |
SQLCONNSTR_ |
SQL Server |
Cuando una variable de entorno se detecta y carga en la configuración con cualquiera de los cuatro prefijos que se muestran en la tabla:
- La clave de configuración se crea al quitar el prefijo de la variable de entorno y al agregar una sección de clave de configuración (
ConnectionStrings
). - Se crea un nuevo par clave-valor de configuración que representa el proveedor de conexión de base de datos (excepto para
CUSTOMCONNSTR_
, que no tiene ningún proveedor indicado).
Clave de variable de entorno | Clave de configuración convertida | Entrada de configuración del proveedor |
---|---|---|
CUSTOMCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Entrada de configuración no creada. |
MYSQLCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Clave: ConnectionStrings:{KEY}_ProviderName :Valor: MySql.Data.MySqlClient |
SQLAZURECONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Clave: ConnectionStrings:{KEY}_ProviderName :Valor: System.Data.SqlClient |
SQLCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Clave: ConnectionStrings:{KEY}_ProviderName :Valor: System.Data.SqlClient |
Proveedor de configuración de archivo
FileConfigurationProvider es la clase base para cargar la configuración del sistema de archivos. Los siguientes proveedores de configuración se derivan de FileConfigurationProvider
:
Proveedor de configuración INI
IniConfigurationProvider carga la configuración desde pares clave-valor de archivo INI en tiempo de ejecución.
El código siguiente agrega varios proveedores de configuración:
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();
En el código anterior, la configuración de los archivos MyIniConfig.ini
y MyIniConfig.{Environment}.ini
se reemplaza por la configuración de:
La descarga de ejemplo contiene el siguiente archivo MyIniConfig.ini
:
MyKey="MyIniConfig.ini Value"
[Position]
Title="My INI Config title"
Name="My INI Config name"
[Logging:LogLevel]
Default=Information
Microsoft=Warning
El siguiente código de la descarga de ejemplo muestra algunas de las configuraciones anteriores:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
Proveedor de configuración JSON
JsonConfigurationProvider carga la configuración desde pares clave-valor de archivos JSON.
Las sobrecargas pueden especificar:
- Si el archivo es opcional.
- Si la configuración se recarga si el archivo cambia.
Observe el código siguiente:
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();
El código anterior:
- Configura el proveedor de configuración JSON para que cargue el archivo
MyConfig.json
con las siguientes opciones:optional: true
: el archivo es opcional.reloadOnChange: true
: el archivo se recarga cuando se guardan los cambios.
- Lee los proveedores de configuración predeterminados antes que el archivo
MyConfig.json
. La configuración del archivoMyConfig.json
invalida la de los proveedores de configuración predeterminados, incluidos el proveedor de configuración de variables de entorno y el proveedor de configuración de línea de comandos.
Normalmente no querrá que un archivo JSON personalizado invalide los valores establecidos en el proveedor de configuración de variables de entorno ni en el proveedor de configuración de línea de comandos.
Proveedor de configuración XML
XmlConfigurationProvider carga la configuración desde pares clave-valor de archivo XML en tiempo de ejecución.
El código siguiente agrega varios proveedores de configuración:
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();
En el código anterior, la configuración de los archivos MyXMLFile.xml
y MyXMLFile.{Environment}.xml
se reemplaza por la configuración de:
La descarga de ejemplo contiene el siguiente archivo MyXMLFile.xml
:
<?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>
El siguiente código de la descarga de ejemplo muestra algunas de las configuraciones anteriores:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
Los elementos de repetición que usan el mismo nombre de elemento funcionan si el atributo name
se usa para distinguir los elementos:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<section name="section0">
<key name="key0">value 00</key>
<key name="key1">value 01</key>
</section>
<section name="section1">
<key name="key0">value 10</key>
<key name="key1">value 11</key>
</section>
</configuration>
El código siguiente lee el archivo de configuración anterior y muestra las claves y los valores:
public class IndexModel : PageModel
{
private readonly IConfiguration Configuration;
public IndexModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var key00 = "section:section0:key:key0";
var key01 = "section:section0:key:key1";
var key10 = "section:section1:key:key0";
var key11 = "section:section1:key:key1";
var val00 = Configuration[key00];
var val01 = Configuration[key01];
var val10 = Configuration[key10];
var val11 = Configuration[key11];
return Content($"{key00} value: {val00} \n" +
$"{key01} value: {val01} \n" +
$"{key10} value: {val10} \n" +
$"{key10} value: {val11} \n"
);
}
}
Los atributos se pueden usar para suministrar valores:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<key attribute="value" />
<section>
<key attribute="value" />
</section>
</configuration>
El archivo de configuración anterior carga las siguientes claves con value
:
- key:attribute
- section:key:attribute
Proveedor de configuración de clave por archivo
KeyPerFileConfigurationProvider usa los archivos de un directorio como pares clave-valor de configuración. La clave es el nombre de archivo. El valor contiene el contenido del archivo. El proveedor de configuración de clave por archivo se usa en escenarios de hospedaje de Docker.
Para activar la configuración de clave por archivo, llame al método de extensión AddKeyPerFile en una instancia de ConfigurationBuilder. La ruta de acceso directoryPath
a los archivos debe ser una ruta de acceso absoluta.
Las sobrecargas permiten especificar:
- Un delegado
Action<KeyPerFileConfigurationSource>
que configura el origen. - Si el directorio es opcional y la ruta de acceso al directorio.
El carácter de subrayado doble (__
) se usa como delimitador de claves de configuración en los nombres de archivo. Por ejemplo, el nombre de archivo Logging__LogLevel__System
genera la clave de configuración Logging:LogLevel:System
.
Llame a ConfigureAppConfiguration
cuando cree el host para especificar la configuración de la aplicación:
.ConfigureAppConfiguration((hostingContext, config) =>
{
var path = Path.Combine(
Directory.GetCurrentDirectory(), "path/to/files");
config.AddKeyPerFile(directoryPath: path, optional: true);
})
Proveedor de configuración de memoria
MemoryConfigurationProvider usa una colección en memoria como pares clave-valor de configuración.
El código siguiente agrega una colección en memoria al sistema de configuración:
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();
El siguiente código de la descarga de ejemplo muestra las opciones de configuración anteriores:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
En el código anterior, config.AddInMemoryCollection(Dict)
se agrega después de los proveedores de configuración predeterminados. Para obtener un ejemplo de ordenación de los proveedores de configuración, consulte la sección Proveedor de configuración JSON.
Consulte la sección Enlace de matrices para ver otro ejemplo que usa MemoryConfigurationProvider
.
Configuración del punto de conexión de Kestrel
La configuración del punto de conexión específico de Kestrel invalida todas las configuraciones del punto de conexión entre servidores. Las configuraciones del punto de conexión entre servidores incluyen:
- UseUrls
--urls
en la línea de comandos- La variable de entorno
ASPNETCORE_URLS
Tenga en cuenta el archivo siguiente appsettings.json
usado en una aplicación web de ASP.NET Core:
{
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://localhost:9999"
}
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Cuando el marcado resaltado anterior se usa en una aplicación web de ASP.NET Core y la aplicación se inicia en la línea de comandos con la siguiente configuración del punto de conexión entre servidores:
dotnet run --urls="https://localhost:7777"
Kestrel se enlaza con el punto de conexión configurado específicamente para Kestrel en el archivo appsettings.json
(https://localhost:9999
) y no https://localhost:7777
.
Considere el punto de conexión específico de Kestrel configurado como una variable de entorno:
set Kestrel__Endpoints__Https__Url=https://localhost:8888
En la variable de entorno anterior, Https
es el nombre del punto de conexión específico de Kestrel. En el archivo appsettings.json
anterior también se define un punto de conexión específico de Kestrel denominado Https
. De manera predeterminada, las variables de entorno que utilizan el proveedor de configuración de variables de entorno se leen después de appsettings.{Environment}.json
, por lo tanto, la variable de entorno anterior se usa para el punto de conexión Https
.
GetValue
ConfigurationBinder.GetValue extrae un único valor de la configuración con una clave determinada y lo convierte al tipo especificado:
public class TestNumModel : PageModel
{
private readonly IConfiguration Configuration;
public TestNumModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var number = Configuration.GetValue<int>("NumberKey", 99);
return Content($"{number}");
}
}
En el código anterior, si NumberKey
no se encuentra en la configuración, se usa el valor predeterminado de 99
.
GetSection, GetChildren y Exists
Para los ejemplos siguientes, considere el siguiente archivo MySubsection.json
:
{
"section0": {
"key0": "value00",
"key1": "value01"
},
"section1": {
"key0": "value10",
"key1": "value11"
},
"section2": {
"subsection0": {
"key0": "value200",
"key1": "value201"
},
"subsection1": {
"key0": "value210",
"key1": "value211"
}
}
}
El código siguiente agrega MySubsection.json
a los proveedores de configuración:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.AddJsonFile("MySubsection.json",
optional: true,
reloadOnChange: true);
builder.Services.AddRazorPages();
var app = builder.Build();
GetSection
IConfiguration.GetSection devuelve una subsección de la configuración con la clave de subsección especificada.
El código siguiente devuelve los valores de 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"]}'");
}
}
El código siguiente devuelve los valores de section2:subsection0
:
public class TestSection2Model : PageModel
{
private readonly IConfiguration Config;
public TestSection2Model(IConfiguration configuration)
{
Config = configuration.GetSection("section2:subsection0");
}
public ContentResult OnGet()
{
return Content(
$"section2:subsection0:key0 '{Config["key0"]}'\n" +
$"section2:subsection0:key1:'{Config["key1"]}'");
}
}
GetSection
nunca devuelve null
. Si no se encuentra una sección que coincida, se devuelve una IConfigurationSection
vacía.
Cuando GetSection
devuelve una sección coincidente, Value no se rellena. Se devuelven Key y Path si la sección existe.
GetChildren y Exists
El código siguiente llama a IConfiguration.GetChildren y devuelve los valores de 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);
}
}
El código anterior llama a ConfigurationExtensions.Exists para comprobar que la sección existe:
Enlace de matrices
ConfigurationBinder.Bind admite enlazar matrices a objetos con los índices de matriz en las claves de configuración. Cualquier formato de matriz que exponga un segmento de clave numérica es capaz de enlazar una matriz a una matriz de clase POCO.
Tenga en cuenta este archivo MyArray.json
de la descarga de ejemplo:
{
"array": {
"entries": {
"0": "value00",
"1": "value10",
"2": "value20",
"4": "value40",
"5": "value50"
}
}
}
El código siguiente agrega MyArray.json
a los proveedores de configuración:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.AddJsonFile("MyArray.json",
optional: true,
reloadOnChange: true);
builder.Services.AddRazorPages();
var app = builder.Build();
El código siguiente lee la configuración y muestra los valores:
public class ArrayModel : PageModel
{
private readonly IConfiguration Config;
public ArrayExample? _array { get; private set; }
public ArrayModel(IConfiguration config)
{
Config = config;
}
public ContentResult OnGet()
{
_array = Config.GetSection("array").Get<ArrayExample>();
if (_array == null)
{
throw new ArgumentNullException(nameof(_array));
}
string s = String.Empty;
for (int j = 0; j < _array.Entries.Length; j++)
{
s += $"Index: {j} Value: {_array.Entries[j]} \n";
}
return Content(s);
}
}
public class ArrayExample
{
public string[]? Entries { get; set; }
}
El código anterior devuelve el siguiente resultado:
Index: 0 Value: value00
Index: 1 Value: value10
Index: 2 Value: value20
Index: 3 Value: value40
Index: 4 Value: value50
En el resultado anterior, el índice 3 tiene el valor value40
, que corresponde a "4": "value40",
en MyArray.json
. Los índices de matriz enlazados son continuos y no están enlazados al índice de la clave de configuración. El enlazador de configuración no es capaz de enlazar los valores NULL ni de crear entradas NULL en objetos enlazados.
Proveedores de configuración personalizada
La aplicación de ejemplo muestra cómo crear un proveedor de configuración básica que lee los pares clave-valor de configuración desde una base de datos mediante Entity Framework (EF).
El proveedor tiene las siguientes características:
- La base de datos en memoria de EF se usa para fines de demostración. Para usar una base de datos que requiere una cadena de conexión, implemente un
ConfigurationBuilder
secundario para suministrar la cadena de conexión desde otro proveedor de configuración. - El proveedor lee una tabla de base de datos en la configuración en el inicio. El proveedor no consulta la base de datos por clave.
- La función de recarga en cambio no se implementa, por lo que actualizar la base de datos después del inicio de la aplicación no afecta a la configuración de la aplicación.
Defina una entidad EFConfigurationValue
para almacenar los valores de configuración en la base de datos.
Models/EFConfigurationValue.cs
:
public class EFConfigurationValue
{
public string Id { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
}
Agregue un EFConfigurationContext
para almacenar y tener acceso a los valores configurados.
EFConfigurationProvider/EFConfigurationContext.cs
:
public class EFConfigurationContext : DbContext
{
public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
{
}
public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}
Cree una clase que implemente 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);
}
Cree el proveedor de configuración personalizado heredando de ConfigurationProvider. El proveedor de configuración inicializa la base de datos cuando está vacía. Puesto que las claves de configuración no distinguen entre mayúsculas y minúsculas, el diccionario empleado para iniciar la base de datos se crea con el comparador que tampoco hace tal distinción (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 método de extensión AddEFConfiguration
permite agregar el origen de configuración 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));
}
}
En el código siguiente se muestra cómo puede usar el EFConfigurationProvider
personalizado en Program.cs
:
//using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddEFConfiguration(
opt => opt.UseInMemoryDatabase("InMemoryDb"));
var app = builder.Build();
app.Run();
Configuración de acceso con inserción de dependencias (DI)
La configuración se puede insertar en los servicios mediante la inserción de dependencias (DI) resolviendo el servicio IConfiguration:
public class Service
{
private readonly IConfiguration _config;
public Service(IConfiguration config) =>
_config = config;
public void DoSomething()
{
var configSettingValue = _config["ConfigSetting"];
// ...
}
}
Para obtener información sobre cómo acceder a valores mediante IConfiguration
, vea GetValue y GetSection, GetChildren y Exists en este artículo.
Acceso a la configuración en Razor Pages
En el código siguiente se muestran los datos de configuración en una página de RazorPages:
@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
En el siguiente código se agrega MyOptions
al contenedor de servicios con Configure y se enlaza a la configuración:
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
En el marcado siguiente se usa la directiva @inject
Razor para resolver y mostrar los valores de las opciones:
@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>
Acceso a la configuración en un archivo de vista de MVC
En el código siguiente se muestran los datos de configuración de una vista de MVC:
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
Acceder a la configuración en Program.cs
El código siguiente accede a la configuración en el archivo 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();
En appsettings.json
para el ejemplo anterior:
{
...
"KeyOne": "Key One Value",
"KeyTwo": 1999,
"KeyThree": true
}
Configurar opciones con un delegado
Las opciones configuradas en un delegado invalidan los valores establecidos en los proveedores de configuración.
En el código siguiente, se agrega un servicio IConfigureOptions<TOptions> al contenedor de servicios. Usa un delegado para configurar los valores de 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();
En el código siguiente se muestran los valores de las opciones:
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}");
}
}
En el ejemplo anterior, los valores de Option1
y Option2
se especifican en appsettings.json
y, luego, se reemplazan por el delegado configurado.
Configuración de host y de aplicación
Antes de configurar e iniciar la aplicación, se configura e inicia un host. El host es responsable de la administración del inicio y la duración de la aplicación. Tanto la aplicación como el host se configuran mediante los proveedores de configuración que se describen en este tema. Los pares clave-valor de configuración del host también se incluyen en la configuración de la aplicación. Para obtener más información sobre cómo se usan los proveedores de configuración cuando se compila el host y cómo afectan los orígenes de configuración a la configuración del host, consulte la información general sobre conceptos básicos de ASP.NET Core.
Configuración predeterminada del host
Para obtener más información sobre la configuración predeterminada al usar el host de web, vea la versión de este tema para ASP.NET Core 2.2.
- La configuración del host la proporcionan los siguientes elementos:
- Las variables de entorno con el prefijo
DOTNET_
(por ejemplo,DOTNET_ENVIRONMENT
) mediante el proveedor de configuración de variables de entorno. El prefijo (DOTNET_
) se quita cuando se cargan los pares clave-valor de configuración. - Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos.
- Las variables de entorno con el prefijo
- La configuración predeterminada del host de web se ha establecido (
ConfigureWebHostDefaults
):- Kestrel se usa como el servidor web y se ha configurado mediante los proveedores de configuración de la aplicación.
- Agregar el middleware de filtrado de host
- Agregue el middleware de encabezados reenviados si la variable de entorno
ASPNETCORE_FORWARDEDHEADERS_ENABLED
se establece entrue
. - Habilite la integración con IIS.
Otra configuración
Este tema solo concierne a la configuración de aplicaciones. Otros aspectos de la ejecución y el hospedaje de aplicaciones ASP.NET Core se configuran mediante archivos de configuración que no se describen en este tema:
launch.json
/launchSettings.json
son archivos de configuración de herramientas para el entorno de desarrollo, que se describen a continuación:- En Usar varios entornos en ASP.NET Core.
- En el conjunto de documentación en el que se usan los archivos para configurar aplicaciones ASP.NET Core para escenarios de desarrollo.
web.config
es un archivo de configuración del servidor, que se describe en los temas siguientes:
Las variables de entorno configuradas en launchSettings.json
invalidan aquellas configuradas en el entorno del sistema.
Para más información sobre cómo migrar la configuración de aplicaciones de versiones anteriores de ASP.NET, consulte Actualización de ASP.NET a ASP.NET Core.
Agregar configuración a partir de un ensamblado externo
Una implementación de IHostingStartup permite agregar mejoras a una aplicación al iniciarla a partir de un ensamblado externo fuera de la clase Startup
de esta. Para obtener más información, consulte Uso de ensamblados de inicio de hospedaje en ASP.NET Core.
Generador de origen de enlace de configuración
El generador de orígenes de enlace de configuración proporciona una configuración AOT y fácil de recortar. Para obtener más información, vea Generador de orígenes de enlace de configuración.
Recursos adicionales
La configuración de aplicaciones en ASP.NET Core se realiza mediante uno o varios proveedores de configuración. Los proveedores de configuración leen los datos sobre los ajustes de los pares clave-valor mediante distintos orígenes de configuración:
- Archivos de configuración, como
appsettings.json
- Variables de entorno
- Azure Key Vault
- Azure App Configuration
- Argumentos de la línea de comandos
- Proveedores personalizados (instalados o creados)
- Archivos de directorio
- Objetos de .NET en memoria
En este artículo se proporciona información sobre la configuración en ASP.NET Core. Para más información sobre el uso de la configuración en las aplicaciones de consola, consulte Configuración de .NET.
Configuración de host y de aplicación
Las aplicaciones de ASP.NET Core configuran e inician un host. El host es responsable de la administración del inicio y la duración de la aplicación. Las plantillas de ASP.NET Core crean un objeto WebApplicationBuilder que contiene el host. Aunque parte de la configuración se puede realizar tanto en los proveedores de configuración tanto del host como de la aplicación, por lo general la configuración necesaria para el host solo se debe realizar en la configuración del host.
La configuración de la aplicación tiene la máxima prioridad y se detalla en la sección siguiente. La configuración del host sigue a la configuración de la aplicación y se describe en este artículo.
Orígenes de configuración de aplicación predeterminados
Las aplicaciones web de ASP.NET Core creadas con dotnet new o con Visual Studio generan el código siguiente:
var builder = WebApplication.CreateBuilder(args);
WebApplication.CreateBuilder inicializa una nueva instancia de la clase WebApplicationBuilder con valores predeterminados preconfigurados. El objeto WebApplicationBuilder
(builder
) inicializado proporciona la configuración predeterminada de la aplicación en el orden siguiente, de la prioridad más alta a la más baja:
- Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos.
- Variables de entorno sin prefijo que usan el proveedor de configuración de variables de entorno sin prefijo
- Secretos del usuario cuando la aplicación se ejecuta en el entorno
Development
. appsettings.{Environment}.json
con el proveedor de configuración JSON. Por ejemplo,appsettings.Production.json
yappsettings.Development.json
.- appsettings.json con el proveedor de configuración JSON.
- Una reserva a la configuración del host (se describe en la siguiente sección)
Orígenes de configuración de host predeterminados
La siguiente lista contiene los orígenes de configuración de host predeterminados, de la prioridad más alta a la más baja para WebApplicationBuilder:
- Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos
- Variables de entorno con el prefijo
DOTNET_
que usan el proveedor de configuración de variables de entorno - Variables de entorno con el prefijo
ASPNETCORE_
que usan el proveedor de configuración de variables de entorno
En el caso del host genérico de .NET y el host web, los orígenes de configuración de host predeterminados de la prioridad más alta a la más baja son los siguientes:
- Variables de entorno con el prefijo
ASPNETCORE_
que usan el proveedor de configuración de variables de entorno - Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos
- Variables de entorno con el prefijo
DOTNET_
que usan el proveedor de configuración de variables de entorno
Si se establece un valor de configuración en la configuración del host y de la aplicación, se usa la configuración de la aplicación.
Variables de host
Las siguientes variables se bloquean pronto al inicializar los generadores de hosts y no se ven influidas por la configuración de la aplicación:
- Nombre de la aplicación
- Nombre del entorno, por ejemplo,
Development
,Production
yStaging
- Raíz del contenido
- Raíz web
- Si se van a buscar ensamblados de inicio de hospedaje y qué ensamblados se van a buscar
- Variables que el código de aplicación y biblioteca lee de HostBuilderContext.Configuration en las devoluciones de llamada IHostBuilder.ConfigureAppConfiguration
Cualquier otra configuración de host se lee de la configuración de la aplicación en lugar de la configuración del host.
URLS
es una de las muchas configuraciones de host comunes que no es una configuración de arranque. Como cualquier otra configuración de host que no figura en la lista anterior, URLS
se lee más adelante desde la configuración de la aplicación. La configuración del host es una reserva de la configuración de la aplicación, con lo cual se puede usar para establecer URLS
, pero quedará invalidada por cualquier origen de configuración de la aplicación, como appsettings.json
.
Para obtener más información, consulte Cambio de la raíz del contenido, el nombre de la aplicación y el entorno y Cambio de la raíz del contenido, el nombre de la aplicación y el entorno por variables de entorno o línea de comandos.
El resto de secciones de este artículo se centran en la configuración de la aplicación.
Proveedores de configuración de la aplicación
El código siguiente muestra los proveedores de configuración habilitados en el orden en el que se han agregado:
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);
}
}
La lista anterior de orígenes de configuración predeterminados ordenados de prioridad más alta a más baja muestra los proveedores en orden opuesto al que se agregan a la aplicación generada por la plantilla. Así, por ejemplo, el proveedor de configuración JSON se agrega antes que el proveedor de configuración de línea de comandos.
Los proveedores de configuración que se agreguen posteriormente tienen mayor prioridad e invalidan los ajustes de configuración de clave anteriores. Por ejemplo, si MyKey
se establece tanto en appsettings.json
como en el entorno, se usará el valor del entorno. Con los proveedores de configuración predeterminados, el proveedor de configuración de línea de comandos reemplaza al resto de proveedores.
Para obtener más información sobre CreateBuilder
, consulte el artículo Configuración predeterminada del generador.
appsettings.json
Fíjese en el siguiente archivo appsettings.json
:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
El siguiente código de la descarga de ejemplo muestra algunas de las configuraciones anteriores:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
El elemento JsonConfigurationProvider predeterminado carga la configuración en el siguiente orden:
appsettings.json
appsettings.{Environment}.json
: por ejemplo, los archivosappsettings.Production.json
yappsettings.Development.json
. La versión del entorno del archivo se carga en función de IHostingEnvironment.EnvironmentName. Para obtener más información, consulte Usar varios entornos en ASP.NET Core.
Los valores de appsettings.{Environment}.json
invalidan las claves en appsettings.json
. Por ejemplo, de forma predeterminada:
- En la fase de desarrollo, la configuración
appsettings.Development.json
sobrescribe los valores encontrados enappsettings.json
. - En la fase de producción, la configuración
appsettings.Production.json
sobrescribe los valores encontrados enappsettings.json
. Por ejemplo, al implementar la aplicación en Azure.
Si se debe garantizar un valor de configuración, consulte GetValue. En el ejemplo anterior solo se leen cadenas y no se admite un valor predeterminado.
Si usa la configuración predeterminada, los archivosappsettings.json
y appsettings.{Environment}.json
están habilitados con reloadOnChange: true. Los cambios realizados en appsettings.json
y el archivo appsettings.{Environment}.json
después de iniciar la aplicación los lee el proveedor de configuración JSON.
Comentarios en appsettings.json
Los comentarios en los archivos appsettings.json
y appsettings.{Environment}.json
se admiten mediante comentarios de estilo C# o JavaScript.
Enlace de datos de configuración jerárquica mediante el patrón de opciones
La mejor manera de leer valores de configuración relacionados es usar el patrón de opciones. Por ejemplo, para leer los siguientes valores de configuración:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Crea la siguiente clase PositionOptions
:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
}
Una clase de opciones:
- Debe ser no abstracta con un constructor público sin parámetros.
- Todas las propiedades de lectura y escritura públicas del tipo están enlazadas.
- Los campos no se enlazan. En el código anterior,
Position
no está enlazado. El campoPosition
se usa para que la cadena"Position"
no se tenga que codificar de forma rígida en la aplicación al enlazar la clase a un proveedor de configuración.
El código siguiente:
- Llama a ConfigurationBinder.Bind para enlazar la clase
PositionOptions
a la secciónPosition
. - Muestra los datos de configuración de
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}");
}
}
En el código anterior, de forma predeterminada, los cambios en el archivo de configuración de JSON producidos una vez iniciada la aplicación se leen.
ConfigurationBinder.Get<T>
enlaza y devuelve el tipo especificado. Puede ser más conveniente usar ConfigurationBinder.Get<T>
que ConfigurationBinder.Bind
. En el código siguiente se muestra cómo puede usar ConfigurationBinder.Get<T>
con la clase 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}");
}
}
En el código anterior, de forma predeterminada, los cambios en el archivo de configuración de JSON producidos una vez iniciada la aplicación se leen.
Un enfoque alternativo a la hora de usar el patrón de opciones consiste en enlazar la sección Position
y agregarla al contenedor del servicio de inserción de dependencias. En el siguiente código se agrega PositionOptions
al contenedor de servicios con Configure y se enlaza a la configuración:
using ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<PositionOptions>(
builder.Configuration.GetSection(PositionOptions.Position));
var app = builder.Build();
A partir del código anterior, el siguiente código lee las opciones de posición:
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}");
}
}
En el código anterior, los cambios en el archivo de configuración de JSON producidos una vez iniciada la aplicación no se leen. Para leer los cambios una vez iniciada la aplicación, usa IOptionsSnapshot.
Si usa la configuración predeterminada, los archivosappsettings.json
y appsettings.{Environment}.json
están habilitados con reloadOnChange: true. Los cambios realizados en appsettings.json
y el archivo appsettings.{Environment}.json
después de iniciar la aplicación los lee el proveedor de configuración JSON.
Consulte la sección Proveedor de configuración JSON en este artículo para obtener información sobre cómo agregar archivos de configuración JSON adicionales.
Combinación de colecciones de servicios
Tenga en cuenta el siguiente método que registra los servicios y configura las opciones:
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();
Los grupos de registros relacionados pueden moverse a un método de extensión para registrar los servicios. Por ejemplo, los servicios de configuración se agregan a la siguiente clase:
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;
}
}
}
Los servicios restantes se registran en una clase similar. El siguiente código usa los nuevos métodos de extensión para registrar los servicios:
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddConfig(builder.Configuration)
.AddMyDependencyGroup();
builder.Services.AddRazorPages();
var app = builder.Build();
Nota: Cada método de extensión services.Add{GROUP_NAME}
agrega servicios y potencialmente los configura. Por ejemplo, AddControllersWithViews agrega los controladores MVC de servicios con las vistas que se requieren y AddRazorPages agrega los servicios que Razor Pages requiere.
Seguridad y secretos de usuario
Directrices para los datos de configuración:
- Nunca almacene contraseñas u otros datos confidenciales en el código del proveedor de configuración o en archivos de configuración de texto sin formato. Se puede usar la herramienta Administrador de secretos para almacenar secretos en desarrollo.
- No use secretos de producción en los entornos de desarrollo o pruebas.
- Especifique los secretos fuera del proyecto para que no se confirmen en un repositorio de código fuente de manera accidental.
- Las aplicaciones de producción deben usar el flujo de autenticación más seguro disponible. Para más información, consulte Flujos de autenticación seguros.
De forma predeterminada, el origen de configuración de los secretos de usuario se registra después de los orígenes de configuración de JSON. Por lo tanto, las claves de secretos de usuario tienen prioridad sobre las claves de appsettings.json
y appsettings.{Environment}.json
.
Para obtener más información sobre cómo almacenar contraseñas u otros datos confidenciales consulte:
- Usar varios entornos en ASP.NET Core
- Caja fuerte almacenamiento de secretos de aplicaciones en el ASP.NET Core: incluye consejos sobre el uso de variables de entorno para almacenar datos confidenciales. La herramienta Administrador de secretos usa el proveedor de configuración de archivo para almacenar secretos de usuario en un archivo JSON en el sistema local.
Azure Key Vault almacena de forma segura secretos de aplicación para aplicaciones de ASP.NET Core. Para obtener más información, vea Proveedor de configuración de Azure Key Vault en ASP.NET Core.
Variables de entorno sin prefijo
Las variables de entorno sin prefijo son variables de entorno distintas de las que exhiben los prefijos ASPNETCORE_
o DOTNET_
. Por ejemplo, las plantillas de aplicación web de ASP.NET Core establecen "ASPNETCORE_ENVIRONMENT": "Development"
en launchSettings.json
. Para obtener más información sobre las variables de entorno ASPNETCORE_
y DOTNET_
, consulte:
- Lista de orígenes de configuración predeterminados ordenados de prioridad más alta a más baja, incluidas las variables de entorno sin prefijo y con los prefijos
ASPNETCORE_
yDOTNETCORE_
- Variables de entorno
DOTNET_
usadas fuera de Microsoft.Extensions.Hosting
Al usar la configuración predeterminada, EnvironmentVariablesConfigurationProvider carga la configuración de los pares clave-valor de la variable de entorno después de leer appsettings.json
, appsettings.{Environment}.json
y los secretos de usuario. Por lo tanto, los valores de clave que se leen del entorno reemplazan los valores que se leen de appsettings.json
, appsettings.{Environment}.json
y los secretos de usuario.
El separador :
no funciona con claves jerárquicas de variables de entorno en todas las plataformas. Por ejemplo, el separador :
no es compatible con Bash. El carácter de subrayado doble, __
, tiene las siguientes características:
- Es compatible con todas las plataformas.
- Se reemplaza automáticamente por dos puntos,
:
.
Los siguientes comandos set
:
- Establecen las claves de entorno y los valores del ejemplo anterior en Windows.
- Prueban la configuración al usar la descarga de ejemplo. El comando
dotnet run
debe ejecutarse en el directorio del proyecto.
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run
Los ajustes de configuración del entorno anteriores:
- Solo se establecen en procesos iniciados desde la ventana de comandos en la que se establecieron.
- No los podrán leer los exploradores que se inician con Visual Studio.
Los siguientes comandos setx se pueden usar para establecer las claves de entorno y los valores en Windows. A diferencia de set
, la configuración de setx
se conserva. /M
establece la variable en el entorno del sistema. Si no se usa el modificador /M
, se establece una variable de entorno de usuario.
setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M
Para comprobar que los comandos anteriores invalidan appsettings.json
y appsettings.{Environment}.json
:
- Con Visual Studio: salga y reinicie Visual Studio.
- Con la CLI: abra una nueva ventana de comandos y escriba
dotnet run
.
Llame a AddEnvironmentVariables con una cadena para especificar un prefijo para las variables de entorno:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
var app = builder.Build();
En el código anterior:
builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_")
se agrega después de los proveedores de configuración predeterminados. Para obtener un ejemplo de ordenación de los proveedores de configuración, consulte la sección Proveedor de configuración JSON.- Las variables de entorno establecidas con el prefijo
MyCustomPrefix_
invalidan los proveedores de configuración predeterminados. Esto incluye las variables de entorno sin el prefijo.
El prefijo se quita cuando se leen los pares clave-valor de configuración.
Los siguientes comandos prueban el prefijo personalizado:
set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run
La configuración predeterminada carga las variables de entorno y los argumentos de la línea de comandos con los prefijos DOTNET_
y ASPNETCORE_
. ASP.NET Core usa los prefijos DOTNET_
y ASPNETCORE_
para la configuración del host y la aplicación, pero no para la del usuario. Para obtener más información sobre la configuración del host y de la aplicación, consulte el artículo Host genérico de .NET.
En Azure App Service, seleccione Nueva configuración de la aplicación en la página Configuración > Configuración. Los ajustes de configuración de Azure App Service:
- Se cifran en rest y se transmiten a través de un canal cifrado.
- Se exponen como variables de entorno.
Para más información, consulte Aplicaciones de Azure: Invalidación de la configuración de la aplicación mediante Azure Portal.
Consulte la sección Prefijos de cadena de conexión para obtener información sobre las cadenas de conexión de base de datos de Azure.
Nomenclatura de variables de entorno
Los nombres de las variables de entorno reflejan la estructura de un archivo appsettings.json
. Cada elemento de la jerarquía está separado por un carácter de subrayado doble (preferible) o un signo de dos puntos. Cuando la estructura del elemento incluye una matriz, el índice de la matriz se debe tratar como un nombre de elemento adicional en esta ruta de acceso. Considere el siguiente archivo appsettings.json
y sus valores equivalentes representados como variables de entorno.
appsettings.json
{
"SmtpServer": "smtp.example.com",
"Logging": [
{
"Name": "ToEmail",
"Level": "Critical",
"Args": {
"FromAddress": "MySystem@example.com",
"ToAddress": "SRE@example.com"
}
},
{
"Name": "ToConsole",
"Level": "Information"
}
]
}
variables de entorno
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
Variables de entorno configuradas en el archivo launchSettings.json generado
Las variables de entorno configuradas en launchSettings.json
invalidan aquellas configuradas en el entorno del sistema. Por ejemplo, las plantillas web ASP.NET Core generan un archivo launchSettings.json
que establece la configuración del punto de conexión en:
"applicationUrl": "https://localhost:5001;http://localhost:5000"
Al configurar applicationUrl
, se establece la variable de entorno ASPNETCORE_URLS
y se invalidan los valores establecidos en el entorno.
Variables de entorno de escape en Linux
En Linux, el valor de las variables de entorno de URL debe ser de escape, para que systemd
pueda analizarlas. Uso de la herramienta de Linux systemd-escape
que produce http:--localhost:5001
groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001
Visualización de las variables de entorno
En el código siguiente se muestran las variables de entorno y los valores en el inicio de la aplicación, lo que puede resultar útil al depurar la configuración del entorno:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
foreach (var c in builder.Configuration.AsEnumerable())
{
Console.WriteLine(c.Key + " = " + c.Value);
}
Línea de comandos
Si se usa la configuración predeterminada, CommandLineConfigurationProvider carga la configuración de los pares de clave-valor de argumento de la línea de comandos después de los siguientes orígenes de configuración:
- archivos
appsettings.json
yappsettings.{Environment}.json
. - Secretos de aplicaciones en el entorno de desarrollo.
- Variables de entorno.
De forma predeterminada, los valores de configuración establecidos en la línea de comandos reemplazan los valores de configuración establecidos con el resto de proveedores de configuración.
Argumentos de la línea de comandos
El comando siguiente establece las claves y los valores mediante =
:
dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick
El comando siguiente establece las claves y los valores mediante /
:
dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick
El comando siguiente establece las claves y los valores mediante --
:
dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick
El valor de la clave:
- Debe seguir a un signo
=
, o bien la clave debe tener un prefijo--
o/
cuando el valor sigue a un espacio. - No es necesario si se usa
=
. Por ejemplo:MySetting=
.
Dentro del mismo comando, no mezcle pares clave-valor de argumento de la línea de comandos que usan =
con pares de clave-valor que usan un espacio.
Asignaciones de modificador
Las asignaciones de modificador admiten la lógica de sustitución de nombres de clave. Proporcione un diccionario de reemplazos de modificador al método AddCommandLine.
Cuando se usa el diccionario de asignaciones de modificador, se comprueba en el diccionario si una clave coincide con la clave proporcionada por un argumento de línea de comandos. Si la clave de la línea de comandos se encuentra en el diccionario, se devuelve el valor del diccionario para establecer el par clave-valor en la configuración de la aplicación. Se requiere una asignación de conmutador para cualquier clave de línea de comandos precedida por un solo guion (-
).
Reglas de clave del diccionario de asignaciones de modificador:
- Los modificadores deben comenzar con
-
o--
. - El diccionario de asignaciones de modificador no debe contener claves duplicadas.
Para usar un diccionario de asignaciones de modificador, páselo a la llamada 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();
La ejecución del siguiente comando sirve para probar el reemplazo de claves:
dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6
El código siguiente muestra los valores de clave para las claves reemplazadas:
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"]}'");
}
}
En el caso de las aplicaciones que usen las asignaciones de modificador, la llamada a CreateDefaultBuilder
no tiene que pasar argumentos. En la llamada de AddCommandLine
al método CreateDefaultBuilder
, no se incluyen modificadores asignados y no hay forma de pasar el diccionario de asignación de modificador a CreateDefaultBuilder
. La solución no es pasar los argumentos de CreateDefaultBuilder
, sino permitir que el método AddCommandLine
del método ConfigurationBuilder
procese tanto los argumentos como el diccionario de asignación de modificador.
Configuración del entorno y de los argumentos de la línea de comandos con Visual Studio
Los argumentos de entorno y de línea de comandos se pueden establecer en Visual Studio desde el cuadro de diálogo de perfiles de inicio:
- En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Propiedades.
- Seleccione la pestaña Depurar > General y luego Abrir la interfaz de usuario de perfiles de inicio de depuración.
Datos de configuración jerárquica
La API de configuración lee los datos de configuración jerárquica al disminuir los datos jerárquicos mediante el uso de un delimitador en las claves de configuración.
La descarga de ejemplo contiene el siguiente archivo appsettings.json
:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
El siguiente código de la descarga de ejemplo muestra algunas de las opciones de configuración:
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 mejor manera de leer datos de configuración jerárquica es usar el patrón de opciones. Para obtener más información, vea la sección Enlace de datos de configuración jerárquica en este documento.
Los métodos GetSection y GetChildren están disponibles para aislar las secciones y los elementos secundarios de una sección en los datos de configuración. Estos métodos se describen más adelante en la sección GetSection, GetChildren y Exists.
Claves y valores de configuración
Advertencia
En este artículo se muestra el uso de cadena de conexión. Con una base de datos local, el usuario no tiene que autenticarse, pero en producción, cadena de conexión a veces incluye una contraseña para autenticarse. Una credencial de contraseña de propietario de recursos (ROPC) es un riesgo de seguridad que se debe evitar en las bases de datos de producción. Las aplicaciones de producción deben usar el flujo de autenticación más seguro disponible. Para obtener más información sobre la autenticación de aplicaciones implementadas para probar o entornos de producción, consulte Flujos de autenticación seguros.
Las claves de configuración:
- No distinguen mayúsculas de minúsculas. Por ejemplo,
ConnectionString
yconnectionstring
se consideran claves equivalente. - Si se establece una clave y un valor en más de un proveedor de configuración, se usa el valor del último proveedor agregado. Para obtener más información, vea la sección Configuración predeterminada.
- Claves jerárquicas
- Dentro de la API de configuración, un separador de dos puntos (
:
) funciona en todas las plataformas. - En las variables de entorno, puede que un separador de dos puntos no funcione en todas las plataformas. Todas las plataformas admiten un carácter de subrayado doble,
__
, que se convierte automáticamente en un signo de dos puntos:
. - En Azure Key Vault, las claves jerárquicas usan
--
como separador. El proveedor de configuración de Azure Key Vault reemplaza automáticamente--
con:
cuando los secretos se cargan en la configuración de la aplicación.
- Dentro de la API de configuración, un separador de dos puntos (
- ConfigurationBinder admite enlazar matrices a objetos con los índices de matriz en las claves de configuración. El enlace de matriz se describe en la sección Enlace de una matriz a una clase.
Los valores de configuración:
- Son cadenas.
- Los valores NULL no se pueden almacenar en la configuración ni enlazar a los objetos.
Proveedores de configuración
La siguiente tabla muestra los proveedores de configuración disponibles para las aplicaciones de ASP.NET Core.
Proveedor | Proporciona la configuración de |
---|---|
Proveedor de configuración de Azure Key Vault | Azure Key Vault |
Proveedor de configuración de aplicaciones de Azure | Configuración de aplicaciones de Azure |
Proveedor de configuración de línea de comandos | Parámetros de la línea de comandos |
Proveedor de configuración personalizada | Origen personalizado |
Proveedor de configuración de variables de entorno | Variables de entorno |
Proveedor de configuración de archivo | Archivos INI, JSON y XML |
Proveedor de configuración de clave por archivo | Archivos de directorio |
Proveedor de configuración de memoria | Colecciones en memoria |
Secretos de usuario | Archivo en el directorio del perfil de usuario |
Los orígenes de configuración se leen en el orden en que se especifican sus proveedores de configuración. Ordene los proveedores de configuración en el código para cumplir con las prioridades relacionadas con los orígenes de configuración subyacentes que la aplicación necesita.
Esta es una secuencia típica de proveedores de configuración:
appsettings.json
appsettings.{Environment}.json
- Secretos de usuario
- Variables de entorno con el proveedor de configuración de variables de entorno.
- Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos.
Una práctica común es agregar el proveedor de configuración de línea de comandos al final en una serie de proveedores para permitir que los argumentos de la línea de comandos reemplacen la configuración establecida por el resto de los proveedores.
La secuencia de proveedores anterior se usa en la configuración predeterminada.
Prefijos de cadena de conexión
Advertencia
En este artículo se muestra el uso de cadena de conexión. Con una base de datos local, el usuario no tiene que autenticarse, pero en producción, cadena de conexión a veces incluye una contraseña para autenticarse. Una credencial de contraseña de propietario de recursos (ROPC) es un riesgo de seguridad que se debe evitar en las bases de datos de producción. Las aplicaciones de producción deben usar el flujo de autenticación más seguro disponible. Para obtener más información sobre la autenticación de aplicaciones implementadas para probar o entornos de producción, consulte Flujos de autenticación seguros.
La API de configuración tiene reglas de procesamiento especiales para cuatro variables de entorno de cadena de conexión. Estas cadenas de conexión están implicadas en la configuración de las cadenas de conexión de Azure para el entorno de la aplicación. Las variables de entorno con los prefijos que se muestran en la tabla se cargan en la aplicación con la configuración predeterminada o cuando no se proporciona ningún prefijo a AddEnvironmentVariables
.
Prefijo de cadena de conexión | Proveedor |
---|---|
CUSTOMCONNSTR_ |
Proveedor personalizado |
MYSQLCONNSTR_ |
MySQL |
SQLAZURECONNSTR_ |
Azure SQL Database |
SQLCONNSTR_ |
SQL Server |
Cuando una variable de entorno se detecta y carga en la configuración con cualquiera de los cuatro prefijos que se muestran en la tabla:
- La clave de configuración se crea al quitar el prefijo de la variable de entorno y al agregar una sección de clave de configuración (
ConnectionStrings
). - Se crea un nuevo par clave-valor de configuración que representa el proveedor de conexión de base de datos (excepto para
CUSTOMCONNSTR_
, que no tiene ningún proveedor indicado).
Clave de variable de entorno | Clave de configuración convertida | Entrada de configuración del proveedor |
---|---|---|
CUSTOMCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Entrada de configuración no creada. |
MYSQLCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Clave: ConnectionStrings:{KEY}_ProviderName :Valor: MySql.Data.MySqlClient |
SQLAZURECONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Clave: ConnectionStrings:{KEY}_ProviderName :Valor: System.Data.SqlClient |
SQLCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Clave: ConnectionStrings:{KEY}_ProviderName :Valor: System.Data.SqlClient |
Proveedor de configuración de archivo
FileConfigurationProvider es la clase base para cargar la configuración del sistema de archivos. Los siguientes proveedores de configuración se derivan de FileConfigurationProvider
:
Proveedor de configuración INI
IniConfigurationProvider carga la configuración desde pares clave-valor de archivo INI en tiempo de ejecución.
El código siguiente agrega varios proveedores de configuración:
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();
En el código anterior, la configuración de los archivos MyIniConfig.ini
y MyIniConfig.{Environment}.ini
se reemplaza por la configuración de:
La descarga de ejemplo contiene el siguiente archivo MyIniConfig.ini
:
MyKey="MyIniConfig.ini Value"
[Position]
Title="My INI Config title"
Name="My INI Config name"
[Logging:LogLevel]
Default=Information
Microsoft=Warning
El siguiente código de la descarga de ejemplo muestra algunas de las configuraciones anteriores:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
Proveedor de configuración JSON
JsonConfigurationProvider carga la configuración desde pares clave-valor de archivos JSON.
Las sobrecargas pueden especificar:
- Si el archivo es opcional.
- Si la configuración se recarga si el archivo cambia.
Observe el código siguiente:
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();
El código anterior:
- Configura el proveedor de configuración JSON para que cargue el archivo
MyConfig.json
con las siguientes opciones:optional: true
: el archivo es opcional.reloadOnChange: true
: el archivo se recarga cuando se guardan los cambios.
- Lee los proveedores de configuración predeterminados antes que el archivo
MyConfig.json
. La configuración del archivoMyConfig.json
invalida la de los proveedores de configuración predeterminados, incluidos el proveedor de configuración de variables de entorno y el proveedor de configuración de línea de comandos.
Normalmente no querrá que un archivo JSON personalizado invalide los valores establecidos en el proveedor de configuración de variables de entorno ni en el proveedor de configuración de línea de comandos.
Proveedor de configuración XML
XmlConfigurationProvider carga la configuración desde pares clave-valor de archivo XML en tiempo de ejecución.
El código siguiente agrega varios proveedores de configuración:
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();
En el código anterior, la configuración de los archivos MyXMLFile.xml
y MyXMLFile.{Environment}.xml
se reemplaza por la configuración de:
La descarga de ejemplo contiene el siguiente archivo MyXMLFile.xml
:
<?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>
El siguiente código de la descarga de ejemplo muestra algunas de las configuraciones anteriores:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
Los elementos de repetición que usan el mismo nombre de elemento funcionan si el atributo name
se usa para distinguir los elementos:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<section name="section0">
<key name="key0">value 00</key>
<key name="key1">value 01</key>
</section>
<section name="section1">
<key name="key0">value 10</key>
<key name="key1">value 11</key>
</section>
</configuration>
El código siguiente lee el archivo de configuración anterior y muestra las claves y los valores:
public class IndexModel : PageModel
{
private readonly IConfiguration Configuration;
public IndexModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var key00 = "section:section0:key:key0";
var key01 = "section:section0:key:key1";
var key10 = "section:section1:key:key0";
var key11 = "section:section1:key:key1";
var val00 = Configuration[key00];
var val01 = Configuration[key01];
var val10 = Configuration[key10];
var val11 = Configuration[key11];
return Content($"{key00} value: {val00} \n" +
$"{key01} value: {val01} \n" +
$"{key10} value: {val10} \n" +
$"{key10} value: {val11} \n"
);
}
}
Los atributos se pueden usar para suministrar valores:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<key attribute="value" />
<section>
<key attribute="value" />
</section>
</configuration>
El archivo de configuración anterior carga las siguientes claves con value
:
- key:attribute
- section:key:attribute
Proveedor de configuración de clave por archivo
KeyPerFileConfigurationProvider usa los archivos de un directorio como pares clave-valor de configuración. La clave es el nombre de archivo. El valor contiene el contenido del archivo. El proveedor de configuración de clave por archivo se usa en escenarios de hospedaje de Docker.
Para activar la configuración de clave por archivo, llame al método de extensión AddKeyPerFile en una instancia de ConfigurationBuilder. La ruta de acceso directoryPath
a los archivos debe ser una ruta de acceso absoluta.
Las sobrecargas permiten especificar:
- Un delegado
Action<KeyPerFileConfigurationSource>
que configura el origen. - Si el directorio es opcional y la ruta de acceso al directorio.
El carácter de subrayado doble (__
) se usa como delimitador de claves de configuración en los nombres de archivo. Por ejemplo, el nombre de archivo Logging__LogLevel__System
genera la clave de configuración Logging:LogLevel:System
.
Llame a ConfigureAppConfiguration
cuando cree el host para especificar la configuración de la aplicación:
.ConfigureAppConfiguration((hostingContext, config) =>
{
var path = Path.Combine(
Directory.GetCurrentDirectory(), "path/to/files");
config.AddKeyPerFile(directoryPath: path, optional: true);
})
Proveedor de configuración de memoria
MemoryConfigurationProvider usa una colección en memoria como pares clave-valor de configuración.
El código siguiente agrega una colección en memoria al sistema de configuración:
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();
El siguiente código de la descarga de ejemplo muestra las opciones de configuración anteriores:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
En el código anterior, config.AddInMemoryCollection(Dict)
se agrega después de los proveedores de configuración predeterminados. Para obtener un ejemplo de ordenación de los proveedores de configuración, consulte la sección Proveedor de configuración JSON.
Consulte la sección Enlace de matrices para ver otro ejemplo que usa MemoryConfigurationProvider
.
Configuración del punto de conexión de Kestrel
La configuración del punto de conexión específico de Kestrel invalida todas las configuraciones del punto de conexión entre servidores. Las configuraciones del punto de conexión entre servidores incluyen:
- UseUrls
--urls
en la línea de comandos- La variable de entorno
ASPNETCORE_URLS
Tenga en cuenta el archivo siguiente appsettings.json
usado en una aplicación web de ASP.NET Core:
{
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://localhost:9999"
}
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Cuando el marcado resaltado anterior se usa en una aplicación web de ASP.NET Core y la aplicación se inicia en la línea de comandos con la siguiente configuración del punto de conexión entre servidores:
dotnet run --urls="https://localhost:7777"
Kestrel se enlaza con el punto de conexión configurado específicamente para Kestrel en el archivo appsettings.json
(https://localhost:9999
) y no https://localhost:7777
.
Considere el punto de conexión específico de Kestrel configurado como una variable de entorno:
set Kestrel__Endpoints__Https__Url=https://localhost:8888
En la variable de entorno anterior, Https
es el nombre del punto de conexión específico de Kestrel. En el archivo appsettings.json
anterior también se define un punto de conexión específico de Kestrel denominado Https
. De manera predeterminada, las variables de entorno que utilizan el proveedor de configuración de variables de entorno se leen después de appsettings.{Environment}.json
, por lo tanto, la variable de entorno anterior se usa para el punto de conexión Https
.
GetValue
ConfigurationBinder.GetValue extrae un único valor de la configuración con una clave determinada y lo convierte al tipo especificado:
public class TestNumModel : PageModel
{
private readonly IConfiguration Configuration;
public TestNumModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var number = Configuration.GetValue<int>("NumberKey", 99);
return Content($"{number}");
}
}
En el código anterior, si NumberKey
no se encuentra en la configuración, se usa el valor predeterminado de 99
.
GetSection, GetChildren y Exists
Para los ejemplos siguientes, considere el siguiente archivo MySubsection.json
:
{
"section0": {
"key0": "value00",
"key1": "value01"
},
"section1": {
"key0": "value10",
"key1": "value11"
},
"section2": {
"subsection0": {
"key0": "value200",
"key1": "value201"
},
"subsection1": {
"key0": "value210",
"key1": "value211"
}
}
}
El código siguiente agrega MySubsection.json
a los proveedores de configuración:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.AddJsonFile("MySubsection.json",
optional: true,
reloadOnChange: true);
builder.Services.AddRazorPages();
var app = builder.Build();
GetSection
IConfiguration.GetSection devuelve una subsección de la configuración con la clave de subsección especificada.
El código siguiente devuelve los valores de 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"]}'");
}
}
El código siguiente devuelve los valores de section2:subsection0
:
public class TestSection2Model : PageModel
{
private readonly IConfiguration Config;
public TestSection2Model(IConfiguration configuration)
{
Config = configuration.GetSection("section2:subsection0");
}
public ContentResult OnGet()
{
return Content(
$"section2:subsection0:key0 '{Config["key0"]}'\n" +
$"section2:subsection0:key1:'{Config["key1"]}'");
}
}
GetSection
nunca devuelve null
. Si no se encuentra una sección que coincida, se devuelve una IConfigurationSection
vacía.
Cuando GetSection
devuelve una sección coincidente, Value no se rellena. Se devuelven Key y Path si la sección existe.
GetChildren y Exists
El código siguiente llama a IConfiguration.GetChildren y devuelve los valores de 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);
}
}
El código anterior llama a ConfigurationExtensions.Exists para comprobar que la sección existe:
Enlace de matrices
ConfigurationBinder.Bind admite enlazar matrices a objetos con los índices de matriz en las claves de configuración. Cualquier formato de matriz que exponga un segmento de clave numérica es capaz de enlazar una matriz a una matriz de clase POCO.
Tenga en cuenta este archivo MyArray.json
de la descarga de ejemplo:
{
"array": {
"entries": {
"0": "value00",
"1": "value10",
"2": "value20",
"4": "value40",
"5": "value50"
}
}
}
El código siguiente agrega MyArray.json
a los proveedores de configuración:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.AddJsonFile("MyArray.json",
optional: true,
reloadOnChange: true);
builder.Services.AddRazorPages();
var app = builder.Build();
El código siguiente lee la configuración y muestra los valores:
public class ArrayModel : PageModel
{
private readonly IConfiguration Config;
public ArrayExample? _array { get; private set; }
public ArrayModel(IConfiguration config)
{
Config = config;
}
public ContentResult OnGet()
{
_array = Config.GetSection("array").Get<ArrayExample>();
if (_array == null)
{
throw new ArgumentNullException(nameof(_array));
}
string s = String.Empty;
for (int j = 0; j < _array.Entries.Length; j++)
{
s += $"Index: {j} Value: {_array.Entries[j]} \n";
}
return Content(s);
}
}
public class ArrayExample
{
public string[]? Entries { get; set; }
}
El código anterior devuelve el siguiente resultado:
Index: 0 Value: value00
Index: 1 Value: value10
Index: 2 Value: value20
Index: 3 Value: value40
Index: 4 Value: value50
En el resultado anterior, el índice 3 tiene el valor value40
, que corresponde a "4": "value40",
en MyArray.json
. Los índices de matriz enlazados son continuos y no están enlazados al índice de la clave de configuración. El enlazador de configuración no es capaz de enlazar los valores NULL ni de crear entradas NULL en objetos enlazados.
Proveedores de configuración personalizada
La aplicación de ejemplo muestra cómo crear un proveedor de configuración básica que lee los pares clave-valor de configuración desde una base de datos mediante Entity Framework (EF).
El proveedor tiene las siguientes características:
- La base de datos en memoria de EF se usa para fines de demostración. Para usar una base de datos que requiere una cadena de conexión, implemente un
ConfigurationBuilder
secundario para suministrar la cadena de conexión desde otro proveedor de configuración. - El proveedor lee una tabla de base de datos en la configuración en el inicio. El proveedor no consulta la base de datos por clave.
- La función de recarga en cambio no se implementa, por lo que actualizar la base de datos después del inicio de la aplicación no afecta a la configuración de la aplicación.
Defina una entidad EFConfigurationValue
para almacenar los valores de configuración en la base de datos.
Models/EFConfigurationValue.cs
:
public class EFConfigurationValue
{
public string Id { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
}
Agregue un EFConfigurationContext
para almacenar y tener acceso a los valores configurados.
EFConfigurationProvider/EFConfigurationContext.cs
:
public class EFConfigurationContext : DbContext
{
public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
{
}
public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}
Cree una clase que implemente 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);
}
Cree el proveedor de configuración personalizado heredando de ConfigurationProvider. El proveedor de configuración inicializa la base de datos cuando está vacía. Puesto que las claves de configuración no distinguen entre mayúsculas y minúsculas, el diccionario empleado para iniciar la base de datos se crea con el comparador que tampoco hace tal distinción (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 método de extensión AddEFConfiguration
permite agregar el origen de configuración 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));
}
}
En el código siguiente se muestra cómo puede usar el EFConfigurationProvider
personalizado en Program.cs
:
//using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddEFConfiguration(
opt => opt.UseInMemoryDatabase("InMemoryDb"));
var app = builder.Build();
app.Run();
Configuración de acceso con inserción de dependencias (DI)
La configuración se puede insertar en los servicios mediante la inserción de dependencias (DI) resolviendo el servicio IConfiguration:
public class Service
{
private readonly IConfiguration _config;
public Service(IConfiguration config) =>
_config = config;
public void DoSomething()
{
var configSettingValue = _config["ConfigSetting"];
// ...
}
}
Para obtener información sobre cómo acceder a valores mediante IConfiguration
, vea GetValue y GetSection, GetChildren y Exists en este artículo.
Acceso a la configuración en Razor Pages
En el código siguiente se muestran los datos de configuración en una página de RazorPages:
@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
En el siguiente código se agrega MyOptions
al contenedor de servicios con Configure y se enlaza a la configuración:
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
En el marcado siguiente se usa la directiva @inject
Razor para resolver y mostrar los valores de las opciones:
@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>
Acceso a la configuración en un archivo de vista de MVC
En el código siguiente se muestran los datos de configuración de una vista de MVC:
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
Acceder a la configuración en Program.cs
El código siguiente accede a la configuración en el archivo 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();
En appsettings.json
para el ejemplo anterior:
{
...
"KeyOne": "Key One Value",
"KeyTwo": 1999,
"KeyThree": true
}
Configurar opciones con un delegado
Las opciones configuradas en un delegado invalidan los valores establecidos en los proveedores de configuración.
En el código siguiente, se agrega un servicio IConfigureOptions<TOptions> al contenedor de servicios. Usa un delegado para configurar los valores de 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();
En el código siguiente se muestran los valores de las opciones:
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}");
}
}
En el ejemplo anterior, los valores de Option1
y Option2
se especifican en appsettings.json
y, luego, se reemplazan por el delegado configurado.
Configuración de host y de aplicación
Antes de configurar e iniciar la aplicación, se configura e inicia un host. El host es responsable de la administración del inicio y la duración de la aplicación. Tanto la aplicación como el host se configuran mediante los proveedores de configuración que se describen en este tema. Los pares clave-valor de configuración del host también se incluyen en la configuración de la aplicación. Para obtener más información sobre cómo se usan los proveedores de configuración cuando se compila el host y cómo afectan los orígenes de configuración a la configuración del host, consulte la información general sobre conceptos básicos de ASP.NET Core.
Configuración predeterminada del host
Para obtener más información sobre la configuración predeterminada al usar el host de web, vea la versión de este tema para ASP.NET Core 2.2.
- La configuración del host la proporcionan los siguientes elementos:
- Las variables de entorno con el prefijo
DOTNET_
(por ejemplo,DOTNET_ENVIRONMENT
) mediante el proveedor de configuración de variables de entorno. El prefijo (DOTNET_
) se quita cuando se cargan los pares clave-valor de configuración. - Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos.
- Las variables de entorno con el prefijo
- La configuración predeterminada del host de web se ha establecido (
ConfigureWebHostDefaults
):- Kestrel se usa como el servidor web y se ha configurado mediante los proveedores de configuración de la aplicación.
- Agregar el middleware de filtrado de host
- Agregue el middleware de encabezados reenviados si la variable de entorno
ASPNETCORE_FORWARDEDHEADERS_ENABLED
se establece entrue
. - Habilite la integración con IIS.
Otra configuración
Este tema solo concierne a la configuración de aplicaciones. Otros aspectos de la ejecución y el hospedaje de aplicaciones ASP.NET Core se configuran mediante archivos de configuración que no se describen en este tema:
launch.json
/launchSettings.json
son archivos de configuración de herramientas para el entorno de desarrollo, que se describen a continuación:- En Usar varios entornos en ASP.NET Core.
- En el conjunto de documentación en el que se usan los archivos para configurar aplicaciones ASP.NET Core para escenarios de desarrollo.
web.config
es un archivo de configuración del servidor, que se describe en los temas siguientes:
Las variables de entorno configuradas en launchSettings.json
invalidan aquellas configuradas en el entorno del sistema.
Para más información sobre cómo migrar la configuración de aplicaciones de versiones anteriores de ASP.NET, consulte Actualización de ASP.NET a ASP.NET Core.
Agregar configuración a partir de un ensamblado externo
Una implementación de IHostingStartup permite agregar mejoras a una aplicación al iniciarla a partir de un ensamblado externo fuera de la clase Startup
de esta. Para obtener más información, consulte Uso de ensamblados de inicio de hospedaje en ASP.NET Core.
Recursos adicionales
La configuración de aplicaciones en ASP.NET Core se realiza mediante uno o varios proveedores de configuración. Los proveedores de configuración leen los datos sobre los ajustes de los pares clave-valor mediante distintos orígenes de configuración:
- Archivos de configuración, como
appsettings.json
- Variables de entorno
- Azure Key Vault
- Azure App Configuration
- Argumentos de la línea de comandos
- Proveedores personalizados (instalados o creados)
- Archivos de directorio
- Objetos de .NET en memoria
En este artículo se proporciona información sobre la configuración en ASP.NET Core. Para más información sobre el uso de la configuración en las aplicaciones de consola, consulte Configuración de .NET.
Configuración de host y de aplicación
Las aplicaciones de ASP.NET Core configuran e inician un host. El host es responsable de la administración del inicio y la duración de la aplicación. Las plantillas de ASP.NET Core crean un objeto WebApplicationBuilder que contiene el host. Aunque parte de la configuración se puede realizar tanto en los proveedores de configuración tanto del host como de la aplicación, por lo general la configuración necesaria para el host solo se debe realizar en la configuración del host.
La configuración de la aplicación tiene la máxima prioridad y se detalla en la sección siguiente. La configuración del host sigue a la configuración de la aplicación y se describe en este artículo.
Orígenes de configuración de aplicación predeterminados
Las aplicaciones web de ASP.NET Core creadas con dotnet new o con Visual Studio generan el código siguiente:
var builder = WebApplication.CreateBuilder(args);
WebApplication.CreateBuilder inicializa una nueva instancia de la clase WebApplicationBuilder con valores predeterminados preconfigurados. El objeto WebApplicationBuilder
(builder
) inicializado proporciona la configuración predeterminada de la aplicación en el orden siguiente, de la prioridad más alta a la más baja:
- Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos.
- Variables de entorno sin prefijo que usan el proveedor de configuración de variables de entorno sin prefijo
- Secretos del usuario cuando la aplicación se ejecuta en el entorno
Development
. appsettings.{Environment}.json
con el proveedor de configuración JSON. Por ejemplo,appsettings.Production.json
yappsettings.Development.json
.- appsettings.json con el proveedor de configuración JSON.
- Una reserva a la configuración del host (se describe en la siguiente sección)
Orígenes de configuración de host predeterminados
La siguiente lista contiene los orígenes de configuración de host predeterminados, de la prioridad más alta a la más baja:
- Variables de entorno con el prefijo
ASPNETCORE_
que usan el proveedor de configuración de variables de entorno - Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos
- Variables de entorno con el prefijo
DOTNET_
que usan el proveedor de configuración de variables de entorno
Si se establece un valor de configuración en la configuración del host y de la aplicación, se usa la configuración de la aplicación.
Consulte la explicación en este comentario de GitHub para saber por qué en la configuración del host las variables de entorno con prefijo ASPNETCORE_
tienen mayor prioridad que los argumentos de la línea de comandos.
Variables de host
Las siguientes variables se bloquean pronto al inicializar los generadores de hosts y no se ven influidas por la configuración de la aplicación:
- Nombre de la aplicación
- Nombre del entorno, por ejemplo,
Development
,Production
yStaging
- Raíz del contenido
- Raíz web
- Si se van a buscar ensamblados de inicio de hospedaje y qué ensamblados se van a buscar
- Variables que el código de aplicación y biblioteca lee de HostBuilderContext.Configuration en las devoluciones de llamada IHostBuilder.ConfigureAppConfiguration
Cualquier otra configuración de host se lee de la configuración de la aplicación en lugar de la configuración del host.
URLS
es una de las muchas configuraciones de host comunes que no es una configuración de arranque. Como cualquier otra configuración de host que no figura en la lista anterior, URLS
se lee más adelante desde la configuración de la aplicación. La configuración del host es una reserva de la configuración de la aplicación, con lo cual se puede usar para establecer URLS
, pero quedará invalidada por cualquier origen de configuración de la aplicación, como appsettings.json
.
Para obtener más información, consulte Cambio de la raíz del contenido, el nombre de la aplicación y el entorno y Cambio de la raíz del contenido, el nombre de la aplicación y el entorno por variables de entorno o línea de comandos.
El resto de secciones de este artículo se centran en la configuración de la aplicación.
Proveedores de configuración de la aplicación
El código siguiente muestra los proveedores de configuración habilitados en el orden en el que se han agregado:
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);
}
}
La lista anterior de orígenes de configuración predeterminados ordenados de prioridad más alta a más baja muestra los proveedores en orden opuesto al que se agregan a la aplicación generada por la plantilla. Así, por ejemplo, el proveedor de configuración JSON se agrega antes que el proveedor de configuración de línea de comandos.
Los proveedores de configuración que se agreguen posteriormente tienen mayor prioridad e invalidan los ajustes de configuración de clave anteriores. Por ejemplo, si MyKey
se establece tanto en appsettings.json
como en el entorno, se usará el valor del entorno. Con los proveedores de configuración predeterminados, el proveedor de configuración de línea de comandos reemplaza al resto de proveedores.
Para obtener más información sobre CreateBuilder
, consulte el artículo Configuración predeterminada del generador.
appsettings.json
Fíjese en el siguiente archivo appsettings.json
:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
El siguiente código de la descarga de ejemplo muestra algunas de las configuraciones anteriores:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
El elemento JsonConfigurationProvider predeterminado carga la configuración en el siguiente orden:
appsettings.json
appsettings.{Environment}.json
: por ejemplo, los archivosappsettings.Production.json
yappsettings.Development.json
. La versión del entorno del archivo se carga en función de IHostingEnvironment.EnvironmentName. Para obtener más información, consulte Usar varios entornos en ASP.NET Core.
Los valores de appsettings.{Environment}.json
invalidan las claves en appsettings.json
. Por ejemplo, de forma predeterminada:
- En la fase de desarrollo, la configuración
appsettings.Development.json
sobrescribe los valores encontrados enappsettings.json
. - En la fase de producción, la configuración
appsettings.Production.json
sobrescribe los valores encontrados enappsettings.json
. Por ejemplo, al implementar la aplicación en Azure.
Si se debe garantizar un valor de configuración, consulte GetValue. En el ejemplo anterior solo se leen cadenas y no se admite un valor predeterminado.
Si usa la configuración predeterminada, los archivosappsettings.json
y appsettings.{Environment}.json
están habilitados con reloadOnChange: true. Los cambios realizados en appsettings.json
y el archivo appsettings.{Environment}.json
después de iniciar la aplicación los lee el proveedor de configuración JSON.
Enlace de datos de configuración jerárquica mediante el patrón de opciones
La mejor manera de leer valores de configuración relacionados es usar el patrón de opciones. Por ejemplo, para leer los siguientes valores de configuración:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Crea la siguiente clase PositionOptions
:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
}
Una clase de opciones:
- Debe ser no abstracta con un constructor público sin parámetros.
- Todas las propiedades de lectura y escritura públicas del tipo están enlazadas.
- Los campos no se enlazan. En el código anterior,
Position
no está enlazado. El campoPosition
se usa para que la cadena"Position"
no se tenga que codificar de forma rígida en la aplicación al enlazar la clase a un proveedor de configuración.
El código siguiente:
- Llama a ConfigurationBinder.Bind para enlazar la clase
PositionOptions
a la secciónPosition
. - Muestra los datos de configuración de
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}");
}
}
En el código anterior, de forma predeterminada, los cambios en el archivo de configuración de JSON producidos una vez iniciada la aplicación se leen.
ConfigurationBinder.Get<T>
enlaza y devuelve el tipo especificado. Puede ser más conveniente usar ConfigurationBinder.Get<T>
que ConfigurationBinder.Bind
. En el código siguiente se muestra cómo puede usar ConfigurationBinder.Get<T>
con la clase 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}");
}
}
En el código anterior, de forma predeterminada, los cambios en el archivo de configuración de JSON producidos una vez iniciada la aplicación se leen.
Un enfoque alternativo a la hora de usar el patrón de opciones consiste en enlazar la sección Position
y agregarla al contenedor del servicio de inserción de dependencias. En el siguiente código se agrega PositionOptions
al contenedor de servicios con Configure y se enlaza a la configuración:
using ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<PositionOptions>(
builder.Configuration.GetSection(PositionOptions.Position));
var app = builder.Build();
A partir del código anterior, el siguiente código lee las opciones de posición:
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}");
}
}
En el código anterior, los cambios en el archivo de configuración de JSON producidos una vez iniciada la aplicación no se leen. Para leer los cambios una vez iniciada la aplicación, usa IOptionsSnapshot.
Si usa la configuración predeterminada, los archivosappsettings.json
y appsettings.{Environment}.json
están habilitados con reloadOnChange: true. Los cambios realizados en appsettings.json
y el archivo appsettings.{Environment}.json
después de iniciar la aplicación los lee el proveedor de configuración JSON.
Consulte la sección Proveedor de configuración JSON en este artículo para obtener información sobre cómo agregar archivos de configuración JSON adicionales.
Combinación de colecciones de servicios
Tenga en cuenta el siguiente método que registra los servicios y configura las opciones:
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();
Los grupos de registros relacionados pueden moverse a un método de extensión para registrar los servicios. Por ejemplo, los servicios de configuración se agregan a la siguiente clase:
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;
}
}
}
Los servicios restantes se registran en una clase similar. El siguiente código usa los nuevos métodos de extensión para registrar los servicios:
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddConfig(builder.Configuration)
.AddMyDependencyGroup();
builder.Services.AddRazorPages();
var app = builder.Build();
Nota: Cada método de extensión services.Add{GROUP_NAME}
agrega servicios y potencialmente los configura. Por ejemplo, AddControllersWithViews agrega los controladores MVC de servicios con las vistas que se requieren y AddRazorPages agrega los servicios que Razor Pages requiere.
Seguridad y secretos de usuario
Directrices para los datos de configuración:
- Nunca almacene contraseñas u otros datos confidenciales en el código del proveedor de configuración o en archivos de configuración de texto sin formato. Se puede usar la herramienta Administrador de secretos para almacenar secretos en desarrollo.
- No use secretos de producción en los entornos de desarrollo o pruebas.
- Especifique los secretos fuera del proyecto para que no se confirmen en un repositorio de código fuente de manera accidental.
- Las aplicaciones de producción deben usar el flujo de autenticación más seguro disponible. Para más información, consulte Flujos de autenticación seguros.
De forma predeterminada, el origen de configuración de los secretos de usuario se registra después de los orígenes de configuración de JSON. Por lo tanto, las claves de secretos de usuario tienen prioridad sobre las claves de appsettings.json
y appsettings.{Environment}.json
.
Para obtener más información sobre cómo almacenar contraseñas u otros datos confidenciales consulte:
- Usar varios entornos en ASP.NET Core
- Caja fuerte almacenamiento de secretos de aplicaciones en el ASP.NET Core: incluye consejos sobre el uso de variables de entorno para almacenar datos confidenciales. La herramienta Administrador de secretos usa el proveedor de configuración de archivo para almacenar secretos de usuario en un archivo JSON en el sistema local.
Azure Key Vault almacena de forma segura secretos de aplicación para aplicaciones de ASP.NET Core. Para obtener más información, vea Proveedor de configuración de Azure Key Vault en ASP.NET Core.
Variables de entorno sin prefijo
Las variables de entorno sin prefijo son variables de entorno distintas de las que exhiben los prefijos ASPNETCORE_
o DOTNET_
. Por ejemplo, las plantillas de aplicación web de ASP.NET Core establecen "ASPNETCORE_ENVIRONMENT": "Development"
en launchSettings.json
. Para obtener más información sobre las variables de entorno ASPNETCORE_
y DOTNET_
, consulte:
- Lista de orígenes de configuración predeterminados ordenados de prioridad más alta a más baja, incluidas las variables de entorno sin prefijo y con los prefijos
ASPNETCORE_
yDOTNETCORE_
- Variables de entorno
DOTNET_
usadas fuera de Microsoft.Extensions.Hosting
Al usar la configuración predeterminada, EnvironmentVariablesConfigurationProvider carga la configuración de los pares clave-valor de la variable de entorno después de leer appsettings.json
, appsettings.{Environment}.json
y los secretos de usuario. Por lo tanto, los valores de clave que se leen del entorno reemplazan los valores que se leen de appsettings.json
, appsettings.{Environment}.json
y los secretos de usuario.
El separador :
no funciona con claves jerárquicas de variables de entorno en todas las plataformas. Por ejemplo, el separador :
no es compatible con Bash. El carácter de subrayado doble, __
, tiene las siguientes características:
- Es compatible con todas las plataformas.
- Se reemplaza automáticamente por dos puntos,
:
.
Los siguientes comandos set
:
- Establecen las claves de entorno y los valores del ejemplo anterior en Windows.
- Prueban la configuración al usar la descarga de ejemplo. El comando
dotnet run
debe ejecutarse en el directorio del proyecto.
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run
Los ajustes de configuración del entorno anteriores:
- Solo se establecen en procesos iniciados desde la ventana de comandos en la que se establecieron.
- No los podrán leer los exploradores que se inician con Visual Studio.
Los siguientes comandos setx se pueden usar para establecer las claves de entorno y los valores en Windows. A diferencia de set
, la configuración de setx
se conserva. /M
establece la variable en el entorno del sistema. Si no se usa el modificador /M
, se establece una variable de entorno de usuario.
setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M
Para comprobar que los comandos anteriores invalidan appsettings.json
y appsettings.{Environment}.json
:
- Con Visual Studio: salga y reinicie Visual Studio.
- Con la CLI: abra una nueva ventana de comandos y escriba
dotnet run
.
Llame a AddEnvironmentVariables con una cadena para especificar un prefijo para las variables de entorno:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
var app = builder.Build();
En el código anterior:
builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_")
se agrega después de los proveedores de configuración predeterminados. Para obtener un ejemplo de ordenación de los proveedores de configuración, consulte la sección Proveedor de configuración JSON.- Las variables de entorno establecidas con el prefijo
MyCustomPrefix_
invalidan los proveedores de configuración predeterminados. Esto incluye las variables de entorno sin el prefijo.
El prefijo se quita cuando se leen los pares clave-valor de configuración.
Los siguientes comandos prueban el prefijo personalizado:
set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run
La configuración predeterminada carga las variables de entorno y los argumentos de la línea de comandos con los prefijos DOTNET_
y ASPNETCORE_
. ASP.NET Core usa los prefijos DOTNET_
y ASPNETCORE_
para la configuración del host y la aplicación, pero no para la del usuario. Para obtener más información sobre la configuración del host y de la aplicación, consulte el artículo Host genérico de .NET.
En Azure App Service, seleccione Nueva configuración de la aplicación en la página Configuración > Configuración. Los ajustes de configuración de Azure App Service:
- Se cifran en rest y se transmiten a través de un canal cifrado.
- Se exponen como variables de entorno.
Para más información, consulte Aplicaciones de Azure: Invalidación de la configuración de la aplicación mediante Azure Portal.
Consulte la sección Prefijos de cadena de conexión para obtener información sobre las cadenas de conexión de base de datos de Azure.
Nomenclatura de variables de entorno
Los nombres de las variables de entorno reflejan la estructura de un archivo appsettings.json
. Cada elemento de la jerarquía está separado por un carácter de subrayado doble (preferible) o un signo de dos puntos. Cuando la estructura del elemento incluye una matriz, el índice de la matriz se debe tratar como un nombre de elemento adicional en esta ruta de acceso. Considere el siguiente archivo appsettings.json
y sus valores equivalentes representados como variables de entorno.
appsettings.json
{
"SmtpServer": "smtp.example.com",
"Logging": [
{
"Name": "ToEmail",
"Level": "Critical",
"Args": {
"FromAddress": "MySystem@example.com",
"ToAddress": "SRE@example.com"
}
},
{
"Name": "ToConsole",
"Level": "Information"
}
]
}
variables de entorno
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
Variables de entorno configuradas en el archivo launchSettings.json generado
Las variables de entorno configuradas en launchSettings.json
invalidan aquellas configuradas en el entorno del sistema. Por ejemplo, las plantillas web ASP.NET Core generan un archivo launchSettings.json
que establece la configuración del punto de conexión en:
"applicationUrl": "https://localhost:5001;http://localhost:5000"
Al configurar applicationUrl
, se establece la variable de entorno ASPNETCORE_URLS
y se invalidan los valores establecidos en el entorno.
Variables de entorno de escape en Linux
En Linux, el valor de las variables de entorno de URL debe ser de escape, para que systemd
pueda analizarlas. Uso de la herramienta de Linux systemd-escape
que produce http:--localhost:5001
groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001
Visualización de las variables de entorno
En el código siguiente se muestran las variables de entorno y los valores en el inicio de la aplicación, lo que puede resultar útil al depurar la configuración del entorno:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
foreach (var c in builder.Configuration.AsEnumerable())
{
Console.WriteLine(c.Key + " = " + c.Value);
}
Línea de comandos
Si se usa la configuración predeterminada, CommandLineConfigurationProvider carga la configuración de los pares de clave-valor de argumento de la línea de comandos después de los siguientes orígenes de configuración:
- archivos
appsettings.json
yappsettings.{Environment}.json
. - Secretos de aplicaciones en el entorno de desarrollo.
- Variables de entorno.
De forma predeterminada, los valores de configuración establecidos en la línea de comandos reemplazan los valores de configuración establecidos con el resto de proveedores de configuración.
Argumentos de la línea de comandos
El comando siguiente establece las claves y los valores mediante =
:
dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick
El comando siguiente establece las claves y los valores mediante /
:
dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick
El comando siguiente establece las claves y los valores mediante --
:
dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick
El valor de la clave:
- Debe seguir a un signo
=
, o bien la clave debe tener un prefijo--
o/
cuando el valor sigue a un espacio. - No es necesario si se usa
=
. Por ejemplo:MySetting=
.
Dentro del mismo comando, no mezcle pares clave-valor de argumento de la línea de comandos que usan =
con pares de clave-valor que usan un espacio.
Asignaciones de modificador
Las asignaciones de modificador admiten la lógica de sustitución de nombres de clave. Proporcione un diccionario de reemplazos de modificador al método AddCommandLine.
Cuando se usa el diccionario de asignaciones de modificador, se comprueba en el diccionario si una clave coincide con la clave proporcionada por un argumento de línea de comandos. Si la clave de la línea de comandos se encuentra en el diccionario, se devuelve el valor del diccionario para establecer el par clave-valor en la configuración de la aplicación. Se requiere una asignación de conmutador para cualquier clave de línea de comandos precedida por un solo guion (-
).
Reglas de clave del diccionario de asignaciones de modificador:
- Los modificadores deben comenzar con
-
o--
. - El diccionario de asignaciones de modificador no debe contener claves duplicadas.
Para usar un diccionario de asignaciones de modificador, páselo a la llamada 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();
La ejecución del siguiente comando sirve para probar el reemplazo de claves:
dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6
El código siguiente muestra los valores de clave para las claves reemplazadas:
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"]}'");
}
}
En el caso de las aplicaciones que usen las asignaciones de modificador, la llamada a CreateDefaultBuilder
no tiene que pasar argumentos. En la llamada de AddCommandLine
al método CreateDefaultBuilder
, no se incluyen modificadores asignados y no hay forma de pasar el diccionario de asignación de modificador a CreateDefaultBuilder
. La solución no es pasar los argumentos de CreateDefaultBuilder
, sino permitir que el método AddCommandLine
del método ConfigurationBuilder
procese tanto los argumentos como el diccionario de asignación de modificador.
Configuración del entorno y de los argumentos de la línea de comandos con Visual Studio
Los argumentos de entorno y de línea de comandos se pueden establecer en Visual Studio desde el cuadro de diálogo de perfiles de inicio:
- En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Propiedades.
- Seleccione la pestaña Depurar > General y luego Abrir la interfaz de usuario de perfiles de inicio de depuración.
Datos de configuración jerárquica
La API de configuración lee los datos de configuración jerárquica al disminuir los datos jerárquicos mediante el uso de un delimitador en las claves de configuración.
La descarga de ejemplo contiene el siguiente archivo appsettings.json
:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
El siguiente código de la descarga de ejemplo muestra algunas de las opciones de configuración:
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 mejor manera de leer datos de configuración jerárquica es usar el patrón de opciones. Para obtener más información, vea la sección Enlace de datos de configuración jerárquica en este documento.
Los métodos GetSection y GetChildren están disponibles para aislar las secciones y los elementos secundarios de una sección en los datos de configuración. Estos métodos se describen más adelante en la sección GetSection, GetChildren y Exists.
Claves y valores de configuración
Advertencia
En este artículo se muestra el uso de cadena de conexión. Con una base de datos local, el usuario no tiene que autenticarse, pero en producción, cadena de conexión a veces incluye una contraseña para autenticarse. Una credencial de contraseña de propietario de recursos (ROPC) es un riesgo de seguridad que se debe evitar en las bases de datos de producción. Las aplicaciones de producción deben usar el flujo de autenticación más seguro disponible. Para obtener más información sobre la autenticación de aplicaciones implementadas para probar o entornos de producción, consulte Flujos de autenticación seguros.
Las claves de configuración:
- No distinguen mayúsculas de minúsculas. Por ejemplo,
ConnectionString
yconnectionstring
se consideran claves equivalente. - Si se establece una clave y un valor en más de un proveedor de configuración, se usa el valor del último proveedor agregado. Para obtener más información, vea la sección Configuración predeterminada.
- Claves jerárquicas
- Dentro de la API de configuración, un separador de dos puntos (
:
) funciona en todas las plataformas. - En las variables de entorno, puede que un separador de dos puntos no funcione en todas las plataformas. Todas las plataformas admiten un carácter de subrayado doble,
__
, que se convierte automáticamente en un signo de dos puntos:
. - En Azure Key Vault, las claves jerárquicas usan
--
como separador. El proveedor de configuración de Azure Key Vault reemplaza automáticamente--
con:
cuando los secretos se cargan en la configuración de la aplicación.
- Dentro de la API de configuración, un separador de dos puntos (
- ConfigurationBinder admite enlazar matrices a objetos con los índices de matriz en las claves de configuración. El enlace de matriz se describe en la sección Enlace de una matriz a una clase.
Los valores de configuración:
- Son cadenas.
- Los valores NULL no se pueden almacenar en la configuración ni enlazar a los objetos.
Proveedores de configuración
La siguiente tabla muestra los proveedores de configuración disponibles para las aplicaciones de ASP.NET Core.
Proveedor | Proporciona la configuración de |
---|---|
Proveedor de configuración de Azure Key Vault | Azure Key Vault |
Proveedor de configuración de aplicaciones de Azure | Configuración de aplicaciones de Azure |
Proveedor de configuración de línea de comandos | Parámetros de la línea de comandos |
Proveedor de configuración personalizada | Origen personalizado |
Proveedor de configuración de variables de entorno | Variables de entorno |
Proveedor de configuración de archivo | Archivos INI, JSON y XML |
Proveedor de configuración de clave por archivo | Archivos de directorio |
Proveedor de configuración de memoria | Colecciones en memoria |
Secretos de usuario | Archivo en el directorio del perfil de usuario |
Los orígenes de configuración se leen en el orden en que se especifican sus proveedores de configuración. Ordene los proveedores de configuración en el código para cumplir con las prioridades relacionadas con los orígenes de configuración subyacentes que la aplicación necesita.
Esta es una secuencia típica de proveedores de configuración:
appsettings.json
appsettings.{Environment}.json
- Secretos de usuario
- Variables de entorno con el proveedor de configuración de variables de entorno.
- Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos.
Una práctica común es agregar el proveedor de configuración de línea de comandos al final en una serie de proveedores para permitir que los argumentos de la línea de comandos reemplacen la configuración establecida por el resto de los proveedores.
La secuencia de proveedores anterior se usa en la configuración predeterminada.
Prefijos de cadena de conexión
Advertencia
En este artículo se muestra el uso de cadena de conexión. Con una base de datos local, el usuario no tiene que autenticarse, pero en producción, cadena de conexión a veces incluye una contraseña para autenticarse. Una credencial de contraseña de propietario de recursos (ROPC) es un riesgo de seguridad que se debe evitar en las bases de datos de producción. Las aplicaciones de producción deben usar el flujo de autenticación más seguro disponible. Para obtener más información sobre la autenticación de aplicaciones implementadas para probar o entornos de producción, consulte Flujos de autenticación seguros.
La API de configuración tiene reglas de procesamiento especiales para cuatro variables de entorno de cadena de conexión. Estas cadenas de conexión están implicadas en la configuración de las cadenas de conexión de Azure para el entorno de la aplicación. Las variables de entorno con los prefijos que se muestran en la tabla se cargan en la aplicación con la configuración predeterminada o cuando no se proporciona ningún prefijo a AddEnvironmentVariables
.
Prefijo de cadena de conexión | Proveedor |
---|---|
CUSTOMCONNSTR_ |
Proveedor personalizado |
MYSQLCONNSTR_ |
MySQL |
SQLAZURECONNSTR_ |
Azure SQL Database |
SQLCONNSTR_ |
SQL Server |
Cuando una variable de entorno se detecta y carga en la configuración con cualquiera de los cuatro prefijos que se muestran en la tabla:
- La clave de configuración se crea al quitar el prefijo de la variable de entorno y al agregar una sección de clave de configuración (
ConnectionStrings
). - Se crea un nuevo par clave-valor de configuración que representa el proveedor de conexión de base de datos (excepto para
CUSTOMCONNSTR_
, que no tiene ningún proveedor indicado).
Clave de variable de entorno | Clave de configuración convertida | Entrada de configuración del proveedor |
---|---|---|
CUSTOMCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Entrada de configuración no creada. |
MYSQLCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Clave: ConnectionStrings:{KEY}_ProviderName :Valor: MySql.Data.MySqlClient |
SQLAZURECONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Clave: ConnectionStrings:{KEY}_ProviderName :Valor: System.Data.SqlClient |
SQLCONNSTR_{KEY} |
ConnectionStrings:{KEY} |
Clave: ConnectionStrings:{KEY}_ProviderName :Valor: System.Data.SqlClient |
Proveedor de configuración de archivo
FileConfigurationProvider es la clase base para cargar la configuración del sistema de archivos. Los siguientes proveedores de configuración se derivan de FileConfigurationProvider
:
Proveedor de configuración INI
IniConfigurationProvider carga la configuración desde pares clave-valor de archivo INI en tiempo de ejecución.
El código siguiente agrega varios proveedores de configuración:
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();
En el código anterior, la configuración de los archivos MyIniConfig.ini
y MyIniConfig.{Environment}.ini
se reemplaza por la configuración de:
La descarga de ejemplo contiene el siguiente archivo MyIniConfig.ini
:
MyKey="MyIniConfig.ini Value"
[Position]
Title="My INI Config title"
Name="My INI Config name"
[Logging:LogLevel]
Default=Information
Microsoft=Warning
El siguiente código de la descarga de ejemplo muestra algunas de las configuraciones anteriores:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
Proveedor de configuración JSON
JsonConfigurationProvider carga la configuración desde pares clave-valor de archivos JSON.
Las sobrecargas pueden especificar:
- Si el archivo es opcional.
- Si la configuración se recarga si el archivo cambia.
Observe el código siguiente:
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();
El código anterior:
- Configura el proveedor de configuración JSON para que cargue el archivo
MyConfig.json
con las siguientes opciones:optional: true
: el archivo es opcional.reloadOnChange: true
: el archivo se recarga cuando se guardan los cambios.
- Lee los proveedores de configuración predeterminados antes que el archivo
MyConfig.json
. La configuración del archivoMyConfig.json
invalida la de los proveedores de configuración predeterminados, incluidos el proveedor de configuración de variables de entorno y el proveedor de configuración de línea de comandos.
Normalmente no querrá que un archivo JSON personalizado invalide los valores establecidos en el proveedor de configuración de variables de entorno ni en el proveedor de configuración de línea de comandos.
Proveedor de configuración XML
XmlConfigurationProvider carga la configuración desde pares clave-valor de archivo XML en tiempo de ejecución.
El código siguiente agrega varios proveedores de configuración:
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();
En el código anterior, la configuración de los archivos MyXMLFile.xml
y MyXMLFile.{Environment}.xml
se reemplaza por la configuración de:
La descarga de ejemplo contiene el siguiente archivo MyXMLFile.xml
:
<?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>
El siguiente código de la descarga de ejemplo muestra algunas de las configuraciones anteriores:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
Los elementos de repetición que usan el mismo nombre de elemento funcionan si el atributo name
se usa para distinguir los elementos:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<section name="section0">
<key name="key0">value 00</key>
<key name="key1">value 01</key>
</section>
<section name="section1">
<key name="key0">value 10</key>
<key name="key1">value 11</key>
</section>
</configuration>
El código siguiente lee el archivo de configuración anterior y muestra las claves y los valores:
public class IndexModel : PageModel
{
private readonly IConfiguration Configuration;
public IndexModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var key00 = "section:section0:key:key0";
var key01 = "section:section0:key:key1";
var key10 = "section:section1:key:key0";
var key11 = "section:section1:key:key1";
var val00 = Configuration[key00];
var val01 = Configuration[key01];
var val10 = Configuration[key10];
var val11 = Configuration[key11];
return Content($"{key00} value: {val00} \n" +
$"{key01} value: {val01} \n" +
$"{key10} value: {val10} \n" +
$"{key10} value: {val11} \n"
);
}
}
Los atributos se pueden usar para suministrar valores:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<key attribute="value" />
<section>
<key attribute="value" />
</section>
</configuration>
El archivo de configuración anterior carga las siguientes claves con value
:
- key:attribute
- section:key:attribute
Proveedor de configuración de clave por archivo
KeyPerFileConfigurationProvider usa los archivos de un directorio como pares clave-valor de configuración. La clave es el nombre de archivo. El valor contiene el contenido del archivo. El proveedor de configuración de clave por archivo se usa en escenarios de hospedaje de Docker.
Para activar la configuración de clave por archivo, llame al método de extensión AddKeyPerFile en una instancia de ConfigurationBuilder. La ruta de acceso directoryPath
a los archivos debe ser una ruta de acceso absoluta.
Las sobrecargas permiten especificar:
- Un delegado
Action<KeyPerFileConfigurationSource>
que configura el origen. - Si el directorio es opcional y la ruta de acceso al directorio.
El carácter de subrayado doble (__
) se usa como delimitador de claves de configuración en los nombres de archivo. Por ejemplo, el nombre de archivo Logging__LogLevel__System
genera la clave de configuración Logging:LogLevel:System
.
Llame a ConfigureAppConfiguration
cuando cree el host para especificar la configuración de la aplicación:
.ConfigureAppConfiguration((hostingContext, config) =>
{
var path = Path.Combine(
Directory.GetCurrentDirectory(), "path/to/files");
config.AddKeyPerFile(directoryPath: path, optional: true);
})
Proveedor de configuración de memoria
MemoryConfigurationProvider usa una colección en memoria como pares clave-valor de configuración.
El código siguiente agrega una colección en memoria al sistema de configuración:
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();
El siguiente código de la descarga de ejemplo muestra las opciones de configuración anteriores:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
En el código anterior, config.AddInMemoryCollection(Dict)
se agrega después de los proveedores de configuración predeterminados. Para obtener un ejemplo de ordenación de los proveedores de configuración, consulte la sección Proveedor de configuración JSON.
Consulte la sección Enlace de matrices para ver otro ejemplo que usa MemoryConfigurationProvider
.
Configuración del punto de conexión de Kestrel
La configuración del punto de conexión específico de Kestrel invalida todas las configuraciones del punto de conexión entre servidores. Las configuraciones del punto de conexión entre servidores incluyen:
- UseUrls
--urls
en la línea de comandos- La variable de entorno
ASPNETCORE_URLS
Tenga en cuenta el archivo siguiente appsettings.json
usado en una aplicación web de ASP.NET Core:
{
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://localhost:9999"
}
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Cuando el marcado resaltado anterior se usa en una aplicación web de ASP.NET Core y la aplicación se inicia en la línea de comandos con la siguiente configuración del punto de conexión entre servidores:
dotnet run --urls="https://localhost:7777"
Kestrel se enlaza con el punto de conexión configurado específicamente para Kestrel en el archivo appsettings.json
(https://localhost:9999
) y no https://localhost:7777
.
Considere el punto de conexión específico de Kestrel configurado como una variable de entorno:
set Kestrel__Endpoints__Https__Url=https://localhost:8888
En la variable de entorno anterior, Https
es el nombre del punto de conexión específico de Kestrel. En el archivo appsettings.json
anterior también se define un punto de conexión específico de Kestrel denominado Https
. De manera predeterminada, las variables de entorno que utilizan el proveedor de configuración de variables de entorno se leen después de appsettings.{Environment}.json
, por lo tanto, la variable de entorno anterior se usa para el punto de conexión Https
.
GetValue
ConfigurationBinder.GetValue extrae un único valor de la configuración con una clave determinada y lo convierte al tipo especificado:
public class TestNumModel : PageModel
{
private readonly IConfiguration Configuration;
public TestNumModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var number = Configuration.GetValue<int>("NumberKey", 99);
return Content($"{number}");
}
}
En el código anterior, si NumberKey
no se encuentra en la configuración, se usa el valor predeterminado de 99
.
GetSection, GetChildren y Exists
Para los ejemplos siguientes, considere el siguiente archivo MySubsection.json
:
{
"section0": {
"key0": "value00",
"key1": "value01"
},
"section1": {
"key0": "value10",
"key1": "value11"
},
"section2": {
"subsection0": {
"key0": "value200",
"key1": "value201"
},
"subsection1": {
"key0": "value210",
"key1": "value211"
}
}
}
El código siguiente agrega MySubsection.json
a los proveedores de configuración:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.AddJsonFile("MySubsection.json",
optional: true,
reloadOnChange: true);
builder.Services.AddRazorPages();
var app = builder.Build();
GetSection
IConfiguration.GetSection devuelve una subsección de la configuración con la clave de subsección especificada.
El código siguiente devuelve los valores de 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"]}'");
}
}
El código siguiente devuelve los valores de section2:subsection0
:
public class TestSection2Model : PageModel
{
private readonly IConfiguration Config;
public TestSection2Model(IConfiguration configuration)
{
Config = configuration.GetSection("section2:subsection0");
}
public ContentResult OnGet()
{
return Content(
$"section2:subsection0:key0 '{Config["key0"]}'\n" +
$"section2:subsection0:key1:'{Config["key1"]}'");
}
}
GetSection
nunca devuelve null
. Si no se encuentra una sección que coincida, se devuelve una IConfigurationSection
vacía.
Cuando GetSection
devuelve una sección coincidente, Value no se rellena. Se devuelven Key y Path si la sección existe.
GetChildren y Exists
El código siguiente llama a IConfiguration.GetChildren y devuelve los valores de 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);
}
}
El código anterior llama a ConfigurationExtensions.Exists para comprobar que la sección existe:
Enlace de matrices
ConfigurationBinder.Bind admite enlazar matrices a objetos con los índices de matriz en las claves de configuración. Cualquier formato de matriz que exponga un segmento de clave numérica es capaz de enlazar una matriz a una matriz de clase POCO.
Tenga en cuenta este archivo MyArray.json
de la descarga de ejemplo:
{
"array": {
"entries": {
"0": "value00",
"1": "value10",
"2": "value20",
"4": "value40",
"5": "value50"
}
}
}
El código siguiente agrega MyArray.json
a los proveedores de configuración:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.AddJsonFile("MyArray.json",
optional: true,
reloadOnChange: true);
builder.Services.AddRazorPages();
var app = builder.Build();
El código siguiente lee la configuración y muestra los valores:
public class ArrayModel : PageModel
{
private readonly IConfiguration Config;
public ArrayExample? _array { get; private set; }
public ArrayModel(IConfiguration config)
{
Config = config;
}
public ContentResult OnGet()
{
_array = Config.GetSection("array").Get<ArrayExample>();
if (_array == null)
{
throw new ArgumentNullException(nameof(_array));
}
string s = String.Empty;
for (int j = 0; j < _array.Entries.Length; j++)
{
s += $"Index: {j} Value: {_array.Entries[j]} \n";
}
return Content(s);
}
}
public class ArrayExample
{
public string[]? Entries { get; set; }
}
El código anterior devuelve el siguiente resultado:
Index: 0 Value: value00
Index: 1 Value: value10
Index: 2 Value: value20
Index: 3 Value: value40
Index: 4 Value: value50
En el resultado anterior, el índice 3 tiene el valor value40
, que corresponde a "4": "value40",
en MyArray.json
. Los índices de matriz enlazados son continuos y no están enlazados al índice de la clave de configuración. El enlazador de configuración no es capaz de enlazar los valores NULL ni de crear entradas NULL en objetos enlazados.
Proveedores de configuración personalizada
La aplicación de ejemplo muestra cómo crear un proveedor de configuración básica que lee los pares clave-valor de configuración desde una base de datos mediante Entity Framework (EF).
El proveedor tiene las siguientes características:
- La base de datos en memoria de EF se usa para fines de demostración. Para usar una base de datos que requiere una cadena de conexión, implemente un
ConfigurationBuilder
secundario para suministrar la cadena de conexión desde otro proveedor de configuración. - El proveedor lee una tabla de base de datos en la configuración en el inicio. El proveedor no consulta la base de datos por clave.
- La función de recarga en cambio no se implementa, por lo que actualizar la base de datos después del inicio de la aplicación no afecta a la configuración de la aplicación.
Defina una entidad EFConfigurationValue
para almacenar los valores de configuración en la base de datos.
Models/EFConfigurationValue.cs
:
public class EFConfigurationValue
{
public string Id { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
}
Agregue un EFConfigurationContext
para almacenar y tener acceso a los valores configurados.
EFConfigurationProvider/EFConfigurationContext.cs
:
public class EFConfigurationContext : DbContext
{
public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
{
}
public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}
Cree una clase que implemente 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);
}
Cree el proveedor de configuración personalizado heredando de ConfigurationProvider. El proveedor de configuración inicializa la base de datos cuando está vacía. Puesto que las claves de configuración no distinguen entre mayúsculas y minúsculas, el diccionario empleado para iniciar la base de datos se crea con el comparador que tampoco hace tal distinción (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 método de extensión AddEFConfiguration
permite agregar el origen de configuración 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));
}
}
En el código siguiente se muestra cómo puede usar el EFConfigurationProvider
personalizado en Program.cs
:
//using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddEFConfiguration(
opt => opt.UseInMemoryDatabase("InMemoryDb"));
var app = builder.Build();
app.Run();
Configuración de acceso con inserción de dependencias (DI)
La configuración se puede insertar en los servicios mediante la inserción de dependencias (DI) resolviendo el servicio IConfiguration:
public class Service
{
private readonly IConfiguration _config;
public Service(IConfiguration config) =>
_config = config;
public void DoSomething()
{
var configSettingValue = _config["ConfigSetting"];
// ...
}
}
Para obtener información sobre cómo acceder a valores mediante IConfiguration
, vea GetValue y GetSection, GetChildren y Exists en este artículo.
Acceso a la configuración en Razor Pages
En el código siguiente se muestran los datos de configuración en una página de RazorPages:
@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
En el siguiente código se agrega MyOptions
al contenedor de servicios con Configure y se enlaza a la configuración:
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
En el marcado siguiente se usa la directiva @inject
Razor para resolver y mostrar los valores de las opciones:
@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>
Acceso a la configuración en un archivo de vista de MVC
En el código siguiente se muestran los datos de configuración de una vista de MVC:
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
Acceder a la configuración en Program.cs
El código siguiente accede a la configuración en el archivo 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();
En appsettings.json
para el ejemplo anterior:
{
...
"KeyOne": "Key One Value",
"KeyTwo": 1999,
"KeyThree": true
}
Configurar opciones con un delegado
Las opciones configuradas en un delegado invalidan los valores establecidos en los proveedores de configuración.
En el código siguiente, se agrega un servicio IConfigureOptions<TOptions> al contenedor de servicios. Usa un delegado para configurar los valores de 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();
En el código siguiente se muestran los valores de las opciones:
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}");
}
}
En el ejemplo anterior, los valores de Option1
y Option2
se especifican en appsettings.json
y, luego, se reemplazan por el delegado configurado.
Configuración de host y de aplicación
Antes de configurar e iniciar la aplicación, se configura e inicia un host. El host es responsable de la administración del inicio y la duración de la aplicación. Tanto la aplicación como el host se configuran mediante los proveedores de configuración que se describen en este tema. Los pares clave-valor de configuración del host también se incluyen en la configuración de la aplicación. Para obtener más información sobre cómo se usan los proveedores de configuración cuando se compila el host y cómo afectan los orígenes de configuración a la configuración del host, consulte la información general sobre conceptos básicos de ASP.NET Core.
Configuración predeterminada del host
Para obtener más información sobre la configuración predeterminada al usar el host de web, vea la versión de este tema para ASP.NET Core 2.2.
- La configuración del host la proporcionan los siguientes elementos:
- Las variables de entorno con el prefijo
DOTNET_
(por ejemplo,DOTNET_ENVIRONMENT
) mediante el proveedor de configuración de variables de entorno. El prefijo (DOTNET_
) se quita cuando se cargan los pares clave-valor de configuración. - Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos.
- Las variables de entorno con el prefijo
- La configuración predeterminada del host de web se ha establecido (
ConfigureWebHostDefaults
):- Kestrel se usa como el servidor web y se ha configurado mediante los proveedores de configuración de la aplicación.
- Agregar el middleware de filtrado de host
- Agregue el middleware de encabezados reenviados si la variable de entorno
ASPNETCORE_FORWARDEDHEADERS_ENABLED
se establece entrue
. - Habilite la integración con IIS.
Otra configuración
Este tema solo concierne a la configuración de aplicaciones. Otros aspectos de la ejecución y el hospedaje de aplicaciones ASP.NET Core se configuran mediante archivos de configuración que no se describen en este tema:
launch.json
/launchSettings.json
son archivos de configuración de herramientas para el entorno de desarrollo, que se describen a continuación:- En Usar varios entornos en ASP.NET Core.
- En el conjunto de documentación en el que se usan los archivos para configurar aplicaciones ASP.NET Core para escenarios de desarrollo.
web.config
es un archivo de configuración del servidor, que se describe en los temas siguientes:
Las variables de entorno configuradas en launchSettings.json
invalidan aquellas configuradas en el entorno del sistema.
Para más información sobre cómo migrar la configuración de aplicaciones de versiones anteriores de ASP.NET, consulte Actualización de ASP.NET a ASP.NET Core.
Agregar configuración a partir de un ensamblado externo
Una implementación de IHostingStartup permite agregar mejoras a una aplicación al iniciarla a partir de un ensamblado externo fuera de la clase Startup
de esta. Para obtener más información, consulte Uso de ensamblados de inicio de hospedaje en ASP.NET Core.
Recursos adicionales
Configuración del punto de conexión de Kestrel
La configuración del punto de conexión específico de Kestrel invalida todas las configuraciones del punto de conexión entre servidores. Las configuraciones del punto de conexión entre servidores incluyen:
- UseUrls
--urls
en la línea de comandos- La variable de entorno
ASPNETCORE_URLS
Tenga en cuenta el archivo siguiente appsettings.json
usado en una aplicación web de ASP.NET Core:
{
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://localhost:9999"
}
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Cuando el marcado resaltado anterior se usa en una aplicación web de ASP.NET Core y la aplicación se inicia en la línea de comandos con la siguiente configuración del punto de conexión entre servidores:
dotnet run --urls="https://localhost:7777"
Kestrel se enlaza con el punto de conexión configurado específicamente para Kestrel en el archivo appsettings.json
(https://localhost:9999
) y no https://localhost:7777
.
Considere el punto de conexión específico de Kestrel configurado como una variable de entorno:
set Kestrel__Endpoints__Https__Url=https://localhost:8888
En la variable de entorno anterior, Https
es el nombre del punto de conexión específico de Kestrel. En el archivo appsettings.json
anterior también se define un punto de conexión específico de Kestrel denominado Https
. De manera predeterminada, las variables de entorno que utilizan el proveedor de configuración de variables de entorno se leen después de appsettings.{Environment}.json
, por lo tanto, la variable de entorno anterior se usa para el punto de conexión Https
.
GetValue
ConfigurationBinder.GetValue extrae un único valor de la configuración con una clave determinada y lo convierte al tipo especificado: Este método es un método de extensión para IConfiguration.
public class TestNumModel : PageModel
{
private readonly IConfiguration Configuration;
public TestNumModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var number = Configuration.GetValue<int>("NumberKey", 99);
return Content($"{number}");
}
}
En el código anterior, si NumberKey
no se encuentra en la configuración, se usa el valor predeterminado de 99
.
GetSection, GetChildren y Exists
Para los ejemplos siguientes, considere el siguiente archivo MySubsection.json
:
{
"section0": {
"key0": "value00",
"key1": "value01"
},
"section1": {
"key0": "value10",
"key1": "value11"
},
"section2": {
"subsection0": {
"key0": "value200",
"key1": "value201"
},
"subsection1": {
"key0": "value210",
"key1": "value211"
}
}
}
El código siguiente agrega MySubsection.json
a los proveedores de configuración:
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 devuelve una subsección de la configuración con la clave de subsección especificada.
El código siguiente devuelve los valores de 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"]}'");
}
}
El código siguiente devuelve los valores de section2:subsection0
:
public class TestSection2Model : PageModel
{
private readonly IConfiguration Config;
public TestSection2Model(IConfiguration configuration)
{
Config = configuration.GetSection("section2:subsection0");
}
public ContentResult OnGet()
{
return Content(
$"section2:subsection0:key0 '{Config["key0"]}'\n" +
$"section2:subsection0:key1:'{Config["key1"]}'");
}
}
GetSection
nunca devuelve null
. Si no se encuentra una sección que coincida, se devuelve una IConfigurationSection
vacía.
Cuando GetSection
devuelve una sección coincidente, Value no se rellena. Se devuelven Key y Path si la sección existe.
GetChildren y Exists
El código siguiente llama a IConfiguration.GetChildren y devuelve los valores de 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);
}
}
El código anterior llama a ConfigurationExtensions.Exists para comprobar que la sección existe:
Enlace de matrices
ConfigurationBinder.Bind admite enlazar matrices a objetos con los índices de matriz en las claves de configuración. Cualquier formato de matriz que exponga un segmento de clave numérica es capaz de enlazar una matriz a una matriz de clase POCO.
Tenga en cuenta este archivo MyArray.json
de la descarga de ejemplo:
{
"array": {
"entries": {
"0": "value00",
"1": "value10",
"2": "value20",
"4": "value40",
"5": "value50"
}
}
}
El código siguiente agrega MyArray.json
a los proveedores de configuración:
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>();
});
}
El código siguiente lee la configuración y muestra los valores:
public class ArrayModel : PageModel
{
private readonly IConfiguration Config;
public ArrayExample _array { get; private set; }
public ArrayModel(IConfiguration config)
{
Config = config;
}
public ContentResult OnGet()
{
_array = Config.GetSection("array").Get<ArrayExample>();
string s = null;
for (int j = 0; j < _array.Entries.Length; j++)
{
s += $"Index: {j} Value: {_array.Entries[j]} \n";
}
return Content(s);
}
}
El código anterior devuelve el siguiente resultado:
Index: 0 Value: value00
Index: 1 Value: value10
Index: 2 Value: value20
Index: 3 Value: value40
Index: 4 Value: value50
En el resultado anterior, el índice 3 tiene el valor value40
, que corresponde a "4": "value40",
en MyArray.json
. Los índices de matriz enlazados son continuos y no están enlazados al índice de la clave de configuración. El enlazador de configuración no es capaz de enlazar los valores NULL ni de crear entradas NULL en objetos enlazados.
El código siguiente carga la configuración de array:entries
con el método de extensión 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>();
});
}
}
El código siguiente lee la configuración de arrayDict
Dictionary
y muestra los valores:
public class ArrayModel : PageModel
{
private readonly IConfiguration Config;
public ArrayExample _array { get; private set; }
public ArrayModel(IConfiguration config)
{
Config = config;
}
public ContentResult OnGet()
{
_array = Config.GetSection("array").Get<ArrayExample>();
string s = null;
for (int j = 0; j < _array.Entries.Length; j++)
{
s += $"Index: {j} Value: {_array.Entries[j]} \n";
}
return Content(s);
}
}
El código anterior devuelve el siguiente resultado:
Index: 0 Value: value0
Index: 1 Value: value1
Index: 2 Value: value2
Index: 3 Value: value4
Index: 4 Value: value5
El índice n.º 3 en el objeto enlazado contiene los datos de configuración para la clave de configuración array:4
y su valor de value4
. Cuando se enlazan datos de configuración que contienen una matriz, los índices de la matriz en las claves de configuración se usan para iterar los datos de configuración al crear el objeto. No se puede conservar un valor NULL en los datos de configuración y no se crea una entrada con valores NULL en un objeto enlazado cuando una matriz en las claves de configuración omite uno o más índices.
Cualquier proveedor de configuración que lea el par clave-valor del índice n.º 3 puede proporcionar el elemento de configuración omitido para el índice n.º 3 antes del enlace a la instancia ArrayExample
. Fíjese en el siguiente archivo Value3.json
de la descarga de ejemplo:
{
"array:entries:3": "value3"
}
El código siguiente incluye la configuración de Value3.json
y el 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>();
});
}
}
El código siguiente lee la configuración anterior y muestra los valores:
public class ArrayModel : PageModel
{
private readonly IConfiguration Config;
public ArrayExample _array { get; private set; }
public ArrayModel(IConfiguration config)
{
Config = config;
}
public ContentResult OnGet()
{
_array = Config.GetSection("array").Get<ArrayExample>();
string s = null;
for (int j = 0; j < _array.Entries.Length; j++)
{
s += $"Index: {j} Value: {_array.Entries[j]} \n";
}
return Content(s);
}
}
El código anterior devuelve el siguiente resultado:
Index: 0 Value: value0
Index: 1 Value: value1
Index: 2 Value: value2
Index: 3 Value: value3
Index: 4 Value: value4
Index: 5 Value: value5
Los proveedores de configuración personalizados no son necesarios para implementar el enlace de matriz.
Proveedores de configuración personalizada
Advertencia
En este artículo se muestra el uso de cadena de conexión. Con una base de datos local, el usuario no tiene que autenticarse, pero en producción, cadena de conexión a veces incluye una contraseña para autenticarse. Una credencial de contraseña de propietario de recursos (ROPC) es un riesgo de seguridad que se debe evitar en las bases de datos de producción. Las aplicaciones de producción deben usar el flujo de autenticación más seguro disponible. Para obtener más información sobre la autenticación de aplicaciones implementadas para probar o entornos de producción, consulte Flujos de autenticación seguros.
La aplicación de ejemplo muestra cómo crear un proveedor de configuración básica que lee los pares clave-valor de configuración desde una base de datos mediante Entity Framework (EF).
El proveedor tiene las siguientes características:
- La base de datos en memoria de EF se usa para fines de demostración. Para usar una base de datos que requiere una cadena de conexión, implemente un
ConfigurationBuilder
secundario para suministrar la cadena de conexión desde otro proveedor de configuración. - El proveedor lee una tabla de base de datos en la configuración en el inicio. El proveedor no consulta la base de datos por clave.
- La función de recarga en cambio no se implementa, por lo que actualizar la base de datos después del inicio de la aplicación no afecta a la configuración de la aplicación.
Defina una entidad EFConfigurationValue
para almacenar los valores de configuración en la base de datos.
Models/EFConfigurationValue.cs
:
public class EFConfigurationValue
{
public string Id { get; set; }
public string Value { get; set; }
}
Agregue un EFConfigurationContext
para almacenar y tener acceso a los valores configurados.
EFConfigurationProvider/EFConfigurationContext.cs
:
// using Microsoft.EntityFrameworkCore;
public class EFConfigurationContext : DbContext
{
public EFConfigurationContext(DbContextOptions options) : base(options)
{
}
public DbSet<EFConfigurationValue> Values { get; set; }
}
Cree una clase que implemente 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);
}
}
Cree el proveedor de configuración personalizado heredando de ConfigurationProvider. El proveedor de configuración inicializa la base de datos cuando está vacía. Puesto que las claves de configuración no distinguen entre mayúsculas y minúsculas, el diccionario empleado para iniciar la base de datos se crea con el comparador que tampoco hace tal distinción (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 método de extensión AddEFConfiguration
permite agregar el origen de configuración 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));
}
}
En el código siguiente se muestra cómo puede usar el EFConfigurationProvider
personalizado en Program.cs
:
// using Microsoft.EntityFrameworkCore;
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddEFConfiguration(
options => options.UseInMemoryDatabase("InMemoryDb"));
})
Acceso a la configuración en métodos Startup
En el código siguiente se muestran los datos de configuración de los métodos 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();
});
}
}
Para ver un ejemplo de cómo acceder a la configuración mediante métodos de conveniencia de inicio, consulte Inicio de la aplicación: Métodos de conveniencia
Acceso a la configuración en Razor Pages
En el código siguiente se muestran los datos de configuración en una página de RazorPages:
@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
En el siguiente código se agrega MyOptions
al contenedor de servicios con Configure y se enlaza a la configuración:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
services.AddRazorPages();
}
En el marcado siguiente se usa la directiva @inject
Razor para resolver y mostrar los valores de las opciones:
@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>
Acceso a la configuración en un archivo de vista de MVC
En el código siguiente se muestran los datos de configuración de una vista de MVC:
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
Configurar opciones con un delegado
Las opciones configuradas en un delegado invalidan los valores establecidos en los proveedores de configuración.
La configuración de opciones con un delegado se muestra como ejemplo 2 en la aplicación de ejemplo.
En el código siguiente, se agrega un servicio IConfigureOptions<TOptions> al contenedor de servicios. Usa un delegado para configurar los valores de MyOptions
:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(myOptions =>
{
myOptions.Option1 = "Value configured in delegate";
myOptions.Option2 = 500;
});
services.AddRazorPages();
}
En el código siguiente se muestran los valores de las opciones:
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}");
}
}
En el ejemplo anterior, los valores de Option1
y Option2
se especifican en appsettings.json
y, luego, se reemplazan por el delegado configurado.
Configuración de host y de aplicación
Antes de configurar e iniciar la aplicación, se configura e inicia un host. El host es responsable de la administración del inicio y la duración de la aplicación. Tanto la aplicación como el host se configuran mediante los proveedores de configuración que se describen en este tema. Los pares clave-valor de configuración del host también se incluyen en la configuración de la aplicación. Para obtener más información sobre cómo se usan los proveedores de configuración cuando se compila el host y cómo afectan los orígenes de configuración a la configuración del host, consulte la información general sobre conceptos básicos de ASP.NET Core.
Configuración predeterminada del host
Para obtener más información sobre la configuración predeterminada al usar el host de web, vea la versión de este tema para ASP.NET Core 2.2.
- La configuración del host la proporcionan los siguientes elementos:
- Las variables de entorno con el prefijo
DOTNET_
(por ejemplo,DOTNET_ENVIRONMENT
) mediante el proveedor de configuración de variables de entorno. El prefijo (DOTNET_
) se quita cuando se cargan los pares clave-valor de configuración. - Argumentos de la línea de comandos con el proveedor de configuración de línea de comandos.
- Las variables de entorno con el prefijo
- La configuración predeterminada del host de web se ha establecido (
ConfigureWebHostDefaults
):- Kestrel se usa como el servidor web y se ha configurado mediante los proveedores de configuración de la aplicación.
- Agregar el middleware de filtrado de host
- Agregue el middleware de encabezados reenviados si la variable de entorno
ASPNETCORE_FORWARDEDHEADERS_ENABLED
se establece entrue
. - Habilite la integración con IIS.
Otra configuración
Este tema solo concierne a la configuración de aplicaciones. Otros aspectos de la ejecución y el hospedaje de aplicaciones ASP.NET Core se configuran mediante archivos de configuración que no se describen en este tema:
launch.json
/launchSettings.json
son archivos de configuración de herramientas para el entorno de desarrollo, que se describen a continuación:- En Usar varios entornos en ASP.NET Core.
- En el conjunto de documentación en el que se usan los archivos para configurar aplicaciones ASP.NET Core para escenarios de desarrollo.
web.config
es un archivo de configuración del servidor, que se describe en los temas siguientes:
Las variables de entorno configuradas en launchSettings.json
invalidan aquellas configuradas en el entorno del sistema.
Para más información sobre cómo migrar la configuración de aplicaciones de versiones anteriores de ASP.NET, consulte Actualización de ASP.NET a ASP.NET Core.
Agregar configuración a partir de un ensamblado externo
Una implementación de IHostingStartup permite agregar mejoras a una aplicación al iniciarla a partir de un ensamblado externo fuera de la clase Startup
de esta. Para obtener más información, consulte Uso de ensamblados de inicio de hospedaje en ASP.NET Core.