This project is read-only.

NullReferenceException if _ViewStart.cshtml not present

Apr 24, 2013 at 11:17 PM
Edited Apr 24, 2013 at 11:30 PM
I have been trying out Razor Generator with my existing MVC 4 project. I set up the project to compile the views via MSBuild.

To test, I built the project and removed my /Views/Login/Login.cshtml view file, to ensure that it would render the pre-compiled view. This worked great.

We also currently have a placeholder _ViewStart.cshtml file in the /Views folder. It currently just has an empty Razor code block
@{
    // all properties set here will serve as defaults for all views
}
When I remove the _ViewStart.cshtml file, I get a NullReferenceException when trying to browse to the Login view.

The generated CS files in the obj/CodGen folder include _ViewStart.cshtml.cs, and it appears to be correctly defined (it inherits from System.Web.Mvc.ViewStartPage).

I understand that I could simply remove _ViewStart.cshtml from the project, but I was curious as to why the Razor Generator view engine doesn't seem to be picking up the pre-compiled _ViewStart page. When I decompile my MVC project's DLL, the ViewStart class is there, but something just doesn't seem to be working.

Also, I am using the default RazorGeneratorMvcStart class that was created when I installed the RazorGenerator.MVC nuget package.

Here is the stack trace for the exception:
System.Web.WebPages.StartPage.GetStartPage(WebPageRenderingBase page, IVirtualPathFactory virtualPathFactory, String appDomainAppVirtualPath, String fileName, IEnumerable`1 supportedExtensions) +275
   System.Web.WebPages.StartPage.GetStartPage(WebPageRenderingBase page, String fileName, IEnumerable`1 supportedExtensions) +235
   RazorGenerator.Mvc.PrecompiledMvcView.Render(ViewContext viewContext, TextWriter writer) +1141
   System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +383
   System.Web.Mvc.<>c__DisplayClass1a.<InvokeActionResultWithFilters>b__17() +32
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +977476
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +265
   System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +964716
   System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +28
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +20
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +67
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +20
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +53
   System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +20
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +53
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +469
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +375
Apr 29, 2013 at 2:53 PM
I tried using the Razor Generator VS extension instead of MS Build, and I noticed the exact same problem. If I removed my _ViewStart.cshtml file, then attempting to render any view would cause a NullReferenceException until the _ViewStart.cshtml was placed back in to the root Views directory.

I should mention that my app is using MVC 4 and I currently have a single MVC project with all views and controllers, rather than a separate library for my views.

Here are the current contents of my RazorGeneratorMvcStart.cs file:
using System.Web;
using System.Web.Mvc;
using System.Web.WebPages;
using RazorGenerator.Mvc;

[assembly: WebActivatorEx.PostApplicationStartMethod(typeof(QGenda.Web.App_Start.RazorGeneratorMvcStart), "Start")]

namespace QGenda.Web.App_Start {
    public static class RazorGeneratorMvcStart {
        public static void Start() {
            var engine = new PrecompiledMvcEngine(typeof(RazorGeneratorMvcStart).Assembly) {
                UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal
            };

            ViewEngines.Engines.Insert(0, engine);

            // StartPage lookups are done by WebPages. 
            VirtualPathFactoryManager.RegisterVirtualPathFactory(engine);
        }
    }
}
Apr 29, 2013 at 5:56 PM
I just tried that and could not repro it:
  • New MVC4 app, internat app
  • Install RazorGenerator.Mvc package
  • Run 'enable-razorgenerator' to convert all views
  • Delete _viewstart.cshtml
And everything runs fine. i.e. pages render without any layout.
Apr 29, 2013 at 11:20 PM
I reverted all of my changes, uninstalled all Razor Generator packages, and started the entire process over. After re-installing RazorGenerator.MVC and RazorGenerator.MSBuild, it appears to be working great.

I think my problem may have been due to files from the obj directory being picked up, as all deployable content (including cshtml files) gets copied there during a publish. I tweaked my project file to tell Razor Generator to ignore all cshtml files in the obj folder. I'm not sure if this was what did the trick, but it's the only thing that I changed from my original configuration.
Apr 29, 2013 at 11:38 PM
Glad you have it working, even if it's not fully clear how! :)