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

C#中如何为Enum配置Data Annotation并使用XUnit做验证测试

解决方案

方案1:使用系统自带RangeAttribute(最简实现)

C#枚举默认基于int类型,枚举值按定义顺序自动分配递增整数值,直接用Range注解即可实现范围校验:

using System.ComponentModel.DataAnnotations;

public class MyDTO {
    [Range(typeof(Month), nameof(Month.March), nameof(Month.October), ErrorMessage = "月份仅允许为3月到10月")]
    public Month Month{ get; set; }

    // 对应测试中调用的Validate校验方法
    public List<ValidationResult> Validate()
    {
        var validationResults = new List<ValidationResult>();
        var validationContext = new ValidationContext(this);
        Validator.TryValidateObject(this, validationContext, validationResults, validateAllProperties: true);
        return validationResults;
    }
}

注意:该方案依赖枚举底层整数值的递增顺序,若后续调整枚举定义顺序,需要同步更新校验规则。

方案2:自定义校验特性(更稳妥,不受枚举顺序影响)

如果要避免枚举顺序调整导致校验失效,可以自定义专门的枚举范围校验特性:
首先自定义注解类:

using System.ComponentModel.DataAnnotations;

public class AllowedMonthAttribute : ValidationAttribute
{
    private static readonly Month[] _allowedMonths = new[]
    {
        Month.March, Month.May, Month.June, Month.July, 
        Month.August, Month.September, Month.October
    };

    public override bool IsValid(object? value)
    {
        if (value is Month inputMonth)
        {
            return _allowedMonths.Contains(inputMonth);
        }
        return false;
    }
}

之后在DTO属性上引用该注解即可:

public class MyDTO {
    [AllowedMonth(ErrorMessage = "月份仅允许为3月到10月")]
    public Month Month{ get; set; }

    // 同上的Validate校验方法
    public List<ValidationResult> Validate()
    {
        var validationResults = new List<ValidationResult>();
        var validationContext = new ValidationContext(this);
        Validator.TryValidateObject(this, validationContext, validationResults, validateAllProperties: true);
        return validationResults;
    }
}

测试用例修正(符合XUnit规范)

原测试用例存在语法问题,修正后如下:

// 合法值测试用例
[Fact]
public void ValidDTO_WithAllowedMonth_ReturnsNoErrors()
{
    var dto = new MyDTO()
    {
        Month = Month.March
    };
    var result = dto.Validate();
    Assert.Empty(result);
}

// 非法值测试用例
[Fact]
public void InvalidDTO_WithDisallowedMonth_ReturnsError()
{
    var dto = new MyDTO()
    {
        Month = Month.February
    };
    var result = dto.Validate();
    Assert.Single(result);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 17:57:04