我有几个ServiceStack请求DTO,它们实现了一个名为IPageable的接口。我有一个验证器,可以验证此接口上的两个属性。我想我最终会为每个请求类型设置一个验证器,但我试图避免在所有这些验证逻辑中复制与IPageable相关的验证逻辑。
public class PageableValidator : AbstractValidator<IPageable>
{
public PageableValidator()
{
RuleFor(req => req.Page)
.GreaterThanOrEqualTo(1);
RuleFor(req => req.PageSize)
.GreaterThanOrEqualTo(1)
.When(req => req.Page > 1);
}
}
我对此有一些想法包括:
看来我不能只使用container.RegisterValidators() 对于所有实现IPageable的请求类型,这是我的 首先想到的。
我可以在所有请求中指定多个<Validator>
属性
定义,以便特定于请求的验证器也运行
作为我的IPageable验证器?
我可以在验证器注册时指定所有类型 实现IPageable,我的IPageable验证器应该运行吗?
我可以为我的特定于请求的验证器编写基类吗? 从我的PageableValidator获取规则并包含/运行它们?
我可以通过继承AbstractValidator<T> where T : IPageable
来做一些工作,但我希望能够以更多面向方面的方式对多个接口进行验证。
答案 0 :(得分:2)
我不知道你问题的答案,但在阅读你的问题之后会想到一些选择。
我不熟悉<Validator>
属性,但就问题2而言,您可以创建一个Filter attribute来运行您的分页验证。这允许您在请求中使用许多属性并设置其优先级。
public class PageableValidator : Attribute, IHasRequestFilter
{
public void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto)
{
if (requestDto is IPageable)
{
var validator = new PageableValidator(); //could use IOC for this
validator.ValidateAndThrow(requestDto as IPageable);
}
}
public IHasRequestFilter Copy()
{
return (IHasRequestFilter)this.MemberwiseClone();
}
public int Priority { get { return -1; //setting to negative value to run it before any other filters} }
}
另一种选择是为分页验证创建一个抽象类。这将需要每个请求的子类,并需要更多的代码和一些重复*。但是,根据您希望如何处理错误消息,您可以移动代码。
public abstract class PagerValidatorBase<T> : AbstractValidator<T>
{
public bool ValidatePage(IPageable instance, int page)
{
if (page >= 1)
return true;
return false;
}
public bool ValidatePageSize(IPageable instance, int pageSize)
{
if (pageSize >= 1 && instance.Page > 1)
return true;
return false;
}
}
public class SomeRequestValidator : PagerValidatorBase<SomeRequest>
{
public SomeRequestValidator()
{
//validation rules for SomeRequest
RuleFor(req => req.Page).Must(ValidatePage);
RuleFor(req => req.PageSize).Must(ValidatePageSize);
}
}