Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Anton 28 posts 116 karma points
    Feb 17, 2017 @ 09:24
    Anton
    1

    Umbraco, views precompilation and virtual path providers

    I am facing strange issue currently. Here is my setup:

    • Umbraco v7.5.3
    • UmbracoFileSystemProviders.Azure
    • ImageProcessor
    • Our.Umbraco.AzureCDNToolkit

    We are having really a lot Views in our development, so, even on decent machines startup can take 5-7 minutes after rebuild. To tackle this problem, we've switched to out-of-webroot development and implemented views precompilation with Updateable=False. However, as soon as there is PrecompiledApp.config present in webroot - Umbraco stops using all VPP's, except static files. So, each request to media item without query string ( like, http://myDevHost/media/1000/1.jpg ) serves ASP.NET 404 error, while same request with query string ( like, http://myDevHost/media/1000/1.jpg?1=1 ) is hapilly processed by ImageProcessor and redirects to CDN, serving me an image.

    As soon as I remove PrecompiledApp.config from webroot app will stop working (this is expected, as there is amibigious types), but - request to media item ( like, http://myDevHost/media/1000/1.jpg ) will hapilly serve my media item from Azure Blob storage

  • Anton 28 posts 116 karma points
    Feb 17, 2017 @ 13:57
    Anton
    101

    With help of Jeroen, I got it sorted: VPP will not work in precompiled apps ( https://twitter.com/crumpled_jeavon/status/832563262218711040 ) without hacks ( https://github.com/JimBobSquarePants/UmbracoFileSystemProviders.Azure/issues/37 ). So, I took https://sunali.com/2008/01/09/virtualpathprovider-in-precompiled-web-sites/ as a base and added following code in our RegisterEvents class, which is inherited from ApplicationEventHandler, in ApplicationStarting method

       private void HackishlyRegisterVpp()
        {
            if (!BuildManager.IsPrecompiledApp)
            {
                //we do not need to register VPP if web app is not precompiled
                return;
            }
            var fs = FileSystemProviderManager.Current.GetUnderlyingFileSystemProvider("media");
            Lazy<IFileSystem> fileSystem = new Lazy<IFileSystem>((Func<IFileSystem>)(() => fs));
            // we create a new instance of our own VirtualPathProvider.
            var providerInstance = new Our.Umbraco.FileSystemProviders.Azure.FileSystemVirtualPathProvider("media", fileSystem);
            // any settings about your VirtualPathProvider may go here.
    
            // we get the current instance of HostingEnvironment class. We can't create a new one
            // because it is not allowed to do so. An AppDomain can only have one HostingEnvironment
            // instance.
            HostingEnvironment hostingEnvironmentInstance = (HostingEnvironment)typeof(HostingEnvironment).InvokeMember("_theHostingEnvironment", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, null, null, null);
            if (hostingEnvironmentInstance == null)
            {
                return;
            }
    
            // we get the MethodInfo for RegisterVirtualPathProviderInternal method which is internal
            // and also static.
            MethodInfo mi = typeof(HostingEnvironment).GetMethod("RegisterVirtualPathProviderInternal", BindingFlags.NonPublic | BindingFlags.Static);
            if (mi == null)
            {
                return;
            }
    
            // finally we invoke RegisterVirtualPathProviderInternal method with one argument which
            // is the instance of our own VirtualPathProvider.
            mi.Invoke(hostingEnvironmentInstance, new object[] { (VirtualPathProvider)providerInstance });
        }
    
Please Sign in or register to post replies

Write your reply to:

Draft