将 JSON 转换为配置很容易,例如与
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
var configuration = new ConfigurationBuilder().AddJsonStream(stream).Build();
IConfigurationRoot
。
是否有一种方法(最好在 Microsoft.Extensions.Configuration 包之一中)执行相反的操作?
上下文:我正在使用 GetConfigurationSettings
下载一堆Azure 应用程序配置设置,并希望将它们导出为 JSON。 Azure 门户中提供了类似的功能,但我也想解析密钥保管库引用。
我可能可以做这样的事情:
// Convert to JSON
var jRoot = new JObject();
foreach (var setting in settings) {
Add(jRoot, setting.Key, setting.Value);
}
Add
方法定义为
private void Add(JObject jObject, string key, string value) {
var index = key.IndexOf(':');
if (index == -1) {
jObject[key] = value;
return;
}
var prefix = key[..index];
if (!jObject.ContainsKey(prefix)) {
jObject[prefix] = new JObject();
}
Add((JObject)jObject[prefix], key[(index + 1)..], value);
}
我可能需要扩展它来支持数组,但我希望我不必重新发明轮子。
目前,我已经扩展了
Add
方法来支持数组:
private void Add(JToken jToken, string key, string value) {
var components = key.Split(":", 3);
if (components.Length == 1) {
// Leaf node
if (jToken is JArray jArray_) {
jArray_.Add(value);
} else {
jToken[components[0]] = value;
}
return;
}
// Next level
JToken nextToken;
var nextTokenIsAnArray = int.TryParse(components[1], out _);
if (jToken is JArray jArray) {
var index = int.Parse(components[0]);
if (jArray.Count == index) {
nextToken = nextTokenIsAnArray ? new JArray() : (JToken)new JObject();
jArray.Add(nextToken);
} else {
nextToken = jArray[index];
}
} else {
nextToken = jToken[components[0]];
if (nextToken == null) {
nextToken = jToken[components[0]] = nextTokenIsAnArray ? new JArray() : (JToken)new JObject();
}
}
Add(nextToken, key[(components[0].Length + 1)..], value);
}
这对我有用,假设数组以正确的顺序出现,例如
"Foo:0"
,值 "Bar"
"Foo:1"
,值 "Baz"
被序列化为
{ "Foo": ["Bar", "Baz"] }