通过请求动态更改语言资源的好方法

时间:2012-06-18 07:04:23

标签: c# asp.net .net localization asp.net-web-api

我有一个ASP.NET Web API应用程序,它应该适当地响应用户的Accept-Language标头。

目前,字符串存储在resx中,并通过Visual Studio生成的类以编译安全的方式访问。我想做的是保持当前的方法并为resx的每个翻译版本创建附属程序集。然后分析用户的Accept-Language标头以查看用户接受的语言,并从附属程序集中加载所请求语言的资源。

我想我可以通过在ResourceManager的帮助下创建一组特定于语言的ResourceSet对象来实现所有这些行为,但是不可能保持编译时的安全性,因为Visual Studio负责自动更新resx文件的类。

动态选择本地化语言资源的最佳方法是什么?

2 个答案:

答案 0 :(得分:11)

通过阅读您的问题,我看不到ASP.NET自动提供的任何内容。您可以将ASP.NET(无论是WebForms还是MVC)配置为使用accept-language请求标头并设置相应的UICulture(将影响ResourceManager加载哪个附属程序集)和Culture(这将影响与区域设置相关的格式)并适当地解析诸如日期和数字。

要将您的应用配置为使用accept-language列表为每个请求设置UICulture和Culture(根据this MSDN page),请按以下方式配置您的web.config:

<globalization uiCulture="auto" culture="auto" />

每页还有一个等效的配置设置。

然后,根据Resource Fallback流程,如果您的应用包含匹配文化的附属程序集(或者,如果其失败,则为其中性文化),资源管理器将使用它。如果没有,那么将使用您的默认资源(如果这是您的基本语言,则为英语)。

答案 1 :(得分:2)

您可以编写一个检测语言标题的HttpModule,并设置当前的线程文化。

public class LanguageModule : IHttpModule
{
    public void Dispose()
    {
    }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(context_BeginRequest);
    }

    void context_BeginRequest(object sender, EventArgs e)
    {
        var application = sender as HttpApplication;
        var context = application.Context;
        var lang = context.Request.Headers["Accept-Language"];

        // eat the cookie (if any) and set the culture
        if (!string.IsNullOrEmpty(lang))
        {
            var culture = new System.Globalization.CultureInfo(lang); // you may need to interpret the value of "lang" to match what is expected by CultureInfo

            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = culture;
        }
    }
}

ResourceManager等人将找出在线程文化中使用的正确的本地化版本。