I'm trying to bind appsettings file into a generic class, but currently I can't map List<object>
values.
I have an appsettings.Development.json hierarchy like this:
{
"AppSettings":{
"ApplicationName":"FOO"
"MyValues":[
{
"Name":"Tryout1",
"QuestionCount": 7
},
{
"Name":"Tryout2"
"SettingName":"ABCDEFG"
}
]
}
}
And my generic class is like this:
public class AppSettings
{
public string ApplicationName {get;set;}
public List<object> MyValues {get;set;}
}
When I use below code to bind this appsettings.Development.json into the generic class like this:
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
variable has the ApplicationName
filled with value foo
but the MyValues
is just an empty array.
I also tried using object[]
instead of List<object>
and at that point it recognizes the amount of objects but all of the elements have the value null
.
I don't want the MyValues
array to be pre-defined because every element can and will have different fields and I want to make this process as generic as possible. How can I achieve this?
So, I found a way of achieving my goal, just not that straightforward but still pretty simple:
First I had to change my appsettings.Development.json file like this:
{
"AppSettings":{
"ApplicationName":"FOO"
"MyValues":[
"Tryout1": {
"Name":"Tryout1",
"QuestionCount": 7
},
"Tryout2": {
"Name":"Tryout2"
"SettingName":"ABCDEFG"
}
]
}
}
After this change, another change in the generic type is necessary, as follows:
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;}
}
This base class is important because we can't really bind the appsettings to an object, we still need a class. And base class, helps us bind these custom values like this:
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;
}
}
This should solve this problem, and huge thanks to andrewlock.net because I got the inital Dictionary<string, T>
idea from there.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.