Skip navigation

The Page Class Reloaded

ASP.NET 2.0 Delivers Enhanced Page Class

CoreCoder

LANGUAGES: C#

ASP.NET VERSIONS: 2.0, BETA 1

 

The Page Class Reloaded

ASP.NET 2.0 Delivers Enhanced Page Class

 

By Dino Esposito

 

In ASP.NET, the Page class represents a .aspx file and provides the basic behavior for all Web pages. The content of the .aspx file is parsed at run time to create a class that represents the page in action, with all of its constituent controls up and running. The dynamic class inherits from the base Page class and is created in C# or Visual Basic.NET, according to the page s language setting. In ASP.NET 1.x, if you use code-behind, then the base class for the dynamic class changes to the code-behind class. This doesn t happen in ASP.NET 2.0. Thanks to partial classes a new feature of the .NET Framework the page s base class in ASP.NET 2.0 is always Page (unless you explicitly change it code-wise).

 

The Page class is a built-in HTTP handler that the ASP.NET runtime invokes through the methods of the IHttpHandler interface to finalize the request processing. Furthermore, the class represents a special type of control because it inherits from TemplateControl. The behavior of each page can be declaratively controlled through the attributes of the @Page directive and the set of properties, methods, and events of the Page class.

 

Overall, the structure of the page has not been revolutionized in the transition from ASP.NET 1.x to ASP.NET 2.0. However, quite a few new features have been added. Some are related to the page as an object; some are inherited from the surrounding run-time environment. In this article, I offer you a quick tour of the enhancements.

 

Model the Page s Code

The most important change in ASP.NET 2.0 pages is the code model. Earlier versions of ASP.NET support two models for writing the code to give any Web page a behavior and a goal: the single-file model and the code-behind model. The single-file model requires you to write all the code in a <script> block marked with the runat attribute. This model continues to be supported in version 2.0. The code-behind model is the primary way of working in Visual Studio.NET and requires that markup and code go in separate files. The code-behind model undergoes significant improvements in ASP.NET 2.0.

 

Fortunately, ASP.NET 2.0 supports the code-behind model of ASP.NET 1.x for backward compatibility. In addition, a modified model the code-beside model is introduced. The code-beside model maintains separation between markup and code, but through a different set of keywords and a different implementation.

 

The code-beside model takes advantage of a new language feature known as partial classes. Any page class must contain two types of information: application code, such as event handlers, and glue code, such as instance variables and event binding. Visual Studio.NET 2003 lets you write application code and slipstreams any needed glue code in hidden regions. Visual Studio.NET 2005 only requires that you type in any application code. As a result, the code file is a partial class and doesn t contain a complete class definition. The class definition is completed at compile time and any missing information is inferred from the ASPX markup.

 

The linkage between the ASPX page and the code-beside page is set through the new CompileWith attribute in the @Page directive:

 

<%@ Page Language="C#" CompileWith="Sample.aspx.cs"

 ClassName="Sample" %>

 

The CompileWith attribute replaces the code-behind attribute used by Visual Studio.NET 2003. The ClassName attribute optionally provides a name for the final class.

 

Overall, the new code model is simpler and more effective to use because it doesn t include any code that is required only to support the designer. In addition, you can add controls in the markup without accessing the underlying class to add the corresponding instance variable. The same glue code consumed by ASP.NET 1.x is still needed, but it gets added automatically at compile time.

 

Master the Page

An oft-requested feature after ASP.NET 1.x was anything that permitted inheritance of some graphical features and layout from an existing page. Visual inheritance la Windows Forms is hard to achieve for architectural reasons; master pages provide an excellent solution indeed. A master page sets the look-and-feel, layout, and standard behavior that you want for a group of application pages. In a master page, you define some replaceable regions and name them unambiguously. Next, a page based on that master will fill any regions with the markup content you want to display. A page based on a master is said to be a content page and can t have content other than that for replaceable regions. When users request a content page, the ASP.NET runtime merges master and content page to produce the final output. A page based on a master adds the MasterPageFile attribute to the @Page directive:

 

<%@ Page Language="C#" MasterPageFile="Main.master" %>

 

