How to use enums with EnumMember attribute in FromBody ViewModel in Web API Request?

后端 未结 1 1428
清酒与你
清酒与你 2021-01-20 22:42

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

相关标签:
1条回答
  • 2021-01-20 23:10

    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:

    • Microsoft.AspNetCore.Mvc.NewtonsoftJson
    • Newtonsoft.Json

    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}");
        }
    }
    
    0 讨论(0)
提交回复
热议问题