【问题标题】:how to get value from appsettings.json如何从 appsettings.json 中获取价值
【发布时间】:2017-10-01 02:47:52
【问题描述】:
public class Bar
{
    public static readonly string Foo = ConfigurationManager.AppSettings["Foo"];
}

在.NET Framework 4.x中,我可以使用ConfigurationManager.AppSettings ["Foo"]得到Webconfig中的Foo,然后通过Bar.Foo就可以很容易地得到Foo的值

但是在.Net core中,我必须注入options,并且无法通过Bar.Foo得到Foo的值

有没有方法,可以直接通过Bar.Foo获取Foo的值?

【问题讨论】:

标签: .net appsettings


【解决方案1】:

所以实际上有两种方法可以解决这个问题。

选项 1:选项类

你有一个 appsettings.json 文件:

{
  "myConfiguration": {
    "myProperty": true 
  }
}

你像这样创建一个配置 POCO:

public class MyConfiguration
{
    public bool MyProperty { get; set; }
}

在您的 startup.cs 中,您的 ConfigureServices 中有一些东西可以注册配置:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyConfiguration>(Configuration.GetSection("myConfiguration"));
}

然后在您的控制器/服务中注入 IOptions 并且它是可用的。

public class ValuesController : Controller
{
    private readonly MyConfiguration _myConfiguration;

    public ValuesController(IOptions<MyConfiguration> myConfiguration)
    {
        _myConfiguration = myConfiguration.Value;
    }
}

就我个人而言,我不喜欢使用 IOptions,因为我认为它会带来一些我并不真正想要的额外垃圾,但你可以做一些很酷的事情,比如热交换和其他东西。

选项 2:配置 POCO

这几乎是相同的,但在您的配置服务方法中,您改为绑定到 POCO 的单例。

public void ConfigureServices(IServiceCollection services)
{
    //services.Configure<MyConfiguration>(Configuration.GetSection("myConfiguration"));
    services.AddSingleton(Configuration.GetSection("myConfiguration").Get<MyConfiguration>());
}

然后你就可以直接注入 POCO 了:

public class ValuesController : Controller
{
    private readonly MyConfiguration _myConfiguration;

    public ValuesController(MyConfiguration myConfiguration)
    {
        _myConfiguration = myConfiguration;
    }
}

有点简单,因为您可能应该使用接口来简化单元测试,但您明白了。

大部分取自这里:http://dotnetcoretutorials.com/2016/12/26/custom-configuration-sections-asp-net-core/

【讨论】:

  • 感谢您的回答。但是,这两种方法都需要IOptions &lt;MyConfiguration&gt; MyConfiguration。使用静态类/静态属性怎么办?
  • @ChiakiYu 你不应该使用静态类或属性进行配置——这被认为是一种不好的做法
  • 有点离题,但我不同意关于单元测试的观点,也许这有点脱离上下文。 MyConfiguration 只是一个 POCO,您可以轻松地提供一个带有您选择的模拟框架的预制测试版本。所以我不确定你真的是否需要一个界面。总而言之,它没有你想隐藏在接口后面的实现。
  • 不错的答案 - 正是我想要的。谢谢。
  • @MindingData 我确实有一个问题:在控制器中,如果我将具体类更改为接口,我的依赖项中的值将变为空 - 有什么建议吗?
【解决方案2】:

您也可以直接使用configuration。您的设置已注入,因此您可以使用 DI 访问它们...

private readonly IConfiguration _configuration;

public MyClass(IConfiguration configuration)
{
    _configuration = configuration;
}

然后你就可以读取你的设置了……

在这种情况下,我要收回一个集合......

var myList = _configuration.GetSection("MyList").Get<List<string>>();

【讨论】:

  • @PinoyDev 当然可以——它是一个构造函数,只读变量可以从构造函数赋值
  • 对于那些可能觉得这很有用的人:这里有一个关于如何读取 JSON 配置的好指南:c-sharpcorner.com/article/…
  • 最好通过IOptions进行配置设置,因为配置中包含很多其他数据,通常你不需要。
【解决方案3】:

上面的解决方案既费时又不简单,这是最有效的方法,启动时不需要设置或任何东西。这就像使用好的 ol Configuration.Manager.AppSettings["setting"]

首先创建一个类似“Credential”的类:

public class Credential
  {
      public string Username {get;set}
      public string Password {get;set;}
  }

现在设置好了,让 IConfiguration 像这样放在你的构造函数上:

    private IConfiguration _configuration;
    public ValuesController(IConfiguration iconfig)
    {
        _configuration = iconfig;
    }

那么你就可以调用它了!

    Credential c = new Credential();
    c.UserName = _configuration.GetValue<string>("Credential:username");
    c.Password = _configuration.GetValue<string>("Credential:password");

假设您的 appsettings.json 如下所示:

"Credential": {
    "username": "myuser",
    "password": "mypassword"
  }

希望这对某人有所帮助。

【讨论】:

  • 如果想要快速从 appsettings 中提取一个值,这就是要走的路。您还可以获得单个值,例如"BaseAddress": "localhost:45492" 在您的 appsettings.json 中,如下所示: string baseAddressConfig = configuration.GetValue("BaseAddress");
  • 当你谈到时间时,是开发时间还是处理时间?
【解决方案4】:
  1. 将此添加到 AppSettings.json 文件中
    "Swagger": { "Title": "API DEVELOPMENT" }

  2. 然后在Startup.cs文件中配置

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }
    
    public IConfiguration Configuration { get; }
    
  3. 接下来从appsettings.json获取值

    var title = Configuration.GetSection("Swagger:Title").Value;
    
  4. 终于放在这里

    services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = title, Version = "v1" }); }
    

【讨论】:

    【解决方案5】:

    补充来自@MindingData 的回答。我喜欢使用Configuration.Bind(settings); 递归地映射我的设置,这样我就不必在ConfigureServices 中添加每个新部分。

    例子:

    appsettings.json:

    {
        "MyConfiguration": {
            "MyProperty": true 
        }
    }
    

    设置类,属性必须匹配appsettings.json名称:

    public class Settings
    {
    
        public MyConfigurationSettings MyConfiguration { get; set; }
    
        public class MyConfigurationSettings
        {
            public bool MyProperty { get; set; }
        }
    
    }
    

    Startup.cs

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        public IConfiguration Configuration { get; }
    
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
    
            var settings = new Settings();
            Configuration.Bind(settings);
            services.AddSingleton(settings);
            ...
    

    可以在这样的控制器中使用:

    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private readonly Settings _settings;
    
        public ValuesController(Settings settings)
        {
            _settings = settings;
        }
    
        [HttpGet("GetValue")]
        public ActionResult<string> Get()
        {
            return Ok(_settings.MyConfiguration.MyProperty);
        }
    }
    

    【讨论】:

      【解决方案6】:

      将你的类定义为

      public class MyClass{
         private readonly IConfiguration _configuration;
         public MyClass(IConfiguration configuration)
              {
                  _configuration = configuration;
              }
         public void myFunction(){
             var value= _configuration.GetValue("xxx");
      }
      }
      

      当您从其他任何地方调用它时

      IConfiguration config = new ConfigurationBuilder()
                          .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false).Build();
      MyClass myclass = new MyClass(config)
      

      【讨论】:

        【解决方案7】:

        如果您已经将配置传递给控制器​​并且不想在启动配置中映射另一个服务,您可以通过这种方式轻松地从配置中获取值:

        public Startup(IConfiguration configuration)
        {
         Configuration = configuration;
          
         var myProperty = _configuration.GetSection("MyConfiguration")["MyProperty"];
        }
        

        使用字典属性。

        享受

        【讨论】:

          猜你喜欢
          • 2017-08-15
          • 1970-01-01
          • 1970-01-01
          • 2018-04-07
          • 1970-01-01
          • 1970-01-01
          • 2018-04-07
          相关资源
          最近更新 更多