Search code examples
asp.netrazorvirtualpathprovider

Virtual Path Provider to serve Razor Files from External Location - When Razor file changes, any way not to require an app pool restart?


I have a working virtual path provider serving razor files that are being dynamically generated. The problem is that when these razor files change an app pool restart is required. I believe that normally the file monitor handles this for traditional razor files on disk.

How can I flag or expire a razor file served via a virtual file provider such that ASP.NET will pick up my new razor changes without an app pool restart?


Solution

  • This is certainly possible.

    You simply need to create your own VirtualPathProvider, (which it looks like you've already done), and be sure to override the method:

    public override CacheDependency GetCacheDependency(string virtualPath, 
                              IEnumerable virtualPathDependencies, DateTime utcStart)
    

    When I did this, my scenario only required returning the cache dependency of the physical file path, e.g.

    string physicalPath = GetPhysicalPath(virtualPath);
    return new CacheDependency(physicalPath);
    

    Depending on what you are doing, that may or may not be sufficient.

    In my particular scenario, I didn't need to worry about the case where virtualPathDependencies had multiple entries (which can occur for example, if the virtualPath represents a directory that contains multiple files). My provider was also pretty simple - I delegated to the default provider for most cases.

    You likely already know this, but for the benefit of future readers, also be sure to register the virtual path provider, e.g. in Application_Start() of the global.asax, which can be done like so:

    //get the default provider if your custom provider delegates to it.
    var defaultProvider = HostingEnvironment.VirtualPathProvider;
    //register the custom provider.
    HostingEnvironment.RegisterVirtualPathProvider(new MyCustomVirtualPathProvider(defaultProvider));