【发布时间】:2014-05-14 05:22:28
【问题描述】:
我正在使用 AttributeRouting:http://attributerouting.net/
如果我有两个具有相同名称的操作,但 GET 的路径与 POST 的路径不同,为什么 Url.Action 会生成与我的 GET 操作匹配的 URL,即使我的操作方法指向到那个是帖子的那个?
我尝试将动词作为
Url.Action("CreateEdit", new { method = "POST" })
但是,这将返回字符串 /enrollments/create,而不是对应于 POST 的 /enrollments/createedit。
我不希望这会起作用,但尝试了它,因为某些路由配置使用了这种技术:
Url.Action("CreateEdit", new { HttpMethodConstraint = new HttpMethodConstraint("POST") })
但是这两个都不能解决问题,并且 URL 仍然是我的 GET 路由。
我已经验证我可以发布到/enrollments/createedit 的硬编码 URL,因此 POST 操作确实具有该路由,只是为了排除 POST 操作的默认 [POST] 默认为预期路由的可能性。
问题是我通常避免使用硬编码的 URL 并使用 Url.Action 或 Html.BeginForm(这也表现出同样的问题),以便所有 URL 都派生自操作路由。
以下是我如何定义我的行为:
[GET("create")]
[GET("edit/{id:guid?}")]
public ActionResult CreateEdit(Guid? id)
...
[POST] //default to "createedit"
public ActionResult CreateEdit()
...
请注意,这个问题不是关于发出实际请求,而是生成路由 url。
你如何向 Url.Action 表明它应该使用来自 [POST] 而不是 GET 的路由。没有采用约束或 HTTP 动词的重载?请注意,Html.BeginForm 在生成操作 URL 属性时会出现同样的问题,这显然是面向 POST 的方法。
如果我将操作路线简化为(尽管以上是我的目标路线),它也不起作用:
[GET("create")]
public ActionResult CreateEdit()
...
[POST("createedit")] //default to "createedit"
public ActionResult CreateEdit()
...
Url.Action("CreateEdit", new { method = "POST" }) 显然返回“/enrollments/create”,因为method = 'POST' 不是为 Url.Action 指定所需路由的正确方法。 有没有办法告诉 Url.Action 或 Html.BeginForm 指定需要 POST 路由? BeginForm 的方法参数影响method="post" html 属性,但仍使用生成的 action 属性错误的/enrollments/create URL。我见过area="Admin" 用于在路由参数中指定区域。是否可以添加一些神奇的属性来指定动词?如果没有,那么显然没有办法始终如一地获得正确的 URL,如果我需要维护所需的路由,我可能需要重命名我的一项操作。我希望有一些路线价值,我可以将 analogous 添加到 new { area = "SomeArea" }。 method = "POST" 只是我对可行方法的疯狂猜测。
请求管道尊重路由约束,如果它们都是相同的路由,那么它可以正常工作。因此,如果两者都是[POST("creatededit")] 和[GET("create"],那么它会正常工作,因为两者的 URL 是相同的,然后当发出实际请求时,由于 HttpMethodContraint,管道会做出区分。
如果我使用参数来区分路由,它会起作用,但前提是我消除了[GET("create")]
如果 Url.Action 没有已知/支持/记录的方式来获取路由属性,那么答案可能只是 Url.Action 没有任何方法让您告诉它所需的动词。
- 如果有人问:有没有办法为 Url.Action 指定区域?
- 答案很简单:
Url.Action("SomeAction", new { area ="SomeArea" }) - 答案不是:弄乱你的路线,这样你就不会在不同的区域有两个同名的操作(或任何其他不能解决问题的事情)。
- 答案是否定的:您不应该在不同的领域有相同名称的操作。 (这可能是一个有效的观点,但它不会为处于绝对必须为不同区域生成 URL 的情况的其他人创建有用的资源。
我不明白这有什么复杂的。
我不是在问如何发出 POST 请求。我知道该怎么做,但我不打算将 URL 硬编码到我的视图中。这变成了一场维护噩梦。
如果我的老板对国有企业不那么执着,我可以改变我的路线。所以我无法消除 [GET("create")] 路线。
我可以通过像这样重命名一个动作来解决:
[GET("create")]
[GET("edit/{id:guid?}")]
public ActionResult CreateEdit(Guid? id)
...
[POST("createedit")]
public ActionResult CreateEditPost()
...
这有点脏,但有效。它仍然没有回答这个问题。
如果有办法为 Url.Action 指定 VERB,我认为答案将是一个有用的资源。也许不像Url.Action("SomeAction", new { area ="SomeArea" }) 那么多人,但它会记录Url.Action 的一个对我来说一直难以捉摸的功能。也许它不支持它。也许我需要深入研究源代码。
【问题讨论】:
-
在浏览器中单击链接始终是 GET。从浏览器发布的唯一方法是使用 POST 方法提交表单。使用哪个动词不会发布到 URL 本身。
-
Url.Action 可用于 POST 和 GET。 BeginForm 也会出现同样的问题。这是一个 URL 生成问题,而不是请求问题。 BeginForm 使用与 Url.Action 相同的过程来生成操作属性 URL。两者都表现出同样的问题。这不是关于请求,而是关于 URL。
-
“这是一个 URL 生成问题,而不是请求问题”我完全不同意。这可能是因为生成的 URL 与您的 POST 路由不匹配,但 URL 就是 URL。它们本身并没有说明将使用什么动词。这是使用 URL 决定的机制,例如表单与链接。
-
您的问题没有包含足够的信息,无法在没有假设的情况下有效回答。
Url.Action生成的 URL 是什么? -
我将对您的问题提出一些修改意见,所以我认为我们都在同一页面上。如果您不喜欢它们,请随时回滚。
标签: asp.net-mvc asp.net-mvc-routing