Rich Internet applications Web

Just another WordPress.com weblog

Dynamic Themes and META Data using ASP.NET 2.0 Master Pages Tháng Tư 16, 2009

Chuyên mục: C# — riasweb @ 11:49 chiều

ASP.NET 2.0 introduced two pieces of functionality that Web application developers have been thirsting for since ASP.NET was first created: Themes and Master Pages. As with any new technology, there are a few caveats that make the default implementation of these new technologies slightly less than ideal. In this tutorial, I will explain a very straightforward way to implement Master Pages and Themes to allow the user to select a theme as well as how to place META data in the header of a Master Page without CodeBehind.

Download Solution: _05_2007_MasterPages.zip (16.0KB)

Part 1: Implementing a Dynamic Theme Mechanism

Allowing users to select their own theme for your Web application is a feature that is gaining large amounts of popularity amongst users. ASP.NET 2.0 offers many ways to accomplish a theme implementation for your website, such as specifying a theme name in the <%@ Page %> directive of a Web Form, specifying a Theme in the Web.config file for your application or setting the Theme property of the Page class. All of these options provide a great way for administrators to apply themes to their apps, but there are some significant drawbacks to each:

  • Specifying a theme name in the <%@ Page %> directive of each Web Form is a nightmare from a maintainability standpoint. In Web apps that may have hundreds of Pages, you would have to update the Theme attribute in every Web Form.
  • Storing the Theme in the <pages/> element of the Web.config file solves the issue of having to update each page individually, but it also comes with its own baggage. If you use the Publish Web Site option in Visual Studio 2005, VS will hard-code the theme name into the Theme attribute of the <%@ Page %> directive on all pages that have any CodeBehind specified. If you then later change the name of the Theme in the Web.config file, all ASPX content pages will reflect the change, but any pages with CodeBehind .dll files in the Bin directory of your app will still use the theme that was specified in the Web.config when you published the site. Also, changing the Theme in the Web.config will cause IIS to recycle the application. Again, this is less than ideal.
  • Finally, setting the Theme programmatically by setting the Theme property of the Page is a pretty appetizing solution. Unfortunately, a Theme is applied to an ASP.NET Web Form very early in execution, so you must do so before the Page initializes. This is typically handled in a PreInit event handler for a page. Furthermore, this requires you to create this event handler in every page of your application that uses your Theme.

I know what many of you are saying: Why can’t I just specify a PreInit event handler in the MasterPage that is used by all of my pages? Unfortunately this does not work because the MasterPage is first compiled, then applied to the Page. The Page class sets the Theme after the MasterPage has already been applied, thus we are once again stuck.

I have seen many posts on forums that show how to accomplish this through a rather lengthy process of using an HttpModule to set the theme. While this solution works fine, it’s a bit of an over complication. To solve this issue we need look no further than one of the most useful techniques in object oriented programming: Inheritance.

By deriving a class from the System.Web.UI.Page class, we are able to create the functionality necessary to give our users a theme rich experience with a simple event handler. In this example, I am using a class named AppCookie to store the theme name and AppPageBase is my Page derived class. The Theme property of the AppCookie class is read from a PreInit event handler that is subscribed to the PreInit event from the body of the AppPageBase constructor.

The event handler body is somewhat simple. A new instance of an AppCookie is created and tested to see if the Theme property is empty. If the property is not empty, the specified theme is applied to the page. If it is empty, the default theme which is defined in the <appSettings/> element of my Web.config file is applied instead.

The last step of the process is to ensure that all pages in the application use our AppPageBase class as the base type for all ASP.NET pages. To do so, we change the inherited class on all CodeBehind class definitions to that of our custom class. We must also change the page base type for all pages in the application that may not use CodeBehind. To accomplish this, specify the pageBaseType attribute of the <pages/> element to be the name of our custom class. Finally, I then added a few <asp:LinkButton /> controls to a Web Form to allow the switching between themes to be done by the user.

This implementation allows the user to control the theme, but could very easily be modified to allow only administrators to control the theme. You could store the selected theme in a text or XML file, or use the Web Configuration API to change the value of the default theme in our app settings. If an admin only theme scenario is what you are facing, I would recommend using an external file to store the selected theme. This way IIS will not restart your app every time you make a theme change, as it would if this data was stored in the Web.config.

Code for Part 1: AppCookie, AppPageBase (A), Web.config

Part 2: META Data in Master Pages

Although META data in the <head/> of an HTML document does not carry as much weight with regard to search engines as it once did, it is still a valuable compliment to any Search Engine Optimization strategy. Unfortunately, when using a MasterPage in ASP.NET 2.0, we lose our declarative control over META data and must rely on programmatic alternatives. Adding a META tag to a Web Form that uses a MasterPage is accomplished by creating an instance of a System.Web.UI.HtmlControls.HtmlMeta object, assigning values to its properties and then adding it to the Controls collection of the Page.Header control. Obviously, this becomes troublesome when using a MasterPage on a Web Form that is only a content page and has no CodeBehind to perform this operation. Luckily, our AppPageBase can be extended to give us the ability to enter META data directly into the <%@ Page %> directive.

In our example we are creating two properties in our AppPageBase class; MetaDescription and MetaKeywords. These are simple string values that will be used to store description and keyword data. To output these values to the page, we will create and attach an event handler to the Init event of the Page in the same manner as before. The body of the event handler will create an instance of an HtmlMeta object and use the two properties defined earlier to add this to the <head/> of the resultant HTML output. Finally, we specify the values for the MetaDescription and the MetaKeywords as attributes of the <%@ Page %> directive for the Web Form.

If you view the pages, you will see that the theme is applied based on user selection. You’ll also note by viewing the source code for page NoCodeBehind.aspx that the META data was properly added to the <head/> of the document without any CodeBehind.

Code for Part 2: AppCookie, AppPageBase (B), Web.config

In closing, you can see where these two techniques can perform leaps and bounds in the maintenance of an ASP.NET 2.0 Web application. An important note: if you have an ASP.NET content page that you do not wish to be themed in your application, simply specify System.Web.UI.Page as the value of the Inherits attribute of the <%@ Page %> directive. This will override the base type from the Web.config. Also note that this article did not cover caching of user defined themed pages. If you wish to explore your caching options, read the ASP.NET Caching Overview on MSDN.

(ASP.NET)

 

Leave a Reply