1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-06-08 00:16:27 +00:00

Updated EnumConverter

This commit is contained in:
Jan Korf 2022-03-09 21:09:41 +01:00
parent d5697250e2
commit 0d1ca30ce3
2 changed files with 58 additions and 13 deletions

View File

@ -147,6 +147,21 @@ namespace CryptoExchange.Net.UnitTests
var output = JsonConvert.DeserializeObject<EnumObject>($"{{ \"Value\": {val} }}"); var output = JsonConvert.DeserializeObject<EnumObject>($"{{ \"Value\": {val} }}");
Assert.AreEqual(output.Value, expected); Assert.AreEqual(output.Value, expected);
} }
[TestCase("1", TestEnum.One)]
[TestCase("2", TestEnum.Two)]
[TestCase("3", TestEnum.Three)]
[TestCase("three", TestEnum.Three)]
[TestCase("Four", TestEnum.Four)]
[TestCase("four", TestEnum.Four)]
[TestCase("Four1", TestEnum.One)]
[TestCase(null, TestEnum.One)]
public void TestEnumConverterNotNullableDeserializeTests(string value, TestEnum? expected)
{
var val = value == null ? "null" : $"\"{value}\"";
var output = JsonConvert.DeserializeObject<NotNullableEnumObject>($"{{ \"Value\": {val} }}");
Assert.AreEqual(output.Value, expected);
}
} }
public class TimeObject public class TimeObject
@ -160,6 +175,11 @@ namespace CryptoExchange.Net.UnitTests
public TestEnum? Value { get; set; } public TestEnum? Value { get; set; }
} }
public class NotNullableEnumObject
{
public TestEnum Value { get; set; }
}
[JsonConverter(typeof(EnumConverter))] [JsonConverter(typeof(EnumConverter))]
public enum TestEnum public enum TestEnum
{ {

View File

@ -4,6 +4,7 @@ using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
namespace CryptoExchange.Net.Converters namespace CryptoExchange.Net.Converters
@ -24,26 +25,48 @@ namespace CryptoExchange.Net.Converters
/// <inheritdoc /> /// <inheritdoc />
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{ {
objectType = Nullable.GetUnderlyingType(objectType) ?? objectType; var enumType = Nullable.GetUnderlyingType(objectType) ?? objectType;
if (!_mapping.TryGetValue(objectType, out var mapping)) if (!_mapping.TryGetValue(enumType, out var mapping))
mapping = AddMapping(objectType); mapping = AddMapping(enumType);
if (reader.Value == null) var stringValue = reader.Value?.ToString();
return null; if (stringValue == null)
var stringValue = reader.Value.ToString();
if (string.IsNullOrWhiteSpace(stringValue))
return null;
if (!GetValue(objectType, mapping, stringValue, out var result))
{ {
Trace.WriteLine($"{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff} | Warning | Cannot map enum value. EnumType: {objectType.Name}, Value: {reader.Value}, Known values: {string.Join(", ", mapping.Select(m => m.Value))}. If you think {reader.Value} should added please open an issue on the Github repo"); // Received null value
return null; var emptyResult = GetDefaultValue(objectType, enumType);
if(emptyResult != null)
// If the property we're parsing to isn't nullable there isn't a correct way to return this as null will either throw an exception (.net framework) or the default enum value (dotnet core).
Trace.WriteLine($"{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff} | Warning | Received null enum value, but property type is not a nullable enum. EnumType: {enumType.Name}. If you think {enumType.Name} should be nullable please open an issue on the Github repo");
return emptyResult;
}
if (!GetValue(enumType, mapping, stringValue!, out var result))
{
var defaultValue = GetDefaultValue(objectType, enumType);
if (string.IsNullOrWhiteSpace(stringValue))
{
if (defaultValue != null)
// We received an empty string and have no mapping for it, and the property isn't nullable
Trace.WriteLine($"{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff} | Warning | Received empty string as enum value, but property type is not a nullable enum. EnumType: {enumType.Name}. If you think {enumType.Name} should be nullable please open an issue on the Github repo");
}
else
// We received an enum value but weren't able to parse it.
Trace.WriteLine($"{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff} | Warning | Cannot map enum value. EnumType: {enumType.Name}, Value: {reader.Value}, Known values: {string.Join(", ", mapping.Select(m => m.Value))}. If you think {reader.Value} should added please open an issue on the Github repo");
return defaultValue;
} }
return result; return result;
} }
private static object? GetDefaultValue(Type objectType, Type enumType)
{
if (Nullable.GetUnderlyingType(objectType) != null)
return null;
return Activator.CreateInstance(enumType); // return default value
}
private static List<KeyValuePair<object, string>> AddMapping(Type objectType) private static List<KeyValuePair<object, string>> AddMapping(Type objectType)
{ {
var mapping = new List<KeyValuePair<object, string>>(); var mapping = new List<KeyValuePair<object, string>>();
@ -76,6 +99,7 @@ namespace CryptoExchange.Net.Converters
try try
{ {
// If no explicit mapping is found try to parse string
result = Enum.Parse(objectType, value, true); result = Enum.Parse(objectType, value, true);
return true; return true;
} }
@ -92,6 +116,7 @@ namespace CryptoExchange.Net.Converters
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <param name="enumValue"></param> /// <param name="enumValue"></param>
/// <returns></returns> /// <returns></returns>
[return: NotNullIfNotNull("enumValue")]
public static string? GetString<T>(T enumValue) public static string? GetString<T>(T enumValue)
{ {
var objectType = typeof(T); var objectType = typeof(T);