2012-02-19 28 views
1

在ASP MVC 3項目中,我希望啓用語言切換。使用ActionLink的ASP MVC 3切換語言

路由的定義是這樣的:

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)的工作原理是這樣的:

而是得到一個URL像下面的(具有後
<li>@Html.ActionLink("Spanish", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "es" })</li>  

選定的西班牙語)

.../es/ControllerName/ActionName 

我得到這個:

.../ControllerName/ActionName?Length=11 

如果我設置了ActionLink的以下(注意最後一個空參數):

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

我得到這個:

.../ControllerName/ActionName?language=es 

我在想什麼? 在此先感謝!

+0

您是否也離開了默認路線?請顯示您的所有路線註冊。 – 2012-02-19 09:35:58

+0

@Darin看看(改變的)公式。我已將所有代碼包含在RegisterRoutes中。 – 2012-02-19 09:53:00

回答

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

現在我明白了!你是對的!非常感謝解釋!我會試試這個! – 2012-02-19 10:10:42

0

這是Darin的回答。

我想有這樣的路線:

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

這最後的路線導致該問題(見達林的答案)。該「黑客」繼續得到這個路線是還定義了另一條路線(第二個命名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> 

完美的作品!

唯一的「缺點」是在視圖中涉及到一些代碼(我想避免),但我認爲它是值得的,因爲它非常簡單!