A master page is similar to a standard page except that it begins with the @Master directive. For more information about master pages, check out Stephen Walther s article Master Pages in ASP.NET 2.0 at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/masterpages.asp.

 

Themes are another key enhancement as far as the appearance of the page is concerned. Much like Windows XP themes, ASP.NET themes assign a set of styles and visual attributes to server controls. A theme consists of CSS files, images, and control skins, and is identified by name. A control skin is a text file that contains default control declarations in which visual properties are set for the control. With this feature enabled, if the developer adds, say, a GridView control to a page, the control is rendered with the default appearance defined in the theme. An empty declaration like the following can provide an attractive graphic result:

 

<asp:gridview runat="server" id="grid" />

 

You attach a theme to a page by using the Theme attribute on the @Page directive:

 

<%@ Page Theme="SmokeAndGlass" %>

 

Each control in the page will inherit the setting as long as theming is enabled for that control. Themes can be defined globally at the Web server level or locally to the application. In the latter case you simply deploy them in the Themes folder below the application s root folder. By the time ASP.NET 2.0 gets closer to its RTM stage, a few themes should be made available as free downloads from the http://www.asp.net Web site.

 

Serve Each User a Custom Page

ASP.NET applications do not necessarily require a rich set of personalization features. However, if you can build an effective personalization layer into your Web application, the application will be friendlier, more functional, and more appealing to use. For some applications (such as portals and shopping centers), though, personalization is crucial. Personalization touches on the graphical appearance (typically themes) of the pages, but also infrastructural aspects, such as the user profile.

 

The user profile is a collection of custom data, and related type-safe API, that is associated with a particular user of an ASP.NET 2.0 application. The application defines its own model of personalized data, and the ASP.NET runtime does the rest by parsing and compiling that model into a class. Each member of the personalized class data corresponds to a piece of information specific to the current user. Loading and saving personalized data is completely transparent to end users and doesn t even require the page author to know much about the internal plumbing. (By the way, a new HTTP module does the job by hooking the begin-request and end-request events.)

 

Any personalization data is persisted on a per-user basis and is permanently stored until someone with administrative privileges deletes it. The layout of the user profile is defined in the <profile> node of the configuration file and consists of a list of properties that can take any of the .NET types:

 

<profile>

 <properties>

  <add name="BackColor" type="string" />

  <add name="ForeColor" type="string" />

  <add name="Height" type="int" />

  <add name="Width" type="int" />

  <add name="LastUpdate" type="System.DateTime" />

 </properties>

</profile>

 

This data is dynamically parsed and compiled into a class that inherits from the HttpProfileBase class (see Figure 1). An instance of the HttpProfile class is attached to the current HttpContext object and is available to pages through the Profile property.

 

A sample user profile class

namespace ASP

{

 public class HttpProfile : HttpProfileBase

 {   

   public virtual string BackColor

   {

     get {(string) GetPropertyValue("BackColor");}

     set {SetPropertyValue("BackColor", value);}

   }

   public virtual string ForeColor

   {

     get {(string) GetPropertyValue("ForeColor");}

     set {SetPropertyValue("ForeColor", value);}

   }

   // Other properties here

   :

   public virtual HttpProfile GetProfile(string username)

   {

     object o = HttpProfileBase.Create(username);

     return (HttpProfile) o;

   }

 }

}

Figure 1: Dynamically parsed data compiled into a class that inherits from HttpProfileBase.

 

Here s how to access the user profile information programmatically:

 

void Page_Load(object sender, EventArgs e)

{

 // Sets the background color of the page

 // (Assumes theBody is the ID of the <body> tag)

 if (Profile.BackColor != Color.Empty)

    theBody.Attributes["bgcolor"] = Profile.BackColor;

 :

}

 

A key element of the personalization system is the data storage system. ASP.NET 2.0 uses ad hoc providers to perform any tasks involved with the storage and retrieval of values. ASP.NET 2.0 comes with two personalization providers, each of which uses a different data engine. In Beta 1, the default provider uses an Access database and the other provider is for SQL Server. (Taking into account the Express Edition of SQL Server 2005, I expect this to change by the time ASP.NET 2.0 ships.)

 

