Behind the scenes of ASPX files

ASP.NET pages usually made up from two files the ASPX file which contain the page visualization declaration and *.cs file which contain 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 (http://www.15seconds.com/issue/020102.htm) this is not the case of ASPX files.

 

Well what is really happened to those ASPX files? In the end of the day ASP.NET turn each ASPX file into assembly. While page is been called for the first time ASP.NET  :

1)      generate *.cs file holding code that match the ASPX declarations.

2)      Using csc.exe (C# compiler) to compile *cs file into DLL (you can see csc.exe if you monitor running processes).

3)      Running the compiled DLL

This sequence is happened just one time resulting with DLL that will be used for other request until one of the page dependencies file will be change and this sequence will be forced again. If you ever wonder why running application for the first time take so much time you probably got good notion why.

 

To understand better what is going on here let’s take very simple page and follow those steps. I create simple page that hold Panel, Textbox and server side script inside ASPX file. Bellow 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. Where the last two folders are randomly numbers 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 file. The last folder also contain folder called Assembly that holds another directory: dl2. The “dl2” folder contains sub folders with randomly number names each for every referenced assembly from the web project, including the application DLL. We will be focused in the folder that contains all the files generated for ASPX, ASCX and ASAX files.

 

The first file that we interest in is XML file holding the page name (WebForm13.aspx.4689d8a0.xml) . This file contains information that map between the web page name and randomly number that will be used by ASP.NET to generate that page files. Beside the mapping information this file contains data on the decency files of that page (change in that files 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 grasping that every file that starting with “jibrfh34“ are files that generated for certain page lets see what every file used to. The most important file is *.cs. this file holds the generated C# lines correspond to ASPX Tags and code, we will discuss it later.  The *res file holds resources that the compiler will use them. *cmdline holds the command line that will be use by ASP.NET to compile the *cs file. The file includes reference to other assemblies and optimization settings. *.err file contains errors (if ocured)  while compiling *.cs file. *out file contain outputs from the compilation process. *.dll and *pdb are naturally the compilation output.

 

Out next step is deep diving into *.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;

        }

    }

}

 

In a fast glimpse 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 from it a lot.

Every file is definition of 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. First the class constructor will be called. The constructor initialize the class dependencies files. The first function to be called is FrameworkInitialize. FrameworkInitialize called __BuildControlTree function that responsible to create all the page controls. __BuildControlTree called __ BuildControlWebForm13 that create the Form and called __BuildControlXXX for every control on the form. If control holds child’s controls a call will be made to the corresponding __BuildControlXXX of every child control. Every function create object by the ASPX declaration set its attribute and attached all events that declared on ASPX file. Every function declared in ASPX file generate as class method and connected to the correspond delegate, if needed.

 

As I mention the *CS file is compiled into assembly just the first time ASP.NET is calling a page. More then once I saw that changes that made in the ASPX file are not reflected in the HTML send to the browser. In such 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 events of control initialization in c# aren’t happened in the code behind file but works perfectly in the ASPX code.

 

After understanding what goes with ASPX files, let 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 calls orders are:

1)      Constructing of adbdef.

2)      Constructing 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 will be declared in ASPX file and code behind, the ASPX event will be called first following by the code behind event.

 

15 Comments

  • Please use the article feature for such a long post! This is more an article than a journal entry.



    thank you

  • I was going to comment something similar :), but I was also going to bring your attention to the &quot;syndicate description/excerpt&quot; feature.



    This will allow you to syndicate a short desc, and then have readers follow through to your blog to read the gory details.



    -Scott

  • This is a great writeup! Thanks!

  • Wonderful article - I have saved this one in my reference toolkit.



    Take care!

  • Very good stuff. I want to translate it to chinese.

  • technofantasy,



    You wellcome to do it.

  • I ought to admit to ignoring it for some time while simply because it seemed like long and tedious work.
    This website assessment criteria can help you realize status
    compared in your competitors. It sounds obvious but some people don't take notice of this one.

  • I have been surfing online greater than three hours these days,
    but I by no means discovered any attention-grabbing article like yours.
    It is pretty worth enough for me. In my view, if all web owners and bloggers made excellent content material as you did, the internet will likely be much
    more useful than ever before.

  • Every weekend i used to pay a visit this site, because i wish for enjoyment,
    for the reason that this this website conations truly good funny stuff
    too.

  • Hi there, after reading this amazing article i am also cheerful to share my know-how here with friends.

  • Definitely believe that which you said. Your favourite
    justification appeared to be on the net the easiest factor to remember of.
    I say to you, I certainly get annoyed whilst folks consider concerns that they plainly don't understand about. You controlled to hit the nail upon the top and defined out the whole thing with no need side-effects , folks can take a signal. Will probably be back to get more. Thanks

  • Magnificent goods from you, man. I have take into account your stuff previous to and you are simply too wonderful.

    I actually like what you've acquired here, certainly like what you are stating and the best way through which you are saying it. You make it entertaining and you still take care of to keep it sensible. I cant wait to learn far more from you. That is really a terrific web site.

  • If some one desires to be updated with most recent technologies
    after that he must be pay a quick visit this web page and be up
    to date all the time.

  • I for all time emailed this weblog post page to all my friends, for the reason that if like
    to read it then my links will too.

  • My brother recommended I might like this website.
    He was totally right. This post truly made my day.

    You can not imagine just how much time I had spent for this info!
    Thanks!

Comments have been disabled for this content.