duy*_*ker 5 c# configuration .net-core asp.net-core
我在Microsoft.Extensions.Configuration绑定包含包含冒号的键的字典时遇到麻烦:。
我已经完成了一个示例,该词典具有字典“ GoodErrorMappings”,该字典在键中不包含任何冒号。这些已正确映射。
我创建了另一个词典“ BadErrorMappings”,该词典在键中带有一个冒号。在字典字典键中看到第一个冒号后,该字典似乎未正确映射。
我快速查看了源代码,但看不到一种明显的方式来替代冒号作为定界符。
任何帮助,将不胜感激。
Doco: https ://docs.microsoft.com/zh-CN/aspnet/core/fundamentals/configuration
程序集版本: “ Microsoft.NETCore.App”“ 1.1.0”
C#代码:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
namespace OptionsTest
{
public class Program
{
public static void Main(string[] args)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
var config = builder.Build();
var services = new ServiceCollection().AddOptions();
services.Configure<ApiConfig>(x => config.GetSection("ApiConfig").Bind(x));
var apiConfig = services.BuildServiceProvider().GetService<IOptions<ApiConfig>>().Value;
Debug.WriteLine(string.Format("\r\nGoodErrorMappings: {0}", JsonConvert.SerializeObject(apiConfig.GoodErrorMappings, Formatting.Indented)));
Debug.WriteLine(string.Format("\r\nBadErrorMappings: {0}", JsonConvert.SerializeObject(apiConfig.BadErrorMappings, Formatting.Indented)));
Console.ReadLine();
}
}
public class ApiConfig
{
public Dictionary<string, ErrorMapping> GoodErrorMappings { get; set; } = new Dictionary<string, ErrorMapping>();
public Dictionary<string, ErrorMapping> BadErrorMappings { get; set; } = new Dictionary<string, ErrorMapping>();
}
public class ErrorMapping
{
public int HttpStatusCode { get; set; }
public int ErrorCode { get; set; }
public string Description { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
AppSettings.json:
{
"ApiConfig": {
"GoodErrorMappings": {
"/SOMEVALUE/BLAH.123": {
"httpStatusCode": "500",
"errorCode": "110012",
"description": "Invalid error description 1"
},
"/SOMEVALUE/BLAH.456": {
"httpStatusCode": "500",
"errorCode": "110013",
"description": "Invalid error description 2"
}
},
"BadErrorMappings": {
"/SOMEVALUE/BLAH:123": {
"httpStatusCode": "500",
"errorCode": "110012",
"description": "Invalid error description 1"
},
"/SOMEVALUE/BLAH:456": {
"httpStatusCode": "500",
"errorCode": "110013",
"description": "Invalid error description 2"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
GoodErrorMappings: {
"/SOMEVALUE/BLAH.123": {
"HttpStatusCode": 500,
"ErrorCode": 110012,
"Description": "Invalid error description 1"
},
"/SOMEVALUE/BLAH.456": {
"HttpStatusCode": 500,
"ErrorCode": 110013,
"Description": "Invalid error description 2"
}
}
BadErrorMappings: {
"/SOMEVALUE/BLAH": {
"HttpStatusCode": 0,
"ErrorCode": 0,
"Description": null
}
}
Run Code Online (Sandbox Code Playgroud)
发生这种情况的原因是冒号在配置绑定中具有特殊含义。
当在字符串中提供冒号时,可以使用它来标识集合。我已经在对示例应用程序的以下代码更改中对此进行了演示。我还将您的BadErrorMappings更新为绑定中的数组,因为这是冒号分隔符正在执行的操作。
程式
public class Program
{
public static void Main(string[] args)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
var config = builder.Build();
var services = new ServiceCollection().AddOptions();
services.Configure<ApiConfig>(x => config.GetSection("ApiConfig").Bind(x));
services.Configure<Fruit>(x => config.GetSection("Fruit").Bind(x));
var serviceProvider = services.BuildServiceProvider();
var apiConfig = serviceProvider.GetService<IOptions<ApiConfig>>().Value;
var fruit = serviceProvider.GetService<IOptions<Fruit>>().Value;
Console.WriteLine(string.Format("\r\nGoodErrorMappings: {0}", JsonConvert.SerializeObject(apiConfig.GoodErrorMappings, Formatting.Indented)));
Console.WriteLine(string.Format("\r\nBadErrorMappings: {0}", JsonConvert.SerializeObject(apiConfig.BadErrorMappings, Formatting.Indented)));
Console.WriteLine(string.Format("\r\nFruit: {0}", JsonConvert.SerializeObject(fruit, Formatting.Indented)));
Console.ReadLine();
}
}
public class Fruit : List<string>
{
}
public class ApiConfig
{
public Dictionary<string, ErrorMapping> GoodErrorMappings { get; set; } = new Dictionary<string, ErrorMapping>();
public Dictionary<string, ErrorMapping[]> BadErrorMappings { get; set; } = new Dictionary<string, ErrorMapping[]>();
}
public class ErrorMapping
{
public int HttpStatusCode { get; set; }
public int ErrorCode { get; set; }
public string Description { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
appsettings.json
{
"ApiConfig": {
"GoodErrorMappings": {
"/SOMEVALUE/BLAH.123": {
"httpStatusCode": "500",
"errorCode": "110012",
"description": "Invalid error description 1"
},
"/SOMEVALUE/BLAH.456": {
"httpStatusCode": "500",
"errorCode": "110013",
"description": "Invalid error description 2"
}
},
"BadErrorMappings": {
"/SOMEVALUE/BLAH:123": {
"httpStatusCode": "500",
"errorCode": "110012",
"description": "Invalid error description 1"
},
"/SOMEVALUE/BLAH:456": {
"httpStatusCode": "500",
"errorCode": "110013",
"description": "Invalid error description 2"
}
}
},
"Fruit:0": "Apple",
"Fruit:1": "Orange"
}
Run Code Online (Sandbox Code Playgroud)
您还可以看到aspnet团队在其单元测试中利用了这一点,因此这是预期的行为。
示例:https: //github.com/aspnet/Configuration/blob/dev/test/Config.Binder.Test/ConfigurationCollectionBindingTests.cs#L396-L423
我发现的最简单的解决方案是将您的Dictionary<string, string>文件转换为List<KeyValuePair<string, ErrorMapping>>. 然后,JSON.NET 将您的 List 转换为格式为 的对象数组{ Key: 'keyname', Value: 'value' }。如果您接受所需的模型更改,这会很有效。
使用List<KeyValuePair<string, ErrorMapping>>而不是Dictionary<string, ErrorMapping>.
public class ApiConfig
{
public List<KeyValuePair<string, ErrorMapping>> GoodErrorMappings { get; set; } = new List<KeyValuePair<string, ErrorMapping>>();
public List<KeyValuePair<string, ErrorMapping>> BadErrorMappings { get; set; } = new List<KeyValuePair<string, ErrorMapping>>();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2357 次 |
| 最近记录: |