trying to write a multilingual web site

L

Lloyd Dupont

I created a
==============
public class LangModule : IHttpModule
{
public void Dispose() {}

public void Init(HttpApplication application)
{
HttpContext context = application.Context;
HttpCookie lc = context.Request.Cookies[LangCookieName];
if (lc == null)
return;

CultureInfo ci = new CultureInfo(lc.Value);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
}
public static string LangCookieName = "UserSelectedLanguage";
public static void SetLocale(HttpContext context, CultureInfo locale)
{
if (locale == null)
return;
HttpCookie lc = new HttpCookie(LangCookieName, locale.Name);
lc.Expires = DateTime.Now.AddDays(360);
context.Response.Cookies.Add(lc);
Thread.CurrentThread.CurrentCulture = locale;
Thread.CurrentThread.CurrentUICulture = locale;
}
}
==============
SetLocale() is successfully called by a LinkButton to either "en-AU" or "fr-FR" and the Init() method is called when there is an incoming query.
I'm trying to test if it works with a very simple literal:
==============
<asp:Literal runat="server" Text="<%$ Resources: Standart, Email %>" />
==============

And in App_GlobalResources I have 2 resources: "Standart.resx" & "Standart.fr-FR.resx".
However I always get the default (English) label, I never get the French label.

Any idea what I'm missing or I have done wrong?
 
K

Karl Seguin [MVP]

First, Init() happens once per module load, not per request. To get code working on each request, you need to write it like:

public void Init(HttpApplication application)
{
application.BeginRequest += new EventHandler(application_BeginRequest);
}

void application_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
//code here
}

Your real problem is timing. By the time the event handler fires, the thing's already been decided and switching the thread's culture doesn't do much.

If possible, I would suggest that you use links with querystring values, which can be read during BeginRequest.

I have an example that uses URL rewriting which could easily be modified to use querystrings:
http://openmymind.net/index.aspx?documentId=4#urlrewrite

Karl

--
http://www.openmymind.net/



I created a
==============
public class LangModule : IHttpModule
{
public void Dispose() {}

public void Init(HttpApplication application)
{
HttpContext context = application.Context;
HttpCookie lc = context.Request.Cookies[LangCookieName];
if (lc == null)
return;

CultureInfo ci = new CultureInfo(lc.Value);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
}
public static string LangCookieName = "UserSelectedLanguage";
public static void SetLocale(HttpContext context, CultureInfo locale)
{
if (locale == null)
return;
HttpCookie lc = new HttpCookie(LangCookieName, locale.Name);
lc.Expires = DateTime.Now.AddDays(360);
context.Response.Cookies.Add(lc);
Thread.CurrentThread.CurrentCulture = locale;
Thread.CurrentThread.CurrentUICulture = locale;
}
}
==============
SetLocale() is successfully called by a LinkButton to either "en-AU" or "fr-FR" and the Init() method is called when there is an incoming query.
I'm trying to test if it works with a very simple literal:
==============
<asp:Literal runat="server" Text="<%$ Resources: Standart, Email %>" />
==============

And in App_GlobalResources I have 2 resources: "Standart.resx" & "Standart.fr-FR.resx".
However I always get the default (English) label, I never get the French label.

Any idea what I'm missing or I have done wrong?
 
L

Lloyd Dupont

damn....
You completely open my mind on that!
(interesting link on your web page, BTW)

I did like that
============== Module ==============
public class LangModule : IHttpModule
{
HttpApplication application;
public void Dispose()
{
if (application != null)
{
application.BeginRequest -= HTranslate;
application = null;
}
}
public void Init(HttpApplication application)
{
this.application = application;
application.BeginRequest += HTranslate;
}
public void HTranslate(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
string lang = context.Request["lang"];

if (lang != null && lang != "" && SetLocale(context, lang))
return;
HttpCookie lc = context.Request.Cookies[LangCookieName];
if (lc == null)
return;

CultureInfo ci = new CultureInfo(lc.Value);
Thread.CurrentThread.CurrentUICulture = ci;
}
public static string LangCookieName = "UserSelectedLanguage";
public static bool SetLocale(HttpContext context, string locale)
{
if (locale == null)
return false;

CultureInfo ci = null;
try { ci = new CultureInfo(locale); }
catch { return false; }

HttpCookie lc = new HttpCookie(LangCookieName, locale);
lc.Expires = DateTime.Now.AddDays(360);
context.Response.Cookies.Add(lc);
Thread.CurrentThread.CurrentUICulture = ci;
return true;
}
}
========== WebControl ==============
<a href="?lang=en-AU"><img id="Img4" runat="server" src="~/datas/flag_au.gif" border="1" width="23" height="17" alt="English" /></a>
<a href="?lang=fr-FR" ><img id="Img5" runat="server" src="~/datas/flag_fr.gif" border="1" width="23" height="17" alt="Fran&ccedil;ais" /></a>
==================================

