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

ASP.NET Core MVC多客户域名路由与品牌定制方案咨询

ASP.NET Core MVC 独立域名多租户品牌定制实现方案

不需要修改默认路由规则,核心实现分三块:域名维度租户识别、带优先级的视图查找、差异化静态资源加载,具体实现如下:

1. 域名维度租户识别

保留默认路由模板{controller=Home}/{action=Index}/{id?}完全不动,通过中间件从请求Host头提取当前访问的客户标识,存入请求上下文供后续链路使用。

  • 实现租户解析中间件
public class TenantResolverMiddleware
{
    private readonly RequestDelegate _next;
    // 实际使用时可把映射关系迁移到配置文件/数据库,支持动态新增客户
    private readonly Dictionary<string, string> _tenantMap = new()
    {
        ["www.customer01.com"] = "Customer01",
        ["www.customer02.com"] = "Customer02",
        ["localhost"] = "Default"
    };

    public TenantResolverMiddleware(RequestDelegate next) => _next = next;

    public async Task InvokeAsync(HttpContext context)
    {
        var host = context.Request.Host.Host.ToLower();
        var tenant = _tenantMap.TryGetValue(host, out var t) ? t : "Default";
        context.Items["CurrentTenant"] = tenant;
        await _next(context);
    }
}

public static class TenantResolverExtension
{
    public static IApplicationBuilder UseTenantResolver(this IApplicationBuilder app)
        => app.UseMiddleware<TenantResolverMiddleware>();
}
  • 注册中间件,注意要放在app.UseRouting()之前:
// Program.cs
var app = builder.Build();
// ... 其他异常处理、HSTS等中间件
app.UseTenantResolver(); // 加在路由中间件之前
app.UseRouting();
// ... 后续授权、路由映射等中间件

2. 带自动回退的视图查找逻辑

自定义视图位置扩展器,让MVC查找视图时优先匹配当前客户的专属视图,找不到时自动回退到默认视图。

  • 实现视图位置扩展器
public class BrandedViewExpander : IViewLocationExpander
{
    public void PopulateValues(ViewLocationExpanderContext context)
    {
        // 写入租户标识做缓存隔离,避免不同租户视图缓存串用
        var tenant = context.ActionContext.HttpContext.Items["CurrentTenant"] as string ?? "Default";
        context.Values["Tenant"] = tenant;
    }

    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
    {
        var tenant = context.Values["Tenant"];
        if (tenant != "Default")
        {
            // 优先查找租户专属视图目录
            yield return $"/Views/Branded/{tenant}/{{1}}/{{0}}.cshtml";
            yield return $"/Views/Branded/{tenant}/Shared/{{0}}.cshtml";
        }
        // 最后返回默认视图路径,专属视图不存在时自动加载默认视图
        foreach (var loc in viewLocations)
        {
            yield return loc;
        }
    }
}
  • 注册扩展器到MVC视图配置:
// Program.cs 服务注册部分
builder.Services.AddControllersWithViews()
    .AddRazorOptions(opt =>
    {
        opt.ViewLocationExpanders.Add(new BrandedViewExpander());
    });
  • 目录结构参考:
    • 默认视图保持原有路径:/Views/Home/Index.cshtml,作为所有客户的回退版本
    • 客户专属视图按租户名分目录存放:比如Customer01的首页视图放在/Views/Branded/Customer01/Home/Index.cshtml,存在该文件时优先加载,不存在自动回退到默认首页
    • 客户专属的布局页、部分视图可以放在对应租户的Shared目录下

3. 差异化CSS等静态资源加载

直接在全局布局页_Layout.cshtml中读取当前租户标识,动态加载对应客户的专属CSS即可:

@{
    var currentTenant = Context.Items["CurrentTenant"] as string ?? "Default";
}
<!-- 先加载通用基础CSS -->
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<!-- 非默认租户加载专属CSS -->
@if (currentTenant != "Default")
{
    <link rel="stylesheet" href="~/css/branded/@currentTenant/site.css" asp-append-version="true" />
}

静态文件按目录存放到wwwroot下即可,比如Customer01的专属CSS放在/wwwroot/css/branded/Customer01/site.css,不需要额外修改静态文件中间件配置。如果需要静态文件也支持自动回退(专属CSS不存在时返回默认CSS),可以补充自定义静态文件提供者,常规场景下按租户判断输出标签即可满足需求。

补充说明

  • 本地测试多域名场景时,修改本机hosts文件把测试客户域名指向127.0.0.1即可,不需要额外部署
  • 租户和域名的映射关系建议存在数据库或配置中心,新增客户时不需要重新发布代码
  • 视图查找逻辑自带缓存隔离,不会出现不同客户视图串号的问题

内容的提问来源于stack exchange,提问作者Bobbler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 13:15:40