2

我有几个实现名为 IPageable 的接口的 ServiceStack 请求 DTO。我有一个验证器,可以验证此接口上的两个属性。我想我最终会为每个请求类型拥有一个验证器,但我试图避免在所有请求中重复与 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);
    }
}

我对此的一些想法包括:

  1. 看来我不能只让 container.RegisterValidators() 将其应用于所有实现 IPageable 的请求类型,但这是我的第一个想法。

  2. 我可以在所有请求定义上指定多个<Validator>属性,以便特定于请求的验证器和我的 IPageable 验证器都运行吗?

  3. 我可以在验证器注册时指定所有实现 IPageable 的类型,我的 IPageable 验证器应该运行吗?

  4. 我可以为特定于请求的验证器编写一个基类,该验证器从我的 PageableValidator 获取规则并包含/运行它们吗?

我可以通过子类化来完成某种工作AbstractValidator<T> where T : IPageable,但我希望能够以更多面向方面的方式对多个接口进行验证。

4

1 回答 1

2

我不知道您的问题的答案,但在阅读您的问题后想到了一些选项。

我不熟悉该<Validator>属性,但关于问题 2,您可以创建一个Filter 属性来运行您的分页验证。这允许您在请求中使用许多属性并设置它们的优先级。

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);
    }
}
  • IMO,重复使代码更加明确(不是坏事)并且没关系,因为它没有重复逻辑。
于 2013-05-28T17:03:57.090 回答