ASP.NET MVC 路由配置和带有长 URL 的国际化

ASP.NET MVC Routes Config and Internationalization with long URLs

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

这是我的路由配置:

      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[=31= 访问] 和 domain/en-us/users/edit/rights/240.

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

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

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

如果您希望您的 URLs 看起来像您的 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 方案。