Obteniendo valor de appsettings.json en .net core

161

No estoy seguro de qué me estoy perdiendo aquí, pero no puedo obtener los valores de mi appsettings.json en mi aplicación .net core. Tengo mi appsettings.json como:

{
    "AppSettings": {
        "Version": "One"
    }
}

Puesta en marcha:

public class Startup
{
    private IConfigurationRoot _configuration;
    public Startup(IHostingEnvironment env)
    {
        _configuration = new ConfigurationBuilder()
    }
    public void ConfigureServices(IServiceCollection services)
    {
      //Here I setup to read appsettings        
      services.Configure<AppSettings>(_configuration.GetSection("AppSettings"));
    }
}

Modelo:

public class AppSettings
{
    public string Version{ get; set; }
}

Controlador:

public class HomeController : Controller
{
    private readonly AppSettings _mySettings;

    public HomeController(IOptions<AppSettings> settings)
    {
        //This is always null
        _mySettings = settings.Value;
    }
}

_mySettingssiempre es nulo. ¿Hay algo que me estoy perdiendo aquí?

un hombre
fuente
3
Por favor lea la documentación sobre el uso de la configuración. Ha configurado incorrectamente la configuración en su clase de inicio.
meter
Gracias por la documentacion. Esto fue útil.
aman
esto puede incluso simplificarse simplemente usando la inyección de dependencia de IConfiguration. Lo que se explica aquí coding-issues.com/2018/10/…
Ranadheer Reddy

Respuestas:

228

Programa y clase de inicio

.NET Core 2.x

No es necesario nuevo IConfigurationen el Startupconstructor. Su implementación será inyectada por el sistema DI.

// Program.cs
public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();            
}

// Startup.cs
public class Startup
{
    public IHostingEnvironment HostingEnvironment { get; private set; }
    public IConfiguration Configuration { get; private set; }

    public Startup(IConfiguration configuration, IHostingEnvironment env)
    {
        this.HostingEnvironment = env;
        this.Configuration = configuration;
    }
}

.NET Core 1.x

StartupDebe indicarle que cargue los archivos de configuración de la aplicación.

// Program.cs
public class Program
{
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .UseApplicationInsights()
            .Build();

        host.Run();
    }
}

//Startup.cs
public class Startup
{
    public IConfigurationRoot Configuration { get; private set; }

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();

        this.Configuration = builder.Build();
    }
    ...
}

Obteniendo valores

Hay muchas formas de obtener el valor que configura desde la configuración de la aplicación:

Digamos que se appsettings.jsonve así:

{
    "ConnectionStrings": {
        ...
    },
    "AppIdentitySettings": {
        "User": {
            "RequireUniqueEmail": true
        },
        "Password": {
            "RequiredLength": 6,
            "RequireLowercase": true,
            "RequireUppercase": true,
            "RequireDigit": true,
            "RequireNonAlphanumeric": true
        },
        "Lockout": {
            "AllowedForNewUsers": true,
            "DefaultLockoutTimeSpanInMins": 30,
            "MaxFailedAccessAttempts": 5
        }
    },
    "Recaptcha": { 
        ...
    },
    ...
}

Manera simple

Puede inyectar toda la configuración en el constructor de su controlador / clase (vía IConfiguration) y obtener el valor que desea con una clave específica:

public class AccountController : Controller
{
    private readonly IConfiguration _config;

    public AccountController(IConfiguration config)
    {
        _config = config;
    }

    [AllowAnonymous]
    public IActionResult ResetPassword(int userId, string code)
    {
        var vm = new ResetPasswordViewModel
        {
            PasswordRequiredLength = _config.GetValue<int>(
                "AppIdentitySettings:Password:RequiredLength"),
            RequireUppercase = _config.GetValue<bool>(
                "AppIdentitySettings:Password:RequireUppercase")
        };

        return View(vm);
    }
}

Patrón de opciones

El ConfigurationBuilder.GetValue<T>funciona muy bien si sólo se necesita uno o dos valores de la configuración de la aplicación. Pero si desea obtener múltiples valores de la configuración de la aplicación, o no desea codificar esas cadenas de teclas en varios lugares, puede ser más fácil usar el Patrón de opciones . El patrón de opciones usa clases para representar la jerarquía / estructura.

