FluentValidation验证枚举值

Jag*_*SWE 8 c# enums json fluentvalidation asp.net-web-api

我有以下型号:

public class ViewDataItem
{
    public string viewName { get; set; }
    public UpdateIndicator updateIndicator { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

使用以下枚举:

public enum UpdateIndicator
{
    Original,
    Update,
    Delete
}
Run Code Online (Sandbox Code Playgroud)

以下验证者:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我怎样才能验证我收到的数据的输入,以查看该值是否实际在Enum中?

Sta*_*ked 30

试试内置的 IsInEnum()

RuleFor(x => x.updateIndicator).IsInEnum();
Run Code Online (Sandbox Code Playgroud)

这将检查提供的枚举值是否在枚举范围内,否则验证将失败:

"'updateIndicator'有一系列不包含'7'的值."

  • 也许最好手动检查默认值“零”。或者也添加`NotNull()`。 (3认同)

kri*_*gar 8

问题产生于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();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果不将该属性设置为null,则在获得该模型时,模型将始终具有有效值.或者,您可以将枚举的第一个值设为虚拟值,但这可能是代码气味.null模型属性更有意义.

如果要查找发送到API端点的实际值是什么,则需要查看创建HTTP处理程序,这超出了此问题的范围.

  • [Stacked 的答案](/sf/answers/3294348711/) 是正确的方法。最好确保这些值在 Enum 的范围内。 (2认同)