Reputation: 2874
When I create a Web Forms project, my code behind is compiled into a DLL, which is processed by an IIS server. When I use Javascript, it's interpreted by the browser and I can find it using things like the Chrome Developer Tools or by inspecting the source.
However, when I create an ASP.NET Web Page using Razor syntax, I can't find the code anywhere. Since it doesn't need to be compiled, it's not put into a DLL and I can't locate any trace of it using Chrome's inspect tools.
So, where does Razor code go?
Upvotes: 2
Views: 1666
Reputation: 1393
Whether you use Razor, conventional code-behind (separate files), or .aspx with inline HTML and C#, more-or-less the same things are happening. It all gets converted into server-side code, and executed server-side, emitting HTML (and injected javascript which you never see in your source pages) at runtime. The HTML in your source pages becomes chunks of text used by the server-side code when it generates the pages to send to the client.
The server typically will compile your pages, and run the compiled code; what appears to be "interpreted" is actually compiled just-in-time on first page load and cached in memory for the benefit of subsequent page loads.
If you can find no evidence of a compiled output for a page anywhere on your site, it is probably because the page is just-in-time compiled and never actually written to a dll.
Upvotes: 2
Reputation: 54359
They are indeed compiled at runtime. You can find a generated code file and temporary DLLs in the same place that compiled web forms are placed:
C:\Windows\Microsoft.NET\Framework64\<version>\Temporary ASP.NET Files\<app>\
You can also can enable compilation along with the rest of the project to detect errors in your views. See: Can Razor views be compiled?. This will increase the compilation time of the solution (in my experience), but it's great for detecting errors that would go unnoticed until runtime. I switch it on when needed.
The Razor parser/generator code is contained in the System.Web.Razor project/assembly (available as part of the MVC source). Since the end result is a c# class, the c# compiler presumably handles it from there as it would any other class.
The generated code for a view looks something like (excerpted from a "reset password" page in one of my projects).
namespace ASP {
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Helpers;
using System.Web.Security;
using System.Web.UI;
using System.Web.WebPages;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Web.Mvc.Html;
using System.Web.Routing;
public class _Page_Areas_Anonymous_Views_Home_ResetPassword_cshtml : System.Web.Mvc.WebViewPage<Web.UI.Areas.Anonymous.ResetPasswordViewModel> {
#line hidden
public _Page_Areas_Anonymous_Views_Home_ResetPassword_cshtml() {
}
protected ASP.global_asax ApplicationInstance {
get {
return ((ASP.global_asax)(Context.ApplicationInstance));
}
}
public override void Execute() {
const string title = "Reset Password";
ViewBag.Title = title;
BeginContext("~/Areas/Anonymous/Views/Home/ResetPassword.cshtml", 302, 63, true);
WriteLiteral("</h1>\r\n </div>\r\n </div>\r\n </div>\r\n <div");
EndContext("~/Areas/Anonymous/Views/Home/ResetPassword.cshtml", 302, 63, true);
BeginContext("~/Areas/Anonymous/Views/Home/ResetPassword.cshtml", 365, 12, true);
WriteLiteral(" class=\"two\"");
EndContext("~/Areas/Anonymous/Views/Home/ResetPassword.cshtml", 365, 12, true);
BeginContext("~/Areas/Anonymous/Views/Home/ResetPassword.cshtml", 377, 15, true);
WriteLiteral(">\r\n <div");
EndContext("~/Areas/Anonymous/Views/Home/ResetPassword.cshtml", 377, 15, true);
BeginContext("~/Areas/Anonymous/Views/Home/ResetPassword.cshtml", 392, 19, true);
WriteLiteral(" class=\"banner-box\"");
EndContext("~/Areas/Anonymous/Views/Home/ResetPassword.cshtml", 392, 19, true);
BeginContext("~/Areas/Anonymous/Views/Home/ResetPassword.cshtml", 411, 5, true);
WriteLiteral(">\r\n\r\n");
#line default
#line hidden
using( @Html.BeginForm( "ResetPassword", "Home", FormMethod.Post, new { id = "main-form" } ) )
{
Write(Html.ValidationSummary());
// etc. etc. Even simple views result in a large code file
Upvotes: 8