I\'m trying to implement an HttpPost method in an ASP.NET Core Web API project with a [FromBody]
view model and enums. In the past, binding view models with the
The code from the question that I posted is indeed valid. In my minimal sample, I forgot to set the [Required]
attribute on the enum. However, then I had the problem how the method should react if then value is not set. It correctly(?) assumed the default value of the enum which is not what I wanted.
I searched around and found this solution https://stackoverflow.com/a/54206737/225808 The enum is nullable which is not ideal but at least I have the validation and I get an error message if the value is missing
Update/Warning: You can use the solution referenced above, but! It seems that the code will compile but instead throws the error message from question. I further compared my own project with the test project and noticed that I also needed two include 2 NuGet packages in order to make everything work:
It seems that Microsoft.AspNetCore.Mvc.NewtonsoftJson overrides from default behavior? If someone can shed some light on this, I'd glady appreciate it.
Update 2: I also updated the referenced so solution to parse the enum value based on the EnumMemberAttribute:
[JsonConverter(typeof(CustomStringToEnumConverter<WeatherEnum>))]
public enum WeatherEnum
{
[EnumMember(Value = "123good")]
Good,
[EnumMember(Value = "bad")]
Bad
}
public class CustomStringToEnumConverter<T> : StringEnumConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (string.IsNullOrEmpty(reader.Value?.ToString()))
{
return null;
}
try
{
return EnumExtensions.GetValueFromEnumMember<T>(reader.Value.ToString());
}
catch (Exception ex)
{
return null;
}
}
}
public static class EnumExtensions
{
public static T GetValueFromEnumMember<T>(string value)
{
var type = typeof(T);
if (!type.IsEnum) throw new InvalidOperationException();
foreach (var field in type.GetFields())
{
var attribute = Attribute.GetCustomAttribute(field,
typeof(EnumMemberAttribute)) as EnumMemberAttribute;
if (attribute != null)
{
if (attribute.Value == value)
return (T)field.GetValue(null);
}
else
{
if (field.Name == value)
return (T)field.GetValue(null);
}
}
throw new ArgumentException($"unknow value: {value}");
}
}