从 appsettings.json 中提取自定义对象数组
Extracting custom object array from appsettings.json
我正在尝试将 appsettings 文件绑定到通用 class,但目前我无法映射 List<object>
值。
我有这样的 appsettings.Development.json 层次结构:
{
"AppSettings":{
"ApplicationName":"FOO"
"MyValues":[
{
"Name":"Tryout1",
"QuestionCount": 7
},
{
"Name":"Tryout2"
"SettingName":"ABCDEFG"
}
]
}
}
而我的通用 class 是这样的:
public class AppSettings
{
public string ApplicationName {get;set;}
public List<object> MyValues {get;set;}
}
当我使用下面的代码将此 appsettings.Development.json 绑定到通用 class 时,如下所示:
static ConfigurationHelper()
{
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile($"appsettings.{environmentName}.json")
.Build();
try
{
var tryout = config.Get(typeof(AppSettings));
}
catch (Exception ex)
{
throw ex;
}
}
tryout
变量的 ApplicationName
填充了值 foo
但 MyValues
只是一个空数组。
我还尝试使用 object[]
而不是 List<object>
,此时它可以识别对象的数量,但所有元素的值都为 null
.
我不希望预定义 MyValues
数组,因为每个元素都可以并且将有不同的字段,我希望这个过程尽可能通用。我怎样才能做到这一点?
所以,我找到了实现目标的方法,虽然不是那么简单,但仍然非常简单:
首先,我必须像这样更改 appsettings.Development.json 文件:
{
"AppSettings":{
"ApplicationName":"FOO"
"MyValues":[
"Tryout1": {
"Name":"Tryout1",
"QuestionCount": 7
},
"Tryout2": {
"Name":"Tryout2"
"SettingName":"ABCDEFG"
}
]
}
}
这次改动后,还需要对泛型类型做一次改动,如下:
public class AppSettings
{
public string ApplicationName {get;set;}
public Dictionary<string, CustomBaseClass> MyValues {get;set;}
public List<object> _MyValues {get;set;}
}
public class CustomBaseClass
{
public string Name { get; set; }
}
public class Tryout1 : CustomBaseClass
{
public int QuestionCount {get;set;}
}
public class Tryout2 : CustomBaseClass
{
public string SettingName {get;set;}
}
这个基础class很重要,因为我们不能真正将appsettings绑定到一个对象,我们仍然需要一个class。 base class 帮助我们像这样绑定这些自定义值:
private static List<Type> CustomTypes = new List<Type> { typeof(Tryout1), typeof(Tryout2) };
static ConfigurationHelper()
{
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile($"appsettings.{environmentName}.json")
.Build();
try
{
AppSettings = config.Get<AppSettingsContainer>();
foreach (var keyValuePair in AppSettings.MyValues)
{
var type = CustomTypes.Where(t => t.Name == keyValuePair.Key).FirstOrDefault();
if (type != null)
{
var myValue = config.GetSection(string.Format("AppSettings:MyValues:{0}", keyValuePair.Key)).Get(type);
if (job != null)
{
AppSettings._MyValues.Add(myValue);
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
这应该可以解决这个问题,非常感谢 andrewlock.net 因为我从那里得到了最初的 Dictionary<string, T>
想法。
我正在尝试将 appsettings 文件绑定到通用 class,但目前我无法映射 List<object>
值。
我有这样的 appsettings.Development.json 层次结构:
{
"AppSettings":{
"ApplicationName":"FOO"
"MyValues":[
{
"Name":"Tryout1",
"QuestionCount": 7
},
{
"Name":"Tryout2"
"SettingName":"ABCDEFG"
}
]
}
}
而我的通用 class 是这样的:
public class AppSettings
{
public string ApplicationName {get;set;}
public List<object> MyValues {get;set;}
}
当我使用下面的代码将此 appsettings.Development.json 绑定到通用 class 时,如下所示:
static ConfigurationHelper()
{
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile($"appsettings.{environmentName}.json")
.Build();
try
{
var tryout = config.Get(typeof(AppSettings));
}
catch (Exception ex)
{
throw ex;
}
}
tryout
变量的 ApplicationName
填充了值 foo
但 MyValues
只是一个空数组。
我还尝试使用 object[]
而不是 List<object>
,此时它可以识别对象的数量,但所有元素的值都为 null
.
我不希望预定义 MyValues
数组,因为每个元素都可以并且将有不同的字段,我希望这个过程尽可能通用。我怎样才能做到这一点?
所以,我找到了实现目标的方法,虽然不是那么简单,但仍然非常简单:
首先,我必须像这样更改 appsettings.Development.json 文件:
{
"AppSettings":{
"ApplicationName":"FOO"
"MyValues":[
"Tryout1": {
"Name":"Tryout1",
"QuestionCount": 7
},
"Tryout2": {
"Name":"Tryout2"
"SettingName":"ABCDEFG"
}
]
}
}
这次改动后,还需要对泛型类型做一次改动,如下:
public class AppSettings
{
public string ApplicationName {get;set;}
public Dictionary<string, CustomBaseClass> MyValues {get;set;}
public List<object> _MyValues {get;set;}
}
public class CustomBaseClass
{
public string Name { get; set; }
}
public class Tryout1 : CustomBaseClass
{
public int QuestionCount {get;set;}
}
public class Tryout2 : CustomBaseClass
{
public string SettingName {get;set;}
}
这个基础class很重要,因为我们不能真正将appsettings绑定到一个对象,我们仍然需要一个class。 base class 帮助我们像这样绑定这些自定义值:
private static List<Type> CustomTypes = new List<Type> { typeof(Tryout1), typeof(Tryout2) };
static ConfigurationHelper()
{
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile($"appsettings.{environmentName}.json")
.Build();
try
{
AppSettings = config.Get<AppSettingsContainer>();
foreach (var keyValuePair in AppSettings.MyValues)
{
var type = CustomTypes.Where(t => t.Name == keyValuePair.Key).FirstOrDefault();
if (type != null)
{
var myValue = config.GetSection(string.Format("AppSettings:MyValues:{0}", keyValuePair.Key)).Get(type);
if (job != null)
{
AppSettings._MyValues.Add(myValue);
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
这应该可以解决这个问题,非常感谢 andrewlock.net 因为我从那里得到了最初的 Dictionary<string, T>
想法。