You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET中如何忽略数据注解里枚举类型的大小写敏感

问题描述

我正在开发REST API,POST请求的JSON输入包含多个参数,其中一个是用户语言。

JSON示例:

{
    "userlanguage":"en"
}

我为所有语言创建了Enum类(仅提供英语、印地语作为参考):

public enum Language
{
    EN = 0,
    HI =1
}

验证类使用了EnumDataType和Required数据注解:

public class UserDetails
{
    [Required]
    [EnumDataType(typeof(Language), ErrorMessage = "Invalid Language Supported.")]
    [JsonProperty("userlanguage")]
    public string? UserLanguage { get; set; }
}

我还创建了扩展类来验证任意类模型:

public static class HttpRequestValidationExtension
{
    public static bool IsValid(this object o, out ICollection<ValidationResult> validationResults)
    {
        validationResults = new List<ValidationResult>();
        return Validator.TryValidateObject(o, new ValidationContext(o, null, null), validationResults, true);
    }
}

控制器类中的用法:

UserDetails userDetails= JsonConvert.DeserializeObject<UserDetails>(requestBody);

if (!userDetails.IsValid(validationResults: out var validationResults))
{
    string errorMessage = "Bad Request.";
    int statusCode = 400;
    return DisplayErrorMessage
        (statusCode, 
        string.Join("", validationResults.Select(s => s.ErrorMessage).FirstOrDefault()),
        functionName, 
        string.Join("", validationResults.Select(s => s.MemberNames).FirstOrDefault()));
}

问题:
当传入EN时验证成功,但传入en时验证失败,请问有没有办法忽略大小写?


解决方案

方法1:自定义大小写不敏感的枚举验证属性

创建自定义属性替代默认的EnumDataTypeAttribute,在验证逻辑中忽略大小写:

public class CaseInsensitiveEnumDataTypeAttribute : EnumDataTypeAttribute
{
    public CaseInsensitiveEnumDataTypeAttribute(Type enumType) : base(enumType) { }

    public override bool IsValid(object value)
    {
        if (value == null) return true;
        
        string stringValue = value.ToString();
        return Enum.TryParse(EnumType, stringValue, ignoreCase: true, out _);
    }
}

修改UserDetails类的属性注解:

public class UserDetails
{
    [Required]
    [CaseInsensitiveEnumDataType(typeof(Language), ErrorMessage = "Invalid Language Supported.")]
    [JsonProperty("userlanguage")]
    public string? UserLanguage { get; set; }
}

方法2:反序列化时统一转换大小写

通过自定义JsonConverter,在反序列化阶段将语言参数统一转为大写(或小写),匹配枚举命名:

public class CaseInsensitiveStringConverter : JsonConverter<string>
{
    public override string ReadJson(JsonReader reader, Type objectType, string existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        string value = reader.Value?.ToString();
        return string.IsNullOrEmpty(value) ? value : value.ToUpperInvariant();
    }

    public override void WriteJson(JsonWriter writer, string value, JsonSerializer serializer)
    {
        writer.WriteValue(value);
    }
}

在UserDetails的属性上应用该转换器:

public class UserDetails
{
    [Required]
    [EnumDataType(typeof(Language), ErrorMessage = "Invalid Language Supported.")]
    [JsonProperty("userlanguage")]
    [JsonConverter(typeof(CaseInsensitiveStringConverter))]
    public string? UserLanguage { get; set; }
}

方法3:修改扩展验证方法,加入大小写忽略逻辑

在现有的IsValid扩展方法中,针对枚举类型的字符串属性单独做大小写不敏感校验:

public static class HttpRequestValidationExtension
{
    public static bool IsValid(this object o, out ICollection<ValidationResult> validationResults)
    {
        validationResults = new List<ValidationResult>();
        bool baseValid = Validator.TryValidateObject(o, new ValidationContext(o, null, null), validationResults, true);

        // 额外处理枚举类型的字符串属性,忽略大小写
        var enumProperties = o.GetType().GetProperties()
            .Where(p => p.PropertyType == typeof(string) && 
                        p.GetCustomAttribute<EnumDataTypeAttribute>() != null);

        foreach (var prop in enumProperties)
        {
            string value = prop.GetValue(o) as string;
            if (string.IsNullOrEmpty(value)) continue;

            var enumAttr = prop.GetCustomAttribute<EnumDataTypeAttribute>();
            if (!Enum.TryParse(enumAttr.EnumType, value, ignoreCase: true, out _))
            {
                validationResults.Add(new ValidationResult(enumAttr.ErrorMessage ?? "Invalid enum value.", new[] { prop.Name }));
                baseValid = false;
            }
        }

        return baseValid;
    }
}

内容的提问来源于stack exchange,提问作者PavanKumar GVVS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 04:10:42