如何在单个Blazor Server项目中实现多域名路由映射到对应专属文件夹
实现方案
Blazor Server 可以通过自定义路由约束+自定义页面路由查找逻辑两步完成需求,具体操作如下:
步骤1:自定义域名路由约束,提取当前请求的域名
首先创建路由约束类,用来获取当前请求的域名,同时过滤允许接入的域名,避免非法域名访问:
public class DomainRouteConstraint : IRouteConstraint { // 允许的域名列表,支持从appsettings.json动态读取 private readonly List<string> _allowedDomains = new() { "www.mydomain1.com", "www.mydomain2.com" }; public bool Match(HttpContext? httpContext, IRouter? route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) { if (httpContext == null) return false; var currentDomain = httpContext.Request.Host.Host.ToLower(); // 将当前域名存入路由参数,后续页面查找时调用 values["CurrentDomain"] = currentDomain; return _allowedDomains.Contains(currentDomain); } }
在 Program.cs 中注册该约束:
builder.Services.AddRouting(options => { options.ConstraintMap.Add("allowedDomain", typeof(DomainRouteConstraint)); });
步骤2:自定义页面路由解析器,按域名匹配对应页面
重写 Blazor 默认的页面查找逻辑,优先匹配当前域名对应文件夹下的页面,匹配失败再查找公共页面:
public class DomainPageRouteProvider : IPageRouteModelConvention { public void Apply(PageRouteModel model) { // 公共页面保留原有路由逻辑,无需修改 if (model.RelativePath.StartsWith("/Pages/Common", StringComparison.OrdinalIgnoreCase)) { return; } // 处理域名专属页面的路由绑定 var pathSegments = model.RelativePath.Split('/'); if (pathSegments.Length >=3 && pathSegments[2].EndsWith(".com", StringComparison.OrdinalIgnoreCase)) { var pageName = Path.GetFileNameWithoutExtension(model.RelativePath); // 给专属页面添加路由,优先级高于公共页面 model.Selectors.Add(new SelectorModel { AttributeRouteModel = new AttributeRouteModel { Template = $"{pageName}", Order = -1 }, EndpointMetadata = { new HttpMethodMetadata(new[] { "GET" }), new DomainRouteConstraint() } }); } } }
在 Program.cs 中注册该路由供应器:
builder.Services.AddRazorPages().AddRazorPagesOptions(options => { options.Conventions.Add(new DomainPageRouteProvider()); });
步骤3:调整页面文件夹结构
按照需求调整 Pages 目录结构即可:
Pages/ ├── mydomain1.com/ │ ├── Page1.razor │ └── Page2.razor ├── mydomain2.com/ │ ├── Page1.razor │ └── Page2.razor ├── CommonPage.razor └── _Host.cshtml
注意:域名专属页面不需要手动加
@page路由属性,公共页面正常添加@page "/CommonPage"即可。
可选优化
如果需要动态新增域名无需修改代码,可以将允许的域名列表配置到 appsettings.json 中,运行时动态读取即可。
内容的提问来源于stack exchange,提问作者Bob5421
相关产品推荐
相关产品推荐