Para usar el patrón de opciones:

  1. Definir clases para representar la estructura.
  2. Registre la instancia de configuración con la que se unen esas clases
  3. Inyecte IOptions<T>en el constructor del controlador / clase en el que desea obtener valores

1. Definir clases de configuración para representar la estructura.

Puede definir clases con propiedades que necesiten coincidir exactamente con las claves en la configuración de su aplicación. El nombre de la clase no tiene que coincidir con el nombre de la sección en la configuración de la aplicación:

public class AppIdentitySettings
{
    public UserSettings User { get; set; }
    public PasswordSettings Password { get; set; }
    public LockoutSettings Lockout { get; set; }
}

public class UserSettings
{
    public bool RequireUniqueEmail { get; set; }
}

public class PasswordSettings
{
    public int RequiredLength { get; set; }
    public bool RequireLowercase { get; set; }
    public bool RequireUppercase { get; set; }
    public bool RequireDigit { get; set; }
    public bool RequireNonAlphanumeric { get; set; }
}

public class LockoutSettings
{
    public bool AllowedForNewUsers { get; set; }
    public int DefaultLockoutTimeSpanInMins { get; set; }
    public int MaxFailedAccessAttempts { get; set; }
}

2. Registre la instancia de configuración

Y luego debe registrar esta instancia de configuración ConfigureServices()en el inicio:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
...

namespace DL.SO.UI.Web
{
    public class Startup
    {
        ...
        public void ConfigureServices(IServiceCollection services)
        {
            ...
            var identitySettingsSection = 
                _configuration.GetSection("AppIdentitySettings");
            services.Configure<AppIdentitySettings>(identitySettingsSection);
            ...
        }
        ...
    }
}

3. Inyectar IOptions

Por último, en el controlador / clase que desea obtener los valores, debe inyectar a IOptions<AppIdentitySettings>través del constructor:

public class AccountController : Controller
{
    private readonly AppIdentitySettings _appIdentitySettings;

    public AccountController(IOptions<AppIdentitySettings> appIdentitySettingsAccessor)
    {
        _appIdentitySettings = appIdentitySettingsAccessor.Value;
    }

    [AllowAnonymous]
    public IActionResult ResetPassword(int userId, string code)
    {
        var vm = new ResetPasswordViewModel
        {
            PasswordRequiredLength = _appIdentitySettings.Password.RequiredLength,
            RequireUppercase = _appIdentitySettings.Password.RequireUppercase
        };

        return View(vm);
    }
}
David Liang
fuente
¿Cómo puedo acceder a los valores en la clase que contiene mis datos?
Lukas Hieronimus Adler
1
@LukasHieronimusAdler: es posible que desee utilizar en IOptionsSnapshot<T>lugar de IOptions<T>. Puedes echar un vistazo a este artículo: offer.solutions/blog/articles/2017/02/17/… . Sin embargo, no he tenido la oportunidad de probarlo.
David Liang
2
¿Podrías hacerlo simple como un fragmento?
Syaiful Nizam Yahya
8
Qué horrible paso atrás de la pila completa .net
Aaron
44
Ok, entonces .NET Core 3 necesita el paquete Microsoft.Extensions.Options.ConfigurationExtensions y funciona bien
Tomas Bruckner
50

Simplemente cree un archivo AnyName.cs y pegue el siguiente código.

using System;
using System.IO;
using Microsoft.Extensions.Configuration;

namespace Custom
{
    static class ConfigurationManager
    {
        public static IConfiguration AppSetting { get; }
        static ConfigurationManager()
        {
            AppSetting = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("YouAppSettingFile.json")
                    .Build();
        }
    }
}

Debe reemplazar el nombre del archivo YouAppSettingFile.json con su nombre de archivo.
Su archivo .json debería verse a continuación.

{
    "GrandParent_Key" : {
        "Parent_Key" : {
            "Child_Key" : "value1"
        }
    },
    "Parent_Key" : {
        "Child_Key" : "value2"
    },
    "Child_Key" : "value3"
}

Ahora puedes usarlo.
No olvide agregar referencia en su clase donde quiera usar.

using Custom;

Código para recuperar valor.

