【问题标题】:Switching language on ASP.NET app using master page使用母版页在 ASP.NET 应用程序上切换语言
【发布时间】:2011-06-02 16:44:02
【问题描述】:

我正在使用 Visual Studio 2008 和 ASP.NET 构建一个 Web 应用程序。我的大部分网页都基于一个母版页。该母版页包含三个按钮链接,用作语言切换; Click 事件处理程序如下所示:

protected void lbuLangEN_Click(object sender, EventArgs e)
{
    this.SwitchLanguage(string.Empty);
}  

protected void lbuLangES_Click(object sender, EventArgs e)
{
    this.SwitchLanguage("es");
}

那我有我的私有方法SwitchLanguage

private void SwitchLanguage(string culture)
{
    Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culture);
}

据我了解,这应该足以使基于我的母版页的页面表现出本地化行为,即根据文化从适当的本地 resx 文件中获取资源。但是,它不起作用。它们总是以西班牙语显示,这是我浏览器的默认语言。我在SwitchLanguage的入口和出口处设置了一些跟踪消息,显然当前线程没有改变它的文化信息:每次调用SwitchLanguage时,当前线程的文化都是“es-ES”,不管我的代码刚刚设置了什么。

我的代码或我采用的方法有什么问题吗?谢谢。

【问题讨论】:

  • 问题是你只是改变当前线程的语言,每个请求都是它自己的线程。
  • @vcsjones:我明白了。所以我需要存储语言设置并以某种方式为每个请求设置它,对吗?有什么常用的技术吗?

标签: asp.net localization master-pages cultureinfo


【解决方案1】:

您可以在Global.asax 中使用OnAcquireRequestState 来改变文化。它在会话加载后立即调用,但在任何母版页事件之前。

因此,在按钮事件处理程序中,您将会话变量设置为所需的当前文化。然后你重定向到当前页面。然后,Global.asax 事件可以在加载母版页之前选择新语言:

protected void OnAcquireRequestState(object sender, EventArgs e)
{
    string cultureName = "en-GB";
    if (HttpContext.Current.Session != null &&
        HttpContext.Current.Session["CultureName"] is string)
        cultureName = HttpContext.Current.Session["CultureName"];

    if (Thread.CurrentThread.CurrentUICulture.Name == cultureName) 
        return;

    Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureName);
    Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture;
}

【讨论】:

  • 谢谢;这听起来是个好方法。我在哪里连接 OnAcquireRequestState 事件处理程序?
  • @CesarGon:字面意思是在名为Global.asax 的文件中。它应该已经存在,否则您可以从新创建的 ASP.NET Web 应用程序中复制它。
  • @Andomar:它不存在(我使用的是 VS 2008),但我添加了它,并在 Application_Start 中添加了这样一行:this.AcquireRequestState += Application_OnAcquireRequestState; 听起来不错?
  • @Andomar:顺便说一句,我得到了一个异常抛出,因为显然,会话状态在OnAcquireRequestState 中不可用,至少在应用程序启动时的前几个调用之一中是这样。任何想法如何解决这个问题?
  • @CesarGon:对,这听起来很熟悉,总是有没有会话的请求。为避免此异常,请使用HttpContext.Current.Session 而不是Request.Session(已在答案中编辑)
【解决方案2】:

对于使用@Andomar 解决方案的任何主体,该方法应命名为 Application_AcquireRequestState,位于 Global.ascx 代码中(例如,在 Application_Start 下方),并且不需要附加任何事件处理程序。 (如果您执行除此之外的任何操作,即使方法主体中没有代码,您也可能遇到 NullReferenceException!或者您的方法根本不会运行)
所以代码会是这样的:

void Application_AcquireRequestState(object sender, EventArgs e)
{
    string cultureName = "en-GB";
    if (HttpContext.Current.Session != null &&
        HttpContext.Current.Session["CultureName"] is string)
        cultureName = HttpContext.Current.Session["CultureName"];

    if (Thread.CurrentThread.CurrentUICulture.Name == cultureName) 
        return;

    Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureName);
    Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture;
}

【讨论】:

    【解决方案3】:

    在页面级别覆盖 InitializeCulture 方法以设置 UICulture

    【讨论】:

    • 我正在处理母版页; MasterPage 没有 InitializeCulture 方法。
    • 这就是为什么我说,在页面级别做,没关系只给我一个-1,jezus :) :)
    • 好吧,我不希望在每一页都重复相同的代码。我确信有一个解决方案可以避免这种情况。
    • 想一想如何避免这种情况,你就有了解决方案:) 顺便说一句,如果你只需要翻译,也要注意设置 CurrentCulture!
    • 我和蒂姆在一起;从您自己的“页面”而不是 System.Web.Page 继承。
    猜你喜欢
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 2013-09-29
    • 2015-12-22
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多