ASP.NET 5 (vNext) - 获取配置设置

Posted

技术标签:

【中文标题】ASP.NET 5 (vNext) - 获取配置设置【英文标题】:ASP.NET 5 (vNext) - Getting a Configuration Setting 【发布时间】:2015-07-27 14:59:41 【问题描述】:

我正在编写一个基本的应用程序来学习 ASP.NET 5。我发现 非常 令人困惑的一个领域是配置。在 ASP.NET 5 之前,我可以执行以下操作:

var settingValue = ConfigurationManager.AppSettings["SomeKey"];

我会在我的代码中散布类似的代码行。现在,在 vNext 世界中,我有一个如下所示的 config.json 文件:

config.json


  "AppSettings": 
    "SomeKey":"SomeValue"
  

然后在 Startup.cs 中,我有以下内容: Startup.cs

public IConfiguration Configuration  get; set; 
public Startup(IHostingEnvironment environment) 

  Configuration = new Configuration()
      .AddJsonFile("config.json");

从那里,我完全被难住了。我在 /src/Website/Code/Models/MyClass.cs 中有 MyClass.cs。

MyClass.cs

public class MyClass

  public string DoSomething() 
  
    var result = string.Empty;
    var keyValue = string.Empty; // TODO: What do I do here? How do I get the value of "AppSettings:SomeKey"?
    return result;
  

如何获取“Ap​​pSettings:SomeKey”的值?

【问题讨论】:

@MStodd - 是的。 MVC6 (ASP.NET 5) 【参考方案1】:

ASP.NET 5 大量使用依赖注入,所以如果你也在使用依赖注入,那么这非常简单。如果您检查示例 MVC6 项目,您会看到它是如何工作的:

首先,在 Properties 中定义了一个类 AppSettings,它是您的类支持的选项的强类型版本。在示例项目中,这仅包含 SiteTitle。

public class AppSettings

    public string SiteTitle  get; set; 

然后,通过ConfigureServices中的依赖注入初始化这个类。 Configuration 这里是你在 Startup 类的构造函数中创建的。

public void ConfigureServices(IServiceCollection services)

    services.Configure<AppSettings>(Configuration.GetSubKey("AppSettings"));
    // ...

然后,假设你的类是由依赖注入容器实例化的,你可以简单地请求一个 IOptions 并且你会得到一个。例如,在控制器中,您可以有以下内容:

public class HomeController

    private string _title;
    public HomeController(IOptions<AppSettings> settings) 
    
        _title = settings.Options.SiteTitle;
    

【讨论】:

我很好奇,您指的是哪个示例 MVC6 项目?有链接吗? 在 Visual Studio 中新建 MVC 项目时得到的结果 @SerjSagan 你是如何做到这一点的。在我的系统上Configuration 没有GetSubKey 方法。 有几种方法。对于根级别的东西使用Configuration.GetSection("AppSettings") 对于嵌套的东西使用Configuration["Data:DefaultConnection:ConnectionString"] 请注意,截至今天,Asp.Net Core RC1 已经发布,RC2即将推出,这个 Options Model 是建议的方式走。界面略有变化:现在是settings.Value.SiteTitle,加上ConfigureServices 需要services.AddOptions(); 来设置DI 选项【参考方案2】:

我使用 ASP.NET 5 依赖注入,就像这样。

config.json:


    "random":  "Hello World!"

startup.cs:

public class Startup

    public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
    
        var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
            .AddJsonFile("config.json");

        Configuration = builder.Build();
    

    public IConfiguration Configuration  get; set; 

    public void ConfigureServices(IServiceCollection services)
    
        services.AddMvc();
        services.AddSingleton<IConfiguration>(sp =>  return Configuration; );
    

    public void Configure(IApplicationBuilder app)
    
        app.UseMvc(routes =>
        
            routes.MapRoute(name: "default", template: "controller=Home/action=Index/id?");
        );

    


控制器:

public class HomeController : Controller


    IConfiguration config;

    public HomeController(IConfiguration config)
    
        this.config = config;
    

    public IActionResult Index()
    
        var template = "<marquee>0</marquee>";
        var content = string.Format(template, config.Get("random"));
        return Content(content, "text/html");
    

【讨论】:

在最新版本的 ASP.NET Core 中,var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json") ... 和 Core 2.0 中的 changed yet again。【参考方案3】:

