路线属性不会生成漂亮的网址

时间:2017-02-08 16:12:19

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

我正在使用ASP.net MVC5,我有以下内容:

[Route("Edit/{id}")]
[HttpGet]
public ActionResult Edit(int id)
{
    // do stuff
    return View(viewModel);
}

[Route("Edit")]
[HttpPost]
public ActionResult Edit(DraftViewModel draft)
{
    if (!ModelState.IsValid) return View(draft);
    // do stuff
    return RedirectToAction("Index");
}

我希望这会生成如下的漂亮网址:

  

草案/编辑/ 5

相反,我得到了这个:

  

草案/编辑?ID = 5

这是为什么?如何使用基于属性的路由获取漂亮的URL?生成带有丑陋URL的链接的代码是:

@Html.ActionLink("Edit", "Edit", "Draft", new { id = draft.Id }, new { @class = "btn btn-primary btn-xs" })

更新

当我删除[POST]操作并且只有[GET]时(当然没用), GET 上的网址看起来很漂亮!所以当我有两个相同名称(但不同的动词)的路线时,框架会跳起来!

2 个答案:

答案 0 :(得分:2)

确保在基于约定的路由

之前在RouteConfig中启用了属性路由
routes.MapMvcAttributeRoutes();

正如您已经发现,当您使用不同的参数进行POST操作时,路由表在生成URL时使用不同的格式,因为Asp.Net MVC框架正在使用约定。

如果您更新POST操作的网址模板以匹配GET的格式,它将按预期工作。

[Route("Edit/{id:int}")]
[HttpGet]
public ActionResult Edit(int id) {
    // do stuff
    return View(viewModel);
}

[Route("Edit/{id:int?}")]
[HttpPost]
public ActionResult Edit(DraftViewModel draft) {
    if (!ModelState.IsValid) return View(draft);
    // do stuff
    return RedirectToAction("Index");
}

使POST路由模板id参数可选,使您无需更新操作签名。

来自...的结果网址

@Html.ActionLink("Edit", "Edit", "Draft", new { id = draft.Id }, new { @class = "btn btn-primary btn-xs" })

将是

  

草案/编辑/ 5

答案 1 :(得分:0)

属性路由在大多数时间工作。但使用属性路由的一个主要缺点是order of attributes are undefined。由于在MVC路由中,放置到路由表中的路由的顺序对于它正常工作至关重要,因此您需要确保在它们使用时使用Order属性的[Route]属性。不明确的。

在路由中,第一个匹配总是获胜,因此将specific routes before general routes放在路由表中绝对至关重要。

[Route("Edit/{id}", Order = 1)]
[HttpGet]
public ActionResult Edit(int id)
{
    // do stuff
    return View(viewModel);
}

[Route("Edit", Order = 2)]
[HttpPost]
public ActionResult Edit(DraftViewModel draft)
{
    if (!ModelState.IsValid) return View(draft);
    // do stuff
    return RedirectToAction("Index");
}

参考:http://rion.io/2015/11/13/understanding-routing-precedence-in-asp-net-mvc/