Acceso a la Configuración de ASP.NET Core Mediante IConfiguration
La interfaz IConfiguration
expone de forma unificada los elementos de configuración, y es la única representación de todos las fuentes u orígenes, tal como se muestra en el siguiente diagrama:
IConfiguration
representa un conjunto de propiedades de configuración en formato clave-valor, y se extiende mediante las siguientes clases:
ConfigurationExtensions
: Expone métodos de extensión para clases de configuración.ConfigurationBinder
: Clase auxiliar estática que permite enlazar objetos fuertemente tipados a valores de configuración.
Claves y Valores de Configuración
El acceso a un valor de configuración se realiza mediante su respectiva clave y la sintaxis de diccionario: builder.Configuration["Clave"]
.
Las claves de configuración:
- No distinguen mayúsculas de minúsculas. Por ejemplo,
MongoDbSettings
ymongodbsettings
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.
- Los objetos de configuración pueden estar organizados de forma jerárquica en secciones, subsecciones, arreglos, etc. Debido a esto, es necesario representar o delimitar su jerarquía mediante el signo de dos puntos :
builder.Configuration["Seccion:Subseccion:Clave"]
.
Los valores de configuración:
- Son cadenas.
- Los valores
NULL
no se pueden almacenar en la configuración ni enlazar a los objetos.
El valor devuelto de cada elemento de configuración es de tipo string
, por lo que es necesario convertirlo explícitamente al tipo requerido antes de usarlo. Sin embargo, existe una mejor forma de hacerlo, mediante el uso del método GetValue
que se verá más adelante.
Considere el siguiente archivo appsettings.json
de ejemplo:
{
"Seccion_0": "Cadena1",
"Seccion_1": 7,
"Seccion_2": true,
"Seccion_3": {
"Clave_1": "Cadena2",
"Clave_2": false
},
"Seccion_4": {
"SubSeccion_4_1": {
"Clave_1": 9.55,
"Clave_2": "Cadena3"
},
"SubSeccion_4_2": {
"SubSeccion_4_2_1": {
"Clave_1": true,
"Clave_2": "Cadena4",
"Clave_3": 1024
}
}
},
"Seccion_5": [
68,
69,
70,
71
]
}
En el código siguiente de una Razor Page, se van a leer los diferentes valores de configuración del archivo appsettings.json
:
public class IndexModel : PageModel
{
private readonly IConfiguration _configuration;
public IndexModel(IConfiguration configuration)
{
_configuration = configuration;
}
public ContentResult OnGet()
{
string? seccion_0 = _configuration["Seccion_0"];
var seccion_1 = _configuration["Seccion_1"];
string? seccion_2 = _configuration["Seccion_2"];
string? seccion_3_Clave_2 = _configuration["Seccion_3:Clave_2"];
string? subSeccion_4_1_Clave1 = _configuration["Seccion_4:SubSeccion_4_1:Clave_1"];
string? subSeccion_4_2_1_Clave3 = _configuration["Seccion_4:SubSeccion_4_2:SubSeccion_4_2_1:Clave_3"];
string? seccion_5_Item0 = _configuration["Seccion_5:0"];
string? seccion_5_Item3 = _configuration["Seccion_5:3"];
return Content($"Seccion_0: {seccion_0} \n" +
$"Seccion_1: {seccion_1} \n" +
$"Seccion_2: {seccion_2} \n" +
$"Seccion_3 Clave_2: {seccion_3_Clave_2} \n" +
$"Seccion_4 SubSeccion_4_1 Clave_1: {subSeccion_4_1_Clave1} \n" +
$"Seccion_4 SubSeccion_4_2 SubSeccion_4_2_1 Clave_3: {subSeccion_4_2_1_Clave3} \n" +
$"Seccion_5 Item_0: {seccion_5_Item0} \n" +
$"Seccion_5 Item_3: {seccion_5_Item3}");
}
}
El código C# anterior:
- Se obtiene el objeto de
IConfiguration
mediante Inyección de dependencias. - Se declaran variables de tipo
string
, y que admitan valoresnull
para obtener el contenido de cada elemento de configuración. Sin embargo, se pueden también declarar variables de tipovar
. - Se obtienen los diferentes valores de configuración mediante su clave, la misma que representa cada jerarquía mediante el uso de los dos puntos.
- La
Seccion_5
contiene un arreglo, el cual se hace referencia mediante el nombre de la sección, el signo de dos puntos y el índice respectivo. - Se omitieron las conversiones explicitas de los valores de configuración obtenidos.
Seccion_0: Cadena1
Seccion_1: 7
Seccion_2: True
Seccion_3 Clave_2: False
Seccion_4 SubSeccion_4_1 Clave_1: 9.55
Seccion_4 SubSeccion_4_2 SubSeccion_4_2_1 Clave_3: 1024
Seccion_5 Item_0: 68
Seccion_5 Item_3: 71
GetValue
El método de extensión ConfigurationBinder.GetValue
obtiene el valor del elemento de configuración mediante su clave, lo convierte al tipo deseado, y permite especificar un valor predeterminado en caso de no encontrarlo.
En el siguiente código de una Razor Page, se van a leer los diferentes valores de configuración del archivo appsettings.json
mediante el uso del método GetValue
:
public class IndexModel : PageModel
{
private readonly IConfiguration _configuration;
public IndexModel(IConfiguration configuration)
{
_configuration = configuration;
}
public ContentResult OnGet()
{
string seccion_0 = _configuration.GetValue("Seccion_0", "Vacío");
int seccion_1 = _configuration.GetValue<int>("Seccion_1", 0);
bool seccion_2 = _configuration.GetValue<bool>("Seccion_2");
string seccion_3_Clave_2 = _configuration.GetValue("Seccion_3:Clave_2", "Vacío");
decimal subSeccion_4_1_Clave1 = _configuration.GetValue<decimal>("Seccion_4:SubSeccion_4_1:Clave_1", 0);
int subSeccion_4_2_1_Clave3 = _configuration.GetValue<int>("Seccion_4:SubSeccion_4_2:SubSeccion_4_2_1:Clave_3", 100);
int seccion_5_Item0 = _configuration.GetValue<int>("Seccion_5:0", -1);
int seccion_5_Item3 = _configuration.GetValue<int>("Seccion_5:333", -1); //Indice 333 NO EXISTE.
return Content($"Seccion_0: {seccion_0} \n" +
$"Seccion_1: {seccion_1} \n" +
$"Seccion_2: {seccion_2} \n" +
$"Seccion_3 Clave_2: {seccion_3_Clave_2} \n" +
$"Seccion_4 SubSeccion_4_1 Clave_1: {subSeccion_4_1_Clave1} \n" +
$"Seccion_4 SubSeccion_4_2 SubSeccion_4_2_1 Clave_3: {subSeccion_4_2_1_Clave3} \n" +
$"Seccion_5 Item_0: {seccion_5_Item0} \n" +
$"Seccion_5 Item_3: {seccion_5_Item3}");
}
}
El código C# anterior:
- Se obtienen los diferentes valores de configuración mediante el uso del método
GetValue
, que define el tipo de dato a convertir y el valor predeterminado en caso de que la clave no se encuentre. - Puesto que la variable
seccion_5_Item3
almacena la configuración de una clave que no existe, se devolverá el valor configurado como predeterminado, -1.
Seccion_0: Cadena1
Seccion_1: 7
Seccion_2: True
Seccion_3 Clave_2: False
Seccion_4 SubSeccion_4_1 Clave_1: 9.55
Seccion_4 SubSeccion_4_2 SubSeccion_4_2_1 Clave_3: 1024
Seccion_5 Item_0: 68
Seccion_5 Item_3: -1
GetSection
El método ConfigurationSection.GetSection
obtiene una sección de configuración mediante la clave especificada.
Para su uso hay que tener presente los siguientes puntos:
GetSection
nunca devuelvenull
. Si no se encuentra una sección que coincida, se devuelve unaIConfigurationSection
vacía.- Cuando
GetSection
devuelve una sección coincidente,Value
no se rellena. Se devuelvenKey
yPath
si la sección existe.
En el siguiente código, se van a leer las diferentes secciones y subsecciones de configuración del archivo appsettings.json
de ejemplo:
public class IndexModel : PageModel
{
private readonly IConfiguration _configuration;
public IndexModel(IConfiguration configuration)
{
_configuration = configuration;
}
public ContentResult OnGet()
{
IConfigurationSection subSeccion_4_1 = _configuration.GetSection("Seccion_4:SubSeccion_4_1");
IConfigurationSection subSeccion_4_2_1 = _configuration.GetSection("Seccion_4")
.GetSection("SubSeccion_4_2")
.GetSection("SubSeccion_4_2_1");
IConfigurationSection seccion_5 = _configuration.GetSection("Seccion_5");
string seccion_0 = _configuration.GetValue("Seccion_0", "Vacío");
int seccion_1 = _configuration.GetValue<int>("Seccion_1", 0);
bool seccion_2 = _configuration.GetValue<bool>("Seccion_2");
string seccion_3_Clave_2 = _configuration.GetValue("Seccion_3:Clave_2", "Vacío");
decimal subSeccion_4_1_Clave1 = subSeccion_4_1.GetValue<decimal>("Clave_1", 0);
int subSeccion_4_2_1_Clave3 = subSeccion_4_2_1.GetValue<int>("Clave_3", 100);
int seccion_5_Item0 = seccion_5.GetValue<int>("0", -1);
int seccion_5_Item3 = seccion_5.GetValue<int>("333", -1); //Item 333 NO EXISTE.
return Content($"Seccion_0: {seccion_0} \n" +
$"Seccion_1: {seccion_1} \n" +
$"Seccion_2: {seccion_2} \n" +
$"Seccion_3 Clave_2: {seccion_3_Clave_2} \n" +
$"Seccion_4 SubSeccion_4_1 Clave_1: {subSeccion_4_1_Clave1} \n" +
$"Seccion_4 SubSeccion_4_2 SubSeccion_4_2_1 Clave_3: {subSeccion_4_2_1_Clave3} \n" +
$"Seccion_5 Item_0: {seccion_5_Item0} \n" +
$"Seccion_5 Item_3: {seccion_5_Item3}");
}
}
El código de C# anterior:
- Se obtienen las diferentes secciones y subsecciones de configuración mediante el uso del método
GetSection
. - Puede obtener una subsección utilizando el delimitador de jerarquía en la clave, o mediante una serie de métodos
GetSection
anidados.
El resultado es exactamente el mismo que el ejemplo de uso del método GetValue
:
Seccion_0: Cadena1
Seccion_1: 7
Seccion_2: True
Seccion_3 Clave_2: False
Seccion_4 SubSeccion_4_1 Clave_1: 9.55
Seccion_4 SubSeccion_4_2 SubSeccion_4_2_1 Clave_3: 1024
Seccion_5 Item_0: 68
Seccion_5 Item_3: -1
GetChildren y Exists
El método IConfiguration.GetChildren
obtiene las subsecciones de configuración descendientes inmediatas y retorna una colección de IConfigurationSection
(IEnumerable<IConfigurationSection>
)
El método ConfigurationExtensions.Exists
determina si la sección tiene un objeto value o elementos secundarios. Devuelve el valor booleano de true
para indicar que la sección tiene valores o elementos secundarios; de lo contrario devuelve false
.
Considere el siguiente código de una Razor Page, que muestra el uso de los métodos GetChildren
y Exists
basado en el archivo appsettings.json
de ejemplo:
public class IndexModel : PageModel
{
private readonly IConfiguration _configuration;
public IndexModel(IConfiguration configuration)
{
_configuration = configuration;
}
public ContentResult OnGet()
{
string contenido = "";
IConfigurationSection seccion_3 = _configuration.GetSection("Seccion_3");
if (!seccion_3.Exists())
throw new Exception("Seccion_3 no existe.");
IEnumerable<IConfigurationSection> subsecciones = seccion_3.GetChildren();
foreach (IConfigurationSection subseccion in subsecciones)
contenido += $"{seccion_3.Key}:{subseccion.Key} Valor = {seccion_3[subseccion.Key]} \n";
return Content(contenido);
}
}
En el código anterior:
- Se usa el método
Exists
para verificar si laseccion_3
tiene elementos secundarios. - Se obtiene la colección de secciones mediante el método
GetChildren
- Por cada elemento de la colección, se obtiene su clave y mediante esta, se obtiene también su valor.
Seccion_3:Clave_1 Valor = Cadena2
Seccion_3:Clave_2 Valor = False
La abstracción IConfiguration
es una forma de acceder a la configuración de ASP.NET Core, sin embargo, no es la óptima. El uso de claves de cadena resulta desordenado y propenso a errores tipográficos y de conversión. En su lugar ASP.NET Core promueve el uso del Patrón de Opciones y el uso de objetos fuertemente tipados.
Artículos Relacionados
Recursos Adicionales
- Configuración en ASP.NET Core.
- Configuración en .NET.
- Interfaz IConfiguration.
- Código Fuente de la Interfaz IConfiguration..
- Interfaz IConfigurationSection.
- Código Fuente de la Interfaz IConfigurationSection.
- Clase ConfigurationSection.
- Código Fuente de la Clase ConfigurationSection.
- Clase ConfigurationBinder.
- Código Fuente de la Clase ConfigurationBinder.
- Clase ConfigurationExtensions.
- Código Fuente de la Clase ConfigurationExtensions.
- Patrón de opciones en .NET.