ASP.NET Core使用IConfiguration获取Json数组

373

在 appsettings.json 中

{
      "MyArray": [
          "str1",
          "str2",
          "str3"
      ]
}
在 Startup.cs 文件中。
public void ConfigureServices(IServiceCollection services)
{
     services.AddSingleton<IConfiguration>(Configuration);
}

在HomeController中

public class HomeController : Controller
{
    private readonly IConfiguration _config;
    public HomeController(IConfiguration config)
    {
        this._config = config;
    }
    
    public IActionResult Index()
    {
        return Json(_config.GetSection("MyArray"));
    }
}

这是我的代码。我得到了null值。如何获取数组?

20个回答

651

您可以安装以下两个 NuGet 包:

using Microsoft.Extensions.Configuration; 
using Microsoft.Extensions.Configuration.Binder;

然后您将有可能使用以下扩展方法:

var myArray = _config.GetSection("MyArray").Get<string[]>();

24
这比其他答案要直接得多。 - jao
24
到目前为止,这是最好的答案。 - Giovanni Bassi
20
针对我的情况,Aspnet core 2.1 Web应用程序中包含这两个NuGet软件包。因此只需更改一行代码即可。谢谢。 - Shibu Thannikkunnath
12
它还可以处理对象数组,例如 _config.GetSection("AppUser").Get<AppUser[]>(); - Giorgos Betsos
13
我不知道为什么他们不能简单地使用GetValue来获取这个键的值:Configuration.GetValue<string[]>("MyArray") - Alexei - check Codidact
显示剩余10条评论

191
如果你想获取第一项的值,那么你应该这样做-
var item0 = _config.GetSection("MyArray:0");

如果您想选择整个数组的值,则应该像这样做 -

IConfigurationSection myArraySection = _config.GetSection("MyArray");
var itemArray = myArraySection.AsEnumerable();

理想情况下,您应该考虑使用官方文档建议的选项模式。这将给您带来更多好处。


53
如果你有一个对象数组,例如 "Clients": [ {..}, {..} ],你应该调用 Configuration.GetSection("Clients").GetChildren() - halllo
93
如果你有一个像 "Clients": [ "", "", "" ] 这样的文字数组,你应该调用 .GetSection("Clients").GetChildren().ToArray().Select(c => c.Value).ToArray() - halllo
17
这个答案实际上会生成4个项,第一个是该部分本身,但其值为空。这是不正确的。 - Giovanni Bassi
@halllo,你能否详细解释一下关于对象数组的方法?实际上,这个方法对我来说并没有起作用。 - user9601917
6
我成功地调用它,如下所示:var clients = Configuration.GetSection("Clients").GetChildren() .Select(clientConfig => new Client { ClientId = clientConfig["ClientId"], ClientName = clientConfig["ClientName"], ... }) .ToArray(); - halllo
3
这些选项都不适用于我,因为在使用hallo的示例时,“Clients”对象返回null。我有信心JSON格式良好,因为它在字符串中插入偏移量["item:0:childItem"]后可以正常工作,格式为"Item":[{...},{...}]。 - Clarence

93

在您的appsettings.json文件中添加一个级别:

{
  "MySettings": {
    "MyArray": [
      "str1",
      "str2",
      "str3"
    ]
  }
}
创建一个代表你的部分的类:
public class MySettings
{
     public List<string> MyArray {get; set;}
}

在您的应用程序启动类中,绑定您的模型并将其注入DI服务:

services.Configure<MySettings>(options => Configuration.GetSection("MySettings").Bind(options));

在您的控制器中,从 DI 服务获取配置数据:

public class HomeController : Controller
{
    private readonly List<string> _myArray;

    public HomeController(IOptions<MySettings> mySettings)
    {
        _myArray = mySettings.Value.MyArray;
    }

    public IActionResult Index()
    {
        return Json(_myArray);
    }
}

如果您需要所有数据,也可以将整个配置模型存储在控制器的属性中:

public class HomeController : Controller
{
    private readonly MySettings _mySettings;

    public HomeController(IOptions<MySettings> mySettings)
    {
        _mySettings = mySettings.Value;
    }

    public IActionResult Index()
    {
        return Json(_mySettings.MyArray);
    }
}

ASP.NET Core的依赖注入服务非常好用 :)


我收到一个错误提示,它需要在"MySettings"和"MyArray"之间加上逗号。 - Markus
谢谢提供信息。我相信这是最好的答案回答了原始问题。 - RobV8R
1
如果不是简单的字符串数组,而是一个数组的数组呢?例如,这个报告定义的数组,我想为每个报告检索cols数组: "reports": [ {"name":"reportA", "id": "1", "cols": [{"order":"1","name":"empid"},{"order":"2","name":"firstname"}]}, {"name":"reportB", "id": "2"}, "cols": [{"order":"1","name":"typeID"},{"order":"2","name":"description"}]] - joym8
1
也许有人看到这个答案,但是使用现代的.NET,你不需要额外的配置级别,因为在.NET 6中IOptions<List<...>>可以完美地工作,参见https://dev59.com/Y7roa4cB1Zd3GeqPdx6K#75589607。 - ViRuSTriNiTy

