Url.Action 结果未使用 Route 属性解析
Url.Action result does not resolve using Route attribute
我正在重建应用程序的前端,由于其复杂性,我必须处理现有的遗留业务层。因此,我们有称为 "News" 和 "Documents" 的东西,但实际上它们都在 "Documents" 的存储位置。
我制作了一个 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)
...
我的视图有以下内容来获取 link
<a href="@Url.Action("Download", "Documents", new { documentGuid = Model.Id, attachmentGuid = attachment.AttachmentId })">Download</a>
每当我将 "Documents" 作为控制器时,这将完美地生成类似于 site/Documents/Download/guid/guid
的 link,但是如果我将 "News" 放在那里,我会得到一个 URL 生成使用类似于 site/News/Download?guid&guid
参数的查询字符串并解析为 404。如果我随后手动删除查询字符串标记并手动格式化 URL 它将很好地解析。
这里出了什么问题,是不是我遗漏了什么冲突的东西?
你的Url.Action的参数是controller的名字和action的名字,它只适用于文档,因为巧合的是你的路由对应正确的名字。如果你想使用特定的路线,你必须命名你的路线,然后使用采用路线名称的方法之一来构造它。
在传入请求中查找路由时,路由将使用 URL 来确定匹配的路由。您传入的 URL 是唯一的,因此可以正常工作。
但是,在查找要生成的路由时,MVC 将使用路由值 来确定匹配的路由。 URL (News/Download/
) 中的 文字段 在这部分过程中被完全忽略。
当使用属性路由时,路由值是从你修饰的方法的控制器名称和动作名称派生的。因此,在这两种情况下,您的路由值为:
| Key | Value |
|-----------------|-----------------|
| controller | Documents |
| action | Download |
| documentGuid | <some GUID> |
| attachmentGuid | <some GUID> |
换句话说,您的路线值不是唯一的。因此,路线 table 中的第一场比赛总是获胜。
要解决此问题,您可以使用命名路由。
[Route("Documents/Download/{documentGuid}/{attachmentGuid}", Name = "Documents")]
[Route("News/Download/{documentGuid}/{attachmentGuid}", Name = "News")]
public ActionResult Download(Guid documentGuid, Guid attachmentGuid)
...
然后,将 URL 解析为 @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>
我正在重建应用程序的前端,由于其复杂性,我必须处理现有的遗留业务层。因此,我们有称为 "News" 和 "Documents" 的东西,但实际上它们都在 "Documents" 的存储位置。
我制作了一个 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)
...
我的视图有以下内容来获取 link
<a href="@Url.Action("Download", "Documents", new { documentGuid = Model.Id, attachmentGuid = attachment.AttachmentId })">Download</a>
每当我将 "Documents" 作为控制器时,这将完美地生成类似于 site/Documents/Download/guid/guid
的 link,但是如果我将 "News" 放在那里,我会得到一个 URL 生成使用类似于 site/News/Download?guid&guid
参数的查询字符串并解析为 404。如果我随后手动删除查询字符串标记并手动格式化 URL 它将很好地解析。
这里出了什么问题,是不是我遗漏了什么冲突的东西?
你的Url.Action的参数是controller的名字和action的名字,它只适用于文档,因为巧合的是你的路由对应正确的名字。如果你想使用特定的路线,你必须命名你的路线,然后使用采用路线名称的方法之一来构造它。
在传入请求中查找路由时,路由将使用 URL 来确定匹配的路由。您传入的 URL 是唯一的,因此可以正常工作。
但是,在查找要生成的路由时,MVC 将使用路由值 来确定匹配的路由。 URL (News/Download/
) 中的 文字段 在这部分过程中被完全忽略。
当使用属性路由时,路由值是从你修饰的方法的控制器名称和动作名称派生的。因此,在这两种情况下,您的路由值为:
| Key | Value |
|-----------------|-----------------|
| controller | Documents |
| action | Download |
| documentGuid | <some GUID> |
| attachmentGuid | <some GUID> |
换句话说,您的路线值不是唯一的。因此,路线 table 中的第一场比赛总是获胜。
要解决此问题,您可以使用命名路由。
[Route("Documents/Download/{documentGuid}/{attachmentGuid}", Name = "Documents")]
[Route("News/Download/{documentGuid}/{attachmentGuid}", Name = "News")]
public ActionResult Download(Guid documentGuid, Guid attachmentGuid)
...
然后,将 URL 解析为 @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>