如何接受一个没有请求体但内容类型为JSON的GET请求?

7
在迁移到ASP.NET Core 2.1后,我们意识到一些API的消费者发送带有“Content-Type”头设置为“application/json”的GET请求。遗憾的是,过去这些请求没有被拒绝(尽管应该),尽管如此,这仍然是一个破坏性的变化。
由于我们的消费者需要在他们的端口修复此问题,这将需要一些时间,因此我们希望暂时接受这些请求,以便不会被困在等待中。
框架(正确地)拒绝以下错误消息的请求:“需要一个非空请求正文。”
操作如下:
[Route("api/file/{id:guid}")]
public async Task<IActionResult> Get(Guid id)
{
     // Some simple code here
}

在错误已经发生之前,由于请求不正确,在action内部的代码无法被执行。@Nkosi的解决方案导致相同的响应。
[HttpGet("api/file/{id:guid}")]
public async Task<IActionResult> Get([FromRoute]Guid id)
{
     // Some simple code here
}

消费者使用的 (PHP) cURL 如下:
$ch = curl_init(self::API_URL."/file/".$id);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "Content-Type: application/json",
    "Application: APPKey ".$this->AppKey,
    "Authorization: APIKey ".$this->ApiKey
));

移除"Content-Type: application/json",这一行将请求转换为有效请求,因此我们99.9%确定添加此标头是罪魁祸首。


1
根据提供的信息,我无法重现此问题。您可能需要一个 [reprex]。 - Kirk Larkin
@IMujagic 添加了消费者请求(PHP cURL,不确定如何查看结果cURL) - Timmeh
1
@KirkLarkin 你是怎么测试的?我用Postman/Insomnia无法重现这个问题,但使用消费者的PHP cURL却可以(已添加到帖子中)。 - Timmeh
2
@Timmeh,您是否考虑添加一个中间件来检查请求并删除GET请求的头信息? - Nkosi
1
@JConstantine 这会导致其他问题,并关闭整个API的验证,我更喜欢在过滤器/中间件中删除标头。 - Timmeh
显示剩余14条评论
1个回答

3

在管道的早期中间件中考虑删除标头。

public void Configure(IApplicationBuilder app) {
    app.Use(async (context, next) => {
        var request = context.Request;
        var method = request.Method;
        IHeaderDictionary headers = request.Headers;
        string key = "Content-Type";
        if (method == "GET" && request.Headers.ContainsKey(key)) {
            headers.Remove(key);
        }

        // Call the next delegate/middleware in the pipeline
        await next();
    });

    //...
}

目前稍后再做(在过滤器中),因此已进行了身份验证,但仍然接受这一点,因为它将起作用。 - Timmeh
特别是因为这只是一个临时的解决方案,直到客户解决了他们的问题。 - Nkosi
1
很可能会是“即将推出™”。 - Timmeh

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