Obtendo valor do appsettings.json no núcleo .net

161

Não tenho certeza do que estou perdendo aqui, mas não consigo obter os valores do meu appsettings.json no meu aplicativo principal .net. Eu tenho meu appsettings.json como:

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

Comece:

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;
    }
}

_mySettingsé sempre nulo. Há algo que estou perdendo aqui?

um homem
fonte
3
Por favor, leia a documentação sobre como usar a configuração. Você definiu incorretamente a configuração na sua classe de inicialização.
cutuca
Obrigado pela documentação. Isso foi útil.
aman
isso pode ser simplificado usando injeção de dependência da configuração ICon. O que é explicado aqui coding-issues.com/2018/10/…
Ranadheer Reddy

Respostas:

228

Classe de programa e inicialização

.NET Core 2.x

Você não precisa ser novo IConfigurationno Startupconstrutor. Sua implementação será injetada pelo 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

Você precisa informar Startuppara carregar os arquivos de configurações de aplicativos.

// 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();
    }
    ...
}

Obtendo valores

Há várias maneiras de obter o valor que você define nas configurações do aplicativo:

Digamos que sua appsettings.jsonaparência seja assim:

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

Maneira simples

Você pode injetar toda a configuração no construtor de seu controlador / classe (via IConfiguration) e obter o valor desejado com uma chave especificada:

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);
    }
}

Padrão de Opções

O ConfigurationBuilder.GetValue<T>funciona muito bem se você só precisa de um ou dois valores de configurações do aplicativo. Mas se você deseja obter vários valores das configurações do aplicativo ou não deseja codificar essas cadeias de caracteres em vários locais, pode ser mais fácil usar o Padrão de Opções . O padrão de opções usa classes para representar a hierarquia / estrutura.

Para usar o padrão de opções:

  1. Definir classes para representar a estrutura
  2. Registre a instância de configuração à qual essas classes se ligam
  3. Injete IOptions<T>no construtor do controlador / classe em que você deseja obter valores

1. Defina classes de configuração para representar a estrutura

Você pode definir classes com propriedades que precisam corresponder exatamente às chaves nas configurações do seu aplicativo. O nome da turma não precisa corresponder ao nome da seção nas configurações do aplicativo:

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 a instância de configuração

E então você precisa registrar esta instância de configuração ConfigureServices()na inicialização:

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. Injete IOptions

Por fim, no controlador / classe que você deseja obter os valores, é necessário injetar IOptions<AppIdentitySettings>através do construtor:

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
fonte
Como posso acessar os valores na classe que contém meus dados?
Lukas Hieronimus Adler
1
@LukasHieronimusAdler: Você pode querer usar em IOptionsSnapshot<T>vez de IOptions<T>. Você pode dar uma olhada neste artigo: offer.solutions/blog/articles/2017/02/17/… . Eu ainda não tive chance de tentar.
David Liang
2
Você poderia simplificar como um trecho?
Syaiful Nizam Yahya 13/07/19
8
Que passo horrível para trás a partir da pilha completa .net
Aaron
4
Ok, então para .NET Core 3 que você precisa pacote Microsoft.Extensions.Options.ConfigurationExtensions e funciona bem
Tomas Bruckner
50

Basta criar um arquivo AnyName.cs e colar o seguinte 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();
        }
    }
}

Deve substituir o nome do arquivo YouAppSettingFile.json pelo seu nome do arquivo.
Seu arquivo .json deve se parecer com abaixo.

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

Agora você pode usá-lo.
Não se esqueça de adicionar referência em sua classe onde você deseja 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
fonte
3
Não use isso na produção. Essa abordagem foi o que causou vazamentos de memória em nossa API da Web. Se você estiver usando o netcore, poderá injetar a configuração ICon literalmente em qualquer lugar, apenas veja as respostas acima.
André Mantas
49

Adicionando à resposta de David Liang para o Core 2.0 -

appsettings.jsonos arquivos estão vinculados à ASPNETCORE_ENVIRONMENTvariável

ASPNETCORE_ENVIRONMENTpode ser configurado para qualquer valor, mas três valores são suportados pela estrutura: Development, Staging, e Production. Se ASPNETCORE_ENVIRONMENTnão estiver definido, o padrão será Production.

Para esses três valores, esses arquivos appsettings.ASPNETCORE_ENVIRONMENT.json são suportados imediatamente -appsettings.Staging.json , appsettings.Development.jsoneappsettings.Production.json

Os três arquivos json de configuração de aplicativo acima podem ser usados ​​para configurar vários ambientes.

Exemplo - appsettings.Staging.json

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

Use Configuration["config_var"]para recuperar qualquer valor de configuração.

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
fonte
1
E os objetos aninhados?
Arthur Attout
8
Objetos aninhados podem ser obtidos com a Configuração ["MyConfig: SomethingNested"]
WeHaveCookies
1
Como pode ser visto no arquivo github.com/aspnet/AspNetCore/blob/master/src/DefaultBuilder/src/… na linha 167, o ASP.NET Core atualmente carrega appsettings.json+ appsettings.{env.EnvironmentName}.json. Portanto, a declaração de que o ASP.NET Core carrega apenas arquivos appsettings.json de desenvolvimento, armazenamento temporário e produção está incorreta no momento.
Mvcgun
1
então eu devo definir a variável do Windows ASPNETCORE_ENVIRONMENTtoda vez? As coisas foram maneira mais fácil em .Net 4. Estes fanáticos JSON fez estragar tudo grande momento
Toolkit
@ Toolkit Você pode definir a variável de ambiente globalmente. docs.microsoft.com/pt-br/aspnet/core/fundamentals/…
Gautam em
29

Eu acho que a maneira mais simples é por DI. Um exemplo de como acessar o Controller.

// 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
fonte
5
Lendo as outras respostas, isso deve ser o melhor.
harveyt
Eu estava desaparecido services.AddSingleton(Configuration);, agora funciona #
Arthur Medeiros
12

No construtor da classe Startup, você pode acessar appsettings.json e muitas outras configurações usando o objeto IConfiguration injetado:

Construtor Startup.cs

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;

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

    }

public IConfiguration Configuration { get; }

Conteúdo de appsettings.json

  {
  "Grandfather": {
    "Father": {
      "Child": "myvalue"
    }
  }
Shadi Namrouti
fonte
2
Foi a sintaxe 'Configuração ["Avô: Pai: Filho"]' que me ajudou.
Jacques Olivier
2
Esta é uma excelente resposta na forma como está estruturada, clara e objetiva.
Boa
6
    public static void GetSection()
    {
        Configuration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .Build();

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

    }
sepideh dalirpour
fonte
4
Resposta incompleta
Carlos ABS
1

No meu caso, era simples como usar o método Bind () no objeto Configuration. E adicione o objeto como singleton no DI.

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

O objeto Instrução pode ser tão complexo quanto você desejar.

{  
 "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
fonte
1

Para o ASP.NET Core 3.1, você pode seguir este guia:

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

Ao criar um novo projeto do ASP.NET Core 3.1, você terá a seguinte linha de configuração Program.cs:

Host.CreateDefaultBuilder(args)

Isso permite o seguinte:

  1. ChainedConfigurationProvider: adiciona uma configuração ICon existente como fonte. No caso da configuração padrão, adiciona a configuração do host e a define como a primeira fonte para a configuração do aplicativo.
  2. appsettings.json usando o provedor de configuração JSON.
  3. appsettings.Environment.json usando o provedor de configuração JSON. Por exemplo, appsettings.Production.json e appsettings.Development.json.
  4. Segredos do aplicativo quando o aplicativo é executado no ambiente de desenvolvimento.
  5. Variáveis ​​de ambiente usando o provedor de configuração Variáveis ​​de Ambiente.
  6. Argumentos de linha de comando usando o provedor de configuração de linha de comando.

Isso significa que você pode injetar IConfiguratione buscar valores com uma chave de cadeia, mesmo valores aninhados. GostarIConfiguration["Parent:Child"];

Exemplo:

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
fonte
Onde posso aprender mais sobre a IConfiguration["Parent:Child"]sintaxe?
xr280xr 29/06
0

Eu acho que a melhor opção é:

  1. Crie uma classe de modelo como esquema de configuração

  2. Registre-se no DI: services.Configure (Configuration.GetSection ("democonfig"));

  3. Obtenha os valores como objeto de modelo de DI em seu controlador:

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

Do núcleo 2.2 do Asp.net para cima, você pode codificar da seguinte forma:

Etapa 1. Crie um arquivo de classe AppSettings.

Este arquivo contém alguns métodos para ajudar a obter valor por chave do arquivo appsettings.json. Veja o código abaixo:

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>();
      }
  }
}

Etapa 2. Configuração inicial do objeto AppSettings

Precisamos declarar e carregar o arquivo appsettings.json quando o aplicativo é iniciado e carregar as informações de configuração do objeto AppSettings. Faremos esse trabalho no construtor do arquivo Startup.cs. Observe a linhaAppSettings.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);       
}

Ok, agora eu tenho um arquivo appsettings.json com algumas teclas, como abaixo:

{
  "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"
    }
  }
}

Etapa 3. Leia o valor de configuração de uma ação

Faço da demo uma ação no controlador Home, como abaixo:

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);
    }
}

E abaixo está o resultado:

Clique para ver o resultado

Para obter mais informações, consulte o artigo obter valor de appsettings.json no núcleo do asp.net para obter um código mais detalhado.

Dung Do Tien
fonte
0

É simples: em appsettings.json

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

No arquivo .cs:

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