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

.NET 7选项模式下,能否为集合内值添加数据验证注解?

问题描述

在采用选项模式的.NET 7应用中,能否为集合内的元素而非集合本身添加数据注解?我有一个接收枚举值列表的配置,希望添加EnumDataType注解以限制仅允许合法枚举值,但直接将注解添加到List属性上时,验证失败并提示‘The field Days is invalid.’,以下是最小复现示例:

using System.ComponentModel.DataAnnotations;

var c = new MyConfig();
Validator.ValidateObject(c, new ValidationContext(c), true);

class MyConfig
{
    [EnumDataType(typeof(DayOfWeek))]
    public List<DayOfWeek> Days { get; set; } = new() { DayOfWeek.Monday };
}
解决方案

直接给List<T>类型的属性加EnumDataType注解行不通,因为这个注解是用来验证单个值的,无法作用于集合整体。要实现集合元素的枚举验证,有两种实用方法:

方法1:自定义集合验证属性

创建继承自ValidationAttribute的自定义属性,遍历集合元素逐一验证枚举合法性:

using System.ComponentModel.DataAnnotations;
using System.Linq;

class EnumCollectionAttribute : ValidationAttribute
{
    private readonly Type _enumType;

    public EnumCollectionAttribute(Type enumType)
    {
        _enumType = enumType;
        if (!_enumType.IsEnum)
        {
            throw new ArgumentException("指定的类型必须是枚举");
        }
    }

    protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
    {
        if (value is not IEnumerable<object> collection)
        {
            return ValidationResult.Success; // 空值或非集合按需求处理,此处视为有效
        }

        var invalidItems = collection
            .Where(item => !Enum.IsDefined(_enumType, item))
            .ToList();

        if (invalidItems.Any())
        {
            return new ValidationResult($"集合中包含无效的{_enumType.Name}值:{string.Join(", ", invalidItems)}");
        }

        return ValidationResult.Success;
    }
}

在配置类中使用该自定义属性:

class MyConfig
{
    [EnumCollection(typeof(DayOfWeek))]
    public List<DayOfWeek> Days { get; set; } = new() { DayOfWeek.Monday };
}

方法2:实现IValidatableObject手动验证

让配置类实现IValidatableObject接口,在自定义验证逻辑中遍历集合元素逐个校验:

using System.ComponentModel.DataAnnotations;
using System.Linq;

class MyConfig : IValidatableObject
{
    public List<DayOfWeek> Days { get; set; } = new() { DayOfWeek.Monday };

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Days == null) yield break;

        var enumValidator = new EnumDataTypeAttribute(typeof(DayOfWeek));
        foreach (var day in Days)
        {
            var result = enumValidator.GetValidationResult(day, validationContext);
            if (result != ValidationResult.Success)
            {
                yield return new ValidationResult($"Days中的值{day}不是有效的DayOfWeek枚举值", new[] { nameof(Days) });
            }
        }
    }
}

选项模式中启用验证

在.NET 7的选项模式配置中,要确保开启数据注解验证,示例如下:

builder.Services.AddOptions<MyConfig>()
    .Bind(builder.Configuration.GetSection("MyConfig"))
    .ValidateDataAnnotations() // 启用数据注解验证
    .ValidateOnStart(); // 启动时触发验证

通过以上方式,就能实现对集合内每个枚举元素的合法性校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:00:14