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

.NET Core 7模块化单体Web API路由404问题求助

解决方案

一、修复ModuleRoutingConvention.Apply未触发问题

  1. 在入口项目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);
  1. 检查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主机管道,需将模块的端点注册逻辑封装为扩展方法,由入口项目调用:

  1. 在模块项目(如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;
    }
}
  1. 在入口项目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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 06:10:22