.NET Core如何处理动态子域名请求并路由至对应控制器
动态子域名请求处理实现方案
ASP.NET Core 原生路由默认不解析域名部分,你需要自定义逻辑提取子域名的租户标识(即示例中的 customer1、customer2),再绑定到路由参数即可实现需求,具体修改如下:
1. 先实现子域名提取路由约束
首先自定义路由约束,用来从请求Host中自动提取子域名部分,存入路由参数:
public class SubdomainRouteConstraint : IRouteConstraint { public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) { if (httpContext == null) return false; var host = httpContext.Request.Host.Host; var hostSegments = host.Split('.'); // 假设你的主域名为两段结构(如 mysite.com),拆分后长度≥3则存在子域名 if (hostSegments.Length >= 3) { var subdomain = hostSegments[0]; values[routeKey] = subdomain; return true; } // 无子域名时可按需设置默认值,不需要匹配的话直接返回false即可 values[routeKey] = "default"; return true; } }
2. 修改 Startup.cs 对应配置
2.1 Startup 构造函数
不需要额外修改,保留基础注入即可,如果需要从配置读取主域名也可以存为类变量:
public IConfiguration Configuration { get; } public IWebHostEnvironment Env { get; } public Startup(IConfiguration configuration, IWebHostEnvironment env) { Configuration = configuration; Env = env; }
2.2 ConfigureServices 方法
注册自定义的路由约束,添加控制器相关服务:
public void ConfigureServices(IServiceCollection services) { // 注册子域名路由约束 services.AddRouting(options => { options.ConstraintMap.Add("subdomain", typeof(SubdomainRouteConstraint)); }); // 原有服务注册保留,比如控制器服务 services.AddControllersWithViews(); }
2.3 Configure 方法
调整端点路由配置,绑定子域名提取规则到customer参数:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 原有中间件保留(异常处理、静态文件、路由、鉴权等) if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { // 新增带子域名约束的路由 endpoints.MapControllerRoute( name: "subdomainRoute", pattern: "{controller}/{action=Index}/{customer?}", constraints: new { customer = new SubdomainRouteConstraint() } ); // 原有默认路由可以保留作为兜底 endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }
3. 控制器接收参数示例
配置完成后即可直接在控制器Action中拿到子域名对应的customer参数:
public class ManageController : Controller { public IActionResult Index(string customer) { // customer的值对应子域名部分,比如customer1、customer2 // 可直接根据该值处理对应租户的业务逻辑 return View(); } }
本地调试注意事项
如果在本地测试,需要先修改系统hosts文件添加测试域名映射:
127.0.0.1 customer1.mysite.com 127.0.0.1 customer2.mysite.com
同时调整程序启动配置,允许监听泛域名,比如在Program.cs中添加UseUrls("http://*.mysite.com:5000")。
内容的提问来源于stack exchange,提问作者Alvin Stefanus
相关产品推荐
相关产品推荐

