【问题标题】:Stop all further validation if multiple validation for first field fails如果对第一个字段的多次验证失败,则停止所有进一步的验证
【发布时间】:2020-01-26 19:45:12
【问题描述】:

我正在尝试编写验证字段的规则以进行验证。

首先我想检查Location Idemptynull 还是数据库中的exist,然后仅进一步处理以进行其他验证。

但是,用我使用的代码,只检查empty,如果Location Id在数据库中不存在,它不会停止。

注册模型

public class RegisterModel
{
    public long LocationId {get;set;}
    public long FirstName {get;set;}
    public long LastName {get;set;}

    //...other property to be added
}

我将 JSON 传递给 API:

{
    "FirstName": "John",
    "LocationId": "1234534",
}

数据库中不存在location id:但我得到的响应为:

{
    "Errors": [
        {
            "FieldName": "LastName",
            "Message": "'Last Name' must not be empty."
        },
        {
            "FieldName": "LocationId",
            "Message": "Invalid request."
        }
    ]
}

我正在使用的验证规则:

public class RegisterModelValidator : AbstractValidator<RegisterModel>
{
    private readonly DbContext _context;

    public RegisterModelValidator(DbContext context)
    {
        this._context = context;
        this.CascadeMode = CascadeMode.StopOnFirstFailure;
        RuleFor(req => req.LocationId)
          .NotEmpty().WithMessage("param1 is missing.")
          .Must(IsValidRequest).WithMessage("Invalid request.");

        When(x => x.LocationId != null, () => {

            RuleFor(x => x.FirstName).Cascade(CascadeMode.StopOnFirstFailure).NotNull().NotEmpty();
            RuleFor(x => x.LastName).Cascade(CascadeMode.StopOnFirstFailure).NotNull().NotEmpty();

        });

    }

    private bool IsValidRequest(string req)
    {
        var locationId = long.TryParse(req, out long result) ? result : 0;
        return _context.Locations.Any(x => x.LocationExtId == locationId);
    }

    private bool BeAValidDate(string value)
    {
        DateTime date;
        return DateTime.TryParse(value, out date);
    }
}

在我的情况下,我想要的是如果 location id 丢失或在数据库中不存在,验证应该立即停止,它不应该检查其他字段。

【问题讨论】:

    标签: fluentvalidation asp.net-core-2.2


    【解决方案1】:

    如果你查看文档here,它被称为

    设置级联模式仅适用于同一 RuleFor 链中的验证器。更改级联模式不会影响对 RuleFor 的单独调用。如果您想在另一条规则失败时阻止一条规则运行,您应该改用Dependent Rules(如下)

    那么你能不能像这样使用Dependent Rules

    RuleFor(x => x.FirstName).NotNull().NotEmpty()
              .DependentRules(d => d.RuleFor(req => req.LocationId)
              .NotEmpty().WithMessage("param1 is missing.")
              .Must(IsValidRequest).WithMessage("Invalid request."));
    

    但我看看如果我们这样使用它,我认为应该为多个属性重复它。

    或者更好的选择是使用PreValidate,因为

    首先我想检查位置 ID 是否为空、null 或是否存在于数据库中

    Prevalidate a property

    【讨论】:

    • 我至少有 10 12 个字段要验证!怎么可以在Dependent Rules上使用?
    • @aakash 这就是为什么我提到了一个更好的选择 prevalidation
    • 是的 prevalidation 似乎是一个不错的选择,但是当我尝试实现它时,我卡在了一些地方!
    • @aakash 卡住了吗?
    • 我有三个条件来验证id,即NOT NULLNOT EMPTYID exist in the database。那么,我是否需要使用三个if else 条件来验证id(在预验证中)?并且正如您在关于我的错误有效负载的问题中看到的那样。我还需要添加fieldname。但通过预验证我只能得到错误消息,但无法在返回响应中添加fieldname
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多