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

ASP.NET Core MVC中如何基于子域名配置数据源并实现全局检测?

ASP.NET Core MVC 根据子域名切换数据源实现方案

核心步骤

1. 解析请求的子域名

从请求Host中提取子域名,根据你的主域名结构调整解析逻辑:

private string ExtractSubDomain(HttpContext context)
{
    var host = context.Request.Host.Host;
    if (string.IsNullOrWhiteSpace(host)) return "default";

    var domainParts = host.Split('.');
    // 针对 mywebapp.com 主域名,提取第一个子域部分
    if (domainParts.Length >= 3 
        && domainParts[^2].Equals("mywebapp", StringComparison.OrdinalIgnoreCase)
        && domainParts[^1].Equals("com", StringComparison.OrdinalIgnoreCase))
    {
        return domainParts[0];
    }
    // 本地环境或不符合规则的域名返回默认值
    return "default";
}

2. 全局拦截请求(中间件实现)

用自定义中间件捕获所有请求,将子域名存入HttpContext.Items,供后续流程使用:

public class SubDomainMiddleware
{
    private readonly RequestDelegate _next;

    public SubDomainMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var subDomain = ExtractSubDomain(context);
        context.Items["CurrentSubDomain"] = subDomain;

        // 可在此提前初始化数据源配置,比如设置全局表前缀
        await _next(context);
    }

    private string ExtractSubDomain(HttpContext context)
    {
        var host = context.Request.Host.Host;
        if (string.IsNullOrWhiteSpace(host)) return "default";

        var domainParts = host.Split('.');
        if (domainParts.Length >= 3 
            && domainParts[^2].Equals("mywebapp", StringComparison.OrdinalIgnoreCase)
            && domainParts[^1].Equals("com", StringComparison.OrdinalIgnoreCase))
        {
            return domainParts[0];
        }
        return "default";
    }
}

// 扩展方法简化中间件注册
public static class SubDomainMiddlewareExtensions
{
    public static IApplicationBuilder UseSubDomainResolver(this IApplicationBuilder app)
    {
        return app.UseMiddleware<SubDomainMiddleware>();
    }
}

在Program.cs中注册中间件(需放在路由中间件之前):

var app = builder.Build();

// 注册子域名解析中间件
app.UseSubDomainResolver();

// 其他中间件配置
app.UseRouting();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

3. 控制器基类统一处理(可选)

让所有业务控制器继承自定义基类,在基类中获取子域名,供Action使用:

public class BaseController : Controller
{
    protected string CurrentSubDomain { get; private set; } = "default";

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (context.HttpContext.Items.TryGetValue("CurrentSubDomain", out var subDomainObj))
        {
            CurrentSubDomain = subDomainObj as string ?? "default";
        }
        base.OnActionExecuting(context);
    }
}

// 业务控制器继承基类
public class HomeController : BaseController
{
    private readonly MyDataRepository _repo;

    public HomeController(MyDataRepository repo)
    {
        _repo = repo;
    }

    public async Task<IActionResult> Index()
    {
        // 直接使用基类的CurrentSubDomain,或通过Repository获取
        var data = await _repo.GetDataAsync();
        return View(data);
    }
}

4. 动态切换数据源/数据表

在数据访问层,通过IHttpContextAccessor获取子域名,动态构造表名或切换数据源:

public class MyDataRepository
{
    private readonly string _subDomain;

    public MyDataRepository(IHttpContextAccessor httpContextAccessor)
    {
        _subDomain = httpContextAccessor.HttpContext?.Items["CurrentSubDomain"] as string ?? "default";
    }

    public async Task<List<MyDataModel>> GetDataAsync()
    {
        // 根据子域名构造专属表名,例如 site1_MyData
        var targetTable = $"{_subDomain}_MyData";
        
        // EF Core 示例:动态指定表查询
        using var dbContext = new MyDbContext();
        return await dbContext.Set<MyDataModel>()
                              .FromSqlRaw($"SELECT * FROM {targetTable}")
                              .ToListAsync();
    }
}

别忘了在Program.cs中注册IHttpContextAccessor:

builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped<MyDataRepository>();

注意事项

  • 子域名解析逻辑需根据实际域名结构调整,比如多层级域名、不同后缀等
  • 动态拼接SQL存在注入风险,建议使用参数化查询或EF Core的动态表映射方案
  • 可添加子域名白名单校验,防止非法子域名访问

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:17:38