Right now, the JsonStringEnumConverter
converter does not support nullable enums.
I think it should.
cc @JeremyKuhne
5.0?
Is there any chance we can make it earlier, if I contribute with a PR? :angel:
Is there any chance we can make it earlier, if I contribute with a PR?
It would be great if you'd like to submit a fix for this against master and we can evaluate whether it makes sense to port it to 3.1 based on risk/complexity and consumer need. Let me know if you need any help with that and definitely ping me on your PR for review whenever you get the chance to work on the fix :)
Can you explain your scenario/use case which is being blocked by the lack of this feature? I also want to try and see if there is a feasible workaround for nullable enums (either via a custom converters or creating your own JsonStringEnumConverter
wrapper).
Thanks for the offer - in that case, perhaps you can help with dotnet/corefx#41344?
We are also blocked from using System.Text.JSON
in our API. We have issues with Swagger since JsonStringEnumConverter
doesn't support nullable enums.
I have the same problem, had to use Newtonsoft because of that.
While this isn't the most elegant solution, it does serve as a workaround until this gets sorted.
public class StringNullableEnumConverter<T> : JsonConverter<T>
{
private readonly Type _underlyingType;
public StringNullableEnumConverter()
{
_underlyingType = Nullable.GetUnderlyingType(typeof(T));
}
public override bool CanConvert(Type typeToConvert)
{
return typeof(T).IsAssignableFrom(typeToConvert);
//return true;
}
public override T Read(ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
string value = reader.GetString();
if (String.IsNullOrEmpty(value)) return default;
try
{
return (T)Enum.Parse(_underlyingType, value);
}
catch (ArgumentException ex)
{
throw new JsonException("Invalid value.", ex);
}
}
public override void Write(Utf8JsonWriter writer,
T value,
JsonSerializerOptions options)
{
writer.WriteStringValue(value?.ToString());
}
}
and you can attach it to your property by decorating it with this
[JsonConverter(typeof(StringNullableEnumConverter<Nullable<MyEnum>>))]
public MyEnum? MyNullableEnum { get; set; }
To slightly improve the performance of the method above, we can remove the try/catch
block with
// for performance, parse with ignoreCase:false first.
if (!Enum.TryParse(_underlyingType, value, ignoreCase: false, out object result) &&
!Enum.TryParse(_underlyingType, value, ignoreCase: true, out result))
{
throw new JsonException($"Unable to convert \"{value}\" to Enum \"{_underlyingType}\".");
}
return (T)result;
the try and catch is a bit expensive for something that can be solved with TryParse
For anyone blocked by this, here's a NuGet package with a converter (JsonStringEnumMemberConverter) we can use ahead of the 5.0 drop: Macross.Json.Extensions
Supports nullable enum types and adds EnumMemberAttribute support.
This is fixed for 5.0 following https://github.com/dotnet/runtime/pull/32006.
Most helpful comment
While this isn't the most elegant solution, it does serve as a workaround until this gets sorted.
and you can attach it to your property by decorating it with this