2012-02-19 3 views
1

В проекте ASP MVC 3 я хочу включить переключение языков.ASP-коммутатор ASP MVC 3 с ActionLink

Маршрутизация определяется следующим образом:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     routes.MapRoute(
      "DefaultWithLanguage", // Route name 
      "{language}/{controller}/{id}/{slug}", // URL with parameters 
      new { language = "en", controller = "Front", action = "Details", id = UrlParameter.Optional, slug = UrlParameter.Optional } // Parameter defaults     
     ); 

     routes.MapRoute(
      "Default", // Route name 
      "{controller}/{action}/{id}", // URL with parameters 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
     ); 

Попытка переключения языков (в _Layout.cshtml) работает следующим образом:

<li>@Html.ActionLink("Spanish", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "es" })</li>  

Вместо того, чтобы получить URL, как следующее (после того, как выбран испанский)

.../es/ControllerName/ActionName 

я «получаю это:

.../ControllerName/ActionName?Length=11 

Если я установить ActionLink к следующему (обратите внимание на последний параметр NULL):

<li>@Html.ActionLink("Spanish", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "es" }, null)</li> 

я получаю это:

.../ControllerName/ActionName?language=es 

Что мне не хватает? Спасибо заранее!

+0

Вы также оставили маршрут по умолчанию? Пожалуйста, покажите все свои регистрационные данные о маршруте. –

+0

@Darin Посмотрите на (измененную) формулировку. Я включил весь код в RegisterRoutes. –

ответ

1

Есть проблемы с регистрацией маршрутов DefaultWithLanguage Регистрация маршрута. Он не позволяет указать {action}. Это означает, что этот маршрут будет соответствовать только действию Details (так как вы указали его в значениях по умолчанию). Другая проблема заключается в том, что вы сделали необязательным параметр {id}. Но это невозможно. Только параметр последнего параметра маршрута может быть необязательным. В вашем случае следует параметр {slug}.

Так одна возможность заключается в следующем:

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

    routes.MapRoute(
     "DefaultWithLanguage", 
     "{language}/{controller}/{action}/{id}", 
     new 
     { 
      language = "en", 
      controller = "Front", 
      action = "Details", 
      id = UrlParameter.Optional 
     } 
    ); 
} 

, а затем:

@Html.ActionLink(
    "Spanish", 
    ViewContext.RouteData.GetRequiredString("action"), 
    ViewContext.RouteData.GetRequiredString("controller"), 
    new { language = "es" }, 
    null 
) 

Если вы хотите добавить параметр {slug}, то ваш {id} больше не может быть факультативным:

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

    routes.MapRoute(
     "DefaultWithLanguage", 
     "{language}/{controller}/{action}/{id}/{slug}", 
     new 
     { 
      language = "en", 
      controller = "Front", 
      action = "Details", 
      slug = UrlParameter.Optional 
     } 
    ); 
} 

и затем:

@Html.ActionLink(
    "Spanish", 
    ViewContext.RouteData.GetRequiredString("action"), 
    ViewContext.RouteData.GetRequiredString("controller"), 
    new { 
     language = "es", 
     id = ViewContext.RouteData.GetRequiredString("id") 
    }, 
    null 
) 
+0

Теперь я вижу! Ты прав! Большое спасибо за объяснение! Я попробую! –

0

Это ответ на ответ Дарина.

Я хочу иметь маршруты, как это:

.../en/ControllerName/Id 
.../en/ControllerName/Id/Slug 
.../en/ControllerName 

Этот последний маршрут вызывает проблему (см ответ Darin). «Взломать», чтобы получать эти маршруты, чтобы определить и другой маршрут (второй по имени DefaultWithLanguageWithoutId):

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

      routes.MapRoute(
       "DefaultWithLanguage", // Route name 
       "{language}/{controller}/{id}/{slug}", // URL with parameters 
       new { language = "en", controller = "Front", action = "Details", id = UrlParameter.Optional, slug = UrlParameter.Optional } // Parameter defaults             
      ); 

      routes.MapRoute(
       "DefaultWithLanguageWithoutId", // Route name 
       "{language}/{controller}", // URL with parameters 
       new { language = "en", controller = "Front", action = "Details"} // Parameter defaults     

      ); 

      routes.MapRoute(
       "Default", // Route name 
       "{controller}/{action}/{id}", // URL with parameters 
       new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
      ); 
     } 

Это вызывает код, который будет корректироваться в главной странице к следующим

<li>@Html.ActionLink("Deutsch", ViewContext.RouteData.Values["action"].ToString() 
, ViewContext.RouteData.Values["controller"].ToString(), new { language = "de" 
, id = ViewContext.RouteData.Values["id"]!=null ? ViewContext.RouteData.Values["id"].ToString():null }, null)</li> 
    <li>@Html.ActionLink("English", ViewContext.RouteData.Values["action"].ToString() 
, ViewContext.RouteData.Values["controller"].ToString(), new { language = "en" 
, id = ViewContext.RouteData.Values["id"] != null ? ViewContext.RouteData.Values["id"].ToString() : null }, null)</li> 

Работает отлично!

Единственный «недостаток» - это тот факт, что в представлении есть некоторый код (я бы хотел, чтобы его избегали), но я думаю, что это стоит того, что это очень просто!

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