Best place to set CurrentCulture for multilingual ASP.NET WebAPI applications

北慕城南 提交于 2019-12-07 01:05:54

问题


based on this question (Best place to set CurrentCulture for multilingual ASP.NET MVC web applications) I'm looking for a global way to do the same for ASP.NET WebAPI.

My current implementation for ASP.NET MVC looks like this:

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;
    }
}

I'm trying to do the same things as in ASP.NET MVC, but following code doesn't work properly.

 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;
     }
 }

With that code, WebAPI cannot find any route anymore :( What have I to do to get this to work!

Regards, Daniel


回答1:


If you want global localization for whole application, you can put the set culture code into the BeginRequest method of the HttpApplication in global asax file. This will set your culture in the most first place of each request and will affect every MVC and webapi request.




回答2:


I'd use a ActionFilter

If you are using 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!

        }
    }
}

In Javascript you can set the language in a cookie named "culture"



来源:https://stackoverflow.com/questions/22505571/best-place-to-set-currentculture-for-multilingual-asp-net-webapi-applications

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!