假设我们有一些验证者:
RuleFor(request => request.User)
.NotEmpty()
.Must(Exist);
RuleFor(request => request.Room)
.NotEmpty()
.Must(Exist);
RuleFor(request => request.Room)
.Must(UserMustHavePermissionForThisRoom);
如果可能的话,如何仅在其他两条规则通过而不使用级联行为的情况下执行第三条规则。我在某处读到,我基本上可以验证请求,然后将所有内容放入 ChildRules 或 DependentRules 中,如下所示:
RuleFor(request => request)
.ChildRules((inlineValidator) => {
inlineValidator.RuleFor(request => request.UserId)
.NotEmpty()
.Must(Exist);
inlineValidator.RuleFor(request => request.Room)
.NotEmpty()
.Must(Exist);
})
.DependenRules(() => {
RuleFor(request => request.Room)
.Must(UserMustHavePermissionForThisRoom);
});
这将使验证器按照我需要的方式工作。但这也弄乱了验证消息中的一些占位符(如
PropertyName
),我认为这是因为我基本上从验证请求本身开始,而且我真的不想手动管理每个属性(我的验证器非常大,有一些复杂的验证)。
是否有更好的方法来处理这样的条件验证?
我通常用
When()
来保护条件规则:
RuleFor(request => request.Room)
.Must(UserMustHavePermissionForThisRoom)
.When(UserAndRoomExist);
这需要在
UserAndRoomExist
方法中添加一些看似重复的逻辑,但如果这个逻辑很简单,我就不会太担心重复。您始终可以将该逻辑分离为私有方法,这些方法从其他两个 Exist
方法和 UserAndRoomExist
方法调用。根据参数,您也许可以调用 Exist
中的其他 UserAndRoomExist
方法。
作为替代方案,如果房间或用户不存在,请考虑在
true
中返回 UserMustHavePermissionForThisRoom
。这将隐式依赖于其他正常工作的 Exist
方法。如果其他验证器存在缺陷,则不存在的用户可能会预订不存在的房间,但编写涵盖这些测试用例的单元测试将相当容易。