簡體   English   中英

ASP.NET Core 使用IConfiguration獲取Json Array

[英]ASP.NET Core Get Json Array using IConfiguration

在 appsettings.json

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

在 Startup.cs 中

public void ConfigureServices(IServiceCollection services)
{
     services.AddSingleton<IConfiguration>(Configuration);
}

在家庭控制器中

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

上面有我的代碼。 我得到的是null,如何得到數組?

您可以安裝以下兩個 NuGet 包:

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

然后您將有可能使用以下擴展方法:

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

如果你想選擇第一項的價值,那么你應該這樣做 -

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

如果你想選擇整個數組的值,那么你應該這樣做 -

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

理想情況下,您應該考慮使用官方文檔建議的選項模式 這會給你帶來更多的好處。

在 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 的依賴注入服務就像一個魅力:)

如果您有像這樣的復雜 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");
}

這對我有用,可以從我的配置中返回一個字符串數組:

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

對於從配置返回一組復雜的 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 };
}

有點老問題,但我可以用 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 現在應該顯示“用戶名”、“電子郵件”和“密碼”的選項。

點網核心 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>>();

在 ASP.NET Core 2.2 及更高版本中,我們可以在應用程序中的任何位置注入 IConfiguration,就像您的情況一樣,您可以在 HomeController 中注入 IConfiguration 並像這樣使用來獲取數組。

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

您可以直接獲取數組,而無需在配置中增加新級別:

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

這對我有用; 創建一些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);

簡寫:

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

它返回一個字符串數組:

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

public class MyArray : List<string> { }

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

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

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

啟動文件

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;

最近,我也有一個需要從讀取一個簡單的字符串數組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配置文件中的值讀取到字符串數組中:

價值上下文的快速觀察

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;

設置.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/"

您可以像這樣使用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)
    {
        this._config = config;
    }

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

在 IOptions 不起作用之后我發現這更簡單,並且在序列化時更不用說了。

//appsettings.json
"DatabaseModelCreationOptions": {
    "Users": [
      {
        "Id": "1",
        "UserName": "adminuser",
        "Email": "youremail@myemail.com",
        "Password": "!Ch4",
        "Player": "Admin",
        "PlayerInitials": "ADMIN",
        "ApiKey": "40753ey"
      }
    ],   
    "UserRoles": [
      {
        "Id": "af9986df",
        "Name": "Admin",
        "ConcurrencyStamp": "ddd53170"
      },
      {
        "Id": "03b82b0e",
        "Name": "Manager",
        "ConcurrencyStamp": "65da3f89"
      }
    ]
}

我需要的類,我不需要向您展示嵌套的類屬性,您可以在上面看到它們。

public class DatabaseModelCreationOptions
{
    public IEnumerable<User>? Users { get; set; }
    public IEnumerable<UserRole>? UserRoles { get; set; }
}

然后只需調用 GetSection("").Get

var dbOptions = configuration.GetSection("DatabaseModelCreationOptions")
    .Get<DatabaseModelCreationOptions>();

在 .Net Core 7.x 中處理對象的不同方法

在 appsettings.json 中:

{
      "People": [
          { "FirstName": "Glen", "LastName": "Johnson", "Age": 30 },
          { "FirstName": "Matt", "LastName": "Smith", "Age": 40 },
          { "FirstName": "Fred", "LastName": "Williams", "Age": 50 }
      ]
}

人 class:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

在代碼中:

var appConfig = App.Current.AppConfiguration;   // Or could be passed in through DI
var children = appConfig.GetSection("People")
    .GetChildren()
    .ToList();

var people = new List<Person>();
foreach (var child in children)
{
    var rec = new Person
    {
        FirstName = appConfig[$"{child.Path}:FirstName"],
        LastName = appConfig[$"{child.Path}:LastName"],
        Age = int.Parse(appConfig[$"{child.Path}:Age"]),
    };
    people.Add(rec);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM