How Things Work – ASP.NET 2.0 – CodeBehind

Series Theme

This how-to series is my personal exploration into figuring out not just how to make things work, but how they actually work. The theme behind this series is: "If it’s not broken, take it apart and try and figure out why". I plan on covering many issues in ASP.NET 2.0. If you are interested in a particular part of ASP.NET 2.0 that I have not covered, please contact me and time permitting, I’ll see if I can figure out how it works.

Abstract

In this article, a simple asp.net 2.0 page will be taken apart and shown how the actual page class is put together. As we know, when an http request comes into asp.net through the http pipeline that is destined to be a page (file type aspx), the objective of asp.net 2.0 is to create a complete class that encapsulates that page request. That page class is an httpHandler of course.

Example Page

The Example Page simply has three Labels and one Button. The Labels and buttons will be as follows:

  • Label1 – Gets Date and Time set in Page_Load event
  • Label2 – Gets Date and Time using databinding
  • Label3 – Gets Date and Time when button is pressed
  • Button1 – Puts Date and Time in Label3 as well as executes DataBind on control Label2

Here is the page code below. (CodeBehindSample1.aspx)

< %@ Page Language="C#" AutoEventWireup="true" CodeFile="CodeBehindSample1.aspx.cs" Inherits="CodeBehindSample1" %>
 
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp :Label ID="Label1" runat="server" ></asp>
        <asp :Label ID="Label2" runat="server"
          Text='<%# DateTime.Now.ToLongTimeString() %>'></asp>
        <asp :Label ID="Label3" runat="server" Text="Label"></asp>
        <asp :Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
 
    </div>
    </form>
</body>
</html>

And the codebehind file itself. ((CodeBehindSample1.aspx.cs)

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
 
public partial class CodeBehindSample1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Label1.Text = DateTime.Now.ToLongTimeString();
    }
 
    protected void Button1_Click(object sender, EventArgs e)
    {
        Label3.Text = DateTime.Now.ToLongTimeString();
        Label2.DataBind();
    }
}

When the project is built that includes this page above, an .net assembly is created that represents the above page. The files are stored in a directory called something like C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\pagecache\6b6b75e0\f0cbf892. There are two files that are worth looking at.

App_Web_qlh7npdn.1.cs and App_Web_qlh7npdn.0.cs (I will refer to them as 1.cs and 0.cs from here on out).

0.cs has two classes of interest to talk about.

The first one, (1.cs) declared as "public partial class CodeBehindSample1 : System.Web.SessionState.IRequiresSessionState {" includes a definition for each of the controls declared on the aspx page. It gives us a reference to Profile and ApplicationInstance from the Context of the application (originally created when the request came in).

The second one, (0.cs) which is created in the namespace ASP, (in our case is called ASP.codebehindsample1_aspx which is because of what is defined in the Page tag Inherits) is the full page that represents this request. It has a method that builds each control including databinding. Notice that this class actually inherits from the first one mentioned (1.cs). The actual declaration is as follows: "public class codebehindsample1_aspx : global::CodeBehindSample1, System.Web.IHttpHandler {"

There are several things to notice about this generated code. Here is a list to pay attention to.

  • In the code generated for the button (private global::System.Web.UI.WebControls.Button @__BuildControlButton1() {

    global::System.Web.UI.WebControls.Button @__ctrl;) notice that the text is set to "Button" and the ID is set to Button1. This is the code created from the attribute definition in the aspx file.
  • Notice how the event handler Button1_Click is created in code. @__ctrl.Click += new System.EventHandler(this.Button1_Click);
  • For databinding on Label2, notice that the member "public void @__DataBindingLabel2(object sender, System.EventArgs e) {". You can see how the datacontainer is created, then the dataBindingExpressionBuilderTarget.Text is set to the current data and time.

Conclusion

In conclusion, you can see that at the end of the day, one class is created (ASP.codebehindsample1_aspx) that fully represents the page. Attributes that are set declaratively in the page are turned into code in the 0.cs file, and databinding is performed using a artificially generated event. Below, I’ve pasted both the code for 0.cs and 1.cs which should be helpful and instructive

0.cs

//------------------------------------------------------------------------------
// <auto -generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.42
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto>
//------------------------------------------------------------------------------
 
 
 
public partial class CodeBehindSample1 : System.Web.SessionState.IRequiresSessionState {
 
 
    protected global::System.Web.UI.WebControls.Label Label1;
    protected global::System.Web.UI.WebControls.Label Label2;
    protected global::System.Web.UI.WebControls.Label Label3;
    protected global::System.Web.UI.WebControls.Button Button1;
    protected global::System.Web.UI.HtmlControls.HtmlForm form1;
 
    protected System.Web.Profile.DefaultProfile Profile {
 
        get {
            return ((System.Web.Profile.DefaultProfile)(this.Context.Profile));
        }
    }
 
    protected System.Web.HttpApplication ApplicationInstance {
        get {
            return ((System.Web.HttpApplication)(this.Context.ApplicationInstance));
        }
    }
}
namespace ASP {
 
 
    using System.Web.Profile;
    using System.Text.RegularExpressions;
    using System.Web.Caching;
    using System.Configuration;
    using System.Collections.Specialized;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls
    using System.Web.UI;
    using System.Collections;
    using System;
    using System.Web.Security;
    using System.Web;
    using System.Web.SessionState;
    using System.Text;
 
 
 
    [System.Runtime.CompilerServices.CompilerGlobalScopeAttribute()]
    public class codebehindsample1_aspx : global::CodeBehindSample1,
           System.Web.IHttpHandler {
 
        private static bool @__initialized;
 
        private static object @__fileDependencies;
 
        public codebehindsample1_aspx() {
            string[] dependencies;
 
            ((System.Web.UI.Page)(this)).AppRelativeVirtualPath =
            "~/CodeBehindSample1.aspx";
 
            #line default
            #line hidden
            if ((global::ASP.codebehindsample1_aspx.@__initialized == false)) {
                dependencies = new string[2];
                dependencies[0] = "~/CodeBehindSample1.aspx";
                dependencies[1] = "~/CodeBehindSample1.aspx.cs";
                global::ASP.codebehindsample1_aspx.@__fileDependencies =
                this.GetWrappedFileDependencies(dependencies);
                global::ASP.codebehindsample1_aspx.@__initialized = true;
            }
            this.Server.ScriptTimeout = 30000000;
        }
 
        private global::System.Web.UI.HtmlControls.HtmlTitle
             @__BuildControl__control3() {
            global::System.Web.UI.HtmlControls.HtmlTitle @__ctrl;
 
 
            @__ctrl = new global::System.Web.UI.HtmlControls.HtmlTitle();
 
 
            System.Web.UI.IParserAccessor @__parser =
            ((System.Web.UI.IParserAccessor)(@__ctrl));
 
 
            @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("Untitled Page"));
 
 
            return @__ctrl;
        }
 
        private global::System.Web.UI.HtmlControls.HtmlHead @__BuildControl__control2() {
            global::System.Web.UI.HtmlControls.HtmlHead @__ctrl;
 
 
            @__ctrl = new global::System.Web.UI.HtmlControls.HtmlHead("head");
 
 
            global::System.Web.UI.HtmlControls.HtmlTitle @__ctrl1;
 
 
            @__ctrl1 = this.@__BuildControl__control3();
 
 
            System.Web.UI.IParserAccessor @__parser =
               ((System.Web.UI.IParserAccessor)(@__ctrl));
 
 
            @__parser.AddParsedSubObject(@__ctrl1);
 
            return @__ctrl;
        }
 
        private global::System.Web.UI.WebControls.Label @__BuildControlLabel1() {
            global::System.Web.UI.WebControls.Label @__ctrl;
 
 
            @__ctrl = new global::System.Web.UI.WebControls.Label();
 
 
            this.Label1 = @__ctrl;
            @__ctrl.ApplyStyleSheetSkin(this);
 
 
            @__ctrl.ID = "Label1";
 
            #line default
            #line hidden
            return @__ctrl;
        }
 
        private global::System.Web.UI.WebControls.Label @__BuildControlLabel2() {
            global::System.Web.UI.WebControls.Label @__ctrl;
 
 
            @__ctrl = new global::System.Web.UI.WebControls.Label();
 
 
            this.Label2 = @__ctrl;
            @__ctrl.ApplyStyleSheetSkin(this);
 
 
            @__ctrl.ID = "Label2";
 
 
            @__ctrl.DataBinding += new System.EventHandler(this.@__DataBindingLabel2);
 
            #line default
            #line hidden
            return @__ctrl;
        }
 
        public void @__DataBindingLabel2(object sender, System.EventArgs e) {
            System.Web.UI.WebControls.Label dataBindingExpressionBuilderTarget;
            System.Web.UI.Page Container;
            dataBindingExpressionBuilderTarget =
            ((System.Web.UI.WebControls.Label)(sender));
            Container =
            ((System.Web.UI.Page)(dataBindingExpressionBuilderTarget.BindingContainer));
 
 
            dataBindingExpressionBuilderTarget.Text =
            System.Convert.ToString( DateTime.Now.ToLongTimeString() ,
             System.Globalization.CultureInfo.CurrentCulture);
 
        }
 
        private global::System.Web.UI.WebControls.Label @__BuildControlLabel3() {
            global::System.Web.UI.WebControls.Label @__ctrl;
 
 
            @__ctrl = new global::System.Web.UI.WebControls.Label();
 
 
            this.Label3 = @__ctrl;
            @__ctrl.ApplyStyleSheetSkin(this);
 
 
            @__ctrl.ID = "Label3";
 
 
            @__ctrl.Text = "Label";
 
            #line default
            #line hidden
            return @__ctrl;
        }
 
        private global::System.Web.UI.WebControls.Button @__BuildControlButton1() {
            global::System.Web.UI.WebControls.Button @__ctrl;
 
 
            @__ctrl = new global::System.Web.UI.WebControls.Button();
 
 
            this.Button1 = @__ctrl;
            @__ctrl.ApplyStyleSheetSkin(this);
 
 
            @__ctrl.ID = "Button1";
 
 
            @__ctrl.Text = "Button";
 
            #line default
            #line hidden
 
 
            @__ctrl.Click += new System.EventHandler(this.Button1_Click);
 
 
            return @__ctrl;
        }
 
        private global::System.Web.UI.HtmlControls.HtmlForm @__BuildControlform1() {
            global::System.Web.UI.HtmlControls.HtmlForm @__ctrl;
 
 
            @__ctrl = new global::System.Web.UI.HtmlControls.HtmlForm();
 
 
            this.form1 = @__ctrl;
 
 
            @__ctrl.ID = "form1";
 
 
            System.Web.UI.IParserAccessor @__parser =
            ((System.Web.UI.IParserAccessor)(@__ctrl));
 
 
            @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n    <div>\r\n    "));
 
 
            global::System.Web.UI.WebControls.Label @__ctrl1;
 
 
            @__ctrl1 = this.@__BuildControlLabel1();
 
 
            @__parser.AddParsedSubObject(@__ctrl1);
 
 
            @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n        "));
 
 
            global::System.Web.UI.WebControls.Label @__ctrl2;
 
 
            @__ctrl2 = this.@__BuildControlLabel2();
 
 
            @__parser.AddParsedSubObject(@__ctrl2);
 
 
            @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n        "));
 
 
            global::System.Web.UI.WebControls.Label @__ctrl3;
 
 
            @__ctrl3 = this.@__BuildControlLabel3();
 
 
            @__parser.AddParsedSubObject(@__ctrl3);
 
            #line default
            #line hidden
 
 
            @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n        "));
 
 
            global::System.Web.UI.WebControls.Button @__ctrl4;
 
 
            @__ctrl4 = this.@__BuildControlButton1();
 
            #line default
            #line hidden
 
 
            @__parser.AddParsedSubObject(@__ctrl4);
 
            #line default
            #line hidden
 
 
            @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n       \r\n    </div>\r\n    "));
 
            #line default
            #line hidden
            return @__ctrl;
        }
 
        private void @__BuildControlTree(codebehindsample1_aspx @__ctrl) {
 
 
            this.InitializeCulture();
 
 
            System.Web.UI.IParserAccessor @__parser = ((System.Web.UI.IParserAccessor)(@__ctrl));
 
 
            @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl
            ("\r\n\r\n< !DOCTYPE html
            PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"
             \"http://www.w3" +
                        ".org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
                        \r\n\r\n<html xmlns=\"http://www.w3.org/1" +
                        "999/xhtml\" >\r\n"));
 
 
            global::System.Web.UI.HtmlControls.HtmlHead @__ctrl1;
 
 
            @__ctrl1 = this.@__BuildControl__control2();
 
            #line default
            #line hidden
 
 
            @__parser.AddParsedSubObject(@__ctrl1);
 
 
            @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n<body>\r\n    "));
 
 
            global::System.Web.UI.HtmlControls.HtmlForm @__ctrl2;
 
 
            @__ctrl2 = this.@__BuildControlform1();
 
 
            @__parser.AddParsedSubObject(@__ctrl2);
 
 
 
            @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n</body>\r\n</html>\r\n"));
 
 
        }
 
 
 
        protected override void FrameworkInitialize() {
            base.FrameworkInitialize();
            this.@__BuildControlTree(this);
            this.AddWrappedFileDependencies(global::ASP.codebehindsample1_aspx.@__fileDependencies);
            this.Request.ValidateInput();
        }
 
 
 
        public override int GetTypeHashCode() {
            return -956737817;
        }
 
        public override void ProcessRequest(System.Web.HttpContext context) {
            base.ProcessRequest(context);
        }
    }
}

1.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
 
public partial class CodeBehindSample1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Label1.Text = DateTime.Now.ToLongTimeString();
    }
 
    protected void Button1_Click(object sender, EventArgs e)
    {
        Label3.Text = DateTime.Now.ToLongTimeString();
        Label2.DataBind();
    }
}
 
 
#line default
#line hidden
About Peter Kellner

Follow me:


Comments

  1. From what has been reported and rumored, there might be a youtube app with it at launch that would let you play videos. ,

  2. Peter Kellner says:

    If you want to find out where your temp files are created for asp.net, check out this blog post:

    http://peterkellner.net/2008/08/18/find-temp-aspnet-assembly-executing-reflection/

Follow

Get every new post delivered to your Inbox

Join other followers: