DataAnnotations命名空间中的Enum值是否有开箱即用的validation器?

C#枚举值不仅限于其定义中列出的值,还可以存储其基类型的任何值。 如果未定义基本类型而不是Int32或者仅使用int

我正在开发一个WCF服务,需要确信某些枚举有一个值,而不是所有枚举为0的默认值。我从一个unit testing开始,找出[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(() => Validator.ValidateObject(entity, new ValidationContext(entity, null, null))); } } 

它没有,第二次测试不会抛出任何exception。

我的问题是:是否有一个validation器属性来检查提供的值是否在Enum.GetValues

更新 。 确保在我的unit testing中使用ValidateObject(Object, ValidationContext, Boolean)其中last参数等于True而不是ValidateObject(Object, ValidationContext)

.NET4 +中有EnumDataType …

确保在对ValidateObject的调用中设置第3个参数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(() => Validator.ValidateObject(entity, new ValidationContext(entity, null, null), true)); } 

你在寻找的是:

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

[更新+ 1]

开箱即用的validation器执行了很多validation,包括这个validation,称为EnumDataType。 确保将validateAllProperties = true设置为ValidateObject,否则测试将失败。

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

  [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; } } 

…但我想它不是开箱即用的呢?