2016-08-24 2 views
0

Моя цель - создать API, поддерживающий несколько языков.Избегайте повторения кода в API-действиях, но при этом поддерживаете многоязычность

Это работает, но только если я буду называть

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

на каждом действии, то, что я полагаю, что можно избежать.


На WebApiConfig.cs файл я создал маршрут для поддержки нескольких языков, помещая этот язык, прежде чем маршрут по умолчанию "{lang}/api/{controller}/{id}". Это означает, что для английского языка я могу позвонить по номеру http://localhost/en/api/service/get и для португальского языка 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 } 
     ); 
    } 
} 

На моем действии я получаю язык и использовать его, чтобы изменить культуру.

ServiceController.cs

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

Когда я называю http://localhost/en/api/service/get или http://localhost/pt/api/service/get я получаю строку в своих языках, прекрасно работает.

Как я могу избежать использования

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

на все действия?

Где я могу написать его один раз в коде, но все еще получая необходимый аргумент lang?

  • Я попытался Global.asax.cs, но я, если я могу (и как) не знаю, что получить lang аргумент.
  • Я не знаю, могу ли я (и как) поставить его на WebApiConfig.cs.
+0

Любые причины, по которым вы хотите указать язык в URL, а не как параметр запроса? Последний чувствует себя более чистым вариантом для меня ... или, конечно, взять его из существующих заголовков в запросе. –

+0

Глядя снова, кажется, что ваш вопрос не * действительно * о маршрутизации - речь идет о том, «как я могу получить ресурс для определенного языка». Было бы полезно, если бы вы удалили постороннюю часть маршрутизации. –

+0

Это поможет, если вы укажете тип 'Resources.Global'.Я предполагаю, что это сгенерированный класс с свойством ResourceManager, которое вы могли бы использовать для извлечения строки с определенной культурой. –

ответ

1

Если вы хотите удалить какой-либо код из всего вашего метода действий и хотите, чтобы в центральном месте, чтобы избежать дублирования кода, вы можете подумать о создании фильтра действий и применить его по всему миру, чтобы он применим ко всем запросам ,

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

Вы можете зарегистрировать этот фильтр глобально внутри Register метода вашего WebApiConfig класса.

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

Абсолютно совершенный. Это было то, что мне нужно. Он применяется ко всем действиям без необходимости устанавливать Культуру в каждом из них. Спасибо, Шию. – Edu

Смежные вопросы