2017-07-10 96 views
1

我有以下型号:FluentValidation验证枚举值

public class ViewDataItem 
{ 
    public string viewName { get; set; } 
    public UpdateIndicator updateIndicator { get; set; } 
} 

用下面的枚举:

public enum UpdateIndicator 
{ 
    Original, 
    Update, 
    Delete 
} 

而下面的验证:

public class ViewValidator : AbstractValidator<ViewDataItem> 
{ 
    public ViewValidator() 
    { 
     RuleFor(x => x.viewName).NotEmpty().WithMessage("View name must be specified"); 
     RuleFor(x => x.updateIndicator).SetValidator(new UpdateIndicatorEnumValidator<UpdateIndicator>()); 
    } 
} 

public class UpdateIndicatorEnumValidator<T> : PropertyValidator 
{ 
    public UpdateIndicatorEnumValidator() : base("Invalid update indicator") {} 

    protected override bool IsValid(PropertyValidatorContext context) 
    { 
     UpdateIndicator enumVal = (UpdateIndicator)Enum.Parse(typeof(UpdateIndicator), context.PropertyValue.ToString()); 

     if (!Enum.IsDefined(typeof(UpdateIndicator), enumVal)) 
      return false; 

     return true; 
    } 
} 

的代码是一个的WebAPI通过JSON接收数据,反序列化到一个对象然后验证,但由于某种原因,我可以发送任何我喜欢的updateIndicator,只要我没有放入一个大于枚举中最大索引的整数值(即1,2或3工作正常,但7会产生错误)。

我怎样才能得到这个验证我收到的数据的输入,看看这个值是否真的在Enum中?

+0

您试图查看'viewName'是否是'UpdateIndicator'中的文本值? – krillgar

+0

我想知道发送的文本值是否为“updateIndicator”实际存在于Enum UpdateIndicator中。也就是说,如果有人发送“香蕉”它应该返回一个错误,但如果有人发送“原始”(存在于枚举中)它应该验证就好。 – JaggenSWE

+1

这不会发生。尝试使用无效值从Postman或Fiddler调用您的端点,然后查看会发生什么情况。它会给你枚举的默认值(第一个值)。如果你想防范这种情况,你可以让这个属性为空,但是你的验证不允许空值。 – krillgar

回答

2

由于API模型构建器会将发送到枚举的内容转换为事实,因此出现问题。如果找不到值,则不填充该值,并使用默认值(因为它将与未填充的任何其他属性数据类型一起使用)。

为了容易判断发送的值是否为有效的枚举值,应该使您的属性为空。这样,如果某个值无法解析,它将被设置为null。如果你想确保该属性已设置,只要让你的验证器不允许为它的空值。

public class ViewDataItem 
{ 
    public string viewName { get; set; } 
    public UpdateIndicator? updateIndicator { get; set; } 
} 

public class ViewValidator : AbstractValidator<ViewDataItem> 
{ 
    public ViewValidator() 
    { 
     RuleFor(x => x.viewName).NotEmpty().WithMessage("View name must be specified"); 
     RuleFor(x => x.updateIndicator).NotNull(); 
    } 
} 

没有将该属性设置为null,当您拥有该模型时,您的模型将始终具有有效值。或者,你可以让你的枚举的第一个值是一个虚拟值,但这将是一种代码味道。空模型属性更有意义。

如果您想知道发送给API端点的实际值是多少,则需要查看创建的HTTP Handler,这超出了此问题的范围。

6

尝试内置IsInEnum()

RuleFor(x => x.updateIndicator).IsInEnum(); 

该检查所提供的枚举值是你的枚举的范围内,如果没有,则验证将失败:

“‘updateIndicator’有一系列值不包括'7'。“