.NET Core 7模块化单体Web API路由404问题求助
解决方案
一、修复ModuleRoutingConvention.Apply未触发问题
- 在入口项目
EntryPoint.Core的Program.cs中,确保将自定义路由约定添加到Mvc配置,并扫描所有模块的控制器程序集:
builder.Services.AddControllers(options => { // 注册自定义路由约定 options.Conventions.Add(new ModuleRoutingConvention()); }) // 逐个添加模块的程序集,让Mvc能扫描到模块内的控制器 .AddApplicationPart(typeof(Modules.Authenticate.Core.Controllers.AuthenticateController).Assembly) .AddApplicationPart(typeof(Modules.ProductCatalog.Core.Controllers.ProductController).Assembly);
- 检查
ModuleRoutingConvention的实现,确保它正确继承IApplicationModelConvention并处理路由前缀:
public class ModuleRoutingConvention : IApplicationModelConvention { public void Apply(ApplicationModel application) { foreach (var controller in application.Controllers) { // 从命名空间提取模块名,比如命名空间为Modules.Authenticate.Core时取Authenticate var moduleName = controller.ControllerType.Namespace?.Split('.')[1]; if (!string.IsNullOrEmpty(moduleName)) { // 给控制器路由添加模块前缀 var existingTemplate = controller.Selectors[0].AttributeRouteModel?.Template ?? string.Empty; controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel { Template = $"Api/{moduleName}/{existingTemplate}" }; } } } }
注意:如果模块控制器已通过[Route]特性定义路由,需调整约定逻辑避免冲突。
二、解决模块内endpoints.MapPost路由无法访问问题
模块内直接调用endpoints.MapPost无效,因为模块没有独立的Web主机管道,需将模块的端点注册逻辑封装为扩展方法,由入口项目调用:
- 在模块项目(如
Modules.Authenticate.Core)中创建端点扩展类:
public static class AuthenticateModuleEndpoints { public static IEndpointRouteBuilder MapAuthenticateEndpoints(this IEndpointRouteBuilder endpoints) { endpoints.MapPost("/Api/Authenticate/CreateToken", async context => { // 这里写你的Token创建逻辑 await context.Response.WriteAsJsonAsync(new { Token = "sample-jwt-token" }); }); return endpoints; } }
- 在入口项目
EntryPoint.Core的Program.cs中,调用模块的端点扩展方法:
var app = builder.Build(); // 中间件配置(Swagger、授权等) app.UseSwagger(); app.UseSwaggerUI(); app.UseRouting(); app.UseAuthorization(); // 先注册控制器路由 app.MapControllers(); // 注册模块的自定义端点 app.MapAuthenticateEndpoints(); // 其他模块同理添加 // app.MapProductCatalogEndpoints(); app.Run();
三、验证Swagger与路由一致性
确保Swagger能识别自定义端点,需在入口项目的Swagger配置中扫描模块程序集,并给自定义端点添加元数据:
builder.Services.AddSwaggerGen(options => { // 加载模块的XML注释文件(如果已生成) var authXmlPath = Path.Combine(AppContext.BaseDirectory, $"{typeof(AuthenticateModuleEndpoints).Assembly.GetName().Name}.xml"); options.IncludeXmlComments(authXmlPath); options.SwaggerDoc("v1", new OpenApiInfo { Title = "模块化Web API", Version = "v1" }); });
测试时需确认请求URL与MapPost定义的完全一致(包括大小写、参数格式)。
四、常见排查点
- 确保模块项目已被入口项目引用,程序集能被正常加载
- 检查
ModuleRoutingConvention是否被正确添加到MvcOptions.Conventions,不要遗漏注册代码 - 避免自定义端点路由与控制器路由冲突,可通过调整路由模板或设置路由优先级解决
内容的提问来源于stack exchange,提问作者jstuardo
相关产品推荐
相关产品推荐

