简体   繁体   English

从 NotFound() 取回不允许的 405 方法

[英]Getting back a 405 Method Not Allowed from NotFound()

In an ASP.NET Core 2.2 MVC app, I have a View that makes an Ajax request back to a controller, the request goes through and gets to the controller where a condition is met that should return a NotFoundResult (404): In an ASP.NET Core 2.2 MVC app, I have a View that makes an Ajax request back to a controller, the request goes through and gets to the controller where a condition is met that should return a NotFoundResult (404):

$.ajax({
    type: "POST",
    url: "/My/AjaxAction",
    data: {
        name: name
    }
})

[HttpPost]
public async Task<IActionResult> AjaxAction(string name)
{
    if (/* condition */)
    {
        return NotFound();
    }

    //....
}

When testing this I get back a 405 Method Not Allowed response instead of a 404. I debugged and verified that I am hitting the NotFound() line.在测试这个时,我得到一个 405 Method Not Allowed 响应而不是 404。我调试并验证我正在点击NotFound()行。 However the EndpointMiddleware is changing the response to a 405 and I don't know why:但是 EndpointMiddleware 正在将响应更改为 405,我不知道为什么:

info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1] Executing HttpStatusCodeResult, setting HTTP status code 404 info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] Executed action MyProject.MyController.AjaxAction (MyProject) in 2071.1794ms info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1] Executed endpoint 'MyProject.MyController.AjaxAction (MyProject)' info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0] Executing endpoint '405 HTTP Method Not Supported'信息:Microsoft.AspNetCore.Mvc.StatusCodeResult[1] 正在执行 HttpStatusCodeResult,设置 HTTP 状态代码 404 信息:Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] 执行动作 MyProject.MyController.AjaxAction (MyProject) in 2071.1794ms 信息:Microsoft .AspNetCore.Routing.EndpointMiddleware[1] 执行端点“MyProject.MyController.AjaxAction (MyProject)”信息:Microsoft.AspNetCore.Routing.EndpointMiddleware[0] 执行端点“405 HTTP 方法不支持”

Other Ajax actions using POST in the application still work fine, it's just this one that is the problem.在应用程序中使用 POST 的其他 Ajax 操作仍然可以正常工作,只是这一个是问题所在。

Update: If I don't satisfy the condition for NotFound() and instead return an Ok() as normal, then it returns the correct response as it should.更新:如果我不满足NotFound()的条件,而是正常返回Ok() ,那么它应该返回正确的响应。 It's only 404s are that being changed to 405s.只有 404 被更改为 405。

This is a long discussion on GitHub: https://github.com/aspnet/Mvc/issues/388这是关于 GitHub 的长时间讨论: https://github.com/aspnet/Mvc/issues/388

In resume you are always calling the url: /My/AjaxAction and you want to sometimes it returns 404 (This endpoint does not exist) and sometimes returns 200 .在简历中,您总是调用 url: /My/AjaxAction并且您希望有时它返回404 (此端点不存在),有时返回200 But it is the same route, so it will be a bit confusing for the consumers of your api.但它是同一条路线,因此对于您的 api 的消费者来说会有些混乱。 I believe that's why Asp.Net teams is doing this.我相信这就是 Asp.Net 团队这样做的原因。

You can make a few changes to solve it.您可以进行一些更改来解决它。

One option is to add the name parameters on url so your url will not be always the same and you'll be able to return not found.一种选择是在 url 上添加名称参数,这样您的 url 将不会总是相同,您将能够返回 not found。

$.ajax({
    type: "POST",
    url: "/My/AjaxAction/"+name,
    data: {
        // other datainfo 
    }
})

[HttpPost]
public async Task<IActionResult> AjaxAction(string id) // Change name to id to asp.net route understand that this parameter is in your route and not on body.
{
    if (/* condition */)
    {
        return NotFound();
    }

    //....
}

Other option is to return other type of http error.其他选项是返回其他类型的 http 错误。 like 400像400

$.ajax({
    type: "POST",
    url: "/My/AjaxAction",
    data: {
        name: name
    }
})

[HttpPost]
public async Task<IActionResult> AjaxAction(string name)
{
    if (/* condition */)
    {
        return BadRequest(); // You can also add an error message or an model;
    }

    //....
}

There is a problem with your calling.你的电话有问题。 Can you change the url to "/My/AjaxAction/test" instead of "/My/AjaxAction"您能否将 url 更改为“/My/AjaxAction/test”而不是“/My/AjaxAction”

$.ajax({
    type: "POST",
    url: "/My/AjaxAction/test",
    data: {
        name: name
    }
})

Also, you can try specifing the route in HttpPost like:此外,您可以尝试在 HttpPost 中指定路由,例如:

[HttpPost("/My/AjaxAction")]
public async Task<IActionResult> AjaxAction(string id) // Change name to id to asp.net route understand that this parameter is in your route and not on body.
{
    if (/* condition */)
    {
        return NotFound();
    }

    //....
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM