【发布时间】:2022-05-09 19:43:35
【问题描述】:
我正在做一个项目,所有事情都通过 mediatR 管道完成。
为了让事情变得简单,管道是这样的: -> 验证 -> 处理程序
验证层正在使用 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();
}
【问题讨论】:
-
我和你一样,但我已经在 BaseController 中创建了方法 Send 并将这个逻辑放在一个地方。
-
您不会在这里遇到
LoginCommand的属性与页面上的内容不匹配的问题吗?例如,验证器可以找到Name的无效输入,但它实际上应该是Data.Name,因为AbstractValidator<LoginCommand>不知道它是一个子对象,但不支持传入页面模型。我有这个问题。
标签: asp.net-core razor-pages fluentvalidation mediatr