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

如何实现基于主机的动态UseStaticFiles静态文件目录映射?

动态主机映射独立静态文件目录的解决方案

针对原方案需要预配置主机列表、修改配置才能生效的问题,下面提供一种无需配置、运行时动态生效的实现方式——核心思路是根据当前请求的主机名自动映射到对应目录,新增主机只需创建物理目录即可。

实现步骤

1. 注册HttpContext访问服务

首先在项目启动时注册IHttpContextAccessor,用于在文件提供程序中获取当前请求的主机信息:

builder.Services.AddHttpContextAccessor();

2. 实现动态主机文件提供程序

自定义IFileProvider,根据当前请求的主机名动态指向对应的静态文件目录:

public class DynamicHostFileProvider : IFileProvider
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly string _contentRootPath;
    private const string StaticDir = "res";

    public DynamicHostFileProvider(IHttpContextAccessor httpContextAccessor, string contentRootPath)
    {
        _httpContextAccessor = httpContextAccessor;
        _contentRootPath = contentRootPath;
    }

    public IDirectoryContents GetDirectoryContents(string subpath)
    {
        var host = _httpContextAccessor.HttpContext?.Request.Host.Host;
        if (string.IsNullOrWhiteSpace(host))
            return new NotFoundDirectoryContents();

        var dirPath = Path.Combine(_contentRootPath, host, StaticDir, subpath.TrimStart('/'));
        return Directory.Exists(dirPath) 
            ? new PhysicalDirectoryContents(dirPath) 
            : new NotFoundDirectoryContents();
    }

    public IFileInfo GetFileInfo(string subpath)
    {
        var host = _httpContextAccessor.HttpContext?.Request.Host.Host;
        if (string.IsNullOrWhiteSpace(host))
            return new NotFoundFileInfo(subpath);

        var filePath = Path.Combine(_contentRootPath, host, StaticDir, subpath.TrimStart('/'));
        var fileInfo = new FileInfo(filePath);
        return fileInfo.Exists ? new PhysicalFileInfo(fileInfo) : new NotFoundFileInfo(subpath);
    }

    public IChangeToken Watch(string filter)
    {
        var host = _httpContextAccessor.HttpContext?.Request.Host.Host;
        if (string.IsNullOrWhiteSpace(host))
            return NullChangeToken.Singleton;

        var watchPath = Path.Combine(_contentRootPath, host, StaticDir, filter.TrimStart('/'));
        return new PhysicalFilesWatcher(
            Path.GetDirectoryName(watchPath),
            new FileSystemWatcher(Path.GetDirectoryName(watchPath), Path.GetFileName(watchPath)),
            recursive: true
        ).CreateChangeToken();
    }
}

3. 配置静态文件中间件

在中间件配置中,使用自定义的文件提供程序替换原有的固定路径配置:

var httpContextAccessor = app.Services.GetRequiredService<IHttpContextAccessor>();

app.UseStaticFiles(new StaticFileOptions
{
    RequestPath = "/res",
    FileProvider = new DynamicHostFileProvider(httpContextAccessor, builder.Environment.ContentRootPath)
});

方案优势

  • 无需修改配置文件:新增主机时仅需在项目根目录下创建[主机名]/res目录即可,无需重启服务
  • 复用官方中间件能力:自动处理内容类型识别、缓存策略、范围请求等特性,无需自行实现
  • 动态生效:请求会实时匹配对应的主机目录,目录创建后立即生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 07:20:07