ASP.NET MVC 5属性路由无法正确解析路由

本文关键字:路由 MVC 属性 ASP NET | 更新日期: 2023-09-27 18:23:40

我的控制器中有以下路由。一次获取和两次发布操作。所有操作名称相同。使用MultipleButton属性区分两个后期操作,如下所述:

[RoutePrefix("incidents")]
public sealed class IncidentsController : Controller
{    
    [HttpGet, Route("action/{id:int?}/{error?}")]
    public async Task<ActionResult> Action(int? id, string error = null)
    [HttpPost, Route("action"), ActionName("Action"), ValidateAntiForgeryToken]
    [MultipleButton(Name = "action", Argument = "Accept")]
    public async Task<ActionResult> ActionAccept(IncidentActionViewModel incident)
    [HttpPost, Route("action"), ActionName("Action"), ValidateAntiForgeryToken]
    [MultipleButton(Name = "action", Argument = "Reject")]
    public async Task<ActionResult> ActionReject(IncidentActionViewModel incident)
}
@Url.Action("Action", "Incidents", new { id = 10 })

上面的路线渲染如下所示。导航到此URL是可行的,但如果我将"id"参数从Nullable更改为int,我就会开始出现错误。

/事件/行动?id=10

它应该呈现如下所示,如果我将"id"参数更改为类型int:,则不会出现错误

/事件/行动/10

我做错了什么?

更新

以下是我的路线注册详细信息:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });

ASP.NET MVC 5属性路由无法正确解析路由

作为解决方案,我发现可以使用命名路由,而不是依赖ASP.NET MVC来使用控制器和操作名称解析路由。所以我最终得到了以下代码:

[RoutePrefix("incidents")]
public sealed class IncidentsController : Controller
{    
    [HttpGet, Route("action/{id:int?}/{error?}", Name = "IncidentsGetAction")]
    public async Task<ActionResult> Action(int? id, string error = null)
    [HttpPost, Route("action", Name = "IncidentsPostActionAccept"), ActionName("Action"), ValidateAntiForgeryToken]
    [MultipleButton(Name = "action", Argument = "Accept")]
    public async Task<ActionResult> ActionAccept(IncidentActionViewModel incident)
    [HttpPost, Route("action", Name = "IncidentsPostActionReject"), ActionName("Action"), ValidateAntiForgeryToken]
    [MultipleButton(Name = "action", Argument = "Reject")]
    public async Task<ActionResult> ActionReject(IncidentActionViewModel incident)
}
// Generate a URL
@Url.RouteUrl("IncidentsGetAction", new { id = 10 })
// Generate a link to a URL
@Html.RouteLink("Link Text", "IncidentsGetAction", new { id = 10 })

这种方法具有更好的性能,因为MVC不必解析URL,它可以直接访问它。它也更容易理解,并减少了出现错误的机会,因为你明确了你想要使用的路线。

我个人已经将所有路由转换为命名路由,并放弃了使用控制器和动作解析路由。看看为什么会出现上述问题仍然很有趣。