FluentValidation 验证枚举值

FluentValidation validate Enum value

我有以下型号:

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

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

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

问题的起因是 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 端点的实际值是什么,您需要查看创建一个 ,这超出了本文的范围问题。

试试内置的 IsInEnum()

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

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

"'updateIndicator' has a range of values which does not include '7'."