C#/.NET控制器中的POST请求一直返回400 Bad Request

3
我正在尝试编写一个简单的API来接收带有请求正文的POST请求。当我尝试测试我的方法时,Postman一直返回400错误请求。我最初认为问题在于反序列化JSON正文。因此,为了确保,我从控制器中剥离了该逻辑,但请求仍然返回400状态码。
所以,我除了方法本身之外,将所有内容都从我的方法中删除,仅返回Ok('Hello World');,但响应仍然是400。
现在我只剩下如下内容:
  [Route("api/v1/service/")]
  public class ServiceController : Controller
  {

    public ServiceController()
    {

    }

    [HttpGet("get")]
    public IActionResult Get()
    {
      return Ok("GET works fine");
    }

    [HttpPost("post")]
    public IActionResult Post()
    {
      return Ok("Hello World"); // <-- Keeps returning 400
    }

  }

GET方法运行良好,但是当我在Postman中向/api/v1/service/post发送一个空的POST请求时,我会收到一个错误请求。
我还注意到,当我将路由更改为不存在的任何不同或随机内容时,也会得到400而不是404。
因此,对api/v1/service/this-route-is-not-defined进行POST调用也会导致错误请求。
我一直在更改请求表单中的小细节,添加/删除ContentType或Accept头,并调整我的StartUp.cs。但是,我向.NET发出的每个POST调用似乎都会导致400状态代码。
编辑
这可能与Startup.cs中的路由相关:
      app.UseHsts();

      app.UseMvc(routes =>
      {
      });
      app.UseRouting();

以下是POST man中的请求:

GET: 这里输入图片描述

POST: 这里输入图片描述

示例代码已被修改为我的原始API方法,但思路相同。我将示例复制到项目中的新文件中,并在Postman中点击“创建新请求”。所以标头是默认的。


你应该发布到 /api/v1/service/post,在问题中提到了 /api/v1/service/ - Kamil Budziewski
@KamilBudziewski 谢谢,当然我正在向 /api/v1/service/post 发送请求。 - OCP30pt1c1l1l43-X1z17
1
添加 Startup.cs 类,也许您已经配置路由错误。 - Max
@Max,我的Startup.cs文件里有很多代码,你能指出我应该查找哪个具体部分吗? - OCP30pt1c1l1l43-X1z17
你能否添加GET和POST的Postman截图? - Anindya Dey
显示剩余3条评论
2个回答

4

首先,对于这个问题给出的答案和评论都非常有帮助。

我找到了罪魁祸首。显然,在 Startup.cs 文件中启用了一个选项,该选项会在所有可以修改内容的 API 调用上放置一个防伪令牌检查,例如 POST、PUT、DELETE。当从前端使用 Javascript 的 fetch() 调用 API 时,这不是问题。令牌被添加到文档中的标签中,您可以像这样将其添加到请求标头中:

headers.append('X-XSRF-TOKEN', (document.getElementsByName("__RequestVerificationToken")[0] as any).value)

例如,要能够从 Postman 进行 POST 调用,您可以在操作上方临时添加此行。

[IgnoreAntiforgeryToken]

因此,工作示例如下:

  [Route("api/v1/service/")]
  public class ServiceController : Controller
  {

    public ServiceController()
    {

    }

    [HttpGet("get")]
    public IActionResult Get()
    {
      return Ok("GET works fine");
    }

    [IgnoreAntiforgeryToken]
    [HttpPost("post")]
    public IActionResult Post()
    {
      return Ok("Hello World"); // <-- Keeps returning 400
    }

  }

在编程中,考虑何时使用[IgnoreAntiforgeryToken]以及何时不使用它非常重要。例如,在已经期望API密钥的方法中,您可以在生产环境中使用它。但是,当方法是公共的时,防伪令牌是一种保护您的方法免受攻击者或试图垃圾邮件您的API的人/机器人的方式。


我会检查您的设置,看起来您已配置为MVC(因此默认情况下添加了反伪造),而不是Web API。但是,如果您正在使用cookie身份验证,并且想在Web API中使用反伪造这就是您要做的 - DalSoft

1

您缺少MapControllers()

在您的startup.cs中添加MapControllers(),这是属性路由所必需的。

app.MapControllers();

如果您使用的.NET版本小于6.0,则需要添加以下内容:
app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

MapControllers 被调用来映射带有属性路由的控制器。


.MapController()的命名空间是什么?我得到了“'IApplicationBuilder'不包含'MapControllers'的定义,最佳扩展方法重载'ControllerEndpointRouteBuilderExtensions.MapControllers(IEndpointRouteBuilder)'需要类型为'IEndpointRouteBuilder'的接收器”的错误提示。 - OCP30pt1c1l1l43-X1z17
我已经有了 using Microsoft.AspNetCore.Mvc;using Microsoft.AspNetCore.Mvc.Core;using Microsoft.AspNetCore.Builder; - OCP30pt1c1l1l43-X1z17
这是 Microsoft.AspNetCore.Builder,尝试在 Startup.cs 中使用第二个示例。看起来您正在使用旧样式模板,而不是 minimal hosting model - DalSoft

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接