You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于CQRS+洋葱架构的.NET项目FluentValidation集成配置困惑

.NET CQRS+洋葱架构下集成FluentValidation的正确配置指导

问题概述

在CQRS+洋葱架构的.NET项目中,需要通过过滤器集成FluentValidation:

  • 应用层已实现CreateBookValidator(对应VM_Create_Book的验证规则)
  • 基础设施层实现了ValidationFilter用于捕获验证错误并返回标准化响应
  • 原写法中AddFluentValidation()已被弃用,现有服务注册配置混乱,需要梳理优化

配置修正步骤

1. 统一应用层的服务注册(符合洋葱架构职责)

将FluentValidation的核心注册逻辑移至应用层的ServiceRegistiration类,保持分层职责清晰:

public static class ServiceRegistiration
{
    public static void AddApplicationService(this IServiceCollection collection)
    {
        collection.AddMediatR(typeof(ServiceRegistiration));
        
        // 注册FluentValidation自动验证机制
        collection.AddFluentValidationAutoValidation();
        // 注册客户端验证适配器(如需支持前端验证)
        collection.AddFluentValidationClientsideAdapters();
        // 自动扫描应用层所有验证器,无需手动逐个注册
        collection.AddValidatorsFromAssemblyContaining<CreateBookValidator>();
        
        collection.AddHttpClient();
    }
}

说明:

  • AddValidatorsFromAssemblyContaining<CreateBookValidator>()会自动扫描并注册该程序集下所有继承AbstractValidator<T>的验证器,替代手动的AddScoped<IValidator<VM_Create_Book>, CreateBookValidator>(),减少重复代码
  • 应用层负责自身依赖(包括验证器)的注册,符合洋葱架构"内层不依赖外层"的原则

2. 简化Program.cs配置

移除Program.cs中重复的FluentValidation注册代码,仅保留控制器和过滤器配置:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddPersistenceServices();
builder.Services.AddApplicationService();

// 注册控制器并添加自定义验证过滤器
builder.Services.AddControllers(options =>
{
    options.Filters.Add<ValidationFilter>();
});

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.MapControllers();
app.Run();

3. 验证现有ValidationFilter的有效性

你的ValidationFilter逻辑无需修改:FluentValidationAutoValidation会自动执行验证规则,并将错误写入ModelState,过滤器只需在ModelState无效时返回标准化的BadRequest响应即可:

public class ValidationFilter:IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        if (!context.ModelState.IsValid)
        {
            var errors = context.ModelState
                .Where(x => x.Value.Errors.Any())
                .ToDictionary(e => e.Key, e => e.Value.Errors.Select(e => e.ErrorMessage))
                .ToArray();

            context.Result = new BadRequestObjectResult(errors);
            return;
        }

        await next();
    }
}

关键注意事项

  • 确保CreateBookValidator正确继承AbstractValidator<VM_Create_Book>,示例:
    public class CreateBookValidator : AbstractValidator<VM_Create_Book>
    {
        public CreateBookValidator()
        {
            RuleFor(x => x.Title).NotEmpty().MaximumLength(100);
            RuleFor(x => x.Price).GreaterThan(0);
            // 其他业务验证规则
        }
    }
    
  • 基础设施层的ValidationFilter属于表现层/基础设施层范畴,符合洋葱架构分层逻辑,无需调整位置
  • 避免重复注册验证器(手动单个注册和自动扫描二选一),防止服务注入冲突

内容的提问来源于stack exchange,提问作者mixail sakaşvil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 09:43:28