ASP.NET CORE

Acceso a la Configuración de ASP.NET Core Mediante IConfiguration

13 de febrero, 2024

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

IConfiguration representa un conjunto de propiedades de configuración en formato clave-valor, y se extiende mediante las siguientes clases:

Claves y Valores de Configuración Subir

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:

Los valores de configuración:

¡Importante!
¡IMPORTANTE!

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:

Resultado:

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 Subir

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:

Resultado:

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 Subir

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:

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:

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 Subir

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:

Resultado:

Seccion_3:Clave_1 Valor = Cadena2 
Seccion_3:Clave_2 Valor = False
¡Importante!
¡IMPORTANTE!

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

Referencias