IT:AD:ASP.NET:Win Forms:HowTo:Set the Current Culture
Summary
Process
Two Cultures, or more
.NET applications work with two Cultures:
- CurrentCulture: controls formatting of numbers, dates, currency.
- CurrentUICulture: defines what strings are used.
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
HTTP Browsers
Most browsers attach a header defining what language they prefer receiving resources in:
Accept-Language:en-NZ,de;q=0.8,en-US;q=0.6,en;q=0.4
ASP.NET WebForms
In an ASP.NET application, the information encoded in the Accept-Language headers can be automatically used to set the current culture on the server side, or falling back to a default (in this case 'en-NZ') using settings in web.config similar to the following:
<configuration>
<system.web>
<globalization culture="auto:en-NZ" uiCulture="auto:en-NZ" />
</system.web>
</configuration>
Application_BeginRequest (even before Session and Page events).
If you ever need to you can retrieve the currently set language using:
culture = CultureInfo.InstalledUICulture.IetfLanguageTag;
if (HttpContext.Current != null && HttpContext.Current.Request.UserLanguages != null)
{
culture = Request.UserLanguages[0];
}
User Defined Culture
The automatic feature of ASP.NET is handy.
But one should go further – allowing users to define their own language from a Profile setting.
Application_BeginRequest is a tempting place to do this – but it's only useful when using Cookies, as it happens prior to Application_AuthenticateRequest, which is where the thread's user gets set by an HttpHandler.
- a production site should allow user customisation, in which case a Profile will be needed.
- a production site will probably end up requiring more than one personal setting. As it's inappropriate to round-trip unnecessarily a cookie for each setting, better to deal with this upcoming reality right from the start. </callout>
protected void Application_BeginRequest()
{
//Don't set your user's preferred Cultures here:
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (HttpContext.Current.User != null)
{
//Thread Identity is set -- use it to get an App User
User u = Helpers.User().SelectByUsername(HttpContext.Current.User.Name, false);
System.Threading.CurrentCulture = user.Culture;
System.Threading.CurrentUICulture = user.Culture;
}
//If anon user, this could be done by cookies?
}
### ASP.NET WebForms ###
The above works for ASP.NET in general. If for any reason you are still using WinForms (why?!?) you need to override the InitializeCulture method1):
<%@ Page Language="C#" uiculture="auto" %>
<%@ Import Namespace="System.Threading" %>
<%@ Import Namespace="System.Globalization" %>
<script runat="server">
protected override void InitializeCulture()
{
if (Request.Form["ctl00$ctl00$ DropDownListMaster "] != null)
{
//Read control on Master page:
string selectedLanguage = Request.Form["ctl00$ctl00$DropDownListMaster"];
//Persist value in Response cookie:
Response.Cookies["CurrentCulture"].Value = selectedLanguage;
//Or persist it in the Users profile
//TODO:....
}
else if (Request.Cookies["CurrentCulture"] != null)
{
selectedLanguage = Request.Cookies["CurrentCulture"].Value;
}
//Then set the cultureCode:
if (!selectedLanguage.IsNullOrEmpty()){
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(selectedLanguage);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(selectedLanguage);
}
base.InitializeCulture();
}
</script>
<html>
<body>
<form id="form1" runat="server">
<div>
<asp:ListBox ID="ListBox1" runat="server">
<asp:ListItem Value="en-US" Selected="True">English</asp:ListItem>
<asp:ListItem Value="es-MX">Español</asp:ListItem>
<asp:ListItem Value="de-DE">Deutsch</asp:ListItem>
</asp:ListBox><br />
<asp:Button ID="Button1" runat="server" Text="Set Language" meta:resourcekey="Button1" />
<br />
<asp:Label ID="Label1" runat="server" Text="" meta:resourcekey="Label1" />
</div>
</form>
</body>
</html>
###
<callout icon=“true” type=“tip”
>
T
hat said, know that Async requests, in a self-hosted environment, can cause issues 2). They remain fine when hosted in IIS though.