从.net Core中的appsettings.json获取价值


160

不知道我在这里缺少什么,但是我无法从.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。我在这里缺少什么吗?


3
阅读有关如何使用配置的文档。您在启动类中未正确设置配置。

感谢您的文档。这很有帮助。
阿曼

仅使用IConfiguration的依赖项注入就可以简化此过程。这是在这里解释coding-issues.com/2018/10/...
Ranadheer雷迪

Answers:


226

程序和启动类

.NET Core 2.x

您不需要IConfigurationStartup构造函数中新建。它的实现将由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;
    }
}

.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<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样子是这样的:

{
    "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可能会更容易。选项模式使用类来表示层次结构/结构。

要使用选项模式:

  1. 定义代表结构的类
  2. 注册那些类绑定到的配置实例
  3. 注入IOptions<T>要获取值的控制器/类的构造函数

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

3.注入IOptions

最后,在要获取值的控制器/类上,需要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);
    }
}

如何访问保存数据的类中的值?
Lukas Hieronimus Adler '18年

1
@LukasHieronimusAdler:您可能要使用IOptionsSnapshot<T>而不是IOptions<T>。您可以看一下这篇文章:offer.solutions/blog/articles/2017/02/17/…。我还没有机会自己尝试一下。
David Liang

2
您能像摘要一样简单吗?
Syaiful Nizam Yahya

8
从全栈.net倒退了多么可怕的一步
亚伦

4
好的,因此对于.NET Core 3,您需要Microsoft.Extensions.Options.ConfigurationExtensions程序包,并且可以正常运行
Tomas Bruckner

50

只需创建一个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"];

3
不要在生产中使用它。这种方法导致了我们的Web API中的内存泄漏。如果您使用的是netcore,则可以在任何地方注入IConfiguration,请参阅上面的答案。
安德烈·曼塔斯(AndréMantas)

49

大卫·梁(David Liang)对Core 2.0的回答-

appsettings.json文件的链接到ASPNETCORE_ENVIRONMENT变量。

ASPNETCORE_ENVIRONMENT可以设置为任意值,但三个值支持的框架:DevelopmentStaging,和Production。如果ASPNETCORE_ENVIRONMENT未设置,则默认为Production

对于这三个值,这些appsettings.ASPNETCORE_ENVIRONMENT.json文件都支持开箱即用- appsettings.Staging.jsonappsettings.Development.jsonappsettings.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; }
}

1
嵌套对象呢?
亚瑟·阿特

8
可以使用Configuration [“ MyConfig:SomethingNested”]获得嵌套对象
WeHaveCookies,2016年

1
从文件github.com/aspnet/AspNetCore/blob/master/src/DefaultBuilder/src/…可以看到,第167行ASP.NET Core当前加载appsettings.json+ appsettings.{env.EnvironmentName}.json。因此,有关ASP.NET Core仅加载Development,Staging和Production appsettings.json文件的说法目前不正确。
mvdgun

1
所以我应该ASPNETCORE_ENVIRONMENT每次都设置Windows变量吗?在.Net 4中,事情变得容易得多。这些JSON狂热者确实浪费了很多时间
Toolkit

@Toolkit可以全局设置环境变量。docs.microsoft.com/en-us/aspnet/core/fundamentals/...
Aseem高塔姆

29

我猜最简单的方法是通过DI。进入Controller的示例。

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

5
阅读其他答案,这应该是最好的。
harveyt '18 -10-26

我很想念 services.AddSingleton(Configuration);,现在可以了
Arthur Medeiros

12

在Startup类的构造函数中,您可以使用注入的IConfiguration对象访问appsettings.json和许多其他设置:

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"
    }
  }

2
正是“ Configuration [“ Grandfather:Father:Child”]'语法帮助了我。
雅克·奥利维尔

2
从结构,清晰和明确的角度来看,这是一个出色的答案。良好的沟通
jolySoft '19

6
    public static void GetSection()
    {
        Configuration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .Build();

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

    }

4
不完整的答案
卡洛斯ABS,

1

就我而言,这很简单,就像在Configuration对象上使用Bind()方法一样。然后在DI中将对象添加为单例。

var instructionSettings = new InstructionSettings();
Configuration.Bind("InstructionSettings", instructionSettings);
services.AddSingleton(typeof(IInstructionSettings), (serviceProvider) => instructionSettings);

指令对象可以任意复杂。

{  
 "InstructionSettings": {
    "Header": "uat_TEST",
    "SVSCode": "FICA",
    "CallBackUrl": "https://UATEnviro.companyName.co.za/suite/webapi/receiveCallback",
    "Username": "s_integrat",
    "Password": "X@nkmail6",
    "Defaults": {
    "Language": "ENG",
    "ContactDetails":{
       "StreetNumber": "9",
       "StreetName": "Nano Drive",
       "City": "Johannesburg",
       "Suburb": "Sandton",
       "Province": "Gauteng",
       "PostCode": "2196",
       "Email": "ourDefaultEmail@companyName.co.za",
       "CellNumber": "0833 468 378",
       "HomeNumber": "0833 468 378",
      }
      "CountryOfBirth": "710"
    }
  }

1

对于ASP.NET Core 3.1,您可以遵循以下指南:

https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1

创建新的ASP.NET Core 3.1项目时,您将在以下配置行中Program.cs

Host.CreateDefaultBuilder(args)

这将启用以下功能:

  1. ChainedConfigurationProvider:添加现有的IConfiguration作为源。在默认配置情况下,添加主机配置并将其设置为应用程序配置的第一个来源。
  2. 使用JSON配置提供程序的appsettings.json。
  3. 使用JSON配置提供程序的appsettings.Environment.json。例如,appsettings.Production.json和appsettings.Development.json。
  4. 当应用程序在开发环境中运行时,应用程序会秘密处理。
  5. 使用环境变量配置提供程序的环境变量。
  6. 使用命令行配置提供程序的命令行参数。

这意味着您可以IConfiguration使用字符串键插入和获取值,甚至是嵌套值。喜欢IConfiguration["Parent:Child"];

例:

appsettings.json

{
  "ApplicationInsights":
    {
        "Instrumentationkey":"putrealikeyhere"
    }
}

WeatherForecast.cs

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;
    private readonly IConfiguration _configuration;

    public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration configuration)
    {
        _logger = logger;
        _configuration = configuration;
    }

    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        var key = _configuration["ApplicationInsights:InstrumentationKey"];

        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}