You can also write custom providers. The provider writes data into the database of choice and is responsible for the final schema of the data. A personalization provider must be able to either serialize the type (by using XML serialization and binary object serialization, for example) or know how to extract significant information from it.

 

There s a tight relationship between user accounts and profile information. The default storage system reserves a record for each registered user and stores there any user-specific information. Anonymous users are supported too. They are assigned a built-in anonymous ID and store and retrieve settings using that. However, if at a certain point a hitherto anonymous user decides to create an account with the Web site, you might need to migrate to its account all the settings that she made as an anonymous user. This migration doesn t occur automatically. The underlying personalization HTTP module fires an event MigrateAnonymous that, properly handled, allows you to import anonymous settings into the profile of a logged-on user (see Figure 2).

 

Migrate the user profile of an anonymous user

void Personalization_MigrateAnonymous(object sender,

   AnonymousIdentificationEventArgs e)

{

 // Get the profile of the anonymous user

 HttpProfile anonProfile;

 anonProfile = Profile.GetProfile(e.AnonymousId);

 // Migrate all properties to the new profile

 Profile.BackColor = anonProfile.BackColor;

 Profile.ForeColor = anonProfile.ForeColor;

 :

}

Figure 2: MigrateAnonymous allows you to import anonymous settings into the profile of a logged-on user.

 

Script Enhancements

A couple of loudly requested script features find their way into ASP.NET 2.0. They are: script callbacks and cross-page posting. In addition, the scripting object model includes methods and properties to set the input focus to a control and get and set the title and the header of the page. Let s focus on script callbacks; refer to the MSDN documentation for the other features.

 

Script callbacks allow you to execute out-of-band calls back to the server. These calls are postbacks and require a roundtrip; however, unlike classic postbacks, script callbacks don t redraw the whole page and give users the illusion that everything is taking place on the client. In ASP.NET 2.0, the TreeView control uses script callbacks extensively to implement its expand/collapse features. A page that supports out-of-band calls must implement the ICallbackEventHandler interface:

 

<%@ Implements Interface=

 "System.Web.UI.ICallbackEventHandler" %>

 

The ICallbackEventHandler interface has only one method, RaiseCallbackEvent. The method receives a string that contains client-side values formatted at your best convenience. It returns another free-formatted string to be passed to the client JavaScript callback:

 

public string RaiseCallbackEvent(string eventArgument)

{

 // Retrieve the updated values for the client page

}

 

You must also provide a JavaScript callback function with a given signature to be invoked when the parallel postback completes. The out-of-band call is triggered by a client event, like a click. Here s how to start a postback when a non-submit button is pressed:

 

// Prepare the JavaScript function to call

string callbackRef = GetCallbackEventReference(this,

 "document.all['cboEmployees'].value",

 "UpdateEmployeeViewHandler", "null", "null");

// Bind the callback to a client button

buttonTrigger.Attributes["onclick"] =

 String.Format("javascript:{0}", callbackRef);

 

GetCallbackEventReference a new method of the Page class returns the JavaScript call that triggers the postback. You pass the expression that retrieves the client-side values to send back to the server and the name of a client JavaScript function being the callback. The callback function UpdateEmployeeViewHandler in the above example receives server values and updates the page using Dynamic HTML. A browser with ActiveX support is required for script callbacks to work; Internet Explorer 5.0 is the minimum browser required.

 

Conclusion

This article condensed in few pages the must-know new features of the Page class in ASP.NET 2.0. For obvious space constraints, no feature has been covered in depth. However, the key enhancements have been illustrated to whet your appetite and encourage you to learn more through books, other articles, and, first and foremost, the MSDN documentation. Happy learning!

 

The sample code accompanying this article is available for download.

 

Dino Esposito is a Wintellect trainer and consultant who specializes in ASP.NET and ADO.NET. Author of Programming Microsoft ASP.NET and the recently released Introducing ASP.NET 2.0 (both from Microsoft Press), Dino also helped several companies architect and build effective products for ASP.NET developers. Dino is the cofounder of http://www.VB2TheMax.com, a popular portal for VB and .NET programmers. Write to him at mailto:[email protected] or join the blog at http://weblogs.asp.net/despos.

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish