Получение значения из appsettings.json в .net core

Не уверен, что мне здесь не хватает, но я не могу получить значения из моего appsettings.json в моем основном приложении .net. У меня есть appsettings.json как:

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

запуска:

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

Модель:

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

Контроллер:

public class HomeController : Controller
{
    private readonly AppSettings _mySettings;

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

_mySettings всегда равен нулю. Есть ли что-то, что мне здесь не хватает?

Ответ 1

Спасибо @Kirk за указание на то, что я не должен это понимать .NET Core 2.0!

Программа и класс запуска

.NET Core 2.x

Вам не нужно новый IConfiguration в конструкторе Startup. Его реализация будет внедрена системой 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

Вы должны указать Startup загрузить файлы настроек приложения.

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


Получение значений

Существует множество способов получить значение, которое вы настраиваете в настройках приложения:

Допустим, ваш appsettings.json выглядит так:

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

Простой способ

Вы можете вставить всю конфигурацию в конструктор вашего контроллера/класса (через IConfiguration) и получить желаемое значение указанным ключом:

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

Шаблон параметров

ConfigurationBuilder.GetValue<T> прекрасно работает, если вам нужно только одно или два значения из настроек приложения. Но если вы хотите получить несколько значений из настроек приложения или не хотите жестко кодировать эти строки ключей в нескольких местах, может быть проще использовать шаблон параметров. Шаблон параметров использует классы для представления иерархии/структуры.

Чтобы использовать шаблон параметров:

  1. Определите классы для представления структуры
  2. Зарегистрируйте экземпляр конфигурации, с которым эти классы связывают
  3. Вставьте IOptions<T> в конструктор контроллера/класса, значения которого вы хотите получить в

1. Определите классы конфигурации для представления структуры

Вы можете определить классы со свойствами, которые должны точно соответствовать ключам в настройках вашего приложения. Имя класса не обязательно должно совпадать с именем раздела в настройках приложения:

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. Зарегистрировать экземпляр конфигурации

А затем вам нужно зарегистрировать этот экземпляр конфигурации в ConfigureServices() при запуске:

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. Внедрить IOptions

Наконец, в контроллере/классе, который вы хотите получить значения, вам нужно вставить IOptions<AppIdentitySettings> через конструктор:

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

Ответ 2

Добавление к Дэвиду Ляну ответа для Core 2.0 -

Файл appsettings.json связан с переменной ASPNETCORE_ENVIRONMENT.

ASPNETCORE_ENVIRONMENT может быть установлено на любое значение, но платформа поддерживает три значения: Development, Staging и Production. Если ASPNETCORE_ENVIRONMENT не установлено, по умолчанию будет Production.

Для этих трех значений эти appsettings.ASPNETCORE_ENVIRONMENT.json файлы поддерживаются "из коробки" - appsettings.Staging.json, appsettings.Development.json и appsettings.Production.json

Вышеупомянутые три приложения, устанавливающие файлы json, можно использовать для настройки нескольких сред.

Пример - appsettings.Staging.json

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

Используйте Configuration["config_var"], чтобы получить любое значение конфигурации.

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

Ответ 3

Просто создайте файл AnyName.cs и вставьте следующий код.

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

Необходимо заменить имя файла YouAppSettingFile.json на имя вашего файла.
Ваш файл .json должен выглядеть следующим образом.

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

Теперь вы можете использовать его.
Не забудьте добавить ссылку в свой класс, где вы хотите использовать.

using Custom;

Код для получения значения.

string value1 = ConfigurationManager.AppSetting["GrandParent_Key:Parent_Key:Child_Key"];
string value2 = ConfigurationManager.AppSetting["Parent_Key:Child_Key"];
string value3 = ConfigurationManager.AppSetting["Child_Key"];

Ответ 4

Я думаю, самый простой способ - это DI. Пример достижения в контроллере.

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

Ответ 5

В конструкторе класса Startup вы можете получить доступ к appsettings.json и многим другим параметрам, используя внедренный объект IConfiguration:

Конструктор Startup.cs

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;

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

    }

public IConfiguration Configuration { get; }

Содержимое appsettings.json

  {
  "Grandfather": {
    "Father": {
      "Child": "myvalue"
    }
  }

Ответ 6

    public static void GetSection()
    {
        Configuration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .Build();

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

    }

Ответ 7

В моем случае это было просто, как использовать метод Bind() для объекта Configuration. А затем добавьте объект как синглтон в DI.

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

Объект Instruction может быть настолько сложным, насколько вы хотите.

{  
 "InstructionSettings": {
    "Header": "uat_TEST",
    "SVSCode": "FICA",
    "CallBackUrl": "https://UATEnviro.companyName.co.za/suite/webapi/receiveCallback",
    "Username": "s_integrat",
    "Password": "[email protected]",
    "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"
    }
  }