I am migrating an old .NET 4.8 Web API to .NET 6 and realized an issue with Json conversion. For example, this is an example Web API in .NET 4.8:
public enum SampleEnum
{
Bar,
Baz,
}
public class Jerry
{
public SampleEnum MyEnum { get; set; }
}
public class ValuesController : ApiController
{
// POST api/values
public void Post([FromBody] Jerry value)
{
var a = value;
}
}
If the request is one with clearly wrong value:
{
"MyEnum": "MonthEnd"
}
Above webapi in .net 4.8 will use the default value for the enum (Bar).
For the same code in .net 6 with NewtonJson or Json.Text, it will throw exception saying I can't understand MonthEnd.
.net 6 is the right behaviour as the user passed a wrong value, but my problem is that our webapi is already on production for very long and we can't risk a sudden surge of customer complain.
Is there a way to mimic the .net 4.8's behaviour (i.e. if an enum value can't be understood, we fallback to deafult )?
CodePudding user response:
You can workaround with custom converter. For example something like the following:
class CustomEnumConverter<T> : JsonConverter<T> where T: struct, Enum
{
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (Enum.TryParse<T>(reader.GetString(), out var r))
{
return r;
}
return default;
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) => writer.WriteStringValue(value.ToString("G"));
}
And then mark corresponding property with it:
public class Jerry
{
[JsonConverter(typeof(CustomEnumConverter<SampleEnum>))]
public SampleEnum MyEnum { get; set; }
}
Or if you need to do it globally - create a converter factory which will reuse this converter.