Introduction
Few months ago, I was developing a website using ASP.NET MVC. I found that there are difficulties to manage deployment if the number of views are huge. View does not generate compile time errors. I Googled and found there are ways to generate a single DLL for an MVC application instead of deploying all .cshtml files. I am going to share the techniques to enable pre-compilation of razor view and single DLL deployment.
Background
One of the features of any compiled language is to validate errors and warnings at compile time. It reduces number of errors at the design phase instead of after running the program. ASP.NET MVC follows a mixed approach for compilation. Models and controllers are pre-compiled but views are compiled at runtime. So, any error in view can’t be detected until it is not run on the browser.
As views are not pre-compiled, startup time to load a MVC application will be slowed down if there are many views in a project.
To overcome this problem, views can be pre-compiled. We are going to discuss how we can do that.
Let’s start with an example.
Using the Code
Open Visual Studio.
Select MVC Web Application.
Select Basic template.
Create a controller Home.
Write few lines of code in controller:
namespace PrecompileView.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.myText = "999";
return View();
}
}
}
Add a view called Index
:
Open Index.cshtml file.
Add the following line with incorrect ViewBag
spelling:
@{
ViewBag.Title = "Home Page";
}
<h3>@Convert.ToInt32(ViewBagg.MyText)</h3>
Run the application.
The following runtime exception will occur:
Instead of getting this runtime error, we can enable pre-compilation of razor view to generate design time compilation error. There are various ways to enable pre-compilation in ASP.NET MVC application.
We will discuss the following approaches:
- Razor pre-compilation using
MvcBuildViews
tag
- Razor pre-compilation using
RazorGenerator
Option #1 - Razor Pre-compilation using MvcBuildViews Tag
This can be achieved by changing value of the MvcBuildViews
in .csProject.
Steps are as follows:
Unload the .csProject:
Edit .csProject:
We can set <MvcBuildViews>True</MvcBuildViews>
to enable pre-compilation, but we can optionally set pre-compilation on Release build.
In the <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
section, set the MvcBuildViews
element to false
: <MvcBuildViews>false</MvcBuildViews>
.
In the <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
section, set the MvcBuildViews
element to true
: <MvcBuildViews>true</MvcBuildViews>.
We need to save the project and reload it.
Now, if we rebuild the project in Debug mode, there will be no error.
We will get the error in Release build:
Option #2 - Razor Pre-compilation using RazorGenerator
Using the previous approach, we can enable pre-compilation, but we need the .cshtml files also to deploy. If we can bind the controller and view into a single DLL, it will be very handy to deploy. By using RazorGenerator
, we can achieve that.
Steps are as follows:
Restore the .csProject file to the earlier state.
Go to Tools, then Extension Manager.
Search for Razor Generator.
Click the Download button.
Once the install has completed, restart Visual Studio.
Insert RazorGenerator
in Custom Tool .
Click on Run Custom Tool on Index.cshtml.
Running the Custom Tool will generate Index.generated.cs file.
The .cshtml file is now compiled into Index.generated.cs file and it looks like the following:
Now, if we build the project, we will get the following compile time error.
We are going to correct the error and successfully build the project.
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.myText = "999";
return View();
}
}
Build will be successful now. Now we are going to observe the most interesting part of this approach and that is deployment.
Open Developer Command Prompt for Visual Studio.
Type ildasm
.
Navigate through PrecompileView.dll. We can see that Index.cshtml is now a part of the DLL.
So, now .cshtml files are no longer required for deployment.
We can deploy only the PrecompileView.dll for our entire MVC application.
You can download the source code here.
Points of Interest
Using RazorGenerator
, we can deploy a single DLL file for an MVC application. For any web application, CSS, JavaScript and image files are part of the application. We can set these files as embedded resources to generate a single DLL.