在 .NET Core 中从 appsettings.json 获取值

22 浏览
0 Comments

在 .NET Core 中从 appsettings.json 获取值

不确定我在这里漏掉了什么,但我无法在我的.Net Core应用程序中获取我的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(_configuration.GetSection("AppSettings"));
    }
}

模型:

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

控制器:

public class HomeController : Controller
{
    private readonly AppSettings _mySettings;
    public HomeController(IOptions settings)
    {
        //This is always null
        _mySettings = settings.Value;
    }
}

_mySettings始终为空。我是否漏掉了些什么?

admin 更改状态以发布 2023年5月21日
0
0 Comments

只需要创建一个任意名称的.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"];

0
0 Comments

程序和启动类

ASP.NET Core 6.x

ASP.NET Core 6.x 在 Program 类中带来了另一个重大变化:

  • 如果选择使用顶层语句,就不需要 Program.Main() 样板代码
  • 隐式使用指令
  • 所有内容都在 Program 文件中,不需要 Startup
  • 引入了 WebApplicationWebApplicationBuilder

有人说这些变化对新手学习 ASP.NET Core 很有帮助,但我有点不这么认为。我觉得 ProgramStartup 的分离更有意义,至少对我来说是这样。

总之……

下面是 Program.cs 的外观:

// Program.cs
public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        builder.Services.AddControllersWithViews();
        var app = builder.Build();
        if (!app.Environment.IsDevelopment())
        {
            app.UseExceptionHandler("/errors");
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthorization();
        app.MapControllerRoute(
            name: "areaRoute",
            pattern: "{area:exists}/{controller=home}/{action=index}/{id?}");
        app.MapControllerRoute(
            name: "default",
            pattern: "{controller=home}/{action=index}/{id?}");
        app.Run();
    }
}

你可以大致看出 WebApplication.CreateBuilder()builder.Build() 之间的部分是旧的 ConfigureServices(IServiceCollection services) 的作用。而在 app.Run() 之前的部分则是旧的 StartupConfigure() 做的事情。

最重要的是,IConfiguration 被注入到管道中,所以你可以在控制器中使用它。

ASP.NET Core 3.x 到 5

ASP.NET Core 3.x 带来了一些变化,试图支持其他方法,比如各种服务,所以将 web 主机替换为更通用的主机构建器:

// Program.cs
public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup();
            }; 
    }
}

虽然如此,Startup 类看起来与 2.x 版本非常相似。

ASP.NET Core 2.x

你不需要在 Startup 构造函数中新建 IConfiguration。它的实现将由 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()
            .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;
    }
}

ASP.NET 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()
            .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 的简单方法
  • 使用选项模式

假设你的 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(
                "AppIdentitySettings:Password:RequiredLength"),
            RequireUppercase = _config.GetValue(
                "AppIdentitySettings:Password:RequireUppercase")
        };
        return View(vm);
    }
}

选项模式

ConfigurationBuilder.GetValue 的作用是从应用程序设置中获取一个或两个值非常好。但如果要从应用程序设置中获取多个值,或者不想在多个地方硬编码这些键字符串,那么使用选项模式可能更容易。选项模式使用类来表示层次结构 / 结构。

要使用选项模式:

  1. 定义类以表示结构
  2. 注册这些类所绑定的配置实例
  3. IOptions注入到您想获取值的控制器/类构造函数中

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

对于 ASP.NET Core 6.x

由于我在 ASP.NET Core 6.x 开头提到的更改,您需要绑定部分并将其添加到 DI 中,如下所示:

// Program.cs
public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        builder.Services.AddControllersWithViews();
        builder.Services.Configure(
            builder.Configuration.GetSection("AppIdentitySettings")
        );
        var app = builder.Build();
        ...
        app.Run();
    }
}

您可以在此处阅读更多有关此话题的信息。

3. 注入 IOptions

最后,在您想获取值的控制器/类上,您需要通过构造函数注入IOptions

public class AccountController : Controller
{
    private readonly AppIdentitySettings _appIdentitySettings;
    public AccountController(IOptions 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);
    }
}

0