andrewdavey / cassette

Manages .NET web application assets (scripts, css and templates)
http://getcassette.net
MIT License
534 stars 143 forks source link

IIS Virtual Directory asset referencing issues #456

Open torymartin88 opened 10 years ago

torymartin88 commented 10 years ago

We are running into an issue using Cassette with asset bundles located in a Virtual Directory set up in IIS (We have Cassette up and running without Virtual Directories btw and it works great!).

Here is an example of our current setup. Each site directory is set up as IIS application as normal. Site location on disk: c:/sitefiles/sitename CMS admin portal location on disk: c:/sitefiles/sharedfiles/adminportal

The CMS admin portal is setup in the IIS as a virtual directory for each site. sitename.com/adminportal -or- c:/sitefiles/sitename/adminportal

So a Cassette reference in /adminportal/Login/Default.aspx looks like this

Bundles.Reference("/adminportal/js/sampleScript.js");
Bundles.Reference("/adminportal/js/sampleBundle.js");

Therefore when Cassette references the bundle we are getting the following error.

[DirectoryNotFoundException: Bundle path not found: ~/adminportal/js/sampleScript.js]
   Cassette.BundleCollection.Add(String applicationRelativePath, IFileSearch fileSearch, Action`1 customizeBundle) +913
   Cassette.BundleCollection.Add(String applicationRelativePath) +78
   sampleassembly.CassetteBundleConfiguration.BundleScriptDirectory(DirectoryInfo di, String path, BundleCollection bundles) +640
   sampleassembly.CassetteBundleConfiguration.BundleScriptDirectory(String path, BundleCollection bundles) +268
   sampleassembly.CassetteBundleConfiguration.Configure(BundleCollection bundles) +103
   Cassette.ConfigurationEnumerableExtensions.Configure(IEnumerable`1 configurations, T configurable) +176
   Cassette.BundleCollectionInitializer.Initialize(BundleCollection bundleCollection) +187
   Cassette.ExceptionCatchingBundleCollectionInitializer.Initialize(BundleCollection bundleCollection) +50

[Exception: Bundle collection rebuild failed. See inner exception for details.]
   Cassette.BundleCollection.GetReadLock() +382
   Cassette.ReferenceBuilder.Reference(String path, String location) +92
   ASP.admin_login_default_aspx.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in c:\sitefiles\sharedfiles\adminportal\Login\Default.aspx:5
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +131
   System.Web.UI.Page.Render(HtmlTextWriter writer) +40
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +150
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +12742749
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5363

Files and bundles outside the Virtual Directory work fine.

Bundles.Reference("/js/sampleScript.js");

So when I copy the admin files directly into the site directory everything works fine. But when outside of the site files and setup as a virtual directory it no longer works.

Obviously we could duplicate the admin portal on each site, but that really puts a kink in our upgrading system.

Just looking to see if anyone else has had this problem. I've found a few that look similar-ish, but not quite.

https://github.com/andrewdavey/cassette/issues/138 (perhaps the same issue, but not well explained, hopefully I've done a little bit better of a job... :) https://github.com/andrewdavey/cassette/issues/209 https://github.com/andrewdavey/cassette/issues/234

torymartin88 commented 10 years ago

I should note that we've tried a good number of things to resolve this. IIS Config, Cassette Settings Config, etc.

I also browsed through the source for Cassette and found this... https://github.com/andrewdavey/cassette/blob/ed1b6c332c37555f6eaca9f02e91beb3c98b5255/src/Cassette/VirtualDirectoryPrepender.cs

But not sure exactly if that's what I'm looking for.

andrewdavey commented 10 years ago

Cassette doesn't work with ASP.NET's "virtual files". It only looks at the physical file system.

In the past, when wanting to share some common bundles between multiple sites, I've created symbolic links (via mklink in cmd) to the common bundle directory. This way they appear to Cassette as just another directory in the file system.

torymartin88 commented 10 years ago

Confirmed that this does work. Like a charm.

mklink /D "C:\sitefiles\sitefolder\adminportal" "D:\sitefiles\sharedfiles\adminportal"

Thanks!