如何从ASP.NET Core中的.json文件读取AppSettings值

440

我已经按照以下方式在appsettings/Config.json文件中设置了我的AppSettings数据:

{
  "AppSettings": {
        "token": "1234"
    }
}

我在网上搜索了如何从 .json 文件中读取 AppSettings 值的方法,但是没有找到有用的信息。

我尝试过:

var configuration = new Configuration();
var appSettings = configuration.Get("AppSettings"); // null
var token = configuration.Get("token"); // null

我知道在 ASP.NET 4.0 中你可以这样做:

System.Configuration.ConfigurationManager.AppSettings["token"];

但是在ASP.NET Core中我该如何实现这个呢?


可能是重复的问题:ASP.NET 5(vNext)-获取配置设置 - mason
提供额外见解的MSDN参考资料:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration?tabs=basicconfiguration - MDMoore313
这可以通过在.NET Core 2.0中使用IConfiguration的依赖注入来简化。具体解释请参见http://www.coding-issues.com/2018/10/read-values-from-appsettings-json-.net-core.html。 - Ranadheer Reddy
6
依赖注入适用于控制器。但是如果有人需要在中间件中读取一个值,该怎么办? - Alexander Ryan Baggett
如果你正在寻找一个 .net core 6 控制台应用程序,你可以看一下这个链接:https://dev59.com/QFEG5IYBdhLWcg3wfviM#70242856 - VivekDev
29个回答

479

这个问题经历了一些曲折。我已经修改了这个答案,使其与ASP.NET Core 2.0保持最新状态(截至2018年2月26日)。

这主要来自官方文档

要在ASP.NET应用程序中使用设置,建议您只在应用程序的Startup类中实例化一个Configuration,然后使用选项模式访问单个设置。假设我们有一个类似于appsettings.json的文件,如下所示:

{
  "MyConfig": {
   "ApplicationName": "MyApp",
   "Version": "1.0.0"
   }

}

我们有一个代表配置的POCO对象:

public class MyConfig
{
    public string ApplicationName { get; set; }
    public int Version { get; set; }
}

现在我们在Startup.cs中构建配置:

public class Startup 
{
    public IConfigurationRoot Configuration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

        Configuration = builder.Build();
    }
}

注意,在.NET Core 2.0中,默认情况下将注册appsettings.json。如果需要,我们还可以针对每个环境注册一个appsettings.{Environment}.json配置文件。

如果我们想将配置注入到控制器中,我们需要在运行时中注册它。我们可以通过Startup.ConfigureServices来实现:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    // Add functionality to inject IOptions<T>
    services.AddOptions();

    // Add our Config object so it can be injected
    services.Configure<MyConfig>(Configuration.GetSection("MyConfig"));
}

我们这样进行注入:

public class HomeController : Controller
{
    private readonly IOptions<MyConfig> config;

    public HomeController(IOptions<MyConfig> config)
    {
        this.config = config;
    }

    // GET: /<controller>/
    public IActionResult Index() => View(config.Value);
}

完整的Startup类:

public class Startup 
{
    public IConfigurationRoot Configuration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

        Configuration = builder.Build();
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        // Add functionality to inject IOptions<T>
        services.AddOptions();

        // Add our Config object so it can be injected
        services.Configure<MyConfig>(Configuration.GetSection("MyConfig"));
    }
}

4
我需要从一个实用类向另一个层传递设置,因此我需要像这样的代码:public static string GetConnectionString() { if (string.IsNullOrEmpty(connectionString)) { var builder = new ConfigurationBuilder() .AddJsonFile("config.json"); Configuration = builder.Build(); connectionString = Configuration.Get("Data:DefaultConnection:ConnectionString"); } return connectionString; } - dnxit
8
在添加了 NuGet 包 Microsoft.Extensions.Options.ConfigurationExtensions 后,它按预期工作。 - Peter
11
这段话的意思是:“在这个代码和旧的 XML 格式之间,有多少人愿意花时间去转换,只为了保存一个字符串?” - Vasil Valchev
7
配置过程的逻辑讲解得很好,但它忽略了一个重要点:SetBasePath()和AddJsonFile()是扩展方法,深埋在框架中不同的程序集中。因此,为了开始使用,除了安装Microsoft.Extensions.Configuration外,还需要安装Microsoft.Extensions.Configuration.FileExtensions和Microsoft.Extensions.Configuration.Json。 - Bozhidar Stoyneff
69
获取应用程序设置的过程如此复杂,真是不可思议。 - The Muffin Man
显示剩余28条评论

159

.NET Core 3.0 / .NET 6

这是一种简洁而简单的解决方案。

文件 appsettings.json

{
    "ConnectionStrings": {
        "DefaultConnection": "****;"
    },
    "AppSettings": {
        "APP_Name": "MY_Service",
        "SampleIntValue": 100
    }
}

控制器:

顶部

using Microsoft.Extensions.Configuration;

在你的代码中:

变量1:

var AppName = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build().GetSection("AppSettings")["APP_Name"];

或者

变量2:(用于读取多个值或数字)

