2012-06-27 6 views
5

MVC 3에서 PL과 EN의 두 언어 사이에서 내보기를 전환하고 싶습니다. Views-EN 및 PL에 두 개의 폴더를 만들었습니다. 이 모든 스레드에 지속적 CultureInfo를 변경 내가 적절한 링크 (언어 스위처)를 클릭경로를 전체적으로 변경하는 방법은 무엇입니까?

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

:

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

에 : 그래서 어떤 사이트에서 해당 언어 링크를 클릭 한 후 나는에서 내 경로 변경을 원하는 . 스위처 _Layout 전망 :

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

및 (또는 각 제어기의 방법에서 본와 요청 사이 영속 될 수있는 정적 변수 LANG 세트) 컨트롤러 :

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"); 
    } 

InitializeCulture 방법 페이지 오버라이드

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(); 
    } 
} 

CultureInfo를 올바르게 설정합니다. 이제는 (현재 CultureInfo에 따라) 모든 탐색 링크의 경로를 전환하고 mysite.com/PL/{controller}/{action}에서 mysite.com/EN/{controller}/{action}로 경로 패턴을 변경하고 싶습니다.

누구든지이 문제에 대한 아이디어 나 더 나은 접근 방법이 있습니까? 그러나 주소는 mysite.com/EN 또는 mysite.com/PL과 같아야합니다 - 차이가 없습니다 (예 : en.mysite.com)

답변

6

가장 먼저 결정해야하는 것은 현재 사용자를 저장할 위치입니다 언어. 이 URL의 일부로서 그것을 가지고 최선의 SEO 목적을 위해 모든 URL

  • 쿠키
  • 세션
  • IMHO의

    • 부분 : 다른 가능성이있다.

      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; 
          } 
      } 
      

      우리는 지금 Global.asax이 사용자 정의 경로를 등록 할 수 있습니다 :

      public static void RegisterRoutes(RouteCollection routes) 
      { 
          routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
      
          routes.Add("Default", new LocalizedRoute()); 
      } 
      

      그래서 나는 URL에서 언어를 분석하고 현재 스레드 문화를 설정하는 사용자 정의 경로를 작성하는 것이 좋습니다

      좋아요, 이제 모델을 보겠습니다 :

      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()); 
          } 
      } 
      

      그리고보기 :

      @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") 
      

      이제 링크 우리가 언어를 변경하고,이 언어는 이제 경로의 일부를 클릭하면. test 링크의 경로에서이 언어가 유지되는 언어를 선택했는지 주목하십시오.

      Scott Hanselman도 체크 아웃 할 가치가있는 ASP.NET의 현지화 및 세계화에 대해 nice blog post이라고 썼습니다. 또한 사전에 경로를 현지화해야 그냥

      /en/home 
      
      /fr/home 
      

      을 할 것입니다

      english: /en/home 
      
      french: /fr/accueil 
      
      english: /en/contactus 
      
      french: /fr/contacteznous 
      

      및 조회를 수행합니다

    +1

    대단히 감사합니다! 나는이 접근법을 시도 할 것이다! – lukaleli

    +0

    그리고 작동하지 않기 때문에 또 다른 질문이 있습니다./ 이유는 모르겠지만 애플리케이션이 시작된 후 라우트가 설정되지 않았다고 생각합니다. 오류가 있습니다 : '/'응용 프로그램의 서버 오류입니다. 리소스를 찾을 수 없습니다. 설명 : HTTP 404. 찾고있는 리소스 (또는 해당 종속성 중 하나)가 제거되었거나 이름이 변경되었거나 일시적으로 사용할 수없는 리소스 일 수 있습니다. 다음 URL을 검토하고 철자가 올바른지 확인하십시오. 요청 된 URL :/ 아이디어가 있으십니까? 나는 ASP.NET과 MVC에서 완전히 초보자입니다. – lukaleli

    +0

    좋습니다, 지금 작동 중입니다. 컨트롤러의 이름을 변경하는 것을 잊었습니다.) – lukaleli

    0

    이 솔루션은이 문제를 해결하지 않습니다.

    관련 문제