Created
September 16, 2021 02:08
-
-
Save flakey-bit/18a3d47973040fe3dd16916016c50dc8 to your computer and use it in GitHub Desktop.
System.Text.Json converter for Either<UnsupportedValue, T> - useful where T is an enum from a 3rd party API and you want to handle unknown values
This file contains hidden or 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
internal class EitherValidOrUnsupportedValueConverterFactory : JsonConverterFactory | |
{ | |
public override bool CanConvert(Type typeToConvert) | |
{ | |
var canConvert = typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(Either<,>) && typeToConvert.GenericTypeArguments[0] == typeof(UnsupportedValue); | |
return canConvert; | |
} | |
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) | |
{ | |
typeToConvert = typeToConvert.GenericTypeArguments[1]; | |
return (JsonConverter)Activator.CreateInstance(typeof(EitherValidOrUnsupportedValueConverter<>).MakeGenericType(typeToConvert)); | |
} | |
} | |
internal class EitherValidOrUnsupportedValueConverter<T> : JsonConverter<Either<UnsupportedValue, T>> | |
{ | |
public override Either<UnsupportedValue, T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
{ | |
try | |
{ | |
var deserialized = JsonSerializer.Deserialize<T>(ref reader, options); | |
return deserialized; | |
} | |
catch (JsonException ex) | |
{ | |
return UnsupportedValue.Instance; | |
} | |
} | |
public override void Write(Utf8JsonWriter writer, Either<UnsupportedValue, T> value, JsonSerializerOptions options) | |
{ | |
throw new NotImplementedException(); | |
} | |
} | |
public record UnsupportedValue | |
{ | |
public static readonly UnsupportedValue Instance = new UnsupportedValue(); | |
private UnsupportedValue() | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For anyone that uses System.Text.Json to consume a 3rd party API (esp where the API returns enum type values) you might find this converter handy.
Let's say nominally your DTO looks like this:
But what if Google invents a new day like DeepFriday but doesn't tell you about it (or they tell you but you are too busy/forget)?
Well you can define your DTO like this instead for deserializing
You can still get the rest of the information from the DTO, and possibly gracefully handle the unsupported case somehow.
Note - this would mean modifying your code obviously (because now you need to handle both the cases where
Day
is a supportedDayOfWeek
value as well as cases where it's anUnsupportedValue
.