MVC RouteConfig 影响了 Html.ActionLink() 帮助程序方法

本文关键字:帮助程序 方法 ActionLink Html RouteConfig 影响 MVC | 更新日期: 2023-09-27 18:30:33

在我的MVC项目中,我有项目控制器和一些操作,如索引

路由配置包括:

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

在某些视图中,我使用帮助程序方法 Html.ActionLink("Items","Index","Item") 为索引操作创建锚点。所以锚点结果的 href 将是 (/项目/索引

现在,我需要映射以下静态 URL:

/

间接项目/索引

到具有默认参数 (间接 = true) 的控制器的索引操作,因此 RouteConfig 将为:

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

看起来没问题,客户端请求被正确映射,但是从Html.ActionLink("Items","Index","Item")帮助程序方法产生的所有锚点都映射到URL(/IndirectItem/Index)而不是(/Item/Index)。

如何在不将所有 Html.ActionLink() 更改为 Html.RouteLink() 或为原始 url 添加其他路由的情况下解决此问题?

MVC RouteConfig 影响了 Html.ActionLink() 帮助程序方法

使用约束将是解决问题的便捷解决方案。

使用以下间接项路由,而不是您的路由。

routes.MapRoute(
           name: "IndirectItem",
           url: "{staticVar}/{action}",
           defaults: new { controller = "Item", action = "Index", indirect = true},
           constraints: new { staticVar = "IndirectItem" }
        );

并且您不需要对默认路由进行任何更改。

它对我很好用。

遇到此问题Html.ActionLink因为它使用路由表生成 URL,并且IndirectItem路由与Html.ActionLink("Items","Index","Item")匹配(因为它在路由和操作链接中都指定了索引操作和项控制器)。由第一个匹配完成的解析,因此路由注册的顺序很重要

通过添加DefaultItem路由:

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

在您当前路线之前:

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

应该解决问题

另一种选择可能是创建从项目控制器继承的空间接项控制器:

public IndirectItemController : ItemController
{
}

然后将路由更改为

routes.MapRoute(
       name: "IndirectItem",
       url: "IndirectItem/Index/,
       defaults: new { controller = "IndirectItem", action = "Index", indirect = true}
); 

Omar Gohar和Alex Art给出的答案具有误导性。

您遇到的问题是生成 URL 时您的路由不匹配。这仅仅是因为您尚未提供所有路由值以在ActionLink中创建匹配项。

@Html.ActionLink("Items", "Index", "Item", new { indirect = true }, null)

如果无法更改ActionLink声明,则可以使用 DataTokens 参数将"indirect"元数据附加到路由。

使用 DataTokens 属性可以检索或分配与路由关联的值,这些值不用于确定路由是否与 URL 模式匹配。这些值将传递到路由处理程序,在那里它们可用于处理请求。

routes.MapRoute(
    name: "IndirectItem",
    url: "IndirectItem/Index",
    defaults: new { controller = "Item", action = "Index" }
).DataTokens = new RouteValueDictionary(new { indirect = true });

最重要的是,RouteValues(如果 URL 模式未提供,则由默认值填充)不用于元数据。它们旨在成为要匹配的真实数据,以使 URL 唯一。

当然,如果您实际上没有将indirect路由值用于任何内容,则可以简单地从路由中省略它。

routes.MapRoute(
    name: "IndirectItem",
    url: "IndirectItem/Index",
    defaults: new { controller = "Item", action = "Index" }
);