MVC RouteConfig影响了Html.ActionLink()辅助方法

时间:2016-01-14 12:11:02

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

在我的MVC项目中,我有项目控制器以及索引等一些操作。

RouteConfig包括:

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

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

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

  

/ IndirectItem /索引

使用默认参数( indirect = 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& #34;)辅助方法映射到URL( / IndirectItem / Index )而不是( / Item / Index )。

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

3 个答案:

答案 0 :(得分:2)

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

使用以下 IndirectItem 路线代替您的路线。

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

您无需对默认路线进行任何更改。

它对我很好。

答案 1 :(得分:0)

您遇到此问题是因为Html.ActionLink使用路由表生成网址,并且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 }
);

应解决问题

另一个选项可能是创建从Item控制器继承的空IndirectItem控制器:

public IndirectItemController : ItemController
{
}

然后将路线更改为

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

答案 2 :(得分:0)

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

您遇到的问题是生成网址时您的路线不匹配。这只是因为您没有提供所有路线值来在ActionLink中创建匹配。

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

如果无法更改ActionLink声明,则可以使用DataTokens parameter"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" }
);