Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Behind the scenes of ASPX files

0.00/5 (No votes)
19 Jan 2004 2  
Describes what goes with ASPX files and how ASPX files affect the page life cycle.

Introduction

ASP.NET pages are usually compound of two files: the ASPX which contains the page visualization declaration and the *.cs which contains the code to handle page events (Code behind). While all the *.cs files compile into one DLL (with the application name) and the page life cycle is well documented, this is not the case of ASPX files.

What has really happened to those ASPX files?

Well, what has really happened to those ASPX files? At the end of the day, ASP.NET turns each ASPX file into assembly. While the page is termed for the first time as ASP.NET, this leads to the:

  1. Generation of a *.cs file holding code that matches the ASPX declarations.
  2. Using of csc.exe (C# compiler) to compile *.cs file into DLL (you can see csc.exe if you monitor running processes).
  3. Running of the compiled DLL

This sequence occurs just once then, resulting with DLL that will be used for other requests until one of the page dependencies files will be changed leading to the re-enforcement of the sequence. If you ever wonder why running an application for the first time takes such a long while, you would probably have some idea already.

To understand better what is going on here, let�s take a very simple page and follow the following steps. I have created a simple page that holds a Panel, Textbox and server side script inside an ASPX file. Below you can see the ASPX file:

<%@ Import Namespace="System.Web" %>
<%@ Page language="c#" Codebehind="WebForm13.aspx.cs" 
  AutoEventWireup="false" Inherits="WebApplication22.WebForm13" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm13</title>
<meta content="Microsoft Visual Studio 7.0" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" 
                                            name="vs_targetSchema">
</HEAD>
<body MS_POSITIONING="GridLayout">
<script language="C#" runat="server">
private void myfunc(object sender, System.EventArgs e)
{
  HttpContext.Current.Response.Write("Text Init"); 
}
</script>
<form id="WebForm13" method="post" runat="server">
<asp:TextBox id="TextBox1" OnLoad="myfunc" 
  style="Z-INDEX: 101; LEFT: 101px; POSITION: absolute; TOP: 114px" 
  runat="server" Width="170px" Height="48px"></asp:TextBox>
<asp:Panel id="LblNav" 
  style="Z-INDEX: 102; LEFT: 22px; POSITION: absolute; TOP: 63px" 
  runat="server" Width="269px">Panel</asp:Panel>
</form>
</body>
</HTML>

All the files that ASP.NET generated will be placed in this folder: C:\$WINDOWSDir$\Microsoft.NET\Framework\v1.0.3705\Temporary ASP.NET Files\$YourWebAppName$\42343\654564. The last two folders are randomly numbered, generated by ASP.NET. The fun begins from the last directory. That folder holds all the files generated for ASPX files, ASCX files (user control) and ASAX files. The last folder also contains a folder called Assembly that holds another directory: dl2. The dl2 folder contains sub folders with randomly numbered names each for every referenced assembly from the web project, including the application DLL. We will focus on the folder that contains all the files generated for ASPX, ASCX and ASAX files.

The first file that we�re interested in is the XML file holding the page name (WebForm13.aspx.4689d8a0.xml). This file contains information that map between the web page name and the random name that will be used by ASP.NET to generate page files. Besides the mapping information, the file consists of data on the decency files of that page (any changes of that file will cause recreation of ASPX files and recompilation):

<preserve assem="jibrfh34" type="ASP.WebForm13_aspx" hash="49b238a170c332">
<filedep name="c:\inetpub\wwwroot\WebApplication22\bin\WebApplication22.DLL" />
<filedep name="c:\inetpub\wwwroot\WebApplication22\WebForm13.aspx" />
</preserve>

After understanding that every file starting with �jibrfh34� is a file that was generated for a certain page, we should examine what is the purpose of every file. The most important file is the *.cs which holds the generated C# lines corresponding to the ASPX tags and code, but we will come back to that later. The *.res file holds resources that the compiler will use then. The *.cmdline holds the command line that will be used by ASP.NET to compile the *.cs file. The *.cmdline file includes a reference to other assemblies and optimization settings. The *.err file contains errors (if they occurred while compiling the *.cs file). The *.out file consists of outputs from the compilation process. The *.dll and *.pdb obviously function as the compilation output.

Our next step will be then exploring the *.cs file:

namespace ASP {
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Configuration;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Caching;
using System.Web.SessionState;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using ASP;


[System.Runtime.CompilerServices.CompilerGlobalScopeAttribute()]
public class WebForm13_aspx : WebApplication22.WebForm13, 
  System.Web.SessionState.IRequiresSessionState {


#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
  protected System.Web.UI.HtmlControls.HtmlForm WebForm13;

#line default

  private static bool __intialized = false;

  private static object __stringResource;

  private static System.Collections.ArrayList __fileDependencies;


#line 13 "http://localhost/WebApplication22/WebForm13.aspx"

  private void myfunc(object sender, System.EventArgs e)
  {
    HttpContext.Current.Response.Write("Text Init"); 
  }

#line default

  public WebForm13_aspx() {
    System.Collections.ArrayList dependencies;
    if ((ASP.WebForm13_aspx.__intialized == false)) {
      ASP.WebForm13_aspx.__stringResource = 
        System.Web.UI.TemplateControl.ReadStringResource(typeof(ASP.WebForm13_aspx));
      dependencies = new System.Collections.ArrayList();
      dependencies.Add("c:\\inetpub\\wwwroot\\WebApplication22\\WebForm13.aspx");
      ASP.WebForm13_aspx.__fileDependencies = dependencies;
      ASP.WebForm13_aspx.__intialized = true;
    }
    this.Server.ScriptTimeout = 30000000;
  }

  protected override bool SupportAutoEvents {
    get {
      return false;
    }
  }

  protected ASP.Global_asax ApplicationInstance {
    get {
      return ((ASP.Global_asax)(this.Context.ApplicationInstance));
    }
  }

  public override string TemplateSourceDirectory {
    get {
      return "/WebApplication22";
    }
  }

  private System.Web.UI.Control __BuildControlTextBox1() {
    System.Web.UI.WebControls.TextBox __ctrl;

#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
    __ctrl = new System.Web.UI.WebControls.TextBox();

#line default
    this.TextBox1 = __ctrl;

#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
    __ctrl.ID = "TextBox1";

#line default

#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
    ((System.Web.UI.IAttributeAccessor)(__ctrl)).SetAttribute("style", 
      "Z-INDEX: 101; LEFT: 101px; POSITION: absolute; TOP: 114px");

#line default

#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
    __ctrl.Width = System.Web.UI.WebControls.Unit.Parse("170px", 
      System.Globalization.CultureInfo.InvariantCulture);

#line default

#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
    __ctrl.Height = System.Web.UI.WebControls.Unit.Parse("48px", 
      System.Globalization.CultureInfo.InvariantCulture);

#line default

#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
    __ctrl.Load -= new System.EventHandler(this.myfunc);

#line default

#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
    __ctrl.Load += new System.EventHandler(this.myfunc);

#line default
    return __ctrl;
  }

  private System.Web.UI.Control __BuildControlLblNav() {
    System.Web.UI.WebControls.Panel __ctrl;

#line 21 "http://localhost/WebApplication22/WebForm13.aspx"
    __ctrl = new System.Web.UI.WebControls.Panel();

#line default
    this.LblNav = __ctrl;

#line 21 "http://localhost/WebApplication22/WebForm13.aspx"
    __ctrl.ID = "LblNav";

#line default

#line 21 "http://localhost/WebApplication22/WebForm13.aspx"
    ((System.Web.UI.IAttributeAccessor)(__ctrl)).SetAttribute("style", 
      "Z-INDEX: 102; LEFT: 22px; POSITION: absolute; TOP: 63px");

#line default

#line 21 "http://localhost/WebApplication22/WebForm13.aspx"
    __ctrl.Width = System.Web.UI.WebControls.Unit.Parse("269px", 
      System.Globalization.CultureInfo.InvariantCulture);

#line default
    System.Web.UI.IParserAccessor __parser = 
      ((System.Web.UI.IParserAccessor)(__ctrl));

#line 21 "http://localhost/WebApplication22/WebForm13.aspx"
    __parser.AddParsedSubObject(new System.Web.UI.LiteralControl("Panel"));

#line default
    return __ctrl;
  }

  private System.Web.UI.Control __BuildControlWebForm13() {
    System.Web.UI.HtmlControls.HtmlForm __ctrl;

#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
    __ctrl = new System.Web.UI.HtmlControls.HtmlForm();

#line default
    this.WebForm13 = __ctrl;

#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
    __ctrl.ID = "WebForm13";

#line default

#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
    __ctrl.Method = "post";

#line default
    System.Web.UI.IParserAccessor __parser = 
      ((System.Web.UI.IParserAccessor)(__ctrl));

#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
    __parser.AddParsedSubObject(new 
      System.Web.UI.LiteralControl("\r\n\t\t\t"));

#line default

#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
    this.__BuildControlTextBox1();

#line default

#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
    __parser.AddParsedSubObject(this.TextBox1);

#line default

#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
    __parser.AddParsedSubObject(new 
      System.Web.UI.LiteralControl("\r\n\t\t\t"));

#line default

#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
    this.__BuildControlLblNav();

#line default

#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
    __parser.AddParsedSubObject(this.LblNav);

#line default

#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
    __parser.AddParsedSubObject(new 
      System.Web.UI.LiteralControl("\r\n\t\t"));

#line default
    return __ctrl;
  }

  private void __BuildControlTree(System.Web.UI.Control __ctrl) {
    System.Web.UI.IParserAccessor __parser = 
      ((System.Web.UI.IParserAccessor)(__ctrl));

#line 1 "http://localhost/WebApplication22/WebForm13.aspx"
    __parser.AddParsedSubObject(this.CreateResourceBasedLiteralControl(0, 397, true));

#line default

#line 1 "http://localhost/WebApplication22/WebForm13.aspx"
    this.__BuildControlWebForm13();

#line default

#line 1 "http://localhost/WebApplication22/WebForm13.aspx"
    __parser.AddParsedSubObject(this.WebForm13);

#line default

#line 1 "http://localhost/WebApplication22/WebForm13.aspx"
    __parser.AddParsedSubObject(new 
        System.Web.UI.LiteralControl("\r\n\r\n\t</body>\r\n</HTML>\r\n"));

#line default
  }

  protected override void FrameworkInitialize() {
    SetStringResourcePointer(ASP.WebForm13_aspx.__stringResource, 397);
    this.__BuildControlTree(this);
    this.FileDependencies = ASP.WebForm13_aspx.__fileDependencies;
    this.EnableViewStateMac = true;
  }

  public override int GetTypeHashCode() {
    return 423941586;
  }
}
}

You can notice that the file contains notes that map the code to the HTML lines in the source ASPX file. You can use those lines to see how ASP.NET converts HTML lines and learn a lot from it.

Every generated *.cs file is a definition of a class that inherits from the code behind class and implement interface:

public class WebForm13_aspx : WebApplication22.WebForm13
  System.Web.SessionState.IRequiresSessionState

This class (WebForm13_aspx) will be called before the code behind class (WebApplication22.WebForm13). Obviously WebForm13_aspx class constructor will be called first. WebForm13_aspx constructor initializes the class dependencies files. The first function to be called is FrameworkInitialize. FrameworkInitialize is a protected function declared in TemplateControl class and implemented just in ASPX file classes. FrameworkInitialize calls __BuildControlTree which is the function that is responsible to create all the page controls. __BuildControlTree calls __ BuildControlWebForm13 that creates the Form and calls __BuildControlXXX for every control on the Form. If control holds child controls, a call will be made to the corresponding __BuildControlXXX of every child control. Every __BuildControlXXX function creates object by the ASPX declaration of the corresponding control, sets its attribute and attaches all events that are declared on the ASPX file. Every function, declared in ASPX file inside SCRIPT block with runat server attribute set to true, generates as class method and connects to the corresponding delegate, if needed.

As I mentioned before, the *.CS file is compiled into assembly in the first instance the ASP.NET is calling a page. More then once, I have observed that changes made in the ASPX file are not reflected in the HTML send to the browser. In such a scenario, deleting the files under the right folder under Temporary ASP.NET will solve the problem since all the files will be recreated. Another issue that you should be aware of is that the events of control initialization in C# do not happen in the code behind file but work perfectly in the ASPX code.

After understanding what goes with ASPX files, we should go back to the page life cycle and update it. There are two classes in that process:

  1. The code behind class � WebForm1.
  2. The generated class for ASPX file � adbdef.

The call orders are:

  1. Construction of adbdef.
  2. Construction of WebForm1.
  3. FrameworkInitialize method of adbdef class will be called.
  4. Calling __ BuildTree and other control build functions.
  5. Calling the Page and controls' events by their order. If event is declared in ASPX file and code behind, the ASPX event will be called first followed by the code behind event.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here