string value1 = ConfigurationManager.AppSetting["GrandParent_Key:Parent_Key:Child_Key"];
string value2 = ConfigurationManager.AppSetting["Parent_Key:Child_Key"];
string value3 = ConfigurationManager.AppSetting["Child_Key"];
shajji
fuente
3
No uses esto en la producción. Este enfoque fue lo que causó pérdidas de memoria en nuestra API web. Si está utilizando netcore, puede inyectar IConfiguration literalmente en cualquier lugar, solo vea las respuestas anteriores.
André Mantas
49

Agregando a la respuesta de David Liang para Core 2.0 -

appsettings.jsonlos archivos están vinculados a la ASPNETCORE_ENVIRONMENTvariable.

ASPNETCORE_ENVIRONMENTse puede ajustar a cualquier valor, pero tres valores están soportados por el marco: Development, Staging, y Production. Si ASPNETCORE_ENVIRONMENTno está configurado, se establecerá por defecto en Production.

Para estos tres valores, estos archivos appsettings.ASPNETCORE_ENVIRONMENT.json son compatibles desde el primer momento appsettings.Staging.json, appsettings.Development.jsonyappsettings.Production.json

Los tres archivos json de configuración de aplicaciones anteriores se pueden usar para configurar múltiples entornos.

Ejemplo appsettings.Staging.json

{
    "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
            "System": "Information",
            "Microsoft": "Information"
        }
    },
    "MyConfig": "My Config Value for staging."
}

Se usa Configuration["config_var"]para recuperar cualquier valor de configuración.

public class Startup
{
    public Startup(IHostingEnvironment env, IConfiguration config)
    {
        Environment = env;
        Configuration = config;
        var myconfig = Configuration["MyConfig"];
    }

    public IConfiguration Configuration { get; }
    public IHostingEnvironment Environment { get; }
}
Aseem Gautam
fuente
1
¿Qué pasa con los objetos anidados?
Arthur Attout
8
Los objetos anidados se pueden obtener con Configuración ["MyConfig: SomethingNested"]
WeHaveCookies
1
Como se puede ver en el archivo github.com/aspnet/AspNetCore/blob/master/src/DefaultBuilder/src/… en la línea 167 ASP.NET Core actualmente carga appsettings.json+ appsettings.{env.EnvironmentName}.json. Por lo tanto, la afirmación de que ASP.NET Core solo carga los archivos appsettings.json de Desarrollo, Estadificación y Producción es actualmente incorrecta.
mvdgun
1
Entonces, ¿se supone que debo configurar la variable de Windows ASPNETCORE_ENVIRONMENTcada vez? Las cosas fueron mucho más fáciles en .Net 4. Estos fanáticos de JSON lo arruinaron a lo grande
Toolkit
@Toolkit Puede establecer la variable de entorno globalmente. docs.microsoft.com/en-us/aspnet/core/fundamentals/…
Aseem Gautam
29

Supongo que la forma más simple es por DI. Un ejemplo de llegar al controlador.

// StartUp.cs
public void ConfigureServices(IServiceCollection services)
{
    ...
    // for get appsettings from anywhere
    services.AddSingleton(Configuration);
}

public class ContactUsController : Controller
{
    readonly IConfiguration _configuration;

    public ContactUsController(
        IConfiguration configuration)
    {
        _configuration = configuration;

        // sample:
        var apiKey = _configuration.GetValue<string>("SendGrid:CAAO");
        ...
    }
}
Harveyt
fuente
55
Leyendo las otras respuestas, esta debería ser la mejor.
harveyt
Me faltaba services.AddSingleton(Configuration);, ahora funciona
Arthur Medeiros
12

En el constructor de la clase Startup, puede acceder a appsettings.json y muchas otras configuraciones utilizando el objeto inyectado IConfiguration:

Startup.cs Constructor

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;

        //here you go
        var myvalue = Configuration["Grandfather:Father:Child"];

    }

public IConfiguration Configuration { get; }

Contenido de appsettings.json

  {
  "Grandfather": {
    "Father": {
      "Child": "myvalue"
    }
  }
Shadi Namrouti
fuente
2
Fue la sintaxis 'Configuration ["Grandfather: Father: Child"]' que me ayudó.
Jacques Olivier
2
Esta es una respuesta sobresaliente en la forma en que está estructurada, clara y al grano. Gran comunicación
jolySoft
6
    public static void GetSection()
    {
        Configuration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .Build();

        string BConfig = Configuration.GetSection("ConnectionStrings")["BConnection"];

    }
sepideh dalirpour
fuente
44
Respuesta incompleta
Carlos ABS
1

En mi caso, era simple como usar el método Bind () en el objeto de configuración. Y luego agregue el objeto como singleton en el DI.

var instructionSettings = new InstructionSettings();
Configuration.Bind("InstructionSettings", instructionSettings);
services.AddSingleton(typeof(IInstructionSettings), (serviceProvider) => instructionSettings);

El objeto Instrucción puede ser tan complejo como desee.

{  
 "InstructionSettings": {
    "Header": "uat_TEST",
    "SVSCode": "FICA",
    "CallBackUrl": "https://UATEnviro.companyName.co.za/suite/webapi/receiveCallback",
    "Username": "s_integrat",
    "Password": "X@nkmail6",
    "Defaults": {
    "Language": "ENG",
    "ContactDetails":{
       "StreetNumber": "9",
       "StreetName": "Nano Drive",
       "City": "Johannesburg",
       "Suburb": "Sandton",
       "Province": "Gauteng",
       "PostCode": "2196",
       "Email": "[email protected]",
       "CellNumber": "0833 468 378",
       "HomeNumber": "0833 468 378",
      }
      "CountryOfBirth": "710"
    }
  }
Lizo Matala
fuente
1

Para ASP.NET Core 3.1 puede seguir esta guía:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1

Cuando cree un nuevo proyecto ASP.NET Core 3.1, tendrá la siguiente línea de configuración en Program.cs:

Host.CreateDefaultBuilder(args)

Esto permite lo siguiente:

  1. ChainedConfigurationProvider: Agrega una IConfiguration existente como fuente. En el caso de configuración predeterminada, agrega la configuración del host y la configura como la primera fuente para la configuración de la aplicación.
  2. appsettings.json usando el proveedor de configuración JSON.
  3. appsettings.Environment.json usando el proveedor de configuración JSON. Por ejemplo, appsettings.Production.json y appsettings.Development.json.
  4. Secretos de la aplicación cuando la aplicación se ejecuta en el entorno de Desarrollo.
  5. Variables de entorno utilizando el proveedor de configuración de Variables de entorno.
  6. Argumentos de la línea de comandos utilizando el proveedor de configuración de la línea de comandos.

Esto significa que puede inyectar IConfigurationy recuperar valores con una clave de cadena, incluso valores anidados. Me gustaIConfiguration["Parent:Child"];

Ejemplo:

appsettings.json

{
  "ApplicationInsights":
    {
        "Instrumentationkey":"putrealikeyhere"
    }
}

WeatherForecast.cs

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;
    private readonly IConfiguration _configuration;

    public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration configuration)
    {
        _logger = logger;
        _configuration = configuration;
    }

    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        var key = _configuration["ApplicationInsights:InstrumentationKey"];

        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}
Ogglas
fuente
¿Dónde puedo obtener más información sobre la IConfiguration["Parent:Child"]sintaxis?
xr280xr
0

Creo que la mejor opción es:

  1. Crear una clase de modelo como esquema de configuración

  2. Registrarse en DI: services.Configure (Configuration.GetSection ("democonfig"));

  3. Obtenga los valores como objeto modelo de DI en su controlador:

    private readonly your_model myConfig;
    public DemoController(IOptions<your_model> configOps)
    {
        this.myConfig = configOps.Value;
    }
Meghnath Das
fuente
0

Desde Asp.net core 2.2 a arriba puede codificar de la siguiente manera:

Paso 1. Cree un archivo de clase AppSettings.

