Precompiled Razor View Using RazorGenerator MVC and PreCompiledViewEngine in MVC 4

A few days ago a question occured to me, can we share a single View across multiple projects? Yes in multiple projects. I thought about it and created a sample application to do that using RazorGenerator.Mvc.

A few days ago a question occured to me, can we share a single View across multiple projects? Yes in multiple projects. I thought about it and created a sample application to do that using RazorGenerator.Mvc.

Sharing Views among projects

ASP.NET MVC makes it very easy to share views within the same website. Multiple controller actions can reference the same view when the shared view lives in the same folder as the other views for that controller or in the website’s Shared folder. But how do you share views across projects?

Step 1: Create a MVC Web application as shown in the following image:



Step 2: Choose an internet template as shown in the following image:



First look at the MVCWebApp shown below:
 

Step 3: Create a Class Library and give name it "PreCompileViewLib".
 


First look at PreCompileViewLib as shown below:
 


Step 4: The Razor Single File Generator

The Razor Single File Generator is an open source Visual Studio extension that allows you to create reusable Razor views that aren’t tied to any specific website.

Installing the Razor Single File Generator

The Razor Single File Generator installer is available in the Visual Studio Extensions Gallery, to install kindly open the Visual Studio Extension Manager ("Tools" → "Extension Manager…") and search the OnlineGallery for “Razor Generator”.

Kindly follow these steps to install Razor Generator.
 


Click on the Extension manager and search for RazorGenerator.Mvc.or you may install it from NuGet in your ClassLibrary project.
 


After installing RazorGenerator.Mvc, the solution will look like the following image.
 


If you notice, RazorGenerator.Mvc.dll has been added to the PreCompiledView Class Library project along with the file RazorGeneratorMvcStart.cs under the App_Start folder.

Step 5: Now move ahead and install the PrecompiledMvcViewEngineContrib from NuGet as shown in the image below.

Or you may install it from the Package Manager Console using this command:

Install-Package PrecompiledMvcViewEngineContrib

Kindly refer to both of the following images to install it from NuGet Packages and the Package Manager Console.
 
 


Step 6: Create a structure as shown below in PreCompiledView to keep the view structure the same as the MVCWebApp project.
 


Note: I’ve deleted the Index.cshtml from the MVCWebApp project. Kindly refer to the image below:
 


Step 7: Creating reusable ASP.NET MVC views with the Razor Single File Generator is nearly the same as creating views within an ASP.NET MVC project itself. When you create a folder structure similar to the ~/Views folder convention that ASP.NET MVC expects, the only thing you need to do is associate the views with the Razor Single File Generator by setting each view’s Custom Tool property to RazorGenerator.

Now open up the properties for the Index.cshtml file and set its Custom Tool property to RazorGenerator, also shown in the following image:
 


Immediately after you specify the Custom Tool property, you should see that the Razor Single File Generator has generated the class Index.generated.cs, grouped underneath Index.cshtml (as shown in figure below).
 


We are almost done and now press F5 to see how it works.

I’ve set a breakpoint in RazorGeneratorMvcStart.cs to determine the mapping managed by the newly created ViewEngine.
 


After executing this line, kindly proceed and see that a new View Engine has been added to the existing list to handle the Precompiled View. It’s really awesome to manage Precompiled Views.
 


Press F5 and see the real output (its same as we have for the same application).
 


ASP.NET MVC now executes the precompiled Index.cshtml file from the class library, not caring that the file did not exist in its local ~/Views folder. But how did the PrecompiledMvcViewEngine know which view to render

Note: But how did the PrecompiledMvcViewEngine know which view to render? Though it may be surprising, PrecompiledMvcViewEngine still relies on the ASP.NET MVC Views folder convention, using relative file paths to locate the views. However, this is slightly misleading. The PrecompiledMvcViewEngine doesn’t look at physical files; it looks for the System.Web.WebPages.PageVirtualPathAttribute that the Razor Single File Generator adds to every view that it generates that includes the view’s relative file path. The following shows the first few lines of the sample view Index.cshtml that includes that

[System.Web.WebPages.PageVirtualPathAttribute ("~/Views/Home/Index.cshtml")]

public partial class Index : System.Web.Mvc.WebViewPage<dynamic>

Since the virtual path name is relative, whether the ~/Views/Home/Index.cshtml view resides in the ASP.NET MVC application or the class library project, its virtual path is the same. Thus, when the ASP.NET MVC application requests the Index view in the Home controller, the precompiledMvcViewEngine knows to use the precompiled Index.cshtml view registered with the virtual path ~/Views/Home/Index.cshtml

Conclusion

This can be a significant improvement in sites with many views as already compiled. Also, you no longer need to deploy the cshtml files at all, resulting in a smaller deployment file set.