【问题标题】:ASP.NET MVC Routes Config and Internationalization with long URLs带有长 URL 的 ASP.NET MVC 路由配置和国际化
【发布时间】:2015-08-07 08:12:40
【问题描述】:

我正在处理国际化和长途路线。 我的网址看起来像 domain/en-us/users/edit/240

这是我的 RouteConfig:

      routes.MapRoute(
            name: "DefaultWithCulture",
            url: "{culture}/{controller}/{action}/{id}",
            defaults: new { culture = CultureHelper.GetDefaultCulture(), controller = "Home", action = "Index", id = UrlParameter.Optional },
                constraints: new { culture = "([a-zA-Z]{2}-[a-zA-Z]{2})|[a-zA-Z]{2}" }
         );

        routes.MapRoute(name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

这是我的控制器用户中的一些操作:

    public ActionResult Edit(int id);
    public ActionResult EditPassword(int id);
    public ActionResult EditRights(int id);

我希望我的操作 EditPasswordEditRights 可以通过 domain/en-us/users/edit/password/240 访问em>domain/en-us/users/edit/rights/240.

我确实找到了一个解决方案,使用 Route Attributes 但在我的 url 中使用文化(en-us、es-mx、fr-ca),它打破了这一切。

【问题讨论】:

  • 这与 Classic ASP 无关。
  • 查看this answer 了解另一种本地化方法。

标签: asp.net-mvc model-view-controller routes internationalization asp.net-mvc-routing


【解决方案1】:

您配置的DefaultWithCulture 路由将匹配 3 或 4 个路由段。您的 URL (en-us/users/edit/password/240) 有 5 个路由段,因此不会匹配。

如果您将配置的操作方法名称传递给它,它匹配:en-us/users/editpassword/240

如果您希望您的网址看起来像带有 5 个分段的示例,您将需要做一些额外的工作。首先,您需要考虑您的操作名称和 URL 不匹配的事实。一种方法是使用ActionName 属性。

[ActionName("password")]
public ActionResult EditPassword(int id);

[ActionName("rights")]
public ActionResult EditRights(int id);

然后您需要一些新的路由和约束来匹配 4 或 5 段 URL。要处理的主要问题是您的某些细分市场重叠。因此,您需要一个约束,以便您可以判断第 4 段何时是 id 或者它是否是一个操作方法。

基本上,要做到这一点,将带有可选 id 参数的 1 条路由分解为带有必需参数的 2 条路由(因为当您向 id 添加约束时,它使其成为必需的)。

然后为本地化和非本地化版本添加另一个路由,以处理 URL 中额外的 edit 段。

// Route to handle culture with 4 segments, ending in numeric id
routes.MapRoute(
    name: "DefaultWithCulture",
    url: "{culture}/{controller}/{action}/{id}",
    defaults: new { culture = CultureHelper.GetDefaultCulture(), controller = "Home", action = "Index" },
    constraints: new { culture = "([a-zA-Z]{2}-[a-zA-Z]{2})|[a-zA-Z]{2}", id = @"\d+" }
);

// Route to handle culture with 3 segments, to make id optional
routes.MapRoute(
    name: "DefaultWithCulture3Segments",
    url: "{culture}/{controller}/{action}",
    defaults: new { culture = CultureHelper.GetDefaultCulture(), controller = "Home", action = "Index" },
    constraints: new { culture = "([a-zA-Z]{2}-[a-zA-Z]{2})|[a-zA-Z]{2}" }
);

// Route to handle culture with 4 or 5 segments
routes.MapRoute(
    name: "DefaultWithCulture5Segments",
    url: "{culture}/{controller}/edit/{action}/{id}",
    defaults: new { culture = CultureHelper.GetDefaultCulture(), controller = "Home", action = "Index", id = UrlParameter.Optional },
    constraints: new { culture = "([a-zA-Z]{2}-[a-zA-Z]{2})|[a-zA-Z]{2}" }
);

// Route to handle default with 3 segments, ending in numeric id
routes.MapRoute(name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index" },
    constraints: new { id = @"\d+" }
);

// Route to handle default with 2 segments, to make id optional
routes.MapRoute(name: "Default2Segments",
    url: "{controller}/{action}",
    defaults: new { controller = "Home", action = "Index" }
);

// Route to handle default with 3 or 4 segments
routes.MapRoute(name: "Default4Segments",
    url: "{controller}/edit/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

如果您希望添加的额外段读取除edit 之外的其他内容,则需要额外的路由,因为 MVC 本身不理解此 URL 方案。

【讨论】:

  • 谢谢NigghtOwl888。这个答案是完美的!不过,我不会通过 myslef 找到它。
猜你喜欢
  • 2011-09-07
  • 2012-02-24
  • 2014-02-09
  • 2017-12-09
  • 1970-01-01
  • 2015-12-26
  • 1970-01-01
  • 2010-11-14
  • 2017-07-12
相关资源
最近更新 更多