Edu
Edu

Reputation: 2643

Avoiding repeating code on API Actions but still supporting multi language

My goal is to create an API that supports multiple languages.

It is working, but only if I call

Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang);

on each Action, something that I suppose that can be avoided.


On WebApiConfig.cs file I created a route to support multiple languages, placing that language before the default route "{lang}/api/{controller}/{id}". That means that for English I can call http://localhost/en/api/service/get and for Portuguese http://localhost/pt/api/service/get.

WebApiConfig.cs:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApiLocalized",
            routeTemplate: "{lang}/api/{controller}/{id}",
            constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})"}, // en or en-US
            defaults: new { id = RouteParameter.Optional }
        );

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

On my Action I receive the language and use it to change the Culture.

ServiceController.cs

public class ServiceController : ApiController
{
    [HttpGet]
    public string Get(string lang)
    {
        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang);
        return Resources.Global.Country;
    }
}

When I call http://localhost/en/api/service/get or http://localhost/pt/api/service/get I get the string in their respective languages, working perfectly.

How can I avoid using

Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang);

on all Actions?

Where can I write it once in the code, but still getting the needed lang argument?

Upvotes: 0

Views: 100

Answers (1)

Shyju
Shyju

Reputation: 218892

If you are after removing some code from all your action method and want that in a central place to avoid code duplication, you may consider creating an action filter and apply it globally so that it will be applicable to all requests.

public class LangSettingActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var routeData= actionContext.Request.GetRouteData();
        object langCode;
        if (routeData.Values.TryGetValue("lang", out langCode))
        {
          //the languageCode from url is in langCode variable. Use it as needed.
          //Thread.CurrentThread.CurrentUICulture =
                                    //CultureInfo.GetCultureInfo(langCode.ToString());

        }
        base.OnActionExecuting(actionContext);
    }
}

You can register this filter globally inside the Register method of your WebApiConfig class.

public static void Register(HttpConfiguration config)
{
   // Your existing route definiton here
   config.Filters.Add(new LangSettingActionFilter());
}

Upvotes: 1

Related Questions