Article

Object Oriented C# for ASP.NET Developers

Page: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Next

Code-Behind Pages in ASP.NET

Okay, so I've waffled on for what must seem like forever, and all you've learned how to do is grow trees (and nuts!). "When's he going to get to the point?!" you must be asking. Either that, or you already know the basic concepts of OOP and you've skipped directly here for the meat.

Well here's the payoff:

Everything in ASP.NET is an object.

Everything... including the pages themselves. Every .aspx page you write is automatically compiled into a class that inherits from the System.Web.UI.Page class, which is built into the .NET Framework.

Everything that ASP.NET pages do automatically is handled by that class (e.g. calling the Page_Load function -- which is actually a method -- before the page is displayed). So creating a site of ASP.NET pages is actually a process of creating subclasses of System.Web.UI.Page. This is illustrated in Fig. 6.

ASP.NET pages inherit from System.Web.UI.Page by defaultFig. 6 ASP.NET pages inherit from System.Web.UI.Page by default

Okay, I can see you're getting impatient again. How about I tell you what this gives you (besides a headache)?

The object-oriented nature of ASP.NET lets you achieve complete separation of design code (HTML) and server-side code. The technique for doing this is called Code-Behind. The idea is that you create a subclass of System.Web.UI.Page that contains all your server-side code, and then make your .aspx page (which contains all your design code) inherit from that class instead of from System.Web.UI.Page (see Fig. 7).

Code-Behind files: server-side logic, and design code are kept separateFig. 7 Code-Behind files: server-side logic, and design code are kept separate

Not convinced? Let's look at an example.

Here's the code for the last example we saw in ASP.NET Form Processing Basics:

<%@ Page Language="C#" %>              
<html>              
<head>              
<title>My First ASP.NET Form</title>              
<script runat="server">              
 protected void Page_Load(Object Source, EventArgs E) {              
   if (IsPostBack) {              
     NameForm.Visible = false;              
     NameLabel.Text = NameBox.Text;              
     NameLabel.Style.Add( "font-weight", "bold" );              
   }              
                 
   TimeLabel.Text = DateTime.Now.ToString();              
 }              
</script>              
</head>              
<body>              
             
<p>Hello <asp:label runat="server" id="NameLabel">there              
</asp:label>!</p>              
             
<form runat="server" id="NameForm">              
 <p>Do you have a name?</p>              
 <p><asp:textbox runat="server" id="NameBox" />              
   <input type="submit" value="Submit" /></p>              
</form>              
             
<p>The time is now: <asp:label runat="server" id="TimeLabel" /></p>              
             
</body>              
</html>

Now, this is a relatively simple ASP.NET page, and yet the server-side code (the Page_Load method) takes up about half the page. An HTML-and-JavaScript designer who had to tweak the design of a more typical ASP.NET page would suffer a coronary at the sight of the code in the file (many ASP developers had trouble keeping designers around for this very reason).

In addition, if a Web development team composed of server-side developers and Web designers had to work on a site collaboratively, the tug-of-war involved in letting team members of both types work on a page at the same time would be next to unmanageable!

Let's create a class called HelloTherePage that contains all the server-side code:

using System;              
using System.Web;              
using System.Web.UI;              
using System.Web.UI.HtmlControls;              
using System.Web.UI.WebControls;              
             
public class HelloTherePage : Page {              
 protected HtmlForm NameForm;              
 protected Label NameLabel;              
 protected Label TimeLabel;              
 protected TextBox NameBox;              
             
 protected void Page_Load(Object Source, EventArgs E) {              
   if (IsPostBack) {              
     NameForm.Visible = false;              
     NameLabel.Text = NameBox.Text;              
     NameLabel.Style.Add( "font-weight", "bold" );              
   }              
                 
   TimeLabel.Text = DateTime.Now.ToString();              
 }              
}

First note the block of using commands at the top of the file. Since we're not inside a .aspx file anymore, we don't have the benefit of all the automatic namespace imports we had before; therefore, we must explicitly import the namespaces we want to use. The five namespaces I've used here are the most common for ASP.NET programs.

The Page_Load method is defined exactly as it was in the .aspx page above. Note that it is declared protected, since the only class that needs to call this class is the subclass we're going to create with our .aspx file (recall that protected means a member is accessible only by the class itself or any of its subclasses).

Also declared in this class are four protected fields: NameForm, NameLabel, TimeLabel, and NameBox. These are the ID's of the page elements that Page_Load accesses in the page. In the .aspx subclass, these fields will be overridden by the actual elements (e.g. <asp:label id="NameLabel"> overrides NameLabel), but they must be declared in this class so that C# doesn't get confused when we refer to them in Page_Load.

Since NameLabel and TimeLabel represent <asp:label> tags in the .aspx page, they should be objects of class System.Web.UI.WebControls.Label (which we can abbreviate as Label, since our file is using the System.Web.UI.WebControls namespace). NameBox is a <asp:textbox> and is therefore a System.Web.UI.WebControls.TextBox. NameForm is an HTML <form> tag, which is represented by an object of class System.Web.UI.HtmlControls.HtmlForm. In general, all ASP.NET tags (<asp:tagName>) have their corresponding classes in the System.Web.UI.WebControls namespace, while HTML tag classes are in System.Web.UI.HtmlControls, and have names of the form HtmlTagName.

Save this file as HelloThere.cs in the same directory as the .aspx page (don't worry -- IIS is smart enough not to allow Web browsers to view C# and other .NET source code files in Web-accessible directories). Now let's re-write HelloThere.aspx to use the Code-Behind file we have just written:

<%@ Page Inherits="HelloTherePage" src="HelloThere.cs" %>              
<html>              
<head>              
<title>My First ASP.NET Form</title>              
</head>              
<body>              
             
<p>Hello <asp:label runat="server" id="NameLabel">there              
</asp:label>!</p>              
             
<form runat="server" id="NameForm">              
 <p>Do you have a name?</p>              
 <p><asp:textbox runat="server" id="NameBox" />              
   <input type="submit" value="Submit" /></p>              
</form>              
             
<p>The time is now: <asp:label runat="server" id="TimeLabel" /></p>              
             
</body>              
</html>

The changes are dramatic, but very simple! I've simply removed the <script> tag that contained the Page_Load method, which is now defined in HelloTherePage, the base class of this page defined in the Code-Behind file, and added two new attributes to the Page directive on the first line. I also removed the Language attribute from this directive, since there is no longer any server-side code in this file for which a language would need to be specified.

The Inherits attribute is set to the name of the class from which this page should inherit. By default, this is System.Web.UI.Page. The src attribute tells the ASP.NET page compiler where to find the source code for the class specified. ASP.NET uses this attribute to intelligently compile the Code-Behind file for you on the fly and put the resulting .dll file in the bin directory of the Web application, so that this page can find it. You could of course do this manually, but it's much easier to let ASP.NET do the work of recompiling the Code-Behind file whenever you make changes automatically.

With HelloThere.cs and HelloThere.aspx in the same directory on your Web server, you should be able to load HelloThere.aspx as usual and find that it behaves exactly as it did before you split the server-side code into a separate file.

If you liked this article, share the love:
Print-Friendly Version Suggest an Article

Sponsored Links