从 appsettings.json 中读取 JSON 对象
Reading a JSON object from appsettings.json
TL;DR: 如何从 appsettings.json 读取复杂的 JSON 对象?
我有一个 .NET Core 2.x 应用程序具有多种类型的配置值。 appsettings.json
看起来像下面的代码片段,我正在尝试将 ElasticSearch:MyIndex:mappings
的值作为单个字符串或 JSON 对象读取。
{
"ConnectionStrings": {
"redis": "localhost"
},
"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Warning"
}
},
"Console": {
"LogLevel": {
"Default": "Warning"
}
}
},
"ElasticSearch": {
"hosts": [ "http://localhost:9200" ],
"MyIndex": {
"index": "index2",
"type": "mytype",
"mappings": {
"properties": {
"property1": {
"type": "string",
"index": "not_analyzed"
},
"location": {
"type": "geo_point"
},
"code": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
我可以通过调用 Configuration.GetValue<string>("ElasticSearch:MyIndex:index")
.
毫无问题地读取简单的配置值(键:值对)
Configuration.GetSection
Configuration.GetSection("ElasticSearch:MyIndex:mappings").Value
为 Value
提供了 null
值。
Configuration.GetValue
Configuration.GetValue<string>("ElasticSearch:MyIndex:mappings")
也 returns 一个空值。这对我来说很有意义,因为根据上述尝试,该部分具有空值。
Configuration.GetValue
Configuration.GetValue<JToken>("ElasticSearch:MyIndex:mappings")
也 returns 一个空值。出于与上述相同的原因,这对我来说也很有意义。
解决方案最终比我最初尝试的任何方法都简单得多:像阅读任何其他 JSON 格式的文件一样阅读 appsettings.json。
JToken jAppSettings = JToken.Parse(
File.ReadAllText(Path.Combine(Environment.CurrentDirectory, "appsettings.json"))
);
string mapping = jAppSettings["ElasticSearch"]["MyIndex"]["mappings"];
Dictionary<string,object> settings = Configuration
.GetSection("ElasticSearch")
.Get<Dictionary<string,object>>();
string json = JsonConvert.SerializeObject(settings);
将您的 JSON 对象转换为转义字符串。为此,您很可能只需要转义所有双引号并将其放在 一行 上,因此它看起来像:
"ElasticSearch": "{\"hosts\": [ \"http://localhost:9200\" ],\"MyIndex\": {\"index\"... "
然后你可以将它读入一个可以解析的字符串:
Configuration["ElasticSearch"]
此解决方案并不适合所有人,因为查看或更新转义的内容并不有趣 json,但如果您只是打算很少更改此配置设置,那么这可能不是最糟糕的主意.
@chris31389 的解决方案很好,得到了我的投票。但是,我的情况需要更通用的解决方案。
private static IConfiguration configuration;
public static TConfig ConfigurationJson<TConfig>(this string key)
{
var keyValue = GetJson();
return Newtonsoft.Json.JsonConvert.DeserializeObject<TConfig>(keyValue);
string GetJson()
{
if (typeof(TConfig).IsArray)
{
var dictArray = configuration
.GetSection(key)
.Get<Dictionary<string, object>[]>();
return Newtonsoft.Json.JsonConvert.SerializeObject(dictArray);
}
var dict = configuration
.GetSection(key)
.Get<Dictionary<string, object>[]>();
return Newtonsoft.Json.JsonConvert.SerializeObject(dict);
}
}
备注:
- 需要 Nuget `Microsoft.Extensions.Configuration.Binder`
-
正如上面提到的 @chris31389,您必须反序列化为一个字典,然后重新序列化为一个字符串,否则您将获得空值。这行不通
configuration
.GetSection(key)
.Get<TConfig>()
- 如果您正在尝试反序列化一个数组,则需要一个 `Dictionary[]`。这就是其他解决方案有时不起作用的原因。
我通过将配置数据绑定到 class 并在任何地方用作服务来获取配置数据,在配置服务中我添加了这个 class
services.Configure<SiteSettings>(options => Configuration.Bind(options));
然后在控制器中我可以通过依赖注入访问它,如下所示:
private readonly IOptionsSnapshot<SiteSettings> _siteSetting;
public TestController(IOptionsSnapshot<SiteSettings> siteSetting) ......
读取配置:
IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true).Build();
然后您可以创建一个映射 JSON 文件(或部分文件)结构的 POCO。
例如,如果 class 名称是 ConnectionStringsConfiguration
public class ConnectionStringsConfiguration { public string Redis {get; set;} }
然后使用:
ConnectionStringsConfiguration appConfig = configuration.GetSection("ConnectionStrings").Get<ConnectionStringsConfiguration>();
TL;DR: 如何从 appsettings.json 读取复杂的 JSON 对象?
我有一个 .NET Core 2.x 应用程序具有多种类型的配置值。 appsettings.json
看起来像下面的代码片段,我正在尝试将 ElasticSearch:MyIndex:mappings
的值作为单个字符串或 JSON 对象读取。
{
"ConnectionStrings": {
"redis": "localhost"
},
"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Warning"
}
},
"Console": {
"LogLevel": {
"Default": "Warning"
}
}
},
"ElasticSearch": {
"hosts": [ "http://localhost:9200" ],
"MyIndex": {
"index": "index2",
"type": "mytype",
"mappings": {
"properties": {
"property1": {
"type": "string",
"index": "not_analyzed"
},
"location": {
"type": "geo_point"
},
"code": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
我可以通过调用 Configuration.GetValue<string>("ElasticSearch:MyIndex:index")
.
Configuration.GetSection
Configuration.GetSection("ElasticSearch:MyIndex:mappings").Value
为 Value
提供了 null
值。
Configuration.GetValue
Configuration.GetValue<string>("ElasticSearch:MyIndex:mappings")
也 returns 一个空值。这对我来说很有意义,因为根据上述尝试,该部分具有空值。
Configuration.GetValue
Configuration.GetValue<JToken>("ElasticSearch:MyIndex:mappings")
也 returns 一个空值。出于与上述相同的原因,这对我来说也很有意义。
解决方案最终比我最初尝试的任何方法都简单得多:像阅读任何其他 JSON 格式的文件一样阅读 appsettings.json。
JToken jAppSettings = JToken.Parse(
File.ReadAllText(Path.Combine(Environment.CurrentDirectory, "appsettings.json"))
);
string mapping = jAppSettings["ElasticSearch"]["MyIndex"]["mappings"];
Dictionary<string,object> settings = Configuration
.GetSection("ElasticSearch")
.Get<Dictionary<string,object>>();
string json = JsonConvert.SerializeObject(settings);
将您的 JSON 对象转换为转义字符串。为此,您很可能只需要转义所有双引号并将其放在 一行 上,因此它看起来像:
"ElasticSearch": "{\"hosts\": [ \"http://localhost:9200\" ],\"MyIndex\": {\"index\"... "
然后你可以将它读入一个可以解析的字符串:
Configuration["ElasticSearch"]
此解决方案并不适合所有人,因为查看或更新转义的内容并不有趣 json,但如果您只是打算很少更改此配置设置,那么这可能不是最糟糕的主意.
@chris31389 的解决方案很好,得到了我的投票。但是,我的情况需要更通用的解决方案。
private static IConfiguration configuration;
public static TConfig ConfigurationJson<TConfig>(this string key)
{
var keyValue = GetJson();
return Newtonsoft.Json.JsonConvert.DeserializeObject<TConfig>(keyValue);
string GetJson()
{
if (typeof(TConfig).IsArray)
{
var dictArray = configuration
.GetSection(key)
.Get<Dictionary<string, object>[]>();
return Newtonsoft.Json.JsonConvert.SerializeObject(dictArray);
}
var dict = configuration
.GetSection(key)
.Get<Dictionary<string, object>[]>();
return Newtonsoft.Json.JsonConvert.SerializeObject(dict);
}
}
备注:
- 需要 Nuget `Microsoft.Extensions.Configuration.Binder`
-
正如上面提到的 @chris31389,您必须反序列化为一个字典,然后重新序列化为一个字符串,否则您将获得空值。这行不通
configuration .GetSection(key) .Get<TConfig>()
- 如果您正在尝试反序列化一个数组,则需要一个 `Dictionary[]`。这就是其他解决方案有时不起作用的原因。
我通过将配置数据绑定到 class 并在任何地方用作服务来获取配置数据,在配置服务中我添加了这个 class
services.Configure<SiteSettings>(options => Configuration.Bind(options));
然后在控制器中我可以通过依赖注入访问它,如下所示:
private readonly IOptionsSnapshot<SiteSettings> _siteSetting;
public TestController(IOptionsSnapshot<SiteSettings> siteSetting) ......
读取配置:
IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true).Build();
然后您可以创建一个映射 JSON 文件(或部分文件)结构的 POCO。 例如,如果 class 名称是 ConnectionStringsConfiguration
public class ConnectionStringsConfiguration { public string Redis {get; set;} }
然后使用:
ConnectionStringsConfiguration appConfig = configuration.GetSection("ConnectionStrings").Get<ConnectionStringsConfiguration>();