Views only found once when deployed in Release mode!

Mar 13, 2012 at 10:52 AM
Edited Mar 13, 2012 at 1:20 PM

I am having a very strange problem! I have extracted a certain area of my app into a separate web project, and set it all up to use RazorGenerator.
The first time I access a page which uses views from the separate assembly, everything works fine. The second time (and onwards) I access the page I get the YSOD below. This only happens if I deploy in release mode - in debug it is fine. I have set the UsePhysicalViewsIfNewer to false everywhere.
Is there some release mode caching or something that is going wrong?

[ArgumentNullException: Value cannot be null.
Parameter name: view]
   System.Web.Mvc.ViewEngineResult..ctor(IView view, IViewEngine viewEngine) +927830
   System.Web.Mvc.VirtualPathProviderViewEngine.FindPartialView(ControllerContext controllerContext, String partialViewName, Boolean useCache) +266
   System.Web.Mvc.ViewEngineCollection.Find(Func`2 lookup, Boolean trackSearchedPaths) +177
   System.Web.Mvc.ViewEngineCollection.Find(Func`2 cacheLocator, Func`2 locator) +23
   ...
 
Mar 13, 2012 at 12:56 PM

Further to this, it is not release mode that is the problem, but 

<compilation debug="false" targetFramework="4.0">

Mar 13, 2012 at 1:25 PM
Edited Mar 13, 2012 at 1:26 PM

Even further to this, I have traced the problem to the ViewLocationCache setting for the ViewEngines.

By initialising my view engines with DefaultViewLocationCache.Null engines, which doesn't cache the view path, I have managed to fix the problem. I think it was attempting to cache the views as if they disk-based, and then it was failing to load them on the second page load. I'm not sure why no-one else has has this problem yet, but anyway, here is the fix (belongs in RazorGeneratorMvcStart.cs)

var engine = new PrecompiledMvcEngine(typeof(RazorGeneratorMvcStart).Assembly) 
{
ViewLocationCache = DefaultViewLocationCache.Null
}
Coordinator
Mar 13, 2012 at 3:55 PM

Strange, I wasn't able to repro this:

  • New MVC3 app
  • Install-Package RazorGenerator.Mvc
  • Enable-RazorGenerator
  • Change to Release configuration
  • Run the app
  • Hit F5 to refresh, and got no error

Are you doing anything differently?

Mar 13, 2012 at 4:00 PM
Edited Mar 13, 2012 at 4:01 PM

I have also deployed the app to an IIS site (so it isn't running from the same directory as the code), and I am loading the views from a second project. I'll give it a try now on a clean solution.

Coordinator
Mar 13, 2012 at 4:12 PM

I still wasn't able to repro in IIS. It might make sense for you to share out your code, in case there is a subtle difference that triggers this.

Mar 13, 2012 at 4:39 PM
Edited Mar 13, 2012 at 4:42 PM

I have created a repro project http://dl.dropbox.com/u/2808109/RazorProblem.7z - Ctrl+F5 to demonstrate

The big difference is that it has two(!) projects which views are loaded from.

  • New MVC3 app RazorProblem
  • New MVC3 apps RazorProblem.Referenced, RazorProblems.Referenced2
  • Created Test.cshtml, and Test2.cshtml in the referenced projects /views/shared, marked with RazorGenerator as build tool
  • Updated Index.html to render views Test and Test2
  • Referenced the two projects from the main project
  • Install-Package RazorGenerator.Mvc to all three
  • Change web.config to compilation debug="true"
  • Run the app :)
  • Hit F5 to refresh :(
Coordinator
Mar 13, 2012 at 4:42 PM

Thanks. I'll try to look at this later today. So I take it it's not necessary to use IIS to repro?

Mar 13, 2012 at 6:08 PM

Nope, plain old VS will do the trick I think

Coordinator
Mar 14, 2012 at 6:04 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Coordinator
Mar 14, 2012 at 6:05 PM

Sorry, I'm swamped and won't have time to look at this soon. I created a bug. Feel free to send a pull request with a fix! :)