我创建了一个VirtualPathProvider,允许根据Request.Host移动自定义文件夹中的所有资源,用一个web应用程序管理多个域。
在我的本地机器上,MVC应用程序可以工作,当我发布到Azure时,我得到了一个不清楚的错误(HTTP 503(,我不明白我必须检查什么才能获得更多信息。
这里实现的提供者:
public class PerSiteVirtualPathProvider : VirtualPathProvider
{
private readonly IDictionary<string, string> domainToPath;
public PerSiteVirtualPathProvider(IDictionary<string, string> domainToPath)
{
this.domainToPath = domainToPath;
}
public override bool FileExists(string virtualPath)
{
return base.FileExists(virtualPath) || PerSiteFileExists(virtualPath);
}
public override bool DirectoryExists(string virtualDir)
{
return base.DirectoryExists(virtualDir) || PerSiteFileExists(virtualDir);
}
public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies)
{
if (PerSiteFileExists(virtualPath))
{
var host = HttpContext.Current.Request.Url.Host.ToLower();
return string.Concat(host, "/", virtualPath);
}
return base.GetFileHash(virtualPath, virtualPathDependencies);
}
public override VirtualFile GetFile(string virtualPath)
{
if (PerSiteFileExists(virtualPath))
{
var physicalPath = CombinePath(virtualPath);
return new PhysicalVirtualFile(virtualPath, physicalPath);
}
return base.GetFile(virtualPath);
}
public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)
{
if (PerSiteFileExists(virtualPath))
{
var host = HttpContext.Current.Request.Url.Host.ToLower();
return new CacheDependency(new[] { CombinePath(virtualPath) }, new[] { host });
}
return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
}
private string CombinePath(string virtualPath)
{
var host = HttpContext.Current.Request.Url.Host.ToLower();
var cleanVirtualPath = virtualPath.TrimStart('~', '/').Replace('/', '\');
if (!domainToPath.ContainsKey(host))
{
throw new InvalidOperationException(string.Format("The specified '{0} domain is not registered.", host));
}
var domainFolder = domainToPath[host];
var path = Path.Combine(domainFolder, cleanVirtualPath);
return path;
}
private bool PerSiteFileExists(string virtualPath)
{
var path = CombinePath(virtualPath);
var fileExists = File.Exists(path);
return fileExists;
}
}
我解决了这个问题,我使用App_Data目录读取了所有资源,这是VirtualPathProvider不允许的,请参阅此处,特别是在备注段中:
不能在虚拟文件系统中存储ASP.NET应用程序文件夹或生成应用程序级程序集的文件。这包括:
- Global.asax文件
- Web.config文件
- XmlSiteMapProvider使用的站点地图数据文件
- 包含应用程序集或生成应用程序集:Bin、App_Code、App_GlobalResources、任何App_LocalResources
- 应用程序数据文件夹App_data