Este archivo contiene algunos métodos para ayudar a obtener valor por clave del archivo appsettings.json. Parece el siguiente código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ReadConfig.Bsl
{
  public class AppSettings
  {
      private static AppSettings _instance;
      private static readonly object ObjLocked = new object();
      private IConfiguration _configuration;

      protected AppSettings()
      {
      }

      public void SetConfiguration(IConfiguration configuration)
      {
          _configuration = configuration;
      }

      public static AppSettings Instance
      {
          get
          {
              if (null == _instance)
              {
                  lock (ObjLocked)
                  {
                      if (null == _instance)
                          _instance = new AppSettings();
                  }
              }
              return _instance;
          }
      }

      public string GetConnection(string key, string defaultValue = "")
      {
          try
          {
              return _configuration.GetConnectionString(key);
          }
          catch
          {
              return defaultValue;
          }
      }

      public T Get<T>(string key = null)
      {
          if (string.IsNullOrWhiteSpace(key))
              return _configuration.Get<T>();
          else
              return _configuration.GetSection(key).Get<T>();
      }

      public T Get<T>(string key, T defaultValue)
      {
          if (_configuration.GetSection(key) == null)
              return defaultValue;

          if (string.IsNullOrWhiteSpace(key))
              return _configuration.Get<T>();
          else
              return _configuration.GetSection(key).Get<T>();
      }

      public static T GetObject<T>(string key = null)
      {
          if (string.IsNullOrWhiteSpace(key))
              return Instance._configuration.Get<T>();
          else
          {
              var section = Instance._configuration.GetSection(key);
              return section.Get<T>();
          }
      }

      public static T GetObject<T>(string key, T defaultValue)
      {
          if (Instance._configuration.GetSection(key) == null)
              return defaultValue;

          if (string.IsNullOrWhiteSpace(key))
              return Instance._configuration.Get<T>();
          else
              return Instance._configuration.GetSection(key).Get<T>();
      }
  }
}

Paso 2. Configuración inicial para el objeto AppSettings

Necesitamos declarar y cargar el archivo appsettings.json cuando se inicia la aplicación, y cargar la información de configuración para el objeto AppSettings. Haremos este trabajo en el constructor del archivo Startup.cs. Por favor nota líneaAppSettings.Instance.SetConfiguration(Configuration);

public Startup(IHostingEnvironment evm)
{
    var builder = new ConfigurationBuilder()
      .SetBasePath(evm.ContentRootPath)
      .AddJsonFile("appsettings.json", true, true)
      .AddJsonFile($"appsettings.{evm.EnvironmentName}.json", true)
      .AddEnvironmentVariables();
    Configuration = builder.Build(); // load all file config to Configuration property 
    AppSettings.Instance.SetConfiguration(Configuration);       
}

Bien, ahora tengo un archivo appsettings.json con algunas claves como se muestra a continuación:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "ConnectionString": "Data Source=localhost;Initial Catalog=ReadConfig;Persist Security Info=True;User ID=sa;Password=12345;"
  },
  "MailConfig": {
    "Servers": {
      "MailGun": {
        "Pass": "65-1B-C9-B9-27-00",
        "Port": "587",
        "Host": "smtp.gmail.com"
      }
    },
    "Sender": {
      "Email": "[email protected]",
      "Pass": "123456"
    }
  }
}

Paso 3. Leer el valor de configuración de una acción

Hago una demostración de una acción en el controlador de inicio como a continuación:

public class HomeController : Controller
{
    public IActionResult Index()
    {
        var connectionString = AppSettings.Instance.GetConnection("ConnectionString");
        var emailSender = AppSettings.Instance.Get<string>("MailConfig:Sender:Email");
        var emailHost = AppSettings.Instance.Get<string>("MailConfig:Servers:MailGun:Host");

        string returnText = " 1. Connection String \n";
        returnText += "  " +connectionString;
        returnText += "\n 2. Email info";
        returnText += "\n Sender : " + emailSender;
        returnText += "\n Host : " + emailHost;

        return Content(returnText);
    }
}

Y a continuación se muestra el resultado:

Haga clic para ver el resultado

Para obtener más información, puede consultar el artículo obtener valor de appsettings.json en asp.net core para obtener más detalles del código.

Dung Do Tien
fuente
0

Es simple: en appsettings.json

  "MyValues": {
    "Value1": "Xyz"
  }

En archivo .cs:

static IConfiguration conf = (new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build());
        public static string myValue1= conf["MyValues:Value1"].ToString();
Abhishek Pandey
fuente