I’m taking a closer look at how the new localization features in ASP.NET work and am playing around with the auto formatting in the Page directive:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="LocalizationTest.aspx.cs" Inherits="LocalizationTest" meta:resourcekey="PageResource1"
Culture="auto" UICulture="auto"
%>
Using the Culture="auto" directive has the effect of making ASP.NET switch cultures of the current thread and executing the request in that culture context which can be useful in some situations (not too many actually <s>).
If you add Caching to this mix though you need to make sure that content gets cached on a per Culture/UICulture setting so you don’t serve the wrong culture from cached data. The way this is supposed to be done is by using a cache declaration like this:
<%@ OutputCache Duration="20" VaryByParam="none" VaryByCustom="Culture" %>
And then implementing the following on your HttpApplication class (global.asax – Global typically):
public override string GetVaryByCustomString(HttpContext Context, string Custom)
{
if (Custom == "Culture")
{
return System.Globalization.CultureInfo.CurrentCulture.Name;
}
return base.GetVaryByCustomString(Context,Custom);
}
Seems logical enough, but when running a few tests with this I noticed that this doesn’t work for me. When stepping through this code I can see that VaryByCustom is being called but the CurrentCulture always shows up as en-US even if I switch my browser to a different language. To test I have one instance of IE open in English and one instance of FireFox with German.
With the Page level Culture="auto" directive the culture always returns as en-US in the GetVaryByCustomString() call. If I place:
Response.Write(CultureInfo.CurrentCulture.Name);
Into the page however, I can see that the culture is correctly set to de-DE later in the request.
So it seems that the auto culture mapping is occurring after the caching is checked – can this be right? If this is true then this seems like a pretty big hole in the auto culture mapping.
The workaround is pretty easy fortunately by reverting back to the more reliable manual culture mapping which can be set up in Application_BeginRequest() instead. I posted about this some time ago and using that approach works correctly.
However, that still doesn’t solve the problem completely. In a really localized application it’s unlikely that the application will just accept ANY culture, but instead the application is likely to be localized into 2 maybe three different languages that are supported with the user selecting her preference. It’s unlikely anybody will translate a Web site into Zulu or Klingon (I had to laugh when I looked at the FireFox languages list to find it in the list!) I suspect with few exceptions <g>.
So most application will allow profile or other configuration level configuration to allow the user to set a preference, which is likely to occur much, much later in the pipeline cycle all the way at the handler level in the Page InitializeCulture() code. Way too late for caching to catch this…
So what’s the right way to get caching to work in this scenario? It seems to me that there’s a big disconnect here – looking through my trusty Internationalization book <g> I see no mention of this (well the ASP.NET section of this book is pretty anyway).
Other Posts you might also like