ASPにおけるFluentValidationを用いたモデル検証ネット


良いAPIの要件の一つは、異なるビジネスルールに依存した入力を検証する能力です.開発者として、クライアントから任意のデータを取得するときは常に妥当性検査を気にします.

The Source code used in the article you can find in our GitHub repository.


ASP .ASP . NETには、APIレベルでの入力ペイロードを検証する組み込みのメカニズムがあります.しかし、入力ペイロードをカスタムビジネスルールで検証しようとしているときには制限されます.我々は、ビジネス層内の検証を移動し、入力モデルのカスタム検証を適用できます.この決定を選択すると、我々はコントローラを薄くしている.適切なモデル結合を行い、必要なサービスメソッドを呼び出します.機能テストはそのような振舞いをカバーすることができました、そして、我々はそのような細いコントローラ行動のために単位テストを書く必要はありません.
私たちのカスタム検証規則を書くことができます、新しい検証ツールを発明し、多くのIFSではあまり便利なコードに来る.この場合、FluentValidationは遊びに入ります.

FluentValidation is a library for building strongly-typed validation rules.



ハンズオン
コードにダイビングを始めましょう
public class ApiController : BaseController
{
    private readonly IService _service;

    public TimeEntryController(IService service)
    {
        _service = service;
    }


    [ProducesResponseType(typeof(Response), StatusCodes.Status201Created)]
    [ProducesResponseType(typeof(ExceptionModel), StatusCodes.Status400BadRequest)]
    [HttpPost]
    public async Task<ObjectResult> CreateAsync([FromBody] CreateRequest request)
    {
        var response = await this._service.CreateAsync(request);
        return this.Ok(response);
    }
}
コントローラはきれいで簡単になります.ASP .NETはまだモデルフィールドの妥当性検査を適用しますが、サービスの検証はサービス層で起こります.
public class Service
{
    private readonly IValidationService _validationService;

    public TimeEntryService(IValidationService validationService)
    {
        _validationService = validationService;
    }

    public async Task<Response> CreateAsync(CreateRequest request)
    {
        this._validationService.EnsureValid(request);
        // Implementation
        return new Response();
    }

}
ビジネスロジックの実装を開始する前に最初にしたいことは、入力ペイロードに検証を適用することです.各ペイロードは適切なバリデータを必要とし、入力モデルを検証するために多くのバリデータをサービスに注入する必要がある場合に状況が発生します.このような場合を回避し、モデル検証のみを担当する別のサービスを導入する方が良いでしょう.また、他のサービスからビジネス検証のすべての複雑さを隠します.
public class ValidationService
{
    private readonly IDictionary<Type, Type> _validators;
    private readonly IServiceProvider _serviceProvider;

    public ValidationService(IServiceProvider serviceProvider)
    {
        this._serviceProvider = serviceProvider;
        this._validators = new Dictionary<Type, Type>
        {
            { typeof(CreateRequest), typeof(CreateRequestValidator) },
        };
    }

    private AbstractValidator<T> GetValidator<T>()
    {
        var modelType = typeof(T);
        var hasValidator = this._validators.ContainsKey(modelType);
        if (hasValidator == false)
        {
            throw new Exception("Missing validator");
        }

        var validatorType = this._validators[modelType];
        var validator = _serviceProvider.GetService(validatorType) as AbstractValidator<T>;
        return validator;
    }

    public void EnsureValid<T>(T model)
    {
        var validator = this.GetValidator<T>();
        var result = validator.Validate(model);
        if (result.IsValid == false)
        {
            throw new Exception(result.ToString());
        }
    }
}
検証のための適切な構造を持ち、モデルバリデータを追加する準備ができています.FluentValidationによって、カスタムバリデータの継承の基本クラスAbstractValidatorが表示されます.
public class CreateRequestValidator : AbstractValidator<CreateRequest>
{
    public CreateRequestValidator()
    {
        RuleFor(r => r.Name).Required();
        RuleFor(r => r.Date.ToUniversalTime()).LessThan(DateTime.UtcNow);
    }
}

結論
私たちは、入力要求のための検証を小さなクラスに分けるきれいな方法を得ました.ビジネスルールに依存した複雑なバリデータを書くことができ、バリデータを小さな独立した部分としてテストするのは簡単です.
任意の質問やコメント?LinkedIn上で私をpingするか、下にコメントしてください.そして、もしあなたがこのポストが好きなら、それを拍手し、すべてのお友達と共有してください.
Twitter
リンケディン
より多くの記事を見つけることができます
https://blog.akyltech.com/