ActionLink为属性路由

时间:2015-08-13 15:39:58

标签: asp.net asp.net-mvc asp.net-mvc-5 visual-studio-2015 attributerouting

我使用属性路由覆盖控制器中的网址。我有两个动作,唯一的区别是第二个动作中出现的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

如何生成预期的网址?

http://localhost:53274/mvc/delivery/1234

3 个答案:

答案 0 :(得分:3)

我找到了答案,感谢this answer concerning ambiguous action methods。在控制器中最多只能有2个具有相同名称的操作方法。

在这种情况下,我确实有第三种方法,因为我认为它是无关的,所以我遗漏了:

[HttpPost]
[Route("mvc/delivery")]
public ActionResult Delivery(DeliveryViewModel model)

将我的第二个动作重命名为SelectDelivery(int id, /*...*/)解决了这个问题。

答案 1 :(得分:1)

由于路由是对订单敏感的,因此您需要使用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);
}

答案 2 :(得分:-1)

你可以使用以下来解决它

    [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);
    }