BTW, since there is a Dispose() method in the module it looks to me as an appropriate place to unregister the event handler, what do you think?



First, Init() happens once per module load, not per request. To get code working on each request, you need to write it like:

public void Init(HttpApplication application)
{
application.BeginRequest += new EventHandler(application_BeginRequest);
}

void application_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
//code here
}

Your real problem is timing. By the time the event handler fires, the thing's already been decided and switching the thread's culture doesn't do much.

If possible, I would suggest that you use links with querystring values, which can be read during BeginRequest.

I have an example that uses URL rewriting which could easily be modified to use querystrings:
http://openmymind.net/index.aspx?documentId=4#urlrewrite

Karl

--
http://www.openmymind.net/



I created a
==============
public class LangModule : IHttpModule
{
public void Dispose() {}

public void Init(HttpApplication application)
{
HttpContext context = application.Context;
HttpCookie lc = context.Request.Cookies[LangCookieName];
if (lc == null)
return;

CultureInfo ci = new CultureInfo(lc.Value);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
}
public static string LangCookieName = "UserSelectedLanguage";
public static void SetLocale(HttpContext context, CultureInfo locale)
{
if (locale == null)
return;
HttpCookie lc = new HttpCookie(LangCookieName, locale.Name);
lc.Expires = DateTime.Now.AddDays(360);
context.Response.Cookies.Add(lc);
Thread.CurrentThread.CurrentCulture = locale;
Thread.CurrentThread.CurrentUICulture = locale;
}
}
==============
SetLocale() is successfully called by a LinkButton to either "en-AU" or "fr-FR" and the Init() method is called when there is an incoming query.
I'm trying to test if it works with a very simple literal:
==============
<asp:Literal runat="server" Text="<%$ Resources: Standart, Email %>" />
==============

And in App_GlobalResources I have 2 resources: "Standart.resx" & "Standart.fr-FR.resx".
However I always get the default (English) label, I never get the French label.

Any idea what I'm missing or I have done wrong?
 
K

Karl Seguin [MVP]

Event handlers don't need to be explicitely released for them to be cleaned up. The only time you'd really remove a handler is if you don't want it to fire anymore but you kept your instance around. Your dispose() isn't bad, but it is unecessary.

Karl

--
http://www.openmymind.net/



damn....
You completely open my mind on that!
(interesting link on your web page, BTW)

I did like that
============== Module ==============
public class LangModule : IHttpModule
{
HttpApplication application;
public void Dispose()
{
if (application != null)
{
application.BeginRequest -= HTranslate;
application = null;
}
}
public void Init(HttpApplication application)
{
this.application = application;
application.BeginRequest += HTranslate;
}
public void HTranslate(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
string lang = context.Request["lang"];

if (lang != null && lang != "" && SetLocale(context, lang))
return;
HttpCookie lc = context.Request.Cookies[LangCookieName];
if (lc == null)
return;

CultureInfo ci = new CultureInfo(lc.Value);
Thread.CurrentThread.CurrentUICulture = ci;
}
public static string LangCookieName = "UserSelectedLanguage";
public static bool SetLocale(HttpContext context, string locale)
{
if (locale == null)
return false;

CultureInfo ci = null;
try { ci = new CultureInfo(locale); }
catch { return false; }

HttpCookie lc = new HttpCookie(LangCookieName, locale);
lc.Expires = DateTime.Now.AddDays(360);
context.Response.Cookies.Add(lc);
Thread.CurrentThread.CurrentUICulture = ci;
return true;
}
}
========== WebControl ==============
<a href="?lang=en-AU"><img id="Img4" runat="server" src="~/datas/flag_au.gif" border="1" width="23" height="17" alt="English" /></a>
<a href="?lang=fr-FR" ><img id="Img5" runat="server" src="~/datas/flag_fr.gif" border="1" width="23" height="17" alt="Fran&ccedil;ais" /></a>
==================================

BTW, since there is a Dispose() method in the module it looks to me as an appropriate place to unregister the event handler, what do you think?



First, Init() happens once per module load, not per request. To get code working on each request, you need to write it like:

public void Init(HttpApplication application)
{
application.BeginRequest += new EventHandler(application_BeginRequest);
}

void application_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
//code here
}

Your real problem is timing. By the time the event handler fires, the thing's already been decided and switching the thread's culture doesn't do much.

If possible, I would suggest that you use links with querystring values, which can be read during BeginRequest.

I have an example that uses URL rewriting which could easily be modified to use querystrings:
http://openmymind.net/index.aspx?documentId=4#urlrewrite

Karl

--
http://www.openmymind.net/



I created a
==============
public class LangModule : IHttpModule
{
public void Dispose() {}

public void Init(HttpApplication application)
{
HttpContext context = application.Context;
HttpCookie lc = context.Request.Cookies[LangCookieName];
if (lc == null)
return;

CultureInfo ci = new CultureInfo(lc.Value);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
}
public static string LangCookieName = "UserSelectedLanguage";
public static void SetLocale(HttpContext context, CultureInfo locale)
{
if (locale == null)
return;
HttpCookie lc = new HttpCookie(LangCookieName, locale.Name);
lc.Expires = DateTime.Now.AddDays(360);
context.Response.Cookies.Add(lc);
Thread.CurrentThread.CurrentCulture = locale;
Thread.CurrentThread.CurrentUICulture = locale;
}
}
==============
SetLocale() is successfully called by a LinkButton to either "en-AU" or "fr-FR" and the Init() method is called when there is an incoming query.
I'm trying to test if it works with a very simple literal:
==============
<asp:Literal runat="server" Text="<%$ Resources: Standart, Email %>" />
==============

And in App_GlobalResources I have 2 resources: "Standart.resx" & "Standart.fr-FR.resx".
However I always get the default (English) label, I never get the French label.

Any idea what I'm missing or I have done wrong?
 
L

Lloyd Dupont

OK, thanks for the precision.
Event handlers don't need to be explicitely released for them to be cleaned up. The only time you'd really remove a handler is if you don't want it to fire anymore but you kept your instance around. Your dispose() isn't bad, but it is unecessary.

Karl

--
http://www.openmymind.net/



damn....
You completely open my mind on that!
(interesting link on your web page, BTW)

I did like that
============== Module ==============
public class LangModule : IHttpModule
{
HttpApplication application;
public void Dispose()
{
if (application != null)
{
application.BeginRequest -= HTranslate;
application = null;
}
}
public void Init(HttpApplication application)
{
this.application = application;
application.BeginRequest += HTranslate;
}
public void HTranslate(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
string lang = context.Request["lang"];

if (lang != null && lang != "" && SetLocale(context, lang))
return;
HttpCookie lc = context.Request.Cookies[LangCookieName];
if (lc == null)
return;

CultureInfo ci = new CultureInfo(lc.Value);
Thread.CurrentThread.CurrentUICulture = ci;
}
public static string LangCookieName = "UserSelectedLanguage";
public static bool SetLocale(HttpContext context, string locale)
{
if (locale == null)
return false;

CultureInfo ci = null;
try { ci = new CultureInfo(locale); }
catch { return false; }

HttpCookie lc = new HttpCookie(LangCookieName, locale);
lc.Expires = DateTime.Now.AddDays(360);
context.Response.Cookies.Add(lc);
Thread.CurrentThread.CurrentUICulture = ci;
return true;
}
}
========== WebControl ==============
<a href="?lang=en-AU"><img id="Img4" runat="server" src="~/datas/flag_au.gif" border="1" width="23" height="17" alt="English" /></a>
<a href="?lang=fr-FR" ><img id="Img5" runat="server" src="~/datas/flag_fr.gif" border="1" width="23" height="17" alt="Fran&ccedil;ais" /></a>
==================================

BTW, since there is a Dispose() method in the module it looks to me as an appropriate place to unregister the event handler, what do you think?



First, Init() happens once per module load, not per request. To get code working on each request, you need to write it like:

public void Init(HttpApplication application)
{
application.BeginRequest += new EventHandler(application_BeginRequest);
}

void application_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
//code here
}

Your real problem is timing. By the time the event handler fires, the thing's already been decided and switching the thread's culture doesn't do much.

If possible, I would suggest that you use links with querystring values, which can be read during BeginRequest.

I have an example that uses URL rewriting which could easily be modified to use querystrings:
http://openmymind.net/index.aspx?documentId=4#urlrewrite

Karl

--
http://www.openmymind.net/



I created a
==============
public class LangModule : IHttpModule
{
public void Dispose() {}

public void Init(HttpApplication application)
{
HttpContext context = application.Context;
HttpCookie lc = context.Request.Cookies[LangCookieName];
if (lc == null)
return;

CultureInfo ci = new CultureInfo(lc.Value);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
}
public static string LangCookieName = "UserSelectedLanguage";
public static void SetLocale(HttpContext context, CultureInfo locale)
{
if (locale == null)
return;
HttpCookie lc = new HttpCookie(LangCookieName, locale.Name);
lc.Expires = DateTime.Now.AddDays(360);
context.Response.Cookies.Add(lc);
Thread.CurrentThread.CurrentCulture = locale;
Thread.CurrentThread.CurrentUICulture = locale;
}
}
==============
SetLocale() is successfully called by a LinkButton to either "en-AU" or "fr-FR" and the Init() method is called when there is an incoming query.
I'm trying to test if it works with a very simple literal:
==============
<asp:Literal runat="server" Text="<%$ Resources: Standart, Email %>" />
==============

And in App_GlobalResources I have 2 resources: "Standart.resx" & "Standart.fr-FR.resx".
However I always get the default (English) label, I never get the French label.

Any idea what I'm missing or I have done wrong?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top