2016-03-05 55 views
3

我正在创建一个应支持多种语言的MVC5网站。该应用程序的结构很复杂,所以我只使用属性路由。 RouteConfig.cs很简单:为多语言站点配置ASP.NET MVC属性路由

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapMvcAttributeRoutes(); 
} 

我想通过网站名称后添加语言标识,以保持语言信息的URL。对于默认语言的英语,URL应该保持“干净”。这里有一个例子:

http://test.com/foo/1/bar/2 
http://test.com/de/foo/1/bar/2 

我第一次尝试使用两个RoutePrefix属性为每个控制器:

[RoutePrefix("foo")] 
[RoutePrefix("{lang}/foo")] 

但MVC不允许使用超过一个RoutePrefix属性的控制器。

所以现在我不使用RoutePrefix属性可言,并指定每个控制器动作全路线:

[Route("foo/{a}/bar/{b}")] 
[Route("{lang}/foo/{a}/bar/{b}")] 

有没有更好的方式来处理lang路线?理想情况下,我想只在一个地方指定,而不是每个控制器。

PS。我通过在自定义过滤器中解析语言路由来设置当前线程文化。

+1

看一看[这个答案](http://stackoverflow.com/questions/32764989/asp-net-mvc-5-culture-in-route-and-url#32839796)。对于属性路由,请阅读注释。 – NightOwl888

+0

所以你的建议只是为每个动作添加两条路线?或者我错过了什么? –

+0

您可以1)每个动作添加2个路由2)使用传统路由或3)分析MapMvcAttributeRoutes源,并为每个Route属性注册一个本地化路由(请务必在调用您的自定义方法之前'MapMvcAttributeRoutes'将路由以正确的顺序放入RouteTable中)。 – NightOwl888

回答

0

如果这些方法都失败,那么我建议你保持你的默认路由的值并存储在语言的查询参数

对于英语,默认语言,URL会你打算保持“干净”。

http://test.com/foo/1/bar/2 

但是对于其他的语言,你包括lang作为查询参数

http://test.com/foo/1/bar/2?lang=De-DE 

然后在您的自定义过滤器,检查查询参数存在。如果是那么改变文化来匹配。否则使用默认语言。

另外:您应该使用5字符编码,而不是2 char全球化ISO代码。 De-DE,而不是DE或fr-FR,而不是FR

+0

我正在考虑这种方法,但我希望尽可能保持URL清洁。 –

1

我发现最简单的解决方案(至少对于ASP.NET MVC 5.2)是使用可选参数的默认值。

例如,如果英语是你的默认语言,你可以使用控制器上的一个属性:

[RoutePrefix("{lang=en}/foo")] 

或行动的单一属性:

[Route("{lang=en}/foo/bar")] 

注意,可选的URI参数(如{lang?})如果位于URL的起始位置,则不起作用。

0

你基本上需要三样东西:

  • 多语言感知路由处理传入的URL(如果你使用MVC5或以上,你也可以去基于属性的路由,而不是,但我仍然倾向于使用全局规则来处理这个问题)。
  • A LocalizationAttribute来处理这些类型的多语言请求。
  • 帮助程序在您的应用程序(Html.ActionLink和/或Url.Action扩展方法)中生成这些URL的帮助方法。

查看this answer了解更多详情和代码示例。

(两者都是用C#编写)

有关其他信息,并进一步样品关于这个主题,你也可以阅读this post

http://www.ryadel.com/en/html-actionlink-extension-method-written-c-handle-multi-language-routes-asp-net-mvc/