如何使用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
扩展方法)。
有关更多详细信息和代码示例,请参阅此答案
有关此主题的其他信息和更多示例,您还可以阅读,您也可以阅读我在此主题上撰写的这篇博客文章 。
- 在asp.net mvc中一次更新多个记录
- 在Asp.Net Mvc中从数据库下载文件
- InvalidOperationException:无法为“Role”创建DbSet,因为此类型未包含在上下文的模型中
- ASP.net Session_Start方法中的dependency injection
- ASP.NET MVC中htmlAttributes的匿名类和IDictionary 之间的区别?
- ASP .NET MVC NonAction含义
- 在AmazonS3 Bucket内部处理文件夹(c#)
- 将特殊字符转换为正常
- 使用ASP.NET和MVC 3,如何创建隐藏字段,以便具有数组的List作为列表中每个项的值正确绑定?