2012-06-27 26 views
5

Tôi muốn chuyển chế độ xem của tôi ở MVC 3 giữa hai ngôn ngữ - PL và EN. Tôi đã tạo hai thư mục trong Views- EN và PL. Vì vậy, sau khi nhấp vào liên kết ngôn ngữ thích hợp tại trang web bất kỳ Tôi muốn thay đổi con đường của tôi từ:Làm cách nào để thay đổi tuyến đường trên toàn cầu?

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

tới:

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

Khi tôi bấm vào liên kết thích hợp (ngôn ngữ switcher) nó thay đổi CultureInfo đó là kiên trì cho tất cả các chủ đề . _Layout View với switcher:

<ul> 
    <li>@Html.ActionLink("En", "ChangeCulture", null, new { lang = "en"}, null)</li> 
    <li>@Html.ActionLink("Pl", "ChangeCulture", null, new { lang = "pl"}, null)</li> 
</ul> 

và điều khiển (trong đó bộ cũng biến tĩnh lang có thể được nhìn thấy trong phương pháp của mỗi bộ điều khiển và kiên trì giữa các yêu cầu):

public ActionResult ChangeCulture(string lang) 
    { 

     PLController.lang = lang; 
     CultureSettings setCulture = new CultureSettings(); 
     setCulture.InitializeCulture(lang); 
     cookie.Value = CultureInfo.CurrentCulture.Name; 
     this.ControllerContext.HttpContext.Response.Cookies.Add(cookie); 
     return View("Index"); 
    } 

phương pháp InitializeCulture được overriden từ trang lớp học như sau:

public class CultureSettings : Page{ 

    public void InitializeCulture(string culture) 
    { 
      String selectedLanguage; 
      if(culture == null) 
      { 
       selectedLanguage = "pl"; 
      } 
      else 
      { 
       selectedLanguage = culture; 
      } 

      UICulture = selectedLanguage; 
      Culture = selectedLanguage; 

      Thread.CurrentThread.CurrentCulture = 
       CultureInfo.CreateSpecificCulture(selectedLanguage); 
      Thread.CurrentThread.CurrentUICulture = new 
       CultureInfo(selectedLanguage); 

     base.InitializeCulture(); 
    } 
} 

Tập hợp CultureInfo đúng cách. Bây giờ tôi muốn (theo CultureInfo) chuyển tuyến đường cho mọi liên kết điều hướng và thay đổi mẫu tuyến đường từ mysite.com/PL/{controller}/{action} thành mysite.com/EN/{controller}/{action}.

Có ai có ý tưởng nào hoặc có thể tiếp cận tốt hơn cho vấn đề này không? Nhưng điều kiện là địa chỉ đó phải giống như thế này mysite.com/EN hoặc mysite.com/PL - không khác (ví dụ: en.mysite.com)

Trả lời

6

Điều đầu tiên bạn phải quyết định là nơi lưu trữ người dùng hiện tại ngôn ngữ. Có khả năng khác nhau:

  • một phần của mỗi url
  • Cookie
  • phiên

IMHO cho mục đích SEO tốt nhất để có nó như một phần của url.

Vì vậy, tôi muốn giới thiệu cách viết một lộ trình tùy chỉnh mà sẽ phân tích ngôn ngữ từ url và thiết lập văn hóa thread hiện hành:

public class LocalizedRoute : Route 
{ 
    public LocalizedRoute() 
     : base(
      "{lang}/{controller}/{action}/{id}", 
      new RouteValueDictionary(new 
      { 
       lang = "en-US", 
       controller = "home", 
       action = "index", 
       id = UrlParameter.Optional 
      }), 
      new RouteValueDictionary(new 
      { 
       lang = @"[a-z]{2}-[a-z]{2}" 
      }), 
      new MvcRouteHandler() 
     ) 
    { 
    } 

    public override RouteData GetRouteData(HttpContextBase httpContext) 
    { 
     var rd = base.GetRouteData(httpContext); 
     if (rd == null) 
     { 
      return null; 
     } 

     var lang = rd.Values["lang"] as string; 
     if (string.IsNullOrEmpty(lang)) 
     { 
      // pick a default culture 
      lang = "en-US"; 
     } 

     var culture = new CultureInfo(lang); 

     Thread.CurrentThread.CurrentCulture = culture; 
     Thread.CurrentThread.CurrentUICulture = culture; 

     return rd; 
    } 
} 

Chúng tôi bây giờ có thể đăng ký lộ trình tùy chỉnh này trong Global.asax:

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

    routes.Add("Default", new LocalizedRoute()); 
} 

Được rồi, bây giờ chúng ta hãy có một mô hình:

public class MyViewModel 
{ 
    [DisplayFormat(DataFormatString = "{0:d}")] 
    public DateTime Date { get; set; } 
} 

A c ontroller:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel 
     { 
      Date = DateTime.Now 
     }); 
    } 

    public ActionResult Test() 
    { 
     return Content(DateTime.Now.ToLongDateString()); 
    } 
} 

Và một cái nhìn:

@model MyViewModel 

@Html.DisplayFor(x => x.Date) 

<ul> 
    <li>@Html.ActionLink("switch to fr-FR", "index", new { lang = "fr-FR" })</li> 
    <li>@Html.ActionLink("switch to de-DE", "index", new { lang = "de-DE" })</li> 
    <li>@Html.ActionLink("switch to en-US", "index", new { lang = "en-US" })</li> 
</ul> 

@Html.ActionLink("Test culture", "test") 

Bây giờ khi bạn nhấp vào liên kết chúng ta đang thay đổi ngôn ngữ và ngôn ngữ này bây giờ là một phần của tuyến đường. Lưu ý cách bạn đã chọn ngôn ngữ mà ngôn ngữ này đang được duy trì trong các tuyến đường cho liên kết test.

Scott Hanselman cũng đã viết nice blog post về bản địa hóa và toàn cầu hóa trong ASP.NET đáng để kiểm tra.

+1

cảm ơn bạn rất nhiều! Tôi sẽ thử phương pháp này! – lukaleli

+0

và tôi cũng có một câu hỏi khác cho bạn vì nó không hoạt động:/ Tôi không biết tại sao, nhưng tôi nghĩ rằng các tuyến đường không được thiết lập sau khi ứng dụng bắt đầu. Có lỗi: Lỗi máy chủ trong ứng dụng '/'. Không thể tìm thấy tài nguyên. Mô tả: HTTP 404. Tài nguyên bạn đang tìm kiếm (hoặc một trong các phụ thuộc của nó) có thể đã bị xóa, tên của nó đã thay đổi hoặc tạm thời không khả dụng. Vui lòng xem lại URL sau và đảm bảo rằng URL được viết đúng chính tả. URL được yêu cầu:/ Bất kỳ ý tưởng nào? Tôi là tổng số newbie trong ASP.NET và MVC – lukaleli

+0

Ok, bây giờ nó đang hoạt động. Tôi quên thay đổi tên của bộ điều khiển;) – lukaleli

0

Giải pháp này sẽ không giải quyết vấn đề này:

english: /en/home 

french: /fr/accueil 

english: /en/contactus 

french: /fr/contacteznous 

Nó sẽ chỉ làm

/en/home 

/fr/home 

Bạn cũng nên khoanh vùng các tuyến đường trong một cuốn từ điển và làm một tra cứu.

Các vấn đề liên quan