无法使ActionLink或RouteLink生成正确的URL
本文关键字:URL RouteLink ActionLink | 更新日期: 2023-09-27 17:58:28
我是ASP.NET MVC的新手(使用版本3),无法使ActionLink
或RouteLink
按预期工作。在这个应用程序中,一个事件可以有很多活动,我希望使用来路由到它们
/事件/1/活动/事件/1/活动/索引(与以前相同)/事件/1/活动/详细信息/5
这两个助手生成的HTML看起来总是这样:
/事件/1
这是代码
查看Razor HTML
@Html.RouteLink("View Sessions", "SubControllerIndex",
new { eventId = Model.Id, controller = "Activity", action = "Index" })
@Html.ActionLink("View Sessions", "Index", "Activity", new { eventId = Model.Id }, null)
路线映射
routes.MapRoute(
"SubControllerIndex",
"Event/{eventId}/{controller}",
new { controller = "Activity", action = "Index" },
new { eventId = @"'d+" }
);
routes.MapRoute(
"ActivityIndex",
"Event/{eventId}/{controller}/{action}/{id}",
new { controller = "Activity", action = "Index", id = UrlParameter.Optional },
new { eventId = @"'d+", id = @"'d*" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { id = @"'d*" }
);
活动控制器
public ActionResult Index(long eventId)
{
var activities = _context.Activities.Where(a => a.Event.Id == eventId).ToList();
return View(activities);
}
你知道我在这里做错了什么吗?
路由系统为路由生成/Event/1
而不是/Event/1/Activity/Index
的原因
routes.MapRoute(
"ActivityIndex",
"Event/{eventId}/{controller}/{action}/{id}",
new { controller = "Activity", action = "Index", id = UrlParameter.Optional },
new { eventId = @"'d+", id = @"'d*" }
);
是因为在生成url时,系统不会在url中包含任何默认值。在这种情况下,控制器的默认值为"活动",而操作的默认值则为"索引"。因此,
@Html.RouteLink("View Sessions", "SubControllerIndex",
new { eventId = Model.Id, controller = "Activity", action = "Index" })
将生成CCD_ 5而不是CCD_。如果单击链接,您仍然应该转到ActivityController上的Index操作方法。
正如mrydengren所指出的,ActionLink和RouteLink方法将去掉与默认值相同的参数。然后URL应该指向你所指向的操作。
如果你仍然想使用完整的URL,你可以创建一个没有默认值的路由,并使用RouteLink创建与该路由的链接。
// Either add this at the end as a new route, or replace the one you already have.
routes.MapRoute("ActivityIndexWithoutParams",
"Event/{eventId/controller/action/id},
new{},
new{ eventId = @"'d+", id = @"'d*"}
);
现在您可以使用RouteLink方法创建正确的路线:
@Html.RouteLink("View Sessions", "ActivityIndexWithoutParameters",
new {eventid = Model.Id, controller = "activity", action = "index"}
);
当我将项目切换到使用区域时,我试图(不断尝试)找到为什么我的自定义RouteBase实现不能在出站路由(生成URL的路由)上工作的答案时,遇到了这个问题。
在分析MVC源代码时,我终于找到了答案:你必须让你的自定义RouteBase实现实现IRouteWithArea
,这样框架才能知道你的自定义路由属于哪个区域
public class CustomRoute: RouteBase, IRouteWithArea
{
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
// Implement custom virtual path (url) here
}
#region IRouteWithArea Members
public string Area
{
get { return "Store"; }
}
#endregion
}
请记住,路由是"贪婪的",第一个匹配将是被处理的路由,因此您需要丢失第一个路由条目,否则将永远无法到达第二个。
这是我能看到你需要做的唯一更改,否则也没关系,如下所示,在视图中添加一个操作链接;
@Html.ActionLink("View Sessions", "Details", "Activity", new { eventId = 12, id = 22 }, null)
您应该看到它在链接中生成了正确的URL。