在哪里可以了解有关IConfiguration["Parent:Child"]语法的更多信息?
xr280xr

0

我认为最好的选择是:

  1. 创建一个模型类作为配置模式

  2. 在DI中注册:services.Configure(Configuration.GetSection(“ democonfig”));

  3. 从控制器中的DI获取值作为模型对象:

    private readonly your_model myConfig;
    public DemoController(IOptions<your_model> configOps)
    {
        this.myConfig = configOps.Value;
    }

0

从Asp.net core 2.2或更高版本,您可以编写以下代码:

步骤1.创建一个AppSettings类文件。

该文件包含一些方法,可帮助您从appsettings.json文件中通过键获取价值。看起来像下面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ReadConfig.Bsl
{
  public class AppSettings
  {
      private static AppSettings _instance;
      private static readonly object ObjLocked = new object();
      private IConfiguration _configuration;

      protected AppSettings()
      {
      }

      public void SetConfiguration(IConfiguration configuration)
      {
          _configuration = configuration;
      }

      public static AppSettings Instance
      {
          get
          {
              if (null == _instance)
              {
                  lock (ObjLocked)
                  {
                      if (null == _instance)
                          _instance = new AppSettings();
                  }
              }
              return _instance;
          }
      }

      public string GetConnection(string key, string defaultValue = "")
      {
          try
          {
              return _configuration.GetConnectionString(key);
          }
          catch
          {
              return defaultValue;
          }
      }

      public T Get<T>(string key = null)
      {
          if (string.IsNullOrWhiteSpace(key))
              return _configuration.Get<T>();
          else
              return _configuration.GetSection(key).Get<T>();
      }

      public T Get<T>(string key, T defaultValue)
      {
          if (_configuration.GetSection(key) == null)
              return defaultValue;

          if (string.IsNullOrWhiteSpace(key))
              return _configuration.Get<T>();
          else
              return _configuration.GetSection(key).Get<T>();
      }

      public static T GetObject<T>(string key = null)
      {
          if (string.IsNullOrWhiteSpace(key))
              return Instance._configuration.Get<T>();
          else
          {
              var section = Instance._configuration.GetSection(key);
              return section.Get<T>();
          }
      }

      public static T GetObject<T>(string key, T defaultValue)
      {
          if (Instance._configuration.GetSection(key) == null)
              return defaultValue;

          if (string.IsNullOrWhiteSpace(key))
              return Instance._configuration.Get<T>();
          else
              return Instance._configuration.GetSection(key).Get<T>();
      }
  }
}

步骤2. AppSettings对象的初始配置

我们需要在应用程序启动时声明并加载appsettings.json文件,并加载AppSettings对象的配置信息。我们将在Startup.cs文件的构造函数中完成此工作。请注意行AppSettings.Instance.SetConfiguration(Configuration);

public Startup(IHostingEnvironment evm)
{
    var builder = new ConfigurationBuilder()
      .SetBasePath(evm.ContentRootPath)
      .AddJsonFile("appsettings.json", true, true)
      .AddJsonFile($"appsettings.{evm.EnvironmentName}.json", true)
      .AddEnvironmentVariables();
    Configuration = builder.Build(); // load all file config to Configuration property 
    AppSettings.Instance.SetConfiguration(Configuration);       
}

好的,现在我有一个带有一些键的appsettings.json文件,如下所示:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "ConnectionString": "Data Source=localhost;Initial Catalog=ReadConfig;Persist Security Info=True;User ID=sa;Password=12345;"
  },
  "MailConfig": {
    "Servers": {
      "MailGun": {
        "Pass": "65-1B-C9-B9-27-00",
        "Port": "587",
        "Host": "smtp.gmail.com"
      }
    },
    "Sender": {
      "Email": "example@gmail.com",
      "Pass": "123456"
    }
  }
}

步骤3.从操作中读取配置值

我使演示动作在Home控制器中如下所示:

public class HomeController : Controller
{
    public IActionResult Index()
    {
        var connectionString = AppSettings.Instance.GetConnection("ConnectionString");
        var emailSender = AppSettings.Instance.Get<string>("MailConfig:Sender:Email");
        var emailHost = AppSettings.Instance.Get<string>("MailConfig:Servers:MailGun:Host");

        string returnText = " 1. Connection String \n";
        returnText += "  " +connectionString;
        returnText += "\n 2. Email info";
        returnText += "\n Sender : " + emailSender;
        returnText += "\n Host : " + emailHost;

        return Content(returnText);
    }
}

结果如下:

点击查看结果

有关更多信息,请参阅asp.net核心中的appsettings.json中的文章获取值,以获取更多详细代码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.