The title is pretty self explanatory. ASP.NET Core 5 doesn't respect neither the JsonConverter nor the TypeConverter.
The symbols e.g. "TRX/USDT" should be split by / and converted to new Symbol("TRX", "USDT") as I already did that. Basically, I want services.Configure<BacktestOptions>(hostingContext.Configuration.GetSection(BacktestOptions.Backtest)) to resolve it automatically.
public IReadOnlyCollection<string> Symbols { get; set; } works fine, but public IReadOnlyCollection<Symbol> Symbols { get; set; } doesn't, because it doesn't recognize the converter class.
This question Asp.Net Core 3.1 Appsettings not respecting JsonConverter, the guy who answered it, states that TypeConverter should work.
appsettings.json
{
"Backtest": {
"StartBalance": 1000,
"StakeCurrency": "USDT",
"Symbols": [ "TRX/USDT", "BTC/USDT", "ETH/USDT" ]
}
}
Snippet
public class Symbol
{
public Symbol()
{
}
public Symbol(string baseAsset, string quoteAsset)
{
BaseAsset = baseAsset;
QuoteAsset = quoteAsset;
}
public string BaseAsset { get; set; }
public string QuoteAsset { get; set; }
}
public class BacktestOptions
{
public const string Backtest = "Backtest";
[Required]
[Range(100, 50000)]
public decimal StartBalance { get; set; }
[Required]
[RegularExpression(@"^[a-zA-Z]+$")]
public string StakeCurrency { get; set; }
[Required]
[TypeConverter(typeof(SymbolConverter))]
public IReadOnlyCollection<Symbol> Symbols { get; set; }
}
public class SymbolConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context,
Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context,
CultureInfo culture, object value)
{
if (value is string v)
{
var parts = v.Split('/');
return new Symbol(parts[0], parts[1]);
}
return base.ConvertFrom(context, culture, value);
}
}
Additionally, JsonConverter example
public class SymbolConverter : JsonConverter<IReadOnlyCollection<Symbol>>
{
public override IReadOnlyCollection<Symbol> Read(ref Utf8JsonReader reader, Type typeToConvert,
JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.StartArray)
{
var values = JsonSerializer.Deserialize<string[]>(ref reader, options);
var symbols = values.Select(value => value.Split('/')).Select(parts => new Symbol(parts[0], parts[1])).ToList();
return new ReadOnlyCollection<Symbol>(symbols);
}
return null;
}
public override void Write(Utf8JsonWriter writer, IReadOnlyCollection<Symbol> value, JsonSerializerOptions options)
=> throw new NotImplementedException();
}