【问题标题】:ASP.NET MVC - Localization routeASP.NET MVC - 本地化路线
【发布时间】:2009-11-11 00:13:16
【问题描述】:

我想为我的网站创建本地化 URL。它们显然应该指向相同的控制器操作,但我希望第一个路由值 - 始终 - 是位置/语言规范。这可能吗?

http://www.website.com/en/us/controller/action

http://www.website.com/en/gb/controller/action

我知道可以通过在每条路线中定义 {language}{location} 来完成,但我正在寻找一个巧妙、非 hacky 的解决方案。

【问题讨论】:

    标签: asp.net-mvc localization routes


    【解决方案1】:

    您可以像这样创建一条内置文化的路线...

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        routes.MapRoute(
            "Default",                                              // Route name
            "{culture}/{controller}/{action}/{id}",                           // URL with parameters
            new { culture="en-US", controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );
    
    }
    

    您可以通过像这样为所有操作添加文化参数来获取文化...

    public ActionResult Index(string culture)
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC! (" + culture + ")";
    
        return View();
    }
    

    您也可以在 Global.asax 中的 Application_BeginRequest 方法中解析 URL 并在那里设置线程文化(下面的代码示例显示了如何设置文化,我将解析留给您)。

    如果您这样做,您可能无法使用 RedirectToAction 和 HTML.ActionLink 类型的方法,因为它们对文化一无所知。当然,你总是可以自己写。

    使用 url 存储文化的缺点是,如果您错过了网站某处的链接,或者用户离开网站然后返回,您可能会丢失用户文化,他们将不得不重新设置(不是世界末日,而是烦人。使用 url 存储文化的一个好处可能是 Google 将索引所有不同的语言。

    如果您更关心用户体验或通过 Google 索引不同文化(实际上取决于您正在构建的网站类型)更容易开发,我建议将文化存储在 cookie 或会话状态中。

    查看How to localize ASP .Net MVC application?。接受的答案指向blog post,它显示了如何本地化 ASP.Net 应用程序。

    如果您将用户选择的文化存储在 cookie、会话状态或查询参数中,然后在 Global.asax 文件的 BeginRequest 方法中设置线程文化。然后使用标准的 Microsoft 本地化程序集完成本地化。

    以下代码将允许您随时更改文化,只需添加culture=??到查询字符串 (MyPage?culture=es-MX)。然后它将被添加到 cookie 中,这样您就无需将其添加到系统中每个链接的末尾。

    protected void Application_BeginRequest()
    {
        var culture = Request["culture"] ?? Request.Cookies["culture"]?.Name;
        if (culture == null) culture = "en-US";
        var ci = CultureInfo.GetCultureInfo(culture);
    
        Thread.CurrentThread.CurrentCulture = ci;
        Thread.CurrentThread.CurrentUICulture = ci;
    
        var cookie = new HttpCookie("culture", ci.Name);
        Response.Cookies.Add(cookie);
    }
    

    【讨论】:

    • 他正在寻求一种在所有路线中添加文化和语言的方法。
    • 我明白这一点。我建议的是一种无需将其添加到路线的方法。将其添加到路由会不必要地使应用程序复杂化。
    • 如果我的问题有答案,您能具体说明一下情况的复杂性吗?
    • 我更新了我的答案,提供了有关如何修改路线以允许 url 中的文化的信息。
    • 我希望有一种路由继承的解决方案成为可能。感谢您的明确回答,看看我的要求,在 URL 中存储文化(谷歌索引)最显着的好处可能不是最需要的。为每种语言创建单独的路由文件(或者显然在每个路由前加上文化路由值)是使用“cultured-urls”并保持 ActionLink.RouteUrl 功能的唯一解决方案吗?
    【解决方案2】:

    输出缓存依赖于 URL 变体。在设计本地化策略时考虑这一点。如果您计划使用输出缓存,请将本地化令牌嵌入 URL 中的某处。

    【讨论】:

      【解决方案3】:

      【讨论】:

      【解决方案4】:

      这是一个博客,其中描述了使用路由机制在 URL 中存储本地化的非常简单且非常强大的方法。 http://adamyan.blogspot.com/2010/07/addition-to-aspnet-mvc-localization.html

      核心是为所有指定类型的路由添加新参数

      public static void RegisterRoutes(RouteCollection routes)
      {
          routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
      
          routes.MapRoute(
               "Default", // Route name
               "{controller}/{action}/{id}", // URL with parameters
               new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
          );
      
          foreach (Route r in routes)
          {
              if (!(r.RouteHandler is SingleCultureMvcRouteHandler))
              {
                  r.RouteHandler = new MultiCultureMvcRouteHandler();
                  r.Url = "{culture}/" + r.Url;
                 //Adding default culture 
                 if (r.Defaults == null)
                 {
                     r.Defaults = new RouteValueDictionary();
                 }
                 r.Defaults.Add("culture", Culture.ru.ToString());
      
                 //Adding constraint for culture param
                 if (r.Constraints == null)
                 {
                     r.Constraints = new RouteValueDictionary();
                 }
                 r.Constraints.Add("culture", new CultureConstraint(Culture.en.ToString(), 
      Culture.ru.ToString()));
              }
         }
      
      }
      

      以及切换控制器动作

      public ActionResult ChangeCulture(Culture lang, string returnUrl)
      {
           if (returnUrl.Length >= 3)
           {
               returnUrl = returnUrl.Substring(3);
           }
           return Redirect("/" + lang.ToString() + returnUrl);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-23
        相关资源
        最近更新 更多