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 });
        }
    
  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies