ActionLink 为属性路由生成错误的 URL
ActionLink generates wrong URL for Attribute Route
我正在使用属性路由来覆盖我控制器中的 URL。我有两个动作,唯一的区别是第二个动作的 ID。其余参数是用于搜索的可选查询参数。
// RouteConfig.cs - I setup AttributeRoutes before any other mapped routes.
routes.MapMvcAttributeRoutes();
// Controllers/DeliveryController.cs
[Route("mvc/delivery")]
public ActionResult Delivery(string hauler, DateTime? startDate, DateTime? endDate, int? page)
{
// ...
return View(model);
}
[Route("mvc/delivery/{id}")]
public ActionResult Delivery(int id, string hauler, DateTime? startDate, DateTime? endDate, int? page)
{
// ...
return View("DeliverySelected", model);
}
当手动导航到 /mvc/delivery
和 /mvc/delivery/1234/
时,两条路线都按预期工作,但链接生成不正确。
@Html.ActionLink("Delivery", "Delivery", new { id = delivery.ID })
@Url.Action("Delivery", new { id = delivery.ID })
这两种方法都会生成如下链接,触发第一个动作而不是第二个动作:
http://localhost:53274/mvc/delivery?id=1234
如何生成预期的 URL?
http://localhost:53274/mvc/delivery/1234
由于路由是顺序敏感的,您需要使用 Order 参数来确保它们以正确的顺序执行。
// Controllers/DeliveryController.cs
[Route("mvc/delivery", Order = 2)]
public ActionResult Delivery(string hauler, DateTime? startDate, DateTime? endDate, int? page)
{
// ...
return View(model);
}
[Route("mvc/delivery/{id}", Order = 1)]
public ActionResult Delivery(int id, string hauler, DateTime? startDate, DateTime? endDate, int? page)
{
// ...
return View("DeliverySelected", model);
}
感谢 this answer concerning ambiguous action methods,我找到了答案。在一个控制器中最多只能有 2 个同名的操作方法。
在这种情况下我确实有第三种方法,但由于我认为它不相关而被遗漏了:
[HttpPost]
[Route("mvc/delivery")]
public ActionResult Delivery(DeliveryViewModel model)
将我的第二个操作重命名为 SelectDelivery(int id, /*...*/)
解决了这个问题。
可以用下面的方法解决
[Route("mvc/delivery/{hauler}/{startdate?}/{enddate}/{page?}")]
public ActionResult Delivery(string hauler, DateTime? startDate, DateTime? endDate, int? page)
{
// ...
return View(model);
}
[Route("mvc/delivery/{id:int}/{hauler}/{startdate?}/{enddate}/{page?}")]
public ActionResult Delivery(int id, string hauler, DateTime? startDate, DateTime? endDate, int? page)
{
// ...
return View("DeliverySelected", model);
}
我正在使用属性路由来覆盖我控制器中的 URL。我有两个动作,唯一的区别是第二个动作的 ID。其余参数是用于搜索的可选查询参数。
// RouteConfig.cs - I setup AttributeRoutes before any other mapped routes.
routes.MapMvcAttributeRoutes();
// Controllers/DeliveryController.cs
[Route("mvc/delivery")]
public ActionResult Delivery(string hauler, DateTime? startDate, DateTime? endDate, int? page)
{
// ...
return View(model);
}
[Route("mvc/delivery/{id}")]
public ActionResult Delivery(int id, string hauler, DateTime? startDate, DateTime? endDate, int? page)
{
// ...
return View("DeliverySelected", model);
}
当手动导航到 /mvc/delivery
和 /mvc/delivery/1234/
时,两条路线都按预期工作,但链接生成不正确。
@Html.ActionLink("Delivery", "Delivery", new { id = delivery.ID })
@Url.Action("Delivery", new { id = delivery.ID })
这两种方法都会生成如下链接,触发第一个动作而不是第二个动作:
http://localhost:53274/mvc/delivery?id=1234
如何生成预期的 URL?
http://localhost:53274/mvc/delivery/1234
由于路由是顺序敏感的,您需要使用 Order 参数来确保它们以正确的顺序执行。
// Controllers/DeliveryController.cs
[Route("mvc/delivery", Order = 2)]
public ActionResult Delivery(string hauler, DateTime? startDate, DateTime? endDate, int? page)
{
// ...
return View(model);
}
[Route("mvc/delivery/{id}", Order = 1)]
public ActionResult Delivery(int id, string hauler, DateTime? startDate, DateTime? endDate, int? page)
{
// ...
return View("DeliverySelected", model);
}
感谢 this answer concerning ambiguous action methods,我找到了答案。在一个控制器中最多只能有 2 个同名的操作方法。
在这种情况下我确实有第三种方法,但由于我认为它不相关而被遗漏了:
[HttpPost]
[Route("mvc/delivery")]
public ActionResult Delivery(DeliveryViewModel model)
将我的第二个操作重命名为 SelectDelivery(int id, /*...*/)
解决了这个问题。
可以用下面的方法解决
[Route("mvc/delivery/{hauler}/{startdate?}/{enddate}/{page?}")]
public ActionResult Delivery(string hauler, DateTime? startDate, DateTime? endDate, int? page)
{
// ...
return View(model);
}
[Route("mvc/delivery/{id:int}/{hauler}/{startdate?}/{enddate}/{page?}")]
public ActionResult Delivery(int id, string hauler, DateTime? startDate, DateTime? endDate, int? page)
{
// ...
return View("DeliverySelected", model);
}