2012-06-27 3 views
5

MVC 3のビューをPLとENの2つの言語に切り替える必要があります。 Views-ENとPLに2つのフォルダを作成しました。それはすべてのスレッドへの持続的であるの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から言語を解析し、現在のスレッドの文化を設定するカスタムルートを書い推薦します

      さて、今すぐモデルを持ってみましょう:

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

      A c ontroller:今

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

      あなたは私たちが言語を変更すると、この言語は、現在のルートの一部であるリンクをクリックしてください:

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

      とビュー。 testリンクのルートでこの言語が永続化されている言語を選択した後は、どのように注意してください。

      Scott Hanselmanも、チェックアウトの価値があるASP.NETのローカリゼーションとグローバリゼーションについてnice blog postと書いています。

    +1

    ありがとうございます!私はこのアプローチを試みます! – lukaleli

    +0

    と私はあなたに別の質問をしています:/ 理由はわかりませんが、アプリケーションの起動後にルートが設定されていないと思います。エラーがあります: '/'アプリケーションのサーバーエラーです。 リソースが見つかりません。 説明:HTTP 404。探しているリソース(またはその依存関係の1つ)が削除されているか、名前が変更されているか、一時的に使用できない可能性があります。次のURLを確認し、正しく入力されていることを確認してください。 リクエストされたURL:/ アイデアはありますか?私はASP.NETとMVCの初心者です – lukaleli

    +0

    さて、それは今働いています。私はコントローラの名前を変更するのを忘れた;) – lukaleli

    0

    このソリューションでは、この問題を解決することはできません。

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

    それはちょうどあなたがまた辞書内のルートをローカライズして検索を行う必要があります

    /en/home 
    
    /fr/home 
    

    を行います。

    関連する問題