ASP.NET MVC - 本地化路由

Rop*_*tah 22 asp.net-mvc localization routes

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

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

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

我知道它可以通过定义{language}{location}在每个路线中完成,但我正在寻找一个光滑,非hacky解决方案.

Bri*_*ian 15

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

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

}
Run Code Online (Sandbox Code Playgroud)

你可以通过为你的所有动作添加一个文化参数来获得文化......

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

    return View();
}
Run Code Online (Sandbox Code Playgroud)

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

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

使用网址存储文化的缺点是,如果您错过了网站某处的链接或用户离开网站然后又回来了,您可能会失去用户文化,他们将不得不重新设置(不是结束)可能是使用网址存储文化的一个好方面是谷歌将索引所有不同的语言.

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

查看如何本地化ASP .Net MVC应用程序?.接受的答案指向博客文章,其中显示了如何本地化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);
}
Run Code Online (Sandbox Code Playgroud)


小智 8

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


Bru*_*ino 7

这似乎是一个更好的方法:http://blog.maartenballiauw.be/post/2010/01/26/Translating-routes-(ASPNET-MVC-and-Webforms).aspx


Che*_*rek 5

这是一个博客,其中描述了使用路由机制在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()));
        }
   }

}
Run Code Online (Sandbox Code Playgroud)

和切换控制器动作

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