`PostAsJsonAsync` 在Azure Functions中返回500内部服务器错误,而Postman以及使用 `StringContent` 的 `PostAsync` 可以成功

后端开发 2026-07-09

我在一个ASP.NET Core 8.0应用中,使用 IHttpClientFactory 调用Azure Functions的 HTTP触发器(v4、Node.js、消费计划)。该函数具有 authLevel: 'function',密钥作为查询参数传递。

使用 PostAsJsonAsync 一直返回500,并且响应体为空:

var client = _httpClientFactory.CreateClient("MyClient");
var payload = new object();

var response = await client.PostAsJsonAsync("api/myfunction", payload, ct);

// response.StatusCode == 500, response.Content has Content-Length: 0

从Postman或 PowerShell的 Invoke-WebRequest 发出的同一请求返回200 OK。

我尝试了以下方法:

  • HTTP版本:Postman也使用HTTP/2,但仍然工作
  • Content-Type:尝试 application/jsonapplication/json; charset=utf-8,两者都返回500
  • 载荷:甚至 new object()(序列化为 {})也返回500
  • 身份验证:密钥是正确的;错误的密钥返回401,而不是500
  • 函数代码:日志显示根本没有调用,因此500在处理程序运行之前就已经返回

切换到 PostAsyncStringContent 可以解决:

var client = _httpClientFactory.CreateClient("MyClient");
var payload = new object();
var json = JsonSerializer.Serialize(payload);

var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync("api/myfunction", content, ct);

// response.StatusCode == 200

据我所见似乎无关,但为了完整性,这里给出Azure函数的实现:

app.http('postSnapshot', {
    methods: ['POST'],
    authLevel: 'function',
    route: 'snapshot', 
    handler: async (request, context) => {
        let body;
        try {
            const text = await request.text();
            context.log('postSnapshot body (%d bytes): %s', text.length, text.slice(0, 500));
            body = JSON.parse(text);
        } catch (err) {
            context.log.error('postSnapshot parse error:', err.message);
            return { status: 400, body: `Invalid JSON body: ${err.message}` };
        }

如前所述,日志和响应体为空。

PostAsJsonAsync 有什么不同,导致Azure Functions在基础设施层面拒绝请求?确实想理解 为什么 修复能起作用。我真的不喜欢那种“工作,但不知道为什么”的情况。更希望“工作,而且知道原因”。 :-)

解决方案

PostAsJsonAsync 实际上是一个扩展方法,它使用 JsonContent 而不是 StringContent。问题可能是 JsonContent 默认使用分块编码(chunked encoding),这在Azure Logic Apps的 HTTP触发器中被记录为一个问题。更多信息请参见 这个Github问题

I have to say the Azure Logic App HTTP trigger doesn't support "chunked encoding". In Handle large messages with chunking in Azure Logic Apps doc, it says:

Logic App triggers don't support chunking because of the increased overhead of exchanging multiple messages.

I was trying to POST a message to Azure Logic App with a HTTP trigger. It because HttpClient's PostAsJsonAsync ONLY support chunked encoding. I know what @davidfowl said not recommend buffering for large JSON payloads, but most of the payload to the Azure Logic App are really small. I think it should have an straightforward option to use PostAsJsonAsync without chunked encoding.

你可以测试文中提到的 变通方法,以验证这是不是Azure Functions HTTP触发器的问题。

var content = JsonContent.Create<T>(json);
await content.LoadIntoBufferAsync();
var response = await httpClient.PostAsync(url, content);

如果有帮助,你可以把代码很容易地改造成一个与 PostAsJsonAsync 类似的方便扩展方法。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章