首页 > 解决方案 > MediatR 管道和 Razor 页面中的 FluentValidation

问题描述

我正在做一个项目,所有事情都通过 mediatR 管道完成。

为了让事情变得简单,管道是这样的:->验证->处理程序

Validation 层正在使用 FluentValidation 并在出现问题时抛出 ValidationException。

public class ValidationBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : notnull
{
    private readonly IEnumerable<IValidator<TRequest>> _validators;

    public ValidationBehaviour(IEnumerable<IValidator<TRequest>> validators)
    {
        _validators = validators;
    }

    public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
    {
        if (_validators.Any())
        {
            var context = new ValidationContext<TRequest>(request);

            var validationResults = await Task.WhenAll(_validators.Select(v => v.ValidateAsync(context, cancellationToken)));
            var failures = validationResults.SelectMany(r => r.Errors).Where(f => f != null).ToList();

            if (failures.Count != 0)
                throw new ValidationException(failures);
        }

        return await next();
    }
}

到目前为止一切正常。

现在,我有这样的页面处理程序:

[BindProperty]
public LoginCommand Data { get; set; }

public async Task<IActionResult> OnPostAsync(CancellationToken cancellationToken)
{
    try
    {
        await _mediator.Send(Data, cancellationToken);
        return LocalRedirect("/Index");
    }
    catch (ValidationException ex)
    {
        var res = new ValidationResult(ex.Errors);
        res.AddToModelState(ModelState, nameof(Data));
        return Page();
    }
}

做这样的事情很好,缺点是它为每个页面处理程序编写了大量代码。

有没有办法让这个处理程序看起来像这样:

[BindProperty]
public LoginCommand Data { get; set; }

public async Task<IActionResult> OnPostAsync(CancellationToken cancellationToken)
{
    await _mediator.Send(Data, cancellationToken);
    return LocalRedirect("/Index");
}

并将这部分代码像过滤器/中间件一样无处不在

    try
    {
        // HANDLER CODE
    }
    catch (ValidationException ex)
    {
        var res = new ValidationResult(ex.Errors);
        res.AddToModelState(ModelState, nameof(VIEWMODEL_NAME));
        return Page();
    }

标签: asp.net-corerazor-pagesfluentvalidationmediatr

解决方案


推荐阅读