路由属性没有生成漂亮的 URL

Route Attribute isn't producing pretty URLs

我正在使用 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");
}

我希望它能产生像这样漂亮的 URLs:

Draft/Edit/5

相反,我得到了这个:

Draft/Edit?id=5

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

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

更新

当我删除 [POST] 操作并且只有 [GET](当然没有用)时,GET 上的 URL 看起来漂亮的!所以当我有两条同名的路由(但动词不同)时,框架就会出错!

确保在 convention-based 路由

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

正如您已经发现的那样,当您使用具有不同参数的 POST 操作来获取路由时 table 在生成 URL 时使用不同的格式作为 Asp.Net MVC 框架正在使用一种约定。

如果您更新 POST 操作的 url 模板以匹配 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 参数设为可选,这样您就不必更新操作签名。

结果 URL 来自...

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

将是

Draft/Edit/5

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

在路由中,第一场比赛总是赢,所以在路由table中放置是绝对关键的。

[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/