A colleague of mine asked me today if there is a better way to set the CurrentUICulture in asp.net 2.0 than handling Application_BeginRequest and doing Thread.CurrentUICulture = new CultureInfo(foo). He asked me this because he was doing something like CommonStrings.Culture = new CultureInfo(whatever), where CommonStrings is a .resx file residing in our App_GlobalResources folder. As you might know, asp.net 2.0 generates a wrapper class around string resources for strongly typed access, so instead of doing ResourceManager.GetString(“SomeKey“) you do Strings.SomeKey. The actual implementation of the wrapper properties is this:
public static string SomeKey
{
get
{
return CommonStrings.ResourceManager.GetString("SomeKey", CommonStrings.resourceCulture);
}
}
I had no idea what the Culture property of the generated CommonStrings class did, so I used Reflector to look it up. Here's the implementation:
[EditorBrowsable(EditorBrowsableState.Advanced)]
public static CultureInfo Culture
{
get
{
return CommonStrings.resourceCulture;
}
set
{
CommonStrings.resourceCulture = value;
}
}... where resource culture is:
private static CultureInfo resourceCulture;
Now that “static” modifier had me raising an eyebrow. As far as I know, declaring such
a variable static means it's static for everybody, not per-context or per-request
static. That means that once I set the generated wrapper class' Culture property, it
“stays” set for all future users, meaning that, for example, if one user changes his
language to German, and the codebehind implements this using the above mechanism, all
other users will get the German interface as well. Wondering if I might be missing
something, I created a small test application and sure enough, the behaviour
is what i suspected.
So, as far as I can see, the Culture property and other properties' implementation,
which calls ResourceManager.GetString(“key“, resourceCulture) is pretty useless.
Why is the generated resources wrapper class even implemented this way? I
cannot see any realistic scenario where this implementation would be of use, given
that the resourceCulture private variable is declared as static. Am I missing something
really big?
ps: if you're not touching the generated wrapper class' Culture property and setting the
Thread.CurrentUICulture instead, the strings will be retrieved correctly because, as you
can see in the example property's implementation above, ResourceManager.GetString is
called with the second parameter null and the GetString implementation does:
if (culture == null)
{
culture = CultureInfo.CurrentUICulture;
}