不知道我在这里缺少什么,但是我无法从.net核心应用程序中的appsettings.json获取值。我有我的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始终为null。我在这里缺少什么吗?
_mySettings
感谢@Kirk指出我不应该认为它是.NET Core 2.0!
您不需要IConfiguration在Startup构造函数中新建。它的实现将由DI系统注入。
IConfiguration
Startup
// 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; } }
您需要告诉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(); } ... }
您可以通过多种方法从应用程序设置中获取配置的值:
ConfigurationBuilder.GetValue<T>
假设您的appsettings.json样子是这样的:
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>,如果你只需要从应用程序设置一个或两个值的伟大工程。但是,如果您想从应用程序设置中获取多个值,或者不想在多个位置对这些键字符串进行硬编码,则使用 Options Pattern 可能会更容易。选项模式使用类来表示层次结构/结构。
要使用选项模式:
IOptions<T>
您可以定义具有 需要与 您的应用程序设置 中 的键 完全匹配 的属性的类。类的名称不必与应用程序设置中的部分名称匹配:
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; } }
然后,您需要ConfigureServices()在启动时注册此配置实例:
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); ... } ... } }
最后,在要获取值的控制器/类上,需要IOptions<AppIdentitySettings>通过构造函数注入:
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); } }