ChatGPT解决这个技术问题 Extra ChatGPT

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

在 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 如何获取数组?


R
Ray

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

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

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

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

这比其他答案要简单得多。
这是迄今为止最好的答案。
在我的例子中,Aspnet core 2.1 web app 包含了这两个 nuget 包。所以它只是一个换行符。谢谢
它也适用于对象数组,例如 _config.GetSection("AppUser").Get<AppUser[]>();
我想知道为什么他们不能通过简单地使用 GetValue 作为该键来使其工作:Configuration.GetValue<string[]>("MyArray")
a
ahsteele

如果您想选择第一项的价值,那么您应该这样做-

var item0 = _config.GetSection("MyArray:0");

如果你想选择整个数组的值,那么你应该这样做 -

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

理想情况下,您应该考虑使用官方文档建议的 options pattern。这会给你带来更多好处。


如果您有像 "Clients": [ {..}, {..} ] 这样的对象数组,则应调用 Configuration.GetSection("Clients").GetChildren()
如果你有一个像 "Clients": [ "", "", "" ] 这样的文字数组,你应该调用 .GetSection("Clients").GetChildren().ToArray().Select(c => c.Value).ToArray()
这个答案实际上会产生 4 个项目,第一个是具有空值的部分本身。这是不正确的。
我成功地像这样调用它:var clients = Configuration.GetSection("Clients").GetChildren() .Select(clientConfig => new Client { ClientId = clientConfig["ClientId"], ClientName = clientConfig["ClientName"], ... }) .ToArray();
这些选项对我都不起作用,因为使用 halo 的示例,对象在“客户”点返回 null。我相信 json 格式正确,因为它可以使用格式为 "Item":[{...},{...}] 的字符串 ["item:0:childItem"] 中插入的偏移量
C
Community

在 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”之间使用逗号。
谢谢(你的)信息。我相信这最好地回答了最初的问题。
如果不是简单的字符串数组而是数组数组怎么办?例如,这个报告定义数组,我想为每个报告检索 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"}]]
D
Dmitry Pavlov

如果您有这样的复杂 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");
}

正是我正在寻找的东西,就像魅力一样,谢谢!
简单明了!
C
CodeThief

这对我有用,可以从我的配置中返回一个字符串数组:

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

B
Bjarki B

点网核心 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>>();

j
jaycer

对于从配置中返回复杂 JSON 对象数组的情况,我已调整 @djangojazz's answer 以使用匿名类型和动态而不是元组。

给定一个设置部分:

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

这太棒了
你的答案很完美。
s
sandy

在 ASP.NET Core 2.2 及更高版本中,我们可以在应用程序的任何位置注入 IConfiguration,就像您的情况一样,您可以在 HomeController 中注入 IConfiguration 并像这样使用来获取数组。

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

N
Nateowami

有点老问题,但我可以给出一个针对 C# 7 标准的 .NET Core 2.1 更新的答案。假设我只有在 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 现在应该显示“用户名”、“电子邮件”和“密码”的选项。


A
Andreas Friedel

您可以直接获取数组,而无需在配置中增加新级别:

public void ConfigureServices(IServiceCollection services) {
    services.Configure<List<String>>(Configuration.GetSection("MyArray"));
    //...
}

R
Roland Roos

这对我有用;创建一些 json 文件:

{
    "keyGroups": [
        {
            "Name": "group1",
            "keys": [
                "user3",
                "user4"
            ]
        },
        {
            "Name": "feature2And3",
            "keys": [
                "user3",
                "user4"
            ]
        },
        {
            "Name": "feature5Group",
            "keys": [
                "user5"
            ]
        }
    ]
}

然后,定义一些映射的类:

public class KeyGroup
{
    public string name { get; set; }
    public List<String> keys { get; set; }
}

nuget包:

Microsoft.Extentions.Configuration.Binder 3.1.3
Microsoft.Extentions.Configuration 3.1.3
Microsoft.Extentions.Configuration.json 3.1.3

然后,加载它:

using Microsoft.Extensions.Configuration;
using System.Linq;
using System.Collections.Generic;

ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

configurationBuilder.AddJsonFile("keygroup.json", optional: true, reloadOnChange: true);

IConfigurationRoot config = configurationBuilder.Build();

var sectionKeyGroups = 
config.GetSection("keyGroups");
List<KeyGroup> keyGroups = 
sectionKeyGroups.Get<List<KeyGroup>>();

Dictionary<String, KeyGroup> dict = 
            keyGroups = keyGroups.ToDictionary(kg => kg.name, kg => kg);

m
mojtaba karimi

简写:

var myArray= configuration.GetSection("MyArray")
                        .AsEnumerable()
                        .Where(p => p.Value != null)
                        .Select(p => p.Value)
                        .ToArray();

它返回一个字符串数组:

{"str1","str2","str3"}


为我工作。谢谢。使用 Microsoft.Extensions.Configuration.Binder 也可以,但是如果一行代码可以完成这项工作,我想远离引用另一个 Nuget 包。
谢谢 这个答案正确处理了值为空数组的情况,例如 MyArray: []
V
Vasily Ivanov
public class MyArray : List<string> { }

services.Configure<ShipmentDetailsDisplayGidRoles>(Configuration.GetSection("MyArray"));

public SomeController(IOptions<MyArray> myArrayOptions)
{
    myArray = myArrayOptions.Value;
}

N
Ngô Thanh Tùng

appsettings.json:

"MySetting": {
  "MyValues": [
    "C#",
    "ASP.NET",
    "SQL"
  ]
},

我的设置类:

namespace AspNetCore.API.Models
{
    public class MySetting : IMySetting
    {
        public string[] MyValues { get; set; }
    }

    public interface IMySetting
    {
        string[] MyValues { get; set; }
    }
}

启动.cs

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.Configure<MySetting>(Configuration.GetSection(nameof(MySetting)));
    services.AddSingleton<IMySetting>(sp => sp.GetRequiredService<IOptions<MySetting>>().Value);
    ...
}

控制器.cs

public class DynamicController : ControllerBase
{
    private readonly IMySetting _mySetting;

    public DynamicController(IMySetting mySetting)
    {
        this._mySetting = mySetting;
    }
}

访问值:

var myValues = this._mySetting.MyValues;

这看起来是正确的。但是选项模式(微软称之为)不需要选项类中的接口。您可以通过注入 IOptions<T> 而不是添加单例的开销来获得您的选择。
K
Kinjal Shah

appsettings.json 获取所有部分的所有值

        public static string[] Sections = { "LogDirectory", "Application", "Email" };
        Dictionary<string, string> sectionDictionary = new Dictionary<string, string>();

        List<string> sectionNames = new List<string>(Sections);
        
        sectionNames.ForEach(section =>
        {
            List<KeyValuePair<string, string>> sectionValues = configuration.GetSection(section)
                    .AsEnumerable()
                    .Where(p => p.Value != null)
                    .ToList();
            foreach (var subSection in sectionValues)
            {
                sectionDictionary.Add(subSection.Key, subSection.Value);
            }
        });
        return sectionDictionary;

s
shine

setting.json 文件:

{
    "AppSetting": {
        "ProfileDirectory": "C:/Users/",
        "Database": {
            "Port": 7002
        },
        "Backend": {
            "RunAsAdmin": true,
            "InstallAsService": true,
            "Urls": [
                "http://127.0.0.1:8000"
            ],
            "Port": 8000,
            "ServiceName": "xxxxx"
        }
    }
}

代码

代码:

public static IConfigurationRoot GetConfigurationFromArgs(string[] args, string cfgDir)
{
    var builder = new ConfigurationBuilder()
            .SetBasePath(cfgDir)
            .AddCommandLine(args ?? new string[0]) // null  in UnitTest null will cause exception
            .AddJsonFile(Path.Combine(cfgDir, "setting.json"), optional: true, reloadOnChange: true)
            .AddEnvironmentVariables()
        // .AddInMemoryollection(configDictionary)
        ;
    var config = builder.Build();
    return config;
}

您可以使用 services.AddOptions<AppSettingOption>("AppSetting") 或直接从 IConfigurationRoot 对象获取对象。

var cfg = GetConfigurationFromArgs(args, appDataDirectory);
cfg.GetSection("AppSetting").Get<AppSettingOption>()

输出:

{App.AppSettingOption}
    Backend: {App.BackendOption}
    Database: {App.DatabaseOption}
    ProfileDirectory: "C:/Users/"

w
worldwildwebdev

您可以像这样使用 Microsoft.Extensions.Configuration.Binder 包:

在您的 appsettings.json

{
      "MyArray": [
          "str1",
          "str2",
          "str3"
      ]
}

创建你的对象来保存你的配置:

 public class MyConfig
 {
     public List<string> MyArray { get; set; }
 }

在您的控制器 Bind 中配置:

public class HomeController : Controller
{
    private readonly IConfiguration _config;
    private readonly MyConfig _myConfig = new MyConfig();

    public HomeController(IConfiguration config)
    {
        _config = config;
    }

    public IActionResult Index()
    {
        return Json(_config.Bind(_myConfig));
    }
}

L
Lemonseed

最近,我还需要从 appsettings.json 文件(和其他类似的 .json 配置文件)中读取一个简单的字符串数组。

对于我的方法,我创建了一个简单的扩展方法来解决问题:

public static class IConfigurationRootExtensions
{
    public static string[] GetArray(this IConfigurationRoot configuration, string key)
    {
        var collection = new List<string>();
        var children = configuration.GetSection(key)?.GetChildren();
        if (children != null)
        {
            foreach (var child in children) collection.Add(child.Value);
        }
        return collection.ToArray();
    }
}

原始海报的 .json 文件如下所示:

{
      "MyArray": [
          "str1",
          "str2",
          "str3"
      ]
}

使用上面的扩展方法,它使读取这个数组成为一个非常简单的单行事务,如下例所示:

var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
string[] values = configuration.GetArray("MyArray");

在运行时,在 values 上使用“QuickWatch”设置断点可验证我们已成功将 .json 配置文件中的值读入字符串数组:

https://i.stack.imgur.com/JyUPS.png