【问题标题】:Configuring ASP.NET MVC Attribute Routing for multi language site为多语言站点配置 ASP.NET MVC 属性路由
【发布时间】:2016-06-19 13:46:20
【问题描述】:

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

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。我通过在自定义过滤器中解析语言路由来设置当前线程文化。

【问题讨论】:

  • 看看this answer。对于属性路由,请阅读 cmets。
  • 所以你的建议只是为每个动作添加两条路线?还是我错过了什么?
  • 您可以 1) 每个操作添加 2 条路由 2) 使用常规路由或 3) 分析 MapMvcAttributeRoutes 的源并制作一个类似的方法,为每个 Route 属性注册一个本地化路由(是确保在MapMvcAttributeRoutes 之前调用您的自定义方法,以将路由以正确的顺序放入 RouteTable)。
  • 我用第三个选项的例子更新了我的other answer
  • 您是否尝试过执行属性路由的代码?当调用方法MapMvcAttributeRoutes() 来创建路由副本时,第一条路由的类型为RouteCollectionRoute,不能转换为Route。即使我忽略了这一点,这些添加的本地化路线也不起作用。

标签: c# asp.net asp.net-mvc routing attributerouting


【解决方案1】:

你基本上需要三样东西:

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

有关更多详细信息和代码示例,请参阅 this answer

(两者都是用 C# 编写的 - 隶属关系免责声明:我制作了这些示例)

有关更多信息和更多示例,您还可以阅读this blog post我写的关于这个主题的文章。

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

【讨论】:

    【解决方案2】:

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

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

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

    或操作上的单个属性:

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

    请注意,如果可选的 URI 参数(例如 {lang?})位于 URL 的开头,它们将不起作用。

    【讨论】:

      【解决方案3】:

      如果一切都失败了,那么我建议您保持默认路由不变并将语言存储在查询参数中

      对于英语,您的默认语言,URL 将如您所愿保持“干净”。

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

      但对于其他语言,您将 lang 包含为查询参数

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

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

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

      【讨论】:

      • 我正在考虑这种方法,但我想保持 URL 尽可能干净。
      猜你喜欢
      • 2012-03-12
      • 1970-01-01
      • 2011-10-08
      • 1970-01-01
      • 2018-10-12
      • 2015-07-19
      • 1970-01-01
      • 2013-12-11
      • 2017-07-12
      相关资源
      最近更新 更多