简体   繁体   English

FluentValidation验证枚举值

[英]FluentValidation validate Enum value

I have the following model: 我有以下型号:

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

With the following enum: 使用以下枚举:

public enum UpdateIndicator
{
    Original,
    Update,
    Delete
}

And the following Validator: 以下验证者:

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

The code is in a WebAPI that receives data via JSON, deserialize it to an object and then validates, but for some reason I can send whatever I please in the updateIndicator , so long as I don't put in an integer value larger than the max index in the enum (ie 1,2 or 3 works fine, but 7 will generate an error). 代码在WebAPI中,通过JSON接收数据,将其反序列化为对象然后验证,但由于某种原因,我可以在updateIndicator发送任何我喜欢的内容,只要我没有输入大于枚举中的最大索引(即1,2或3工作正常,但7会产生错误)。

How can I get this to validate the input of the data I receive to see if that value is actually in the Enum? 我怎样才能验证我收到的数据的输入,以查看该值是否实际在Enum中?

Try the built-in IsInEnum() 试试内置的IsInEnum()

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

This checks if the provided enum value is within the range of your enum, if not, the validation will fail: 这将检查提供的枚举值是否在枚举范围内,否则验证将失败:

"'updateIndicator' has a range of values which does not include '7'." “'updateIndicator'有一系列不包含'7'的值。”

The problem arises from the fact that the API model builder will convert what is sent to an enum. 问题产生于API模型构建器将转换发送到枚举的内容。 If a value isn't found, it doesn't populate it, and the default value is used (as it would be with any other property data type that isn't populated). 如果未找到值,则不会填充该值,并使用默认值(与未填充的任何其他属性数据类型一样)。

In order to easily tell if the value sent is a valid enum value, you should make your property nullable. 为了便于判断发送的值是否为有效的枚举值,您应该使您的属性可以为空。 That way, if a value isn't able to be parsed, it will be set to null . 这样,如果无法解析值,则将其设置为null If you want to ensure that the property is set, just have your validator not allow null values for it. 如果要确保设置属性,只需让验证程序不允许空值。

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

Without setting the property to null, your model will always have a valid value when you have it. 如果不将该属性设置为null,则在获得该模型时,模型将始终具有有效值。 Alternatively, you could have the first value of your enum be a dummy value, but that would be a code smell. 或者,您可以将枚举的第一个值设为虚拟值,但这可能是代码气味。 A null model property makes far more sense. null模型属性更有意义。

If you want to find out what the actual value that was sent to the API endpoint was, you'll need to look at creating an HTTP Handler , which is beyond the scope of this question. 如果要查找发送到API端点的实际值是什么,则需要查看创建HTTP处理程序 ,这超出了此问题的范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM