2

I have just created a customized VirtualPathProvider for my ASP.NET web application. It basically maps all virtual files in "~/Storage" and subdirectories to a directory other than the solution's directory.

Code essentials

    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);
    }

In my case VirtualRootPath = "~/Storage", but that it configurable.

The problem

In IIS Express, when I debug via Visual Studio, the two public methods, required to resolve a virtual path, are not always called.

  • Calling http://localhost:7749/Storage triggers breakpoints on both methods. A 404 error is returned and desired. This is a correct behaviour to me
  • Calling http://localhost:7749/Storage/ExistingFile.txt doesn't trigger debug, and a different 404 error is returned. This is not correct

The difference between the two 404 errors is that when I call for the directory, it's ASP.NET responding (Server error in application '/') but when I call for the file inside that directory, it's IIS 8.0 responding (HTTP Error 404.0 - Not Found).

The question

Why, even if I correctly registered the VirtualPathProvider in my HostingEnvironment, doesn't IIS 8.0 let ASP.NET pipeline handle the HTTP request so it could be resolved correctly?

The workaround

After reading VirtualPathProvider doesn't (quite) work in production on IIS 7.5 I realized it could be a Web.config problem. Judging from the other question, it looks like that IIS handles certain file extensions independently, no matter if ASP.NET maps those to a virtual resource, a controller, or anything else. So, since I was trying to read an XML file (and perhaps not a JPEG), IIS didn't bother ASP.NET.

The workaround has been putting this line in Web.config's system.webServer.handlers section:

<add name="AspNetStaticFileHandler-XML" path="*.xml" verb="*" type="System.Web.StaticFileHandler" />

But this workaround works only for XML files. How to make a permanent fix that works for all files under the storage directory?

Community
  • 1
  • 1
usr-local-ΕΨΗΕΛΩΝ
  • 26,101
  • 30
  • 154
  • 305

1 Answers1

0

You can specify the storage directory as part of the 'path' field in the config, as follows:

<add name="AspNetStaticFileHandler-Storage" path="Storage/*" verb="*" type="System.Web.StaticFileHandler" />
Murray
  • 1,948
  • 1
  • 12
  • 18
  • Although this code may be help to solve the problem, providing additional context regarding _why_ and/or _how_ it answers the question would significantly improve its long-term value. Please [edit] your answer to add some explanation. – Toby Speight Jun 29 '16 at 11:49