【问题标题】:Url.Action result does not resolve using Route attribute使用 Route 属性无法解析 Url.Action 结果
【发布时间】:2016-11-14 19:29:59
【问题描述】:

我正在重建应用程序的前端,由于其复杂性,我必须处理现有的遗留业务层。因此,我们有称为“新闻”和“文档”的东西,但实际上两者都是存储它的“文档”。

我已经制作了一个 DocumentsController,它可以很好地处理所有事情,在控制器上添加 [Route("News/{action=index}")][Route("Documents/{action=index}")] 可以让我将控制器称为新闻或文档。到目前为止,一切都很好。使用具有 [Route("Documents/View/{id}"][Route("News/View/{id}"] 属性的单个 ActionResult 查看特定文档也可以正常工作。但是,当我尝试使用除 id 以外的任何参数但仅用于新闻部分时,我遇到了问题。

我的ActionResult 方法有如下定义

[Route("Documents/Download/{documentGuid}/{attachmentGuid}")]
[Route("News/Download/{documentGuid}/{attachmentGuid}")]
public ActionResult Download(Guid documentGuid, Guid attachmentGuid)
...

而我的视图有以下获取链接

<a href="@Url.Action("Download", "Documents", new { documentGuid = Model.Id, attachmentGuid = attachment.AttachmentId })">Download</a>

每当我将“文档”作为控制器时,这将完美地生成类似于site/Documents/Download/guid/guid 的链接,但是如果我将“新闻”放在那里,我会生成一个使用类似于site/News/Download?guid&amp;guid 参数的查询字符串并解析为404. 如果我随后手动删除查询字符串标记并手动格式化 URL,它将很好地解决。

这里出了什么问题,我错过了什么冲突吗?

【问题讨论】:

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


    【解决方案1】:

    在传入请求中查找路由时,路由将使用 URL 来确定匹配的路由。您的传入 URL 是唯一的,因此可以正常工作。

    但是,当查找要生成的路由时,MVC 将使用 路由值 来确定哪个路由匹配。在此部分过程中,URL (News/Download/) 中的文字段 将被完全忽略。

    当使用属性路由时,路由值是从你装饰的方法的控制器名和动作名派生的。因此,在这两种情况下,您的路线值都是:

    | Key             | Value           |
    |-----------------|-----------------|
    | controller      | Documents       |
    | action          | Download        |
    | documentGuid    | <some GUID>     |
    | attachmentGuid  | <some GUID>     |
    

    换句话说,您的路线值不是唯一的。因此,路由表中的第一个匹配总是获胜。

    要解决这个问题,您可以使用命名路由。

    [Route("Documents/Download/{documentGuid}/{attachmentGuid}", Name = "Documents")]
    [Route("News/Download/{documentGuid}/{attachmentGuid}", Name = "News")]
    public ActionResult Download(Guid documentGuid, Guid attachmentGuid)
    ...
    

    然后,使用@Url.RouteUrl@Html.RouteLink 解析网址。

    @Html.RouteLink("Download", "News", new { controller = "Documents", action = "Download", documentGuid = Model.Id, attachmentGuid = attachment.AttachmentId })
    

    或者

    <a href="@Url.RouteUrl("News", new { controller = "Documents", action = "Download", documentGuid = Model.Id, attachmentGuid = attachment.AttachmentId })">Download</a>
    

    【讨论】:

    • 感谢您的详细回答,这正是问题所在,也是一个可行的解决方案:)
    【解决方案2】:

    您的 Url.Action 的参数是控制器的名称和操作的名称,它仅适用于文档,因为巧合的是,您的路线对应于正确的名称。如果您想使用特定路由,您必须命名您的路由,然后使用采用路由名称的方法之一来构造它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-25
      • 2014-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多