2011-07-19 127 views
17

這是關於asp.net的MVC多語言網址/路由和搜索引擎優化的最佳做法/收益兩部分的問題...asp.net mvc的多語言網址/路由

問題第1部分)

我被要求創建一個新的ASP.NET MVC網站,將支持兩種語言(英語和法語)的最低(最初),也許在未來,3種語言...

就本地化應用程序(標籤,jQuery錯誤等),應該使用資源文件,我已經找到了很多這方面的例子......但我的意見/更多關於URL的問題。

在SEO方面,這兩種時尚之間推薦的做法是什麼?

Fashion 1 (no culture folder) 
www.mydomain.com/create-account 
www.mydomain.com/creer-un-compte 

Fashion 2 (with built in culture folder) 
www.mydomain.com/create-account 
www.mydomain.com/fr/creer-un-compte <--notice the 「fr」 folder 

是否存在已知的問題/使用懲罰之一?

還是它太小,它變得無關緊要!


問題第2部分)

爲了實現時尚2,我已經在這裏找到了一篇文章: ASP.NET MVC - Localization route

但我很好奇,想如何實現時尚1

有沒有人有任何鏈接?

另外,據我所知,網址重寫是而不是我在找什麼,因爲我不想「重定向」用戶...我只是希望網址以適當的語言顯示,而不必以顯示網址中的文化

在此先感謝您的幫助!

回答

18

您可以創建具有如下定位邏輯基本控制器:如果你想忽略文化夾,只是沒有在指定郎

public abstract class LocalizedController : Controller 
{ 
    protected override void ExecuteCore() 
    { 
     HttpCookie cookie; 
     string lang = GetCurrentCulture(); 
     Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang, false); 

     // set the lang value into route data 
     RouteData.Values["lang"] = lang; 

     // save the location into cookie 
     cookie = new HttpCookie("DPClick.CurrentUICulture", 
      Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName) 
      { 
       Expires = DateTime.Now.AddYears(1) 
      }; 

     HttpContext.Response.SetCookie(cookie); 
     base.ExecuteCore(); 
    } 

    private string GetCurrentCulture() 
    { 
     string lang; 

     // set the culture from the route data (url) 

     if (RouteData.Values["lang"] != null && 
      !string.IsNullOrWhiteSpace(RouteData.Values["lang"].ToString())) 
     { 
      lang = RouteData.Values["lang"].ToString(); 
      if (Localization.Locales.TryGetValue(lang, out lang)) 
      { 
       return lang; 
      } 
     } 
     // load the culture info from the cookie 
     HttpCookie cookie = HttpContext.Request.Cookies["DPClick.CurrentUICulture"]; 
     if (cookie != null) 
     { 
      // set the culture by the cookie content 
      lang = cookie.Value; 
      if (Localization.Locales.TryGetValue(lang, out lang)) 
      { 
       return lang; 
      } 

     } 
     // set the culture by the location if not speicified 
     lang = HttpContext.Request.UserLanguages[0]; 
     if (Localization.Locales.TryGetValue(lang, out lang)) 
     { 
      return lang; 
     } 
     //English is default 
     return Localization.Locales.FirstOrDefault().Value; 

    } 

} 

上述控制器滿足你的問題的時尚2 RouteDate。offcourse實現時尚2你必須添加路由文化如下:

  routes.MapRoute(
      "Localization", // Route name 
      "{lang}/{controller}/{action}/{id}", // URL with parameters 
      new {controller = "Default", action = "Index", id = UrlParameter.Optional}, // Parameter defaults 
      new {lang = @"\w{2,3}(-\w{4})?(-\w{2,3})?"} 
      ); 
+0

哇謝謝費拉斯!這段代碼非常好,可以幫助我更多地瞭解路由和本地化。 – Vlince

+0

歡迎隨時。 –

+5

@FerasKayyali嗨費拉斯,感謝分享信息。我正在使用您的代碼,但發現VS 2012無法識別本地化。它的名稱空間和dll是什麼? Thx – Franva

1

達到你想要什麼,你基本上需要實現三兩件事:

多語言感知路由處理傳入的URL:

routes.MapRoute(
    name: "DefaultLocalized", 
    url: "{lang}/{controller}/{action}/{id}", 
    constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})" }, // en or en-US 
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
); 

一個LocalizationAttribute來處理這些多語言要求:

public class LocalizationAttribute : ActionFilterAttribute 
{ 
    private string _DefaultLanguage = "en"; 

    public LocalizationAttribute(string defaultLanguage) 
    { 
     _DefaultLanguage = defaultLanguage; 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     string lang = (string)filterContext.RouteData.Values["lang"] ?? _DefaultLanguage; 
     if (lang != _DefaultLanguage) 
     { 
      try 
      { 
       Thread.CurrentThread.CurrentCulture = 
       Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang); 
      } 
      catch (Exception e) 
      { 
       throw new NotSupportedException(String.Format("ERROR: Invalid language code '{0}'.", lang)); 
      } 
     } 
    } 
} 

一種輔助方法來生成你的應用程序中的這些URL:這可以通過多種方式來實現,這取決於你應用邏輯。例如,如果您需要在Razor Views中執行此操作,則最好的做法是編寫一對擴展方法,以使您的Html.ActionLinkUrl.Action接受CultureInfo對象作爲參數(和/或使用CultureInfo.CurrentCulture作爲默認值),如下列:

(兩者都是用C#編寫)

你可以也避免了擴展方法模式,並將它們寫爲MultiLanguageActionLink/MultiLanguageAction

有關此主題的其他信息和更多示例,您還可以閱讀this post