C# .Net Fluent验证集执行顺序

C# .Net Fluent验证集执行顺序,c#,.net,validation,C#,.net,Validation,我需要设置验证的执行顺序,以便在第一次失败后停止验证 但是,我想知道还有什么其他方法可以做到这一点 通常我会有这样的东西: public Constructor(){ // Simple validation RuleFor(x => x.Id).NotNull().NotEmpty(); // advanced validation // item must exist in database RuleFor(x => x.Id).Mus

我需要设置验证的执行顺序,以便在第一次失败后停止验证

但是,我想知道还有什么其他方法可以做到这一点

通常我会有这样的东西:

public Constructor(){

    // Simple validation
    RuleFor(x => x.Id).NotNull().NotEmpty();

    // advanced validation
    // item must exist in database
    RuleFor(x => x.Id).Must(ExistsInDatabase);

    // item must exist in database previously
    // item must be some of the allowed names -- fetched from db
    RuleFor(x => x.Id).Must(BeAReferenceInSomeTable);

    private bool ExistsInDatabase(){}

    private bool BeAReferenceInSomeTable(){}

}
public Constructor(){

    CascadeMode = FluentValidation.CascadeMode.StopOnFirstFailure;

    // simple validation stays the same
    ...

    // advanced validation
    RuleFor(x => x.Id)
        .Must(ExistsInDatabase)
        .Must(BeAReferenceInSomeTable)
        .When(x => !string.IsNullOrEmpty(x.Id) &&
                    !string.IsNullOrEmpty(x.Name)
        );  
}
public Constructor(){

    // Simple validation
    RuleFor(x => x.Id).Cascade(CascadeMode.StopOnFirstFailure).NotNull().WithMessage("Must not be null");

    RuleFor(x => x.Id).NotEmpty().WithMessage("Must not be empty");


    // advanced validation
    // item must exist in database
    RuleFor(x => x.Id).Must(ExistsInDatabase).WithMessage("Must exist in database");

    // item must exist in database previously
    // item must be some of the allowed names -- fetched from db
    RuleFor(x => x.Id).Must(BeAReferenceInSomeTable).WithMessage("Must not be referenced");

    private bool ExistsInDatabase(){}

    private bool BeAReferenceInSomeTable(){}
但使用此BearReferenceInSometable可以在现有数据库之前执行。 所以,当表中不存在Id时,BearReferenceInSometable验证将引发异常,而不是因为ExistsInDatabase验证而导致验证失败

首先想到的解决方法是:

public Constructor(){

    // Simple validation
    RuleFor(x => x.Id).NotNull().NotEmpty();

    // advanced validation
    // item must exist in database
    RuleFor(x => x.Id).Must(ExistsInDatabase);

    // item must exist in database previously
    // item must be some of the allowed names -- fetched from db
    RuleFor(x => x.Id).Must(BeAReferenceInSomeTable);

    private bool ExistsInDatabase(){}

    private bool BeAReferenceInSomeTable(){}

}
public Constructor(){

    CascadeMode = FluentValidation.CascadeMode.StopOnFirstFailure;

    // simple validation stays the same
    ...

    // advanced validation
    RuleFor(x => x.Id)
        .Must(ExistsInDatabase)
        .Must(BeAReferenceInSomeTable)
        .When(x => !string.IsNullOrEmpty(x.Id) &&
                    !string.IsNullOrEmpty(x.Name)
        );  
}
public Constructor(){

    // Simple validation
    RuleFor(x => x.Id).Cascade(CascadeMode.StopOnFirstFailure).NotNull().WithMessage("Must not be null");

    RuleFor(x => x.Id).NotEmpty().WithMessage("Must not be empty");


    // advanced validation
    // item must exist in database
    RuleFor(x => x.Id).Must(ExistsInDatabase).WithMessage("Must exist in database");

    // item must exist in database previously
    // item must be some of the allowed names -- fetched from db
    RuleFor(x => x.Id).Must(BeAReferenceInSomeTable).WithMessage("Must not be referenced");

    private bool ExistsInDatabase(){}

    private bool BeAReferenceInSomeTable(){}

但在这种情况下,如何设置propper消息进行验证,因为消息必须在执行之前给出。

请尝试以下操作:

public Constructor(){

    // Simple validation
    RuleFor(x => x.Id).NotNull().NotEmpty();

    // advanced validation
    // item must exist in database
    RuleFor(x => x.Id).Must(ExistsInDatabase);

    // item must exist in database previously
    // item must be some of the allowed names -- fetched from db
    RuleFor(x => x.Id).Must(BeAReferenceInSomeTable);

    private bool ExistsInDatabase(){}

    private bool BeAReferenceInSomeTable(){}

}
public Constructor(){

    CascadeMode = FluentValidation.CascadeMode.StopOnFirstFailure;

    // simple validation stays the same
    ...

    // advanced validation
    RuleFor(x => x.Id)
        .Must(ExistsInDatabase)
        .Must(BeAReferenceInSomeTable)
        .When(x => !string.IsNullOrEmpty(x.Id) &&
                    !string.IsNullOrEmpty(x.Name)
        );  
}
public Constructor(){

    // Simple validation
    RuleFor(x => x.Id).Cascade(CascadeMode.StopOnFirstFailure).NotNull().WithMessage("Must not be null");

    RuleFor(x => x.Id).NotEmpty().WithMessage("Must not be empty");


    // advanced validation
    // item must exist in database
    RuleFor(x => x.Id).Must(ExistsInDatabase).WithMessage("Must exist in database");

    // item must exist in database previously
    // item must be some of the allowed names -- fetched from db
    RuleFor(x => x.Id).Must(BeAReferenceInSomeTable).WithMessage("Must not be referenced");

    private bool ExistsInDatabase(){}

    private bool BeAReferenceInSomeTable(){}
}

并为执行命令链接:

RuleFor(x => x.Id).Cascade(CascadeMode.StopOnFirstFailure)
    .NotNull().WithMessage("Must not be null")
    .NotEmpty().WithMessage("Must not be empty")
    .Must(ExistsInDatabase).WithMessage("Must exist in database")
    .Must(BeAReferenceInSomeTable).WithMessage("Must not be referenced");

试着这样做:

public Constructor(){

    // Simple validation
    RuleFor(x => x.Id).NotNull().NotEmpty();

    // advanced validation
    // item must exist in database
    RuleFor(x => x.Id).Must(ExistsInDatabase);

    // item must exist in database previously
    // item must be some of the allowed names -- fetched from db
    RuleFor(x => x.Id).Must(BeAReferenceInSomeTable);

    private bool ExistsInDatabase(){}

    private bool BeAReferenceInSomeTable(){}

}
public Constructor(){

    CascadeMode = FluentValidation.CascadeMode.StopOnFirstFailure;

    // simple validation stays the same
    ...

    // advanced validation
    RuleFor(x => x.Id)
        .Must(ExistsInDatabase)
        .Must(BeAReferenceInSomeTable)
        .When(x => !string.IsNullOrEmpty(x.Id) &&
                    !string.IsNullOrEmpty(x.Name)
        );  
}
public Constructor(){

    // Simple validation
    RuleFor(x => x.Id).Cascade(CascadeMode.StopOnFirstFailure).NotNull().WithMessage("Must not be null");

    RuleFor(x => x.Id).NotEmpty().WithMessage("Must not be empty");


    // advanced validation
    // item must exist in database
    RuleFor(x => x.Id).Must(ExistsInDatabase).WithMessage("Must exist in database");

    // item must exist in database previously
    // item must be some of the allowed names -- fetched from db
    RuleFor(x => x.Id).Must(BeAReferenceInSomeTable).WithMessage("Must not be referenced");

    private bool ExistsInDatabase(){}

    private bool BeAReferenceInSomeTable(){}
}

并为执行命令链接:

RuleFor(x => x.Id).Cascade(CascadeMode.StopOnFirstFailure)
    .NotNull().WithMessage("Must not be null")
    .NotEmpty().WithMessage("Must not be empty")
    .Must(ExistsInDatabase).WithMessage("Must exist in database")
    .Must(BeAReferenceInSomeTable).WithMessage("Must not be referenced");

您可以使用
.WithMessage(“您的消息”)
为验证失败添加适当的消息,这也适用于链接(这是您在第二个示例中所做的)。是的,但ExistsInDatabase应返回:“Id does note exist in database”,BearReference应返回:“Id未在某些表中引用”。使用WithMessage,只能传递静态预定义字符串。但这并不好,因为我只希望返回一条消息。您可以使用
。WithMessage(“您的消息”)
为验证失败添加适当的消息,这也适用于链接(这是您在第二个示例中所做的)。是的,但ExistsInDatabase应返回:“Id does note exist in database”,BearReference应返回:“Id未在某些表中引用”。使用WithMessage,只能传递静态预定义字符串。但这并不好,因为当您在第一行设置级联模式时,我只希望返回一条消息,它仅用于该链。因此,在没有多个条件的情况下使用它是没有效果的。代码的其余部分将我带到打开主题的同一个问题。您添加的WithMessage将呈现正确的验证错误,但验证可能不会按顺序执行。然后使用链接来实现执行顺序。我扩展了您的示例,确实得到了我需要的,但这会导致冗余操作。你认为有更好的办法吗?我会将您的解决方案标记为正确的解决方案,因为它接近(但不完全)我所需要的。RuleFor(x=>x.Id).Must(ExistsInDatabase).WithMessage(“必须存在于数据库中”).When(x=>x.Id.NotNullOrEmpty())RuleFor(x=>x.Id).Must(BeAReferenceInSomeTable).WithMessage(“不得被引用”).When(x=>x.NotNullOrEmpty()&&ExistsInDatabase(x));正在执行哪些“冗余操作”?对于验证BearReferenceInSometable ExistsInDatabase,在验证之前执行。对于验证ExistsInDatabase,再次执行相同的方法。这不是这个小测试的问题,但它可以在更大的测试中扩展。当您在第一行中设置级联模式时,它仅用于该链。因此,在没有多个条件的情况下使用它是没有效果的。代码的其余部分将我带到打开主题的同一个问题。您添加的WithMessage将呈现正确的验证错误,但验证可能不会按顺序执行。然后使用链接来实现执行顺序。我扩展了您的示例,确实得到了我需要的,但这会导致冗余操作。你认为有更好的办法吗?我会将您的解决方案标记为正确的解决方案,因为它接近(但不完全)我所需要的。RuleFor(x=>x.Id).Must(ExistsInDatabase).WithMessage(“必须存在于数据库中”).When(x=>x.Id.NotNullOrEmpty())RuleFor(x=>x.Id).Must(BeAReferenceInSomeTable).WithMessage(“不得被引用”).When(x=>x.NotNullOrEmpty()&&ExistsInDatabase(x));正在执行哪些“冗余操作”?对于验证BearReferenceInSometable ExistsInDatabase,在验证之前执行。对于验证ExistsInDatabase,再次执行相同的方法。这不是这个小测试的问题,但它可以在更大的测试中扩展。