无法从 appsettings.json 的 IConfiguration 提供商映射实例
Can't map instance from IConfiguration provider of appsettings.json
在我的appsettings.test.json中,我有以下结构。
{
"ViewOptionsConfiguration": {
"Default": {
"GroupingOptions": [
{ "Key": "SortKey1", "Label": "SortVal1" },
{ "Key": "SortKey2", "Label": "SortVal2" }
]
}
}
}
然后,我可以使用以下语法读取它(获取正确的值)。
string path = "ViewOptionsConfiguration:Default:GroupingOptions";
string key0 = config.GetValue<string>(path + ":0:Key")
string lab0 = config.GetValue<string>(path + ":0:Label")
string key1 = config.GetValue<string>(path + ":1:Label")
string lab1 = config.GetValue<string>(path + ":1:Label")
现在,我像这样引入了一个 class ViewOption
,目的是将配置映射到此类元素的数组。
public class ViewOption
{
public string Key { get; set; }
public string Label { get; set; }
}
我原以为以下内容会起作用。遗憾的是,映射的值似乎是null
,所以我猜映射无法识别这些值。
ViewOption option0 = config.GetValue<ViewOption>(path + ":0")
List<ViewOption> options = config.GetValue<List<ViewOption>>(path)
我在映射中遗漏了什么?
我的解决方法是执行如下操作。然而,它丑得像鸭子,而且,我还需要单独计算出数组的元素数量,这更加丑陋和鸭子。
ViewOption option0 = new ViewOption(
config.GetValue<string>(path + ":0:Key"),
config.GetValue<string>(path + ":0:Label"));
如果我理解正确的话,这里的目的是使用自定义类型来表示来自配置的数据片段。
引入 Options Pattern 是为了将自定义设置与配置 API(例如 IConfiguration
)分离。一个选项通常绑定到一个名称代表该选项实例的部分。在您的情况下,它可能是 class 和 GroupingOptions
属性:
public class MyViewOptions
{
public List<MyGroupingOption> GroupingOptions {get; set;}
}
public class MyGroupingOption
{
public string Key {get; set;}
public string Value {get; set;}
}
[...]
// Bind configuration sections to corresponding named options
public void ConfigureServices(IServiceCollection services)
{
// Bind default (unnamed) option
services.Configure<MyViewOptions>(Configuration.GetSection("ViewOptionsConfiguration:Default");
// Bind named options
services.Configure<MyViewOptions>(Configuration.GetSection("ABC", "ViewOptionsConfiguration:ABC");
services.Configure<MyViewOptions>(Configuration.GetSection("DEF", "ViewOptionsConfiguration:DEF");
}
用法:
// for default options only
MyService(IOptions<MyViewOptions> options)
{
var opts = options.Value;
}
// for named (and default) options
MyService(IOptionsSnapshot<MyViewOptions> options)
{
var defaultOptions = options.Value;
var abcOptions = options.Get("ABC");
var defOptions = options.Get("DEF");
}
我认为你非常接近。我在 .Net 5 目标控制台应用程序中做了类似下面的事情。我已经在 .
上为其他人发布了我的完整答案
List<string> emailAddresses = _config.GetSection("EmailAddresses").Get<List<string>>();
foreach (string emailAddress in emailAddresses)
{
Console.WriteLine(emailAddress);
}
我的appsettings.json是:
{
"AppSettings": {
"FTPLocation": "\\FTPHostname\\c$\\Folder\\ftpSite\\Prod\",
"FTPUri": "ftp://ftphostname/myFolder/",
"CSVFileName": "TestData.csv",
},
"ConnectionStrings": {
"AppDbConnString": "Server=sqlserverhost.domain.com;Database=DBName; Trusted_Connection=True; MultipleActiveResultSets=true"
,
"IdentityConnection": "Server=hostname.domain.com;Database=IdentityDBName; Trusted_Connection=True; MultipleActiveResultSets=true"
},
"EmailAddresses": [
"email1@test.com",
"email2@test.com",
"email3@test.com"
],
"Logging": {
"LogLevel": {
"Default": "Warning"
}
}
}
在我的appsettings.test.json中,我有以下结构。
{
"ViewOptionsConfiguration": {
"Default": {
"GroupingOptions": [
{ "Key": "SortKey1", "Label": "SortVal1" },
{ "Key": "SortKey2", "Label": "SortVal2" }
]
}
}
}
然后,我可以使用以下语法读取它(获取正确的值)。
string path = "ViewOptionsConfiguration:Default:GroupingOptions";
string key0 = config.GetValue<string>(path + ":0:Key")
string lab0 = config.GetValue<string>(path + ":0:Label")
string key1 = config.GetValue<string>(path + ":1:Label")
string lab1 = config.GetValue<string>(path + ":1:Label")
现在,我像这样引入了一个 class ViewOption
,目的是将配置映射到此类元素的数组。
public class ViewOption
{
public string Key { get; set; }
public string Label { get; set; }
}
我原以为以下内容会起作用。遗憾的是,映射的值似乎是null
,所以我猜映射无法识别这些值。
ViewOption option0 = config.GetValue<ViewOption>(path + ":0")
List<ViewOption> options = config.GetValue<List<ViewOption>>(path)
我在映射中遗漏了什么?
我的解决方法是执行如下操作。然而,它丑得像鸭子,而且,我还需要单独计算出数组的元素数量,这更加丑陋和鸭子。
ViewOption option0 = new ViewOption(
config.GetValue<string>(path + ":0:Key"),
config.GetValue<string>(path + ":0:Label"));
如果我理解正确的话,这里的目的是使用自定义类型来表示来自配置的数据片段。
引入Options Pattern 是为了将自定义设置与配置 API(例如 IConfiguration
)分离。一个选项通常绑定到一个名称代表该选项实例的部分。在您的情况下,它可能是 class 和 GroupingOptions
属性:
public class MyViewOptions
{
public List<MyGroupingOption> GroupingOptions {get; set;}
}
public class MyGroupingOption
{
public string Key {get; set;}
public string Value {get; set;}
}
[...]
// Bind configuration sections to corresponding named options
public void ConfigureServices(IServiceCollection services)
{
// Bind default (unnamed) option
services.Configure<MyViewOptions>(Configuration.GetSection("ViewOptionsConfiguration:Default");
// Bind named options
services.Configure<MyViewOptions>(Configuration.GetSection("ABC", "ViewOptionsConfiguration:ABC");
services.Configure<MyViewOptions>(Configuration.GetSection("DEF", "ViewOptionsConfiguration:DEF");
}
用法:
// for default options only
MyService(IOptions<MyViewOptions> options)
{
var opts = options.Value;
}
// for named (and default) options
MyService(IOptionsSnapshot<MyViewOptions> options)
{
var defaultOptions = options.Value;
var abcOptions = options.Get("ABC");
var defOptions = options.Get("DEF");
}
我认为你非常接近。我在 .Net 5 目标控制台应用程序中做了类似下面的事情。我已经在
List<string> emailAddresses = _config.GetSection("EmailAddresses").Get<List<string>>();
foreach (string emailAddress in emailAddresses)
{
Console.WriteLine(emailAddress);
}
我的appsettings.json是:
{
"AppSettings": {
"FTPLocation": "\\FTPHostname\\c$\\Folder\\ftpSite\\Prod\",
"FTPUri": "ftp://ftphostname/myFolder/",
"CSVFileName": "TestData.csv",
},
"ConnectionStrings": {
"AppDbConnString": "Server=sqlserverhost.domain.com;Database=DBName; Trusted_Connection=True; MultipleActiveResultSets=true"
,
"IdentityConnection": "Server=hostname.domain.com;Database=IdentityDBName; Trusted_Connection=True; MultipleActiveResultSets=true"
},
"EmailAddresses": [
"email1@test.com",
"email2@test.com",
"email3@test.com"
],
"Logging": {
"LogLevel": {
"Default": "Warning"
}
}
}