2013-04-18 2 views
1

Я пытаюсь реализовать локализацию в моем приложении ASP.NET MVC с использованием маршрутизации.ASP.NET MVC Routing. Ресурс не найден

Например: www.example.com/Home/Index - отобразит содержание для культуры по умолчанию. www.example.com/en/Home/Index - покажет содержание на английском языке. www.example.com/ru/Home/Index - русский и так далее ...

Итак, я создал Локализация Атрибут для каждого действия:

public class LocalizationAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (filterContext.RouteData.Values["lang"] != null && !String.IsNullOrWhiteSpace(filterContext.RouteData.Values["lang"].ToString())) 
      { 
       var lang = filterContext.RouteData.Values["lang"].ToString(); 
       Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang); 
       Thread.CurrentThread.CurrentUICulture =    CultureInfo.CreateSpecificCulture(lang); 
      } 
      else 
      { 
       var langHeader = String.Empty; 
       langHeader = filterContext.HttpContext.Request.UserLanguages[0]; 
       Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(langHeader); 
       Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader); 
      } 

      base.OnActionExecuting(filterContext); 
     } 
    } 

Я добавляю этот атрибут для каждого действия в моих контроллеров.

И регистрирующие маршруты:

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapRoute(
      "Localization", 
      "{lang}/{controller}/{action}/{id}", 
      new { lang = "en-US", controller = "Home", action = "Index", id = UrlParameter.Optional } 
      ); 

    routes.MapRoute(
      "Default", 
      "{controller}/{action}/{id}", 
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
      ); 

} 

навигации к www.example.com/About/Contacts работает отлично. Но когда я перехожу на www.example.com/en/About/Contacts или что-то в этом роде, я получаю 404 error: ресурс не найден. Итак, что может быть проблемой?

Заранее благодарим за вашу помощь!

ответ

2

При переходе на www.example.com/en/About/Contacts вы по-прежнему вызываете маршрут по умолчанию. В этом случае оба маршрута будут совпадать, но будет вызываться только последний указанный (верхний к внизу).

Итак, когда вы переходите к этому URL маршрута по умолчанию примет следующий: контроллера: ан действий: О Id: Контакты

Вы должны добавить ограничения на маршруты, чтобы сделать их более конкретными. Или вы можете переместить маршрут «Локализация» ниже маршрута «По умолчанию», таким образом, оба будут по-прежнему совпадать, но в этом случае последним будет «Локализация».

Если вам нужно устранить что-либо подобное в будущем, я предлагаю вам использовать пакет RouteDebugger NuGet, это поможет вам понять, какие маршруты соответствуют запросу и какой из них действительно будет выполняться, и с какими параметрами .. Вот ссылка на Phil Haack запись в блоге об этом: http://haacked.com/archive/2011/04/12/routedebugger-2.aspx

+0

Большое вам спасибо за помощь! Я установил RouteDebugger, и он действительно говорит следующее Контроллер: ru Действие: О программе ID: Контакты. Итак, я добавляю ограничение для lang и controller: constraints: new {lang = @ "^ [az] {2} $", controller = @ "^ [a-zA-Z] {3,} $"} Но при этом показывается следующее: Контроллер: ru Действие: Около ID: Контакты. –

+0

Не имеет значения, что вы добавили ограничение на маршрут «Локализация», поскольку он просто делает этот маршрут более конкретным. Поскольку я сказал, что маршрут, который вы хотите сопоставить, действительно соответствует, но вместо этого вызывается «Default», поскольку он является последним, добавленным в маршруты (более «важные» маршруты внизу). Попробуйте переключить порядок маршрутов или добавьте (например) числовое ограничение в параметре Id на маршруте «По умолчанию», чтобы он больше не сопоставлял маршрут по умолчанию для этого конкретного запроса. – chrisd84

+0

Нет, ничего. Но я заметил, что мой маршрут «Локализация» даже не отображается в таблице «All Routes» RouteDebugger, где отображается маршрут «По умолчанию». И если я удалю маршрут «По умолчанию», ничего не изменится. Спасибо за ваше время! –