The power of IHttpModule…

I have been reading Marco Bellinaso’s ASP.NET 2.0 Website Programming Problem – Design – Solution. To begin with, the topic that I was interested in was the selectable theme technique explained in Chapter 2 (pages 38 – 41). I thought about his approach and I should admit that the idea was very good, but I was still not convinced and decided to code it using a more efficient approach using IHttpModule. IHttpModule is powerful and efficient enough and this is how I achieved the same functionality:

1. In my approach, there is no need for the ThemeSelector user control. I added the DropDownlist control in the Master page itself. Everybody knows that there is no Page_PreInit() event for Master pages. But, to set a user selectable theme at runtime, Page_PreInit() is the only event that is pluggable for theme selection.
2. On the Page_Load of the master page, code as shown in page 38.
3. On page 39 of his book, there is a bug in the GetThemes() method that returns themes string array. The variable themes is unreachable. So, modify your code to fix that.
4. Create a new regular folder under App_Code by name Modules.
5. Create a new class and name it ThemeModule.cs and copy the following code by overwriting all of the code in your class:


using System;
using System.Data;
using System.Configuration;
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;
using System.Web.Configuration;

public class ThemeModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.PreRequestHandlerExecute +=new EventHandler(application_PreRequestHandlerExecute);
}

public void Dispose()
{
}

private void application_PreRequestHandlerExecute(object sender, EventArgs e)
{
Page page = HttpContext.Current.CurrentHandler as Page;
if (page != null)
{
page.EnableTheming = true;
page.PreInit +=new EventHandler(page_PreInit);
}
}
public void page_PreInit(object sender, EventArgs e)
{
Page page = (Page)sender;
if (page != null)
{
if (HttpContext.Current.Request.Form["__EVENTTARGET"] == "ctl00$ddlThemes")
{
page.Theme = (string)HttpContext.Current.Request.Form["ctl00$ddlThemes"];
HttpContext.Current.Session["CurrentTheme"] = page.Theme;
}
else
{
if (HttpContext.Current.Session["CurrentTheme"] != null)
{
page.Theme = (string)HttpContext.Current.Session["CurrentTheme"];
}
else
{
PagesSection pagesSection = (PagesSection)ConfigurationManager.GetSection("system.web/pages");
page.Theme = pagesSection.Theme;
HttpContext.Current.Session["CurrentTheme"] = page.Theme;
}
}
}
}
}

All the code does is to check whether the page is requested for the first time. If it is, it reads web.config for the pages section and gets the theme entry and stores the value in a session variable. If the same user requests the same page or some other page, the theme will be loaded from the session. Lastly, if the same user selects a different theme from the dropdownlist, the code checks for postback information by reading the __EVENTTARGET and reading the value of the control’s unique id (ctl00$ddlThemes) and rewrites the session variable.

This code is definitely more efficient than coding a base page that derives from the System.Web.UI.Page and having to change it for every new page you create. Also, this approach is completely transparent and there is nothing that the other developer should do to use this.

Btw, don’t forget to configure your web.config like this:

<httpModules><add name =ThemeModule type=ThemeModule/></

httpModules><pages theme=TemplateMonster masterPageFile=~/Template.master />

Advertisements

2 Responses to “The power of IHttpModule…”

  1. Elmer Bulthuis Says:

    Hi,

    I used tp experience the same problems with setting the culture (language) of a page, i came up with the following solution:

    i store the selected culture in a cookie. If i do this in javascript the value is present at the next page reqeust. If you set the value at the server, the value is not present in the next request, because that is the request where the cookie is set.

    I put the following code in the PreRender event of my LocalizationSelect control

    Page.ClientScript.RegisterOnSubmitStatement(GetType(), ClientID, string.Format(“document.cookie = ‘locale=’ + $get(‘{0}’).value + ‘;expires={1:R};path=/’;”, list.ClientID, DateTime.UtcNow.AddDays(300)));

    also, i set the AutoPostBack property of my list containing the available cultures to true.

    Now, every time the culture is changed, a postback is invoked. The script sets the locale cookie to the value of the selected item in de culture list before every postback. When the postback is processed, the value of the cookie is already updated!

    next, i add the following to the init method of a HttpModule:

    context.PreRequestHandlerExecute += delegate(object sender, EventArgs e)
    {
    HttpCookie cookie;

    cookie = context.Request.Cookies[“locale”];
    if (cookie != null)
    {
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cookie.Value);
    Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(cookie.Value);
    }
    };

    I also have a LocalizationChange event on my LocalizationSelect control. For some controls (Menu control) it’s neccesary to rebind them after the culture has changed. This event allows me to do so.

    greets, Elmer

  2. hi

    i have used this tech for select them and it work fine.
    great stuff.

    thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: