我正在尝试在网站上为用户实施文化切换,他可以从下拉列表中选择他喜欢的语言。
problem and solution posted here似乎是一个很好的起点,所以我将代码实现到我的global.asax中:
void Application_BeginRequest(Object sender, EventArgs e)
{
// Code that runs on application startup
HttpCookie cookie = HttpContext.Current.Request.Cookies["CultureInfo"];
if (cookie != null && cookie.Value != null)
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(cookie.Value);
Thread.CurrentThread.CurrentCulture = new CultureInfo(cookie.Value);
}
else
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE");
Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
}
}
因此,如果未设置cookie,请将文化设置为de-DE
。在此之后,我将第二段代码复制到我的主站点的Page_Load
方法中:
if (!Page.IsPostBack)
{
if (Session["ddindex"] != null)
{
ddlanguage.SelectedValue = Session["ddindex"].ToString();
ddlanguage.SelectedIndex = Convert.ToInt32(Session["ddindex"].ToString());
//display current values in dummy label - remove later on.
currentCulture.Text = Thread.CurrentThread.CurrentCulture.ToString() + " " + Thread.CurrentThread.CurrentUICulture;
}
else
{
ddlanguage.SelectedValue = Thread.CurrentThread.CurrentCulture.Name;
}
}
加上DropdDownBox的SelectedIndexChanged
方法:
protected void ddlanguage_SelectedIndexChanged(object sender, EventArgs e)
{
Session["language"] = ddlanguage.SelectedValue;
//Sets the cookie that is to be used by Global.asax
HttpCookie cookie = new HttpCookie("CultureInfo");
cookie.Value = ddlanguage.SelectedValue;
Response.Cookies.Add(cookie);
//Set the culture and reload for immediate effect.
//Future effects are handled by Global.asax
Thread.CurrentThread.CurrentCulture = new CultureInfo(ddlanguage.SelectedValue);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(ddlanguage.SelectedValue);
if (cookie.Value == "en-US")
{
Session["ddindex"] = "0";
}
else if (cookie.Value == "de-DE")
{
Session["ddindex"] = "1";
}
Server.Transfer(Request.Path);
}
标记:
<asp:DropDownList ID="ddlanguage" runat="server"
OnSelectedIndexChanged="ddlanguage_SelectedIndexChanged"
AutoPostBack="true">
<asp:ListItem Selected="False" Value="en-US" Text="English"></asp:ListItem>
<asp:ListItem Selected="False" Value="de-DE" Text="Deutsch"></asp:ListItem>
</asp:DropDownList>
我的资源中为某些<asp:Hyperlinks>
设置了一些值,这些值在调用网站后可以从德语正确翻译成英语。
但是,在通过asp:dropdownbox
切换当前选定的文化时,文化保留在en-US(我的开发机器上的默认浏览器文化)。标签currentCulture.Text
也保留在en-US上,所有翻译仍为英文。
我在这里做错了什么?
答案 0 :(得分:1)
重写InitializeCulture并在那里从Page_Load中执行。
protected override void InitializeCulture()
{
var culture = new System.Globalization.CultureInfo("<Culture Name Here>");
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
base.InitializeCulture();
}
啊,我不知道你想在Masterpage上使用它。无论如何,您可以创建一个模块并在web.config中注册它。
namespace YourNameSpaceHere
{
public class LanguageModule : IHttpModule
{
public void Init(System.Web.HttpApplication context)
{
context.AcquireRequestState += OnAcquireRequestState;
}
public void OnAcquireRequestState(object sender, EventArgs eventArgs)
{
HttpApplication httpApplication = sender as HttpApplication;
string lang = null;
if (httpApplication.Request.Cookies["<CookieNameHere>"] == null)
{
lang = Thread.CurrentThread.CurrentCulture.Name;
httpApplication.Response.Cookies["<CookieNameHere>"].Value = lang;
}
else
{
lang = httpApplication.Request.Cookies["<CookieNameHere>"].Value;
}
if (lang != Thread.CurrentThread.CurrentCulture.Name)
{
if (Language.IsValidCultureInfoName(lang))
{
var culture = new System.Globalization.CultureInfo(lang);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
httpApplication.Response.Cookies["<CookieNameHere>"].Value = lang;
}
}
}
public void Dispose()
{
}
}
}
system.web下的web.config,我认为是system.webServer
<httpModules>
<add type="YourNameSpaceHere.LanguageModule, YourNameSpaceHere" name="LanguageHandlerModule" />
</httpModules>
答案 1 :(得分:0)
我遇到了同样的问题。 看看这个Microsoft Bug:Race condition in System.Resources.ResourceManager leads to incorrect resources being loaded
看看我在那里发布的解决方法。
基本上,资源管理器存在一个问题,即内部竞争条件导致它将所有文化加载为en-US文化。
我在MVC项目中所做的是在应用程序启动时“初始化”所有资源集。以下代码来自我的Global.asax
文件,MvcApplication
类的Application_Start()
方法:
Resources.ResourceManager.GetResourceSet(new System.Globalization.CultureInfo("en-US"), true, true);
Resources.ResourceManager.GetResourceSet(new System.Globalization.CultureInfo("es-ES"), true, true);
Resources.ResourceManager.GetResourceSet(new System.Globalization.CultureInfo("tr-TR"), true, true);
Resources.ResourceManager.GetResourceSet(new System.Globalization.CultureInfo("he-IL"), true, true);
这将强制资源管理器正确加载。它很糟糕,但似乎微软并没有给这个bug任何关注。
您需要为上面的代码添加一条代码,用于您拥有的每种文化。 不过,我不确定将此代码放在ASP.NET 非MVC 应用程序中的哪个位置。只需找到应用程序的起点并将其放在那里。