为多语言ASP.NET WebAPI应用程序设置CurrentCulture的最佳位置

时间:2014-03-19 12:17:06

标签: asp.net globalization asp.net-web-api

基于这个问题(Best place to set CurrentCulture for multilingual ASP.NET MVC web applications)我正在寻找一种全局的方法来为ASP.NET WebAPI做同样的事情。

我对ASP.NET MVC的当前实现如下所示:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {

        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);


        ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory(new CultureAwareControllerActivator()));


    }
}


public class CultureAwareControllerActivator : System.Web.Mvc.IControllerActivator
{
    public System.Web.Mvc.IController Create(System.Web.Routing.RequestContext requestContext, System.Type controllerType)
    {
        string cultureName = null;

        // Attempt to read the culture cookie from Request
        HttpCookie cultureCookie = requestContext.HttpContext.Request.Cookies["_culture"];
        if (cultureCookie != null)
            cultureName = cultureCookie.Value;
        else
            cultureName = requestContext.HttpContext.Request.UserLanguages != null && requestContext.HttpContext.Request.UserLanguages.Length > 0 ?
                      requestContext.HttpContext.Request.UserLanguages[0] :  // obtain it from HTTP header AcceptLanguages
                      null;

        // Validate culture name
        cultureName = RoedingGmbh.Pis2Go.Web.Mvc.Helpers.CultureHelper.GetImplementedCulture(cultureName); // This is safe

        // Modify current thread's cultures            
        System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName);
        // Currently the UI Language is only english
        //Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

        return DependencyResolver.Current.GetService(controllerType) as IController;
    }
}

我尝试做与ASP.NET MVC相同的事情,但是以下代码无法正常工作。

 public static class WebApiConfig
 {
      public static void Register(HttpConfiguration config)
      {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                 name: "DefaultApi",
                 routeTemplate: "api/{controller}/{id}",
                 defaults: new { id = RouteParameter.Optional }
            );

            GlobalConfiguration.Configuration.Services.Replace(typeof(System.Web.Http.Dispatcher.IHttpControllerActivator), new CultureAwareHttpControllerActivator());

          }
 }


 public class CultureAwareHttpControllerActivator : System.Web.Http.Dispatcher.IHttpControllerActivator
 {
     public System.Web.Http.Controllers.IHttpController Create(System.Net.Http.HttpRequestMessage request, System.Web.Http.Controllers.HttpControllerDescriptor controllerDescriptor, Type controllerType)
     {
        System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("DE-de");
        return GlobalConfiguration.Configuration.DependencyResolver.GetService(controllerType) as System.Web.Http.Controllers.IHttpController;
     }
 }

使用该代码,WebAPI再也找不到任何路由:( 我该怎么做才能让它发挥作用!

此致 丹尼尔

2 个答案:

答案 0 :(得分:7)

如果要为整个应用程序进行全局本地化,可以将设置区域性代码放入全局asax文件中HttpApplication的BeginRequest方法中。这将使您的文化在每个请求的最前端设置,并将影响每个MVC和webapi请求。

答案 1 :(得分:3)

我会使用ActionFilter

如果您使用的是Asp.Net MVC

//A foreigner, has possibly brew a cookie for me
public class SpeakNativeTongueAttribute : ActionFilterAttribute, IActionFilter
{
    const string cookieName = "culture";

     void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
        var cookieKeys = filterContext.RequestContext.HttpContext.Request.Cookies.AllKeys;

        if (cookieKeys.Contains(cookieName))
        {
            //eat the cookie
            var theCultureCookie = filterContext.RequestContext.HttpContext.Request.Cookies[cookieName];
            var theCulture = theCultureCookie.Value;

            //say thanks in native tongue
            System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo(theCulture);
            System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(theCulture);
        }
        else
        {
            //Didn't receive a cookie, don't speak their language, those bastards!

        }
    }
}

在Javascript中,您可以在名为“culture”的cookie中设置语言