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
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 });
}
Umbraco, views precompilation and virtual path providers
I am facing strange issue currently. Here is my setup:
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
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
is working on a reply...