var MyConfig = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
    var IntExample = MyConfig.GetValue<int>("AppSettings:SampleIntValue");
    var AppName = MyConfig.GetValue<string>("AppSettings:APP_Name");

15
@Essej:您需要安装Microsoft.Extensions.Configuration.Json NuGet包才能使用AddJsonFile方法。 - Baccata
5
我发现在 .Net Core 的 Program.cs 文件中唯一可行的方法。同意不同答案评论中的观点: 为获取设置文件需要如此多的复杂操作。 - MBielski
1
哇,非常感谢!其他人没有提供的缺失部分是如何访问设置,例如 .GetSection("AppSettings")["APP_Name"] - Steve Silberberg
绕过应用程序主机框架有时是最好的选择,例如对于一些简单的控制台应用程序。感谢您的回答。 - fartwhif
5
终于有一个简单的解决方案了,谢谢。为什么在Core中微软要把这个变得如此困难? - Moby's Stunt Double
显示剩余4条评论

79

首先: Microsoft.Framework.ConfigurationModel 的程序集名称和命名空间已更改为 Microsoft.Framework.Configuration。因此,您应该使用: 例如:

Microsoft.Framework.Configuration
"Microsoft.Framework.Configuration.Json": "1.0.0-beta7"

project.json 中作为依赖项。如果你没有安装 7 版本,则使用 beta5 或 6。 然后你可以在 Startup.cs 中像这样做。

public IConfiguration Configuration { get; set; }

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
     var configurationBuilder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
        .AddJsonFile("config.json")
        .AddEnvironmentVariables();
     Configuration = configurationBuilder.Build();
}

如果您想要从config.json中检索变量,可以直接使用以下方式获取:

public void Configure(IApplicationBuilder app)
{
    // Add .Value to get the token string
    var token = Configuration.GetSection("AppSettings:token");
    app.Run(async (context) =>
    {
        await context.Response.WriteAsync("This is a token with key (" + token.Key + ") " + token.Value);
    });
}

或者你可以创建一个叫做AppSettings的类,像这样:

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

然后像这样配置服务:

public void ConfigureServices(IServiceCollection services)
{       
    services.AddMvc();

    services.Configure<MvcOptions>(options =>
    {
        //mvc options
    });

    services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
}

然后可以通过像这样的控制器访问它:

public class HomeController : Controller
{
    private string _token;

    public HomeController(IOptions<AppSettings> settings)
    {
        _token = settings.Options.token;
    }
}

请问你能否分享一下“AppSettings”的配置JSON,以供参考? - Ankit Mori
我需要将整个 appSettings.json 配置以类的形式呈现。为此,我根据 JSON 设计了一个类,并使用 Configuration.Get<AppSettings>() 将整个文件反序列化,而不是只反序列化特定部分。 - Nilay Mehta

70

对于.NET Core 2.0,有些变化。启动构造函数以Configuration对象作为参数,所以不需要使用ConfigurationBuilder。这是我的:

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)
{
    services.Configure<StorageOptions>(Configuration.GetSection("AzureStorageConfig"));
}

我的POCO是顶部提到的StorageOptions对象:

namespace FictionalWebApp.Models
{
    public class StorageOptions
    {
        public String StorageConnectionString { get; set; }
        public String AccountName { get; set; }
        public String AccountKey { get; set; }
        public String DefaultEndpointsProtocol { get; set; }
        public String EndpointSuffix { get; set; }

        public StorageOptions() { }
    }
}

而配置实际上是我的appsettings.json文件的一个子部分,名为AzureStorageConfig

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;",
    "StorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=fictionalwebapp;AccountKey=Cng4Afwlk242-23=-_d2ksa69*2xM0jLUUxoAw==;EndpointSuffix=core.windows.net"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },

  "AzureStorageConfig": {
    "AccountName": "fictionalwebapp",
    "AccountKey": "Cng4Afwlk242-23=-_d2ksa69*2xM0jLUUxoAw==",
    "DefaultEndpointsProtocol": "https",
    "EndpointSuffix": "core.windows.net",
    "StorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=fictionalwebapp;AccountKey=Cng4Afwlk242-23=-_d2ksa69*2xM0jLUUxoAw==;EndpointSuffix=core.windows.net"
  }
}

我唯一需要补充的是,由于构造函数已更改,我尚未测试是否需要执行额外操作才能加载appsettings.<environmentname>.json而不是appsettings.json


只是想提醒一下,您仍然需要将 .AddJsonFile("yourfile.json") 添加到 ConfigConfiguration 中。也就是说,您需要告诉它文件的位置。我没有在答案中看到这一点。 - Eric
Eric,我会重新测试一下,我不记得添加那行代码了;如果JSON文件的名称不是默认名称,这行代码是否必要? - MDMoore313
根据MSDN的说法,对于ASPNETCORE 2.0来说并不是必需的,尽管它似乎对我也没有起作用。 https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.webhost.createdefaultbuilder?view=aspnetcore-2.0#Microsoft_AspNetCore_WebHost_CreateDefaultBuilder - Sat Thiru
1
我可以确认,我需要构建一个ConfigurationBuilder()对象并调用AddJSONFile()方法将appSettings.json文件加载到配置字典中。这是ASP.NET Core 2.0。这是否是一个错误,因为它与MSDN所说的相反? - Sat Thiru
1
你能举个例子说明如何将StorageOptions注入到你的控制器中吗?如果我使用hug的依赖注入方法,即使用public HomeController(IOptions<StorageOptions> settings),我会得到以下错误信息:模型绑定的复杂类型不能是抽象或值类型,并且必须具有无参数构造函数。 - Jpsy
显示剩余2条评论

