如何使用MVC路由多语言URL

我需要现有控制器的多语言URL路由。 让我解释一下:

我有一个名为“Product”的控制器和名为“Software”的View; 因此,默认情况下,如果用户输入“ http://example.com/en/Product/Software ”,请获取正确的内容(实际存在于http://example.com/Product/Software中 ),

但是,如果另一个用户 – 法国用户 – 键入“ http://example.com/fr/Produits/logiciels ”,则必须获得控制器并显示正确的内容(同样http://example.com/Product/软件,但有法语文本)。

注意:我使用“{language} / {controller} / {action} / {id}”设置路由表

任何其他无效的url都必须显示404页面。

可能吗?

在Dan的post的基础上,我使用底层来翻译我的控制器和动作名称。

我创建了一个表来存储值,这可能并且可能应该保存在资源文件中以保持所有内容; 但是我使用了数据库表,因为它可以更好地与我公司的流程配合使用

CREATE TABLE [dbo].[RoutingTranslations]( [RouteId] [int] IDENTITY(1,1) NOT NULL, [ControllerName] [nvarchar](50) NOT NULL, [ActionName] [nvarchar](50) NOT NULL, [ControllerDisplayName] [nvarchar](50) NOT NULL, [ActionDisplayName] [nvarchar](50) NOT NULL, [LanguageCode] [varchar](10) NOT NULL) 

然后将RouteConfig.cs文件更改为:

 public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); //Build up routing table based from the database. //This will stop us from having to create shedloads of these statements each time a new language, controller or action is added using (GeneralEntities db = new GeneralEntities()) { List rt = db.RoutingTranslations.ToList(); foreach (var r in rt) { routes.MapRoute( name: r.LanguageCode + r.ControllerDisplayName + r.ActionDisplayName, url: r.LanguageCode + "/" + r.ControllerDisplayName + "/" + r.ActionDisplayName + "/{id}", defaults: new { culture = r.LanguageCode, controller = r.ControllerName, action = r.ActionName, id = UrlParameter.Optional }, constraints: new { culture = r.LanguageCode } ); } } //Global catchall routes.MapRoute( name: "Default", url: "{culture}/{controller}/{action}/{id}", defaults: new {culture = CultureHelper.GetDefaultCulture(), controller = "Default", action = "Index", id = UrlParameter.Optional } //defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } } 

默认情况下,它将始终使用英语控制器和操作名称,但允许您通过在表中输入值来提供覆盖。

(我的国际化代码主要基于这篇伟大的博客文章.http://afana.me/post/aspnet-mvc-internationalization-part-2.aspx )

正如之前所建议的那样,这确实背离了网站url(和路线)使用英语的惯例。

尽管如此,它是可能的,但为了做到这一点,你可能不得不考虑为每种外语生成一个每个动作的路径。 因此,对于一个包含20个动作和三种语言(英语,法语和德语)的网站,您需要41条路线(20条法语,20条德语和1条英语)。 我承认,这不是最有效的系统,但它可以按照您的意愿运行。

 //You'll only need one of these, which is the default. routes.MapRoute( "English route", "en/{controller}/{action}/{id}" new { controller = "Home", action = "Index", language = "en" }, ); routes.MapRoute( "FrenchHome", "fr/Demarrer/Index/{id}", new { controller = "Home", action = "Index", language = "fr" } ); routes.MapRoute( "GermanHome", "de/Heim/Index/{id}", //'Heim' is, I believe the correct usage of Home in German. new { controller = "Home", action = "Index", language = "de" } ); //Some more routes... routes.MapRoute( "FrenchSoftware", "fr/Produit/Logiciels/{id}", new { controller = "Product", action = "Software", language = "fr" } ); routes.MapRoute( "GermanSoftware", "de/Produkt/Software/{id}", //In this instance, Software should be the same in German and English. new { controller = "Product", action = "Software", language = "de" } ); //And finally, the 404 action. routes.MapRoute( "Catchall", "{language}/{*catchall}", new { controller = "Home", action = "PageNotFound", language = "en" }, new { language = "^(en|fr|de)$" } ); //This is for the folks who didn't put a language in their url. routes.MapRoute( "Catchall", "{*catchall}", new { controller = "Home", action = "PageNotFound", language = "en" } ); 

在您的行动中,例如产品/软件……

 public ActionResult Software(string language, int id) { //This would go off to the DAL and get the content in whatever language you want. ProductModel model = ProductService.GetSoftware(language, id); return View(model); } 

我会喜欢它,如果有人出现并说有更好的方法这样做,因为我同意使用外语的url不好,并且鉴于互联网本身正朝着允许非罗马字符的方向发展url,我们越早看到解决方案就越好。

不仅如此,我知道自豪的法国人不喜欢看到他们的网站url包含英文。 🙂

您应该为英语提供类似“ http://mysite.com/en/Product/Software ”的URL,为法语提供“ http://mysite.com/fr/Product/Software ”,这将非常有意义。

两者使用相同的视图。

快乐的编码。

我强烈建议使用以下方法在MVC 5(和<)Web应用程序中实现多语言,因为我发现它是我在最近几年尝试过的最通用的一种。

你基本上需要实现三件事:

  • 一种用于处理传入URL 的多语言感知路由 (如果您使用MVC5或更高版本,您也可以使用基于属性的路由 ,但我仍然更喜欢使用全局规则来处理此问题)。
  • LocalizationAttribute用于处理这些类型的多语言请求。
  • 在应用程序中生成这些URL的辅助方法Html.ActionLink和/或Url.Action扩展方法)。

有关更多详细信息和代码示例,请参阅此答案

有关此主题的其他信息和更多示例,您还可以阅读,您也可以阅读我在此主题上撰写的这篇博客文章 。