我强烈建议使用OptionsModel 而不是直接读取配置。它允许强类型模型绑定到配置。

这里是一个例子:GitHub.com/aspnet/Options/test/Microsoft.Extensions.Options.Test/OptionsTest.cs

为您的特定情况创建一个模型:

class AppSettings 
    public string SomeSetting get;set;

然后将其绑定到您的配置:

var config = // The configuration object
var options = ConfigurationBinder.Bind<AppSettings>(config); 
Console.WriteLine(options.SomeSetting);

这样您就不必担心设置的来源、存储方式或结构。您只需预定义您的期权模型,奇迹就会发生。

【讨论】:

使用OptionsModel 方法,对于更复杂的config.json 场景应该如何定义AppSettings?例如,如果 config.json 看起来像 "AppSettings": "SiteTitle":"My Site", "SearchSettings":"Service.Key":"12345" 创建几个具有属性的类。类似于具有NestedOptions的代码here 我重新审视了 OptionsModel 方法。然而,我不清楚强类型值以外的值。我认为 OptionsModel 方法存在的更大问题是将值放入可重用的库中。例如,如果我想创建一个可重用的日志库怎么办?选项将如何进入该库? 在我看来,这个功能与其说是 OptionsModel 不如说是 ConfigurationBinder 在工作中。我一直在试图弄清楚选项的意义(IOptionOptionManager 等),但还没有真正到达。 @VictorHurdugaci 感谢您修复链接,不幸的是我仍然不知道如何从project.jsonconfig.json 实际获取数据。【参考方案4】:

使用这个:

var value = Configuration.Get("AppSettings:SomeKey");

基于this blog post。冒号类似于点符号,用于向下导航。

如果你需要其他类中的值,你应该注入它。ASP.NET 已经内置了依赖注入,但是如果你只需要一个 MyClass 的实例,你可以新建它而不是设置一个 DI 容器。

public IConfiguration Configuration  get; set; 

public Startup(IHostingEnvironment environment) 

    Configuration = new Configuration()
      .AddJsonFile("config.json");
    //generally here you'd set up your DI container. But for now we'll just new it up
    MyClass c = new MyClass(Configuration.Get("AppSettings:SomeKey"));


public class MyClass

    private readonly string Setting; //if you need to pass multiple objects, use a custom POCO (and interface) instead of a string.

    public MyClass(string setting) //This is called constructor injection
    
        Setting = setting;
    

    public string DoSomething() 
    
        var result = string.Empty;
        //Use setting here
        return result;
    

【讨论】:

Configuration 属性/类从何而来?我在MyClass.cs 的顶部添加了using Microsoft.Framework.ConfigurationModel。但是,我不能使用Configuration.Get 它在Microsoft.Framework.ConfigurationModel。您可以将配置存储在内存中的任何位置,而不是每次都从文件中读取。但我建议你集中它,这样你就不会把它全部散布在你的代码中。 抱歉,我对您的答案投了反对票,因为您可以将 OptionsModel 用于模型绑定。无需自己阅读配置。 (见我的回答) @VictorHurdugaci 当然欢迎您使用您认为合适的反对票。但我认为这是一个非常糟糕的理由来否决某人的答案。这是一个新的架构,我不知道有什么选择。我看过贵公司的大量演示,但没有一个显示强类型模型绑定选项。我的回答会很好,并且清楚地展示了如何解决问题。当然强类型模型绑定很好,但我认为四处投票给有替代工作答案的人是不礼貌的,特别是如果我的公司是建议他们的人。 @Victor 仅仅因为您更喜欢自己的答案而否决别人的答案,这是一种非常糟糕的形式。否决票是针对错误答案或不适当答案的。如果答案以一种有效的方式回答了问题,那么就表现出一些尊重。

以上是关于ASP.NET 5 (vNext) - 获取配置设置的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET 5 (vNext) 中的身份验证

ASP.NET 5 - 启动 ASP.NET vNext 项目

在 asp.net 5/vnext 上的磁盘上没有 dll 的代码合同

防止在 asp.net 5 (vNext) 中对预检 OPTIONS 请求进行基于令牌的授权

如何在 ASP.NET 5 MVC 6 (vNext) 中定义 Identity 的密码规则?

在 ASP.NET 5 (vNext) MVC 6 中实现自定义路由器