单宿主托管两个同路径ASP.NET Core应用出现端点匹配冲突如何解决
解决方案
你遇到的冲突是因为ASP.NET Core默认MapControllers规则会扫描所有当前宿主引用的程序集中的控制器,两个入口点的宿主实例默认都加载了全部两个项目的控制器,相同路由路径就会触发匹配歧义。下面提供两种适配不同场景的解决方案:
方案1:按程序集过滤控制器(适配你当前多项目拆分的结构)
该方案完全贴合你把第二入口点放在独立项目的设计,仅需修改两个Startup的服务注册逻辑即可生效:
第一步:修改主入口Startup的ConfigureServices
在注册控制器的逻辑中添加程序集过滤,仅加载主项目的控制器:
public void ConfigureServices(IServiceCollection services) { // 其他原有服务注册逻辑... services.AddControllers() .ConfigureApplicationPartManager(apm => { // 清空默认加载的所有应用程序部件 apm.ApplicationParts.Clear(); // 仅添加当前主项目的程序集,只扫描该程序集下的控制器 apm.ApplicationParts.Add(new AssemblyPart(typeof(Startup).Assembly)); }); }
第二步:修改第二入口SecondEndpoint项目Startup的ConfigureServices
同理仅加载当前SecondEndpoint项目的控制器:
public void ConfigureServices(IServiceCollection services) { // 其他原有服务注册逻辑... services.AddControllers() .ConfigureApplicationPartManager(apm => { apm.ApplicationParts.Clear(); // 仅加载SecondEndpoint项目的程序集 apm.ApplicationParts.Add(new AssemblyPart(typeof(Startup).Assembly)); }); }
修改完成后两个宿主实例只会扫描对应程序集内的控制器,不会互相干扰,相同路径的路由不会再出现匹配冲突。
方案2:自定义路由约束(适用于单项目多入口场景)
如果你的两个入口点放在同一个项目中,可以给控制器添加自定义端口约束特性,只有请求端口匹配时才会命中对应控制器:
首先自定义约束特性类:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class PortConstraintAttribute : Attribute, IActionConstraint { private readonly int[] _allowedPorts; public int Order => 0; public PortConstraintAttribute(params int[] allowedPorts) { _allowedPorts = allowedPorts; } public bool Accept(ActionConstraintContext context) { var requestPort = context.RouteContext.HttpContext.Connection.LocalPort; return _allowedPorts.Contains(requestPort); } }
给对应控制器/接口添加特性即可:
// 主项目控制器仅监听默认端口(示例为5000) [PortConstraint(5000)] [ApiController] [Route("[controller]")] public class FruitsController : ControllerBase { // 接口逻辑 } // 第二入口控制器仅监听5500端口 [PortConstraint(5500)] [ApiController] [Route("[controller]")] public class FruitsController : ControllerBase { // 接口逻辑 }
内容的提问来源于stack exchange,提问作者SmnHgr
相关产品推荐
相关产品推荐

