Tuesday 18 November 2008

Using HTTPModules to globalize a website

I am going so you a simple example of using HTTPModules to globalize a website. There are many reasons to use HTTPModules in this case - read more here.

First lets automatically detect the browser's prefered language in the web.config:

<system.web>

<globalization uiCulture="auto" culture="auto" />
<
system.web>

Next lets create an XML file of cultures our website supports:

xml version="1.0" encoding="UTF-8"?>

<Cultures>

<Culture Name="en-GB" NativeName="English (United Kingdom)"/>

<Culture Name="it-IT" NativeName="Italian (Italy)"/>

Cultures>

Lets call the XML file SupportedCultures.xml.

Next we will create the resx files that contain the language strings. Create the App_GlobalResources folder if it doesn't already exist within Visual Studio. Add the following resex files:





This is the contents of LocalizedText.resx:









This is the contents of LocalizedText.it-IT.resx:








Now lets move on and work on the web form:

<body>

<form id="form1" runat="server">

<div>

<div>

Browser culture: <asp:Literal ID="CurrentCulture" runat="server" Text="Current culture:{0} Current UI culture:{1}">asp:Literal>

div>

<div>

Force culture:

<asp:DropDownList ID="CultureList" runat="server"

DataSourceID="SupportedCulturesDataSource" DataTextField="NativeName"

DataValueField="Name" AutoPostBack="True"

ondatabound="CultureList_DataBound"

onselectedindexchanged="CultureList_SelectedIndexChanged">

asp:DropDownList>

div>

<h1>

<asp:Literal ID="Header" runat="server" Text="<%$ Resources:LocalizedText, Heading %>">asp:Literal>h1>

<asp:Literal ID="MainBody" runat="server" Text="<%$ Resources:LocalizedText, Body %>">asp:Literal>

<div>

<asp:Literal ID="HomePageText" runat="server" Text="<%$ Resources:LocalizedText, HomeText %>">asp:Literal>

div>

<asp:Literal ID="Footer" runat="server" Text="<%$ Resources:LocalizedText, Footer %>">asp:Literal>

div>

<asp:XmlDataSource ID="SupportedCulturesDataSource" runat="server"

DataFile="~/Resources/SupportedCultures.xml">asp:XmlDataSource>

form>

body>

html>


On this web form we have created a literal to display the browers current culture settings (CurrentCulture). We have a drop down list (CultureList) that is databound to the XML file we created eariler which displays a list of supported cultures. You can see we using explicit localization i.e. <%$ Resources:LocalizedText, Body %>.

Now lets wire up the events:

protected void Page_Load(object sender, EventArgs e)

{

CurrentCulture.Text = string.Format(CurrentCulture.Text, Thread.CurrentThread.CurrentCulture.Name,

Thread.CurrentThread.CurrentUICulture.Name);

}

protected void CultureList_SelectedIndexChanged(object sender, EventArgs e)

{

Response.Redirect(Request.Url.AbsolutePath + "?culture=" + CultureList.SelectedValue);

}

protected void CultureList_DataBound(object sender, EventArgs e)

{

CultureList.SelectedValue = Thread.CurrentThread.CurrentCulture.Name;

}

The HTTPModule code to handle every request is below:

using System;

using System.Data;

using System.Configuration;

using System.Globalization;

using System.Linq;

using System.Threading;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.HtmlControls;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Xml.Linq;

namespace Sandbox.CondeNet.Platform20.HTTPModules

{

public class GlobalizationModule : IHttpModule

{

#region Implement IHttpModule

public void Init(System.Web.HttpApplication context)

{

context.BeginRequest += new EventHandler(Context_BeginRequest);

}

public void Dispose()

{

}

#endregion

private void Context_BeginRequest(object sender, EventArgs e)

{

HttpRequest request = ((HttpApplication)sender).Request;

HttpContext context = ((HttpApplication)sender).Context;

string culture = request.QueryString.Get("culture");

if (string.IsNullOrEmpty(culture) == false)

{

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culture);

Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

}

context.RewritePath(request.Url.AbsolutePath);

}

}

}

Now link this in the web.config of your web site:

<httpModules>

<add name="GlobalizationModule" type="Sandbox.CondeNet.Platform20.HTTPModules.GlobalizationModule, Sandbox.CondeNet.Platform20.HTTPModules" />

httpModules>

No comments: