nop*_*nop 5 c# appsettings jsonconverter
我想创建一个 appsettings.json 转换器,将其转换Symbols为IReadOnlyCollection<Symbol>. 转换器应按 分割字符串/,这将生成 BaseAsset/QuoteAsset。然后应该检查是否QuoteAsset等于StakeCurrency。如果没有,则抛出异常。使用自定义转换器实现此目的的最佳方法是什么?我不想使用绑定。是否可以使用自定义 JsonConverter?
{
"BacktestConfiguration": {
"StakeCurrency": "USDT",
"Symbols": [ "TRX/USDT", "BTC/USDT", "ETH/USDT" ]
}
}
Run Code Online (Sandbox Code Playgroud)
{
"BacktestConfiguration": {
"StakeCurrency": "USDT",
"Symbols": [ "TRX/USDT", "BTC/USDT", "ETH/USDT" ]
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用自定义 JsonConverter 来处理从字符串数组到IReadOnlyCollection<Symbol>.
使用转换器 Type 修饰类Symbols的属性BacktestOptions,并在自定义转换器的方法中处理转换Read(),在该方法中,您可以拆分数组中的字符串以生成Symbol带有各个部分的新对象。\n然后从生成的对象列表中
返回一个新的。ReadOnlyCollection<Symbol>Symbol
我使用处理程序类BacktestConfigurationHandler来包含对象并提供基本转换和反序列化功能。
调用静态Deserialize()方法,传递 JSON 作为参数。\nBacktestConfiguration当 StakeCurrency 值与任何 Symbol[].QuoteAsset 值之间不存在不匹配时,它会返回一个对象。
\nJsonException如果不匹配,它会抛出 a 。
称其为:
\nvar configuration = BacktestConfigurationHandler.Deserialize(json);\nRun Code Online (Sandbox Code Playgroud)\nBacktestConfigurationHandler班级:
\xe2\x96\xba 它仅处理反序列化。如您所见,序列化未实现:该Write()方法不执行任何操作。
public class BacktestConfigurationHandler\n{\n public class BacktestRoot {\n public BacktestConfiguration BacktestConfiguration { get; set; }\n }\n\n public class BacktestConfiguration\n {\n public const string Position = "BacktestConfiguration";\n\n public string StakeCurrency { get; set; }\n\n [JsonConverter(typeof(SymbolConverter))]\n public IReadOnlyCollection<Symbol> Symbols { get; set; }\n }\n\n public class Symbol\n {\n public Symbol() : this("", "") { }\n public Symbol(string baseAsset, string quoteAsset) {\n BaseAsset = baseAsset;\n QuoteAsset = quoteAsset;\n }\n\n public string BaseAsset { get; set; }\n public string QuoteAsset { get; set; }\n }\n\n public static BacktestConfiguration Deserialize(string json)\n {\n var root = JsonSerializer.Deserialize<BacktestRoot>(json);\n var stakeCurrency = root.BacktestConfiguration.StakeCurrency;\n if (root.BacktestConfiguration.Symbols.Any(s => s.QuoteAsset != stakeCurrency)) {\n throw new JsonException("StakeCurrency mismatch");\n }\n return root.BacktestConfiguration;\n }\n\n public class SymbolConverter : JsonConverter<IReadOnlyCollection<Symbol>>\n {\n public override IReadOnlyCollection<Symbol> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n {\n if (reader.TokenType == JsonTokenType.StartArray) {\n var symbols = new List<Symbol>();\n var values = JsonSerializer.Deserialize<string[]>(ref reader, options);\n\n foreach (string value in values) {\n var parts = value.Split('/');\n symbols.Add(new Symbol(parts[0], parts[1]));\n\n }\n return new ReadOnlyCollection<Symbol>(symbols);\n }\n return null;\n\n public override void Write(Utf8JsonWriter writer, IReadOnlyCollection<Symbol> value, JsonSerializerOptions options)\n => throw new NotImplementedException();\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n编辑:
\n尝试类 Model 的这些变体和改编的自定义转换器,包括 JSON 转换器和分配给 Symbols 属性的 TypeConverter。
我已经在基本场景中测试了转换器,直接从 JSON 转换为类模型,并使用 TypeConverter 调用的隐式运算符访问/转换对象。
\npublic class BacktestOptionsRoot\n{\n public BacktestOptions BacktestConfiguration { get; set; }\n}\n\npublic class BacktestOptions\n{\n public const string Position = "BacktestConfiguration";\n\n public string StakeCurrency { get; set; }\n\n [JsonConverter(typeof(JsonSymbolConverter))]\n [TypeConverter(typeof(BacktestSymbolsConverter))]\n public BacktestSymbols Symbols { get; set; }\n}\n\npublic class Symbol\n{\n public Symbol() : this("", "") { }\n public Symbol(string baseAsset, string quoteAsset)\n {\n BaseAsset = baseAsset;\n QuoteAsset = quoteAsset;\n }\n\n public string BaseAsset { get; set; }\n public string QuoteAsset { get; set; }\n}\n\npublic class BacktestSymbolsConverter : TypeConverter\n{\n public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)\n {\n if (destinationType == typeof(string[])) {\n return (BacktestSymbols)(value as string[]);\n }\n return base.ConvertTo(context, culture, value, destinationType);\n }\n\n public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)\n {\n if (value is BacktestSymbols) {\n return (string[])(value as BacktestSymbols);\n }\n return base.ConvertFrom(context, culture, value);\n }\n}\n\npublic class JsonSymbolConverter : JsonConverter<BacktestSymbols>\n{\n public override bool CanConvert(Type typeToConvert)\n {\n return typeToConvert == typeof(BacktestSymbols);\n }\n\n public override BacktestSymbols Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n {\n if (reader.TokenType == JsonTokenType.StartArray) {\n return JsonSerializer.Deserialize<string[]>(ref reader, options);\n }\n return null;\n }\n\n public override void Write(Utf8JsonWriter writer, BacktestSymbols value, JsonSerializerOptions options)\n {\n throw new NotImplementedException();\n }\n}\n\n\npublic class BacktestSymbols\n{\n public ReadOnlyCollection<Symbol> Value { get; }\n public string[] Symbols => Value.Select(v => $"{v.BaseAsset}/{v.QuoteAsset}").ToArray();\n\n public BacktestSymbols(string[] source)\n {\n var symbols = new List<Symbol>();\n\n if (source != null && source.Length > 0) {\n foreach (string value in source) {\n var parts = value.Split('/');\n symbols.Add(new Symbol(parts[0], parts[1]));\n }\n }\n Value = new ReadOnlyCollection<Symbol>(symbols);\n }\n\n public static implicit operator BacktestSymbols(string[] source) => new BacktestSymbols(source);\n public static implicit operator string[](BacktestSymbols instance) => instance.Symbols;\n public override string ToString() => $"[ {string.Join(",", Symbols)} ]";\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1983 次 |
| 最近记录: |