Ham*_*mid 20 c# model-view-controller asp.net-mvc routing url-rewriting
我需要现有控制器的多语言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}"设置路由表
任何其他无效的网址都必须显示404页面.
可能吗?
在Dan的帖子的基础上,我使用底层来翻译我的控制器和动作名称.
我创建了一个表来存储值,这可能并且可能应该保存在资源文件中以保持所有内容; 但是我使用了数据库表,因为它可以更好地与我公司的流程配合使用
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)
Run Code Online (Sandbox Code Playgroud)
然后将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<RoutingTranslation> 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 }
);
}
}
Run Code Online (Sandbox Code Playgroud)
默认情况下,它将始终使用英语控制器和操作名称,但允许您通过在表中输入值来提供覆盖.
(我的国际化代码主要基于这篇伟大的博客文章 .http://afana.me/post/aspnet-mvc-internationalization-part-2.aspx)
如前所述,这确实与网站网址(和路线)使用英语的约定背道而驰。
尽管如此,这是可能的,但是要做到这一点,您可能必须考虑为每种外语在每个动作中生成一条路线。因此,对于具有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" }
);
Run Code Online (Sandbox Code Playgroud)
在您的操作中,例如产品/软件...
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);
}
Run Code Online (Sandbox Code Playgroud)
如果有人说我有一种更好的方法,我会喜欢的,因为我同意以外语提供url不好,并且考虑到Internet本身正朝着允许非罗马字符输入的方向发展。网址,我们越早寻找解决方案越好。
不仅如此,而且我知道骄傲的法国人不喜欢看到他们的网站网址包含英语。:)
| 归档时间: |
|
| 查看次数: |
10960 次 |
| 最近记录: |