57

使用 .NET Core 2.2,以最简单的方式...

public IActionResult Index([FromServices] IConfiguration config)
{
    var myValue = config.GetValue<string>("MyKey");
}

appsettings.json会自动加载,可以通过构造函数或操作注入调用,而且IConfiguration还有一个GetSection方法。如果你只需要使用appsettings.json,则不需要修改Startup.csProgram.cs文件。


6
更简洁的写法:var myValue = config["MyKey"]。该语句可以从名为“config”的对象中获取键名为“MyKey”的值,并将其赋给名为“myValue”的变量。 - jokab
3
你可以使用 config["Storage:ConnectionString"] 来获取 JSON 内部元素。我可以确认这种技术适用于 .NET Core 3 并可在构造注入中使用。 - Mário Meyrelles

43

如果你只想获取令牌的值,那么使用:

Configuration["AppSettings:token"]


9
要使此功能正常工作,您需要先通过 ConfigurationBuilder 初始化一个 IConfiguration 实例。 - Ε Г И І И О

26

我怀疑这不是一个好的实践,但本地工作正常。如果在发布/部署(到IIS Web服务)时失败,我将更新此内容。

步骤1 - 将此程序集添加到您的类顶部(在我的情况下,控制器类):

using Microsoft.Extensions.Configuration;

第二步 - 添加这个或类似的内容:

var config = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json").Build();

第三步 - 通过以下方式调用您的密钥值(返回字符串):

config["NameOfYourKey"]

1
我认为只要 appsettings.json 文件在正确的目录中,这应该是没问题的。 - Ju66ernaut
2
config["AppSettings:JWT_Secret"] 感谢您的使用。 - Z.W.Huang

23
对于ASP.NET Core 3.1,您可以遵循以下文档:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1。当您创建新的ASP.NET Core 3.1项目或.NET 5项目时,在Program.cs中会有以下配置行:
Host.CreateDefaultBuilder(args)

这使得以下内容可行:

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

这意味着您可以注入IConfiguration并使用字符串键获取值,甚至可以嵌套值。例如:IConfiguration ["Parent:Child"];

示例:

appsettings.json

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

天气预报.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();
    }
}

2
@Ogglas...如何获取调用WeatherForecastController()的类实现了IConfiguration接口? - Johnny Wu
这在我的Net 6上运行良好,但我在program.cs中没有找到Host.CreateDefaultBuilder(args),而是有 var builder = WebApplication.CreateBuilder(args); 假设具有相同的功能,因为其余部分都可以正常工作。 - cabaji99

22

这对我很有用.Net 5/6

我有一个 appsettings.development.json 文件。我选择了“Development”环境,所以我的开发环境中有设置在development.json 文件中。你可以使用带有默认环境的 appsettings.josn。

输入图像描述

使用此配置

输入图像描述

创建一个带有配置属性的类

输入图像描述

在 Startup 中注册我的调用

输入图像描述

现在我可以在我的控制器中访问

输入图像描述


我们能否使用JsonProperty修饰模型属性(名称类似于appsettings,但不是属性名称)? - ravithejag
不确定,从未尝试过。你可以试一下并告诉我结果。 - Ali
1
我尝试过了,但没有找到解决方案。我已经修改了appsettings键以符合我的项目需求。 - ravithejag
1
嘿,只是想说谢谢你提供了一个深思熟虑和全面的解释,这真的帮助了我。 - d0rf47

17
以下内容适用于控制台应用程序:
  1. 安装以下 NuGet 包(.csproj);

    <ItemGroup>
        <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0-preview2-35157" />
        <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0-preview2-35157" />
        <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0-preview2-35157" />
    </ItemGroup>
    
  2. 在根目录创建appsettings.json文件。右键单击该文件,并选择“复制到输出目录”作为“如果较新则复制”。

  3. 示例配置文件:

  4. {
      "AppConfig": {
        "FilePath": "C:\\temp\\logs\\output.txt"
      }
    }
    
  5. Program.cs

    configurationSection.KeyconfigurationSection.Value将包含配置属性。

  6. static void Main(string[] args)
    {
        try
        {
    
            IConfigurationBuilder builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
    
            IConfigurationRoot configuration = builder.Build();
            // configurationSection.Key => FilePath
            // configurationSection.Value => C:\\temp\\logs\\output.txt
            IConfigurationSection configurationSection = configuration.GetSection("AppConfig").GetSection("FilePath");
    
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接