it-roy-ru.com

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

Не уверен, что мне здесь не хватает, но я не могу получить значения из моего 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 всегда нулевой. Есть ли что-то, что мне здесь не хватает?

61
aman

Core 2.0

Вам не нужно новое 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;
    }
}

Бонус:

Если вы разделяете свое решение на несколько проектов с использованием библиотек классов, Microsoft.Extensions.Options.ConfigurationExtensions package пригодится для чтения значений из файлов appsettings и внедрения их в ваши классы конфигурации в проектах.

Он имеет 2 расширения, которые вы можете использовать:

public static T Get<T>(this IConfiguration configuration);
public static IServiceCollection Configure<TOptions>(this IServiceCollection services, 
    IConfiguration config) where TOptions : class;

Пример:

Я поместил все службы, связанные с безопасностью, используя Microsoft.AspNetCore.Identity, в собственный проект под названием DL.SO.Services.Security

Настройки безопасности в appsettings.json

Я определяю конфигурации, называемые «AppIdentitySettings», для опций идентификации, которые я хочу установить в рамках ASP.NET Core Identity в моем веб-проекте/проекте запуска.

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

Классы конфигурации

Затем вам нужно определить классы конфигурации, которые являются просто POCO, для представления вашей структуры конфигурации в appsettings.json. Имя класса конфигурации не обязательно должно совпадать с именем раздела, который вы определили в appsettings.json, а имена свойств должны совпадать. 

namespace DL.SO.Services.Security
{
    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; }
    }
}

метод расширения

Вы можете настроить привязку между appsettings.json и этими классами конфигурации в Startup вашего веб-проекта. Но я предпочитаю определять методы расширения в отдельном проекте, чтобы вы могли подключиться и играть.

using DL.SO.Services.Security.Entities;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace DL.SO.Services.Security.Extensions
{
    public static class ServiceCollectionExtensions
    {
        public static void AddIdentitySecurityService(this IServiceCollection services, 
            IConfiguration configuration)
        {
            string connectionString = configuration.GetConnectionString("AppDbConnection");
            string assemblyNamespace = typeof(AppIdentityDbContext).Namespace;

            var settingsSection = configuration.GetSection("AppIdentitySettings");
            var settings = settingsSection.Get<AppIdentitySettings>();

            // Inject AppIdentitySettings so that others can use too
            services.Configure<AppIdentitySettings>(settingsSection);

            services.AddDbContext<AppIdentityDbContext>(options =>
                options.UseSqlServer(connectionString, optionsBuilder =>
                    optionsBuilder.MigrationsAssembly(assemblyNamespace)
                )
            );

            services.AddIdentity<AppUser, AppRole>(options =>
            {
                // User settings
                options.User.RequireUniqueEmail = settings.User.RequireUniqueEmail;

                // Password settings
                options.Password.RequireDigit = settings.Password.RequireDigit;
                options.Password.RequiredLength = settings.Password.RequiredLength;
                options.Password.RequireLowercase = settings.Password.RequireLowercase;
                options.Password.RequireNonAlphanumeric = settings.Password.RequireNonAlphanumeric;
                options.Password.RequireUppercase = settings.Password.RequireUppercase;

                // Lockout settings
                options.Lockout.AllowedForNewUsers = settings.Lockout.AllowedForNewUsers;
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(settings.Lockout.DefaultLockoutTimeSpanInMins);
                options.Lockout.MaxFailedAccessAttempts = settings.Lockout.MaxFailedAccessAttempts;
            })
            .AddEntityFrameworkStores<AppIdentityDbContext>()
            .AddDefaultTokenProviders();
        }
    }
}

Подключить к основному запуску

namespace DL.SO.Web.UI
{
    ...

    public void ConfigureServices(IServiceCollection services)
    {
        // Configure ASP.NET Core Identity
        services.AddIdentitySecurityService(this.Configuration);

        ...
    }
}

Core 1.x

Вам нужно указать Startup для загрузки файлов appsettings.

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

Спасибо @Kirk за то, что указал на это!

85
David Liang

Добавление к ответу Дэвида Ляна для 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; }
}
29
Aseem Gautam

Просто создайте файл 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"];
24
shajji

Я думаю, самый простой способ - это 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");
        ...
    }
}
8
harveyt

В конструкторе класса 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"
    }
  }
3
Shadi Namrouti
    public static void GetSection()
    {
        Configuration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .Build();

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

    }
2
sepideh dalirpour

В моем случае это было просто: использовать метод Bind () для объекта конфигурации. А затем добавить объект как синглтон в 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"
    }
  }
0
Lizo Matala