我刚刚为我的 ASP.NET Web 应用程序创建了一个自定义的 VirtualPathProvider。它基本上将“~/Storage”和子目录中的所有虚拟文件映射到解决方案目录以外的目录。
代码要点
private bool IsPathVirtual(string virtualPath)
{
String checkPath = VirtualPathUtility.ToAppRelative(virtualPath);
return checkPath.StartsWith(VirtualRootPath, StringComparison.InvariantCultureIgnoreCase);
}
public override bool DirectoryExists(string virtualDir)
{
return IsPathVirtual(virtualDir) ? ((FileSystemVirtualDirectory)GetDirectory(virtualDir)).Exists() : Previous.DirectoryExists(virtualDir);
}
public override bool FileExists(string virtualPath)
{
return IsPathVirtual(virtualPath) ? ((FileSystemVirtualFile)GetFile(virtualPath)).Exists() : Previous.FileExists(virtualPath);
}
就我而言VirtualRootPath = "~/Storage"
,但它是可配置的。
问题
在 IIS Express 中,当我通过 Visual Studio 进行调试时,解析虚拟路径所需的两个公共方法并不总是被调用。
- 调用
http://localhost:7749/Storage
会在两种方法上触发断点。返回并需要 404 错误。这对我来说是正确的行为 - 调用
http://localhost:7749/Storage/ExistingFile.txt
不会触发调试,并返回不同的 404 错误。这是不正确的
两个 404 错误之间的区别在于,当我调用目录时,它是 ASP.NET 响应 ( Server error in application '/'
),但是当我调用该目录中的文件时,它是 IIS 8.0 响应 ( HTTP Error 404.0 - Not Found
)。
问题
为什么即使我VirtualPathProvider
在我的 中正确注册了HostingEnvironment
IIS 8.0 也不让 ASP.NET 管道处理 HTTP 请求以便正确解析它?
解决方法
在阅读VirtualPathProvider 在 IIS 7.5 上的生产中没有(相当)工作后,我意识到这可能是一个Web.config
问题。从另一个问题来看,IIS似乎独立处理某些文件扩展名,无论 ASP.NET 是否将这些文件扩展名映射到虚拟资源、控制器或其他任何东西。因此,由于我试图读取 XML 文件(可能不是 JPEG),IIS 并没有打扰 ASP.NET。
解决方法是将此行放在Web.config
'ssystem.webServer.handlers
部分:
<add name="AspNetStaticFileHandler-XML" path="*.xml" verb="*" type="System.Web.StaticFileHandler" />
但此解决方法仅适用于 XML 文件。如何对存储目录下的所有文件进行永久修复?