【问题标题】:Getting back a 405 Method Not Allowed from NotFound()从 NotFound() 取回不允许的 405 方法
【发布时间】:2020-01-28 00:59:10
【问题描述】:

在 ASP.NET Core 2.2 MVC 应用程序中,我有一个视图,它向控制器发出 Ajax 请求,请求通过并到达满足条件的控制器,该条件应返回 NotFoundResult (404):

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

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

    //....
}

在测试这个时,我得到一个 405 Method Not Allowed 响应而不是 404。我调试并验证我正在点击NotFound() 行。但是 EndpointMiddleware 正在将响应更改为 405,我不知道为什么:

信息:Microsoft.AspNetCore.Mvc.StatusCodeResult[1] 执行HttpStatusCodeResult,设置HTTP状态码404 信息:Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] 执行动作 MyProject.MyController.AjaxAction (MyProject) 在 2071.1794ms 信息:Microsoft.AspNetCore.Routing.EndpointMiddleware[1] 执行端点'MyProject.MyController.AjaxAction(MyProject)' 信息:Microsoft.AspNetCore.Routing.EndpointMiddleware[0] 执行端点'405 HTTP Method Not Supported'

在应用程序中使用 POST 的其他 Ajax 操作仍然可以正常工作,只是这一个是问题所在。

更新:如果我不满足NotFound() 的条件,而是正常返回Ok(),那么它会返回应有的正确响应。改成405的只是404。

【问题讨论】:

  • 如果没有“NotFound()”的作用,我们无能为力。我们只能说服务器发送了一个 HTTP 错误 405。
  • 您发送的 uri 是什么?它真的会击中那个动作吗?
  • @TMcKeown 是的,它触发了操作并按原样返回NotFoundResult,然后 EndpointMiddleware 将其更改为 405。
  • 这里不足以回答您的问题。这可能是由于某些自定义错误处理程序造成的,但我们没有代码可以判断是否是这种情况。

标签: c# ajax asp.net-core


【解决方案1】:

你的电话有问题。你能把网址改成 "/My/AjaxAction/test" 而不是 "/My/AjaxAction"

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

另外,您可以尝试在 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();
    }

    //....
}

【讨论】:

    【解决方案2】:

    这是 GitHub 上的长篇讨论:https://github.com/aspnet/Mvc/issues/388

    在简历中,您总是调用 url:/My/AjaxAction,并且您希望有时它返回 404(此端点不存在),有时返回 200。但它是同一条路线,因此对于您的 api 的消费者来说会有些混乱。我相信这就是 Asp.Net 团队这样做的原因。

    你可以做一些改变来解决它。

    一种选择是在 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();
        }
    
        //....
    }
    

    其他选项是返回其他类型的 http 错误。像 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;
        }
    
        //....
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-28
      • 2011-06-21
      • 1970-01-01
      • 2021-12-20
      • 2023-03-23
      相关资源
      最近更新 更多