在DataAnnotations命名空间中是否有现成的枚举值验证器

本文关键字:枚举 验证 命名空间 DataAnnotations 是否 | 更新日期: 2023-09-27 17:53:51

c#枚举值不仅限于其定义中列出的值,而且可以存储其基类型的任何值。如果没有定义基类型,则使用Int32或仅使用int

我正在开发一个WCF服务,该服务需要确信某些枚举具有分配的值,而不是所有枚举的默认值为0。我从一个单元测试开始,看看[Required]是否会在这里做正确的工作。

using System.ComponentModel.DataAnnotations;
using Xunit;
public enum MyEnum
{
    // I always start from 1 in order to distinct first value from the default value
    First = 1,
    Second,
}
public class Entity
{
    [Required]
    public MyEnum EnumValue { get; set; }
}
public class EntityValidationTests
{
    [Fact]
    public void TestValidEnumValue()
    {
        Entity entity = new Entity { EnumValue = MyEnum.First };
        Validator.ValidateObject(entity, new ValidationContext(entity, null, null));
    }
    [Fact]
    public void TestInvalidEnumValue()
    {
        Entity entity = new Entity { EnumValue = (MyEnum)(-126) };
        // -126 is stored in the entity.EnumValue property
        Assert.Throws<ValidationException>(() =>
            Validator.ValidateObject(entity, new ValidationContext(entity, null, null)));
    }
}

没有,第二个测试没有抛出任何异常。

我的问题是:是否有验证器属性来检查提供的值是否在Enum.GetValues中?

。确保使用最后一个参数等于TrueValidateObject(Object, ValidationContext, Boolean),而不是像我在单元测试中那样使用ValidateObject(Object, ValidationContext)

在DataAnnotations命名空间中是否有现成的枚举值验证器

有EnumDataType在. net +…

确保在调用ValidateObject时设置了第三个参数validateAllProperties=true

所以从你的例子:

public class Entity
{
    [EnumDataType(typeof(MyEnum))]
    public MyEnum EnumValue { get; set; }
}
[Fact]
public void TestInvalidEnumValue()
{
    Entity entity = new Entity { EnumValue = (MyEnum)(-126) };
    // -126 is stored in the entity.EnumValue property
    Assert.Throws<ValidationException>(() =>
        Validator.ValidateObject(entity, new ValidationContext(entity, null, null), true));
}

你要找的是:

 Enum.IsDefined(typeof(MyEnum), entity.EnumValue)

[更新+ 1]

这个开箱即用的验证器做了很多验证包括这个叫做EnumDataType。确保您将validateAllProperties=true设置为ValidateObject,否则您的测试将失败。

如果只是想检查枚举是否定义,可以使用上面一行的自定义验证器:

    [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = false)]
    public sealed class EnumValidateExistsAttribute : DataTypeAttribute
    {
        public EnumValidateExistsAttribute(Type enumType)
            : base("Enumeration")
        {
            this.EnumType = enumType;
        }
        public override bool IsValid(object value)
        {
            if (this.EnumType == null)
            {
                throw new InvalidOperationException("Type cannot be null");
            }
            if (!this.EnumType.IsEnum)
            {
                throw new InvalidOperationException("Type must be an enum");
            }
            if (!Enum.IsDefined(EnumType, value))
            {
                return false;
            }
            return true;
        }
        public Type EnumType
        {
            get;
            set;
        }
    }

…但我想它还没有开箱即用,对吧?

我简单地基于这个网站https://kristinaalberto.com/making-enum-parameters-required-in-asp-net-core-mvc/解决了我的需求

    public enum CreatedBySelfOrOthersEnumValues
    {
        Self,
        Others
    }
  
    public class CampaignRegisterValidationModel
    {
        [Required]
        public string Name { get; set; }
        [Required]
        public CreatedBySelfOrOthersEnumValues CreatedForSelfOrOthers { get; set; }
        [Required]
        public int CountryCode { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
    }

然后验证

     if (ModelState.IsValid)
     {
     }