78

如果您有一个包含复杂JSON对象的数组,例如:

{
  "MySettings": {
    "MyValues": [
      { "Key": "Key1", "Value":  "Value1" },
      { "Key": "Key2", "Value":  "Value2" }
    ]
  }
}
您可以通过以下方式检索设置:
var valuesSection = configuration.GetSection("MySettings:MyValues");
foreach (IConfigurationSection section in valuesSection.GetChildren())
{
    var key = section.GetValue<string>("Key");
    var value = section.GetValue<string>("Value");
}

4
正是我所需要的,运行得很好,非常感谢! - Roni Antonio
2
简单明了! - ehsan_kabiri_33

49

以下方法适用于我,从我的配置文件中返回一个字符串数组:

var allowedMethods = Configuration.GetSection("AppSettings:CORS-Settings:Allow-Methods")
    .Get<string[]>();

我的配置部分看起来像这样:

"AppSettings": {
    "CORS-Settings": {
        "Allow-Origins": [ "http://localhost:8000" ],
        "Allow-Methods": [ "OPTIONS","GET","HEAD","POST","PUT","DELETE" ]
    }
}

32

DotNet Core 3.1:

Json配置:

"TestUsers": 
{
    "User": [
    {
      "UserName": "TestUser",
      "Email": "Test@place.com",
      "Password": "P@ssw0rd!"
    },
    {
      "UserName": "TestUser2",
      "Email": "Test2@place.com",
      "Password": "P@ssw0rd!"
    }]
}

然后创建一个 User.cs 类,其中包含与上面 Json 配置中的 User 对象相对应的自动属性。接下来,您可以引用 Microsoft.Extensions.Configuration.Abstractions 并执行:

List<User> myTestUsers = Config.GetSection("TestUsers").GetSection("User").Get<List<User>>();

25

对于从配置中返回一个复杂的JSON对象数组的情况,我已经改编了@djangojazz的答案,使用了匿名类型和动态类型而不是元组。

假设有以下设置部分:

"TestUsers": [
{
  "UserName": "TestUser",
  "Email": "Test@place.com",
  "Password": "P@ssw0rd!"
},
{
  "UserName": "TestUser2",
  "Email": "Test2@place.com",
  "Password": "P@ssw0rd!"
}],

您可以使用以下方式返回对象数组:

public dynamic GetTestUsers()
{
    var testUsers = Configuration.GetSection("TestUsers")
                    .GetChildren()
                    .ToList()
                    .Select(x => new {
                        UserName = x.GetValue<string>("UserName"),
                        Email = x.GetValue<string>("Email"),
                        Password = x.GetValue<string>("Password")
                    });

    return new { Data = testUsers };
}

这太棒了。 - Vladimir Demirev
你的答案完美无缺。 - Garry

19

这个问题有点老了,但我可以给出一个更新版本的答案,适用于.NET Core 2.1和C# 7标准。假设我只在appsettings.Development.json中列出了一个清单,例如:

"TestUsers": [
  {
    "UserName": "TestUser",
    "Email": "Test@place.com",
    "Password": "P@ssw0rd!"
  },
  {
    "UserName": "TestUser2",
    "Email": "Test2@place.com",
    "Password": "P@ssw0rd!"
  }
]
我可以在任何实现并已连接了Microsoft.Extensions.Configuration.IConfiguration的地方提取它们,代码如下所示:
var testUsers = Configuration.GetSection("TestUsers")
   .GetChildren()
   .ToList()
    //Named tuple returns, new in C# 7
   .Select(x => 
         (
          x.GetValue<string>("UserName"), 
          x.GetValue<string>("Email"), 
          x.GetValue<string>("Password")
          )
    )
    .ToList<(string UserName, string Email, string Password)>();

现在我有一个经过良好类型化的对象列表。如果我运行testUsers.First(),Visual Studio 将显示“UserName”、“Email”和“Password”的选项。


18
在ASP.NET Core 2.2及更高版本中,我们可以在应用程序的任何地方注入IConfiguration,例如在您的情况下,您可以在HomeController中注入IConfiguration并像这样使用来获取数组。
string[] array = _config.GetSection("MyArray").Get<string[]>();

9
您可以直接获取数组,而无需在配置中增加新级别:
public void ConfigureServices(IServiceCollection services) {
    services.Configure<List<String>>(Configuration.GetSection("MyArray"));
    //...
}

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