首页 > 解决方案 > 如何使用数据注释在 C# 中处理枚举并使用 XUnit 对其进行测试

问题描述

我想限制我的 DTO 的值。

我有几个月的枚举:

public enum Month
{
    January,
    February,
    March,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December
}

现在在我的 DTO 中,我有:

public class MyDTO {
    public Month Month{ get; set; }
}

我需要使用数据注释才能仅接受 From MarchtoOctober并对其进行测试。与https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-dotnet-testXunit _

[Fact]
public void valid DTO_Months_ok()
{
    var dto = MyDTO()
    {
        Month = Month.March
    }
    var result = dto.validate();
    Assert.Equal(0, result.Count);
}

并检查错误

[Fact]
public void valid DTO_Months_Error()
{
    var dto = MyDTO()
    {
        Month = Month.February
    }
    var result = dto.validate();
    Assert.Equal(1, result.Count);
}

我的问题是 DataAnnotation。

如何将 DataAnnotation 与 Enum 一起使用?

标签: c#enumsdata-annotationsxunit

解决方案


这看起来有点“hacky”恕我直言。DataAnnotations 是应用于类属性的规则,以防止输入无效值。这确认该值将始终有效。通常它应用于“太大”和“可以输入的值不同”的值。例如[StringLength(50, MinimumLength = 3)],您限制 a 的长度string

在 enum 的情况下:您不想使用其他值然后 from Marchto October,那么为什么将它们保留在 enum 本身中呢?从问题来看,您似乎只想拥有这些值,因此它是有意义的:

public enum RestrictedMonth
{
    March,
    May,
    June,
    July,
    August,
    September,
    October,
}

无论如何,如果这对您来说还不够,您可以使用参数将自定义数据注释定义为数组

public class EnumInRangeAttribute : ValidationAttribute
{
    public Month[] ValidMonths { get; set; }

    public EnumInRangeAttribute()
    {
        ValidMonths = new Month[0];
    }

    public EnumInRangeAttribute(params Month[] ValidMonths)
    {
        this.ValidMonths = ValidMonths;
    }

    public override bool IsValid(object value)
    {
        if (value is Month monthValue)
        {
            return ValidMonths.Contains(monthValue);
        }
        return true;
    }
}

public class MyDTO {
    [EnumInRange(Month.March,
        Month.May,
        Month.June,
        Month.July,
        Month.August,
        Month.September,
        Month.October)]
    public Month Month { get; set; }
}

推荐阅读