Last active
October 12, 2020 08:58
-
-
Save niikoo/7d08c3f3fd78ee11d1e84694f6d67938 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reflection; | |
using Newtonsoft.Json; | |
using Newtonsoft.Json.Converters; | |
namespace Faktum.Ics.Library.Utilities.Json | |
{ | |
/// <inheritdoc /> | |
/// <summary> | |
/// Defaults enum to the default value (first element). Can be overridden by setting an int as default value. | |
/// <example> | |
/// </example> | |
/// [JsonConverter(typeof(TolerantJsonEnumConverter), (int) Unknown)] | |
/// public enum Colors | |
/// { | |
/// Red = 0, | |
/// Blue, | |
/// Green, | |
/// Unknown | |
/// } | |
/// </summary> | |
public class TolerantJsonEnumConverter : StringEnumConverter | |
{ | |
/// <summary> | |
/// The default value used to fallback on when a enum is not convertable. | |
/// </summary> | |
private readonly int _defaultValue; | |
/// <inheritdoc /> | |
/// <summary> | |
/// Default constructor. Defaults the default value to 0. | |
/// </summary> | |
public TolerantJsonEnumConverter() | |
{ | |
} | |
/// <inheritdoc /> | |
/// <summary> | |
/// Sets the default value for the enum value. | |
/// </summary> | |
/// <param name="defaultValue">The default value to use.</param> | |
public TolerantJsonEnumConverter(int defaultValue) | |
{ | |
_defaultValue = defaultValue; | |
} | |
/// <inheritdoc /> | |
/// <summary> | |
/// Reads the provided JSON and attempts to convert using StringEnumConverter. If that fails set the value to the default value. | |
/// </summary> | |
/// <param name="reader">Reads the JSON value.</param> | |
/// <param name="objectType">Current type that is being converted.</param> | |
/// <param name="existingValue">The existing value being read.</param> | |
/// <param name="serializer">Instance of the JSON Serializer.</param> | |
/// <returns>The deserialized value of the enum if it exists or the default value if it does not.</returns> | |
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) | |
{ | |
var nonNullableType = objectType.IsNullable() ? objectType.GetNonNullable() : objectType; | |
try | |
{ | |
return base.ReadJson(reader, nonNullableType, existingValue, serializer); | |
} | |
catch | |
{ | |
return Enum.Parse(objectType, $"{_defaultValue}"); | |
} | |
} | |
/// <inheritdoc /> | |
/// <summary> | |
/// Validates that this converter can handle the type that is being provided. | |
/// </summary> | |
/// <param name="objectType">The type of the object being converted.</param> | |
/// <returns>True if the base class says so, and if the value is an enum and has a default value to fall on.</returns> | |
public override bool CanConvert(Type objectType) | |
{ | |
var nonNullableType = objectType.IsNullable() ? objectType.GetNonNullable() : objectType; | |
return base.CanConvert(nonNullableType) && nonNullableType.GetTypeInfo().IsEnum && Enum.IsDefined(nonNullableType, _defaultValue); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment