调用Azure Function时PostAsJsonAsync请求体丢失问题排查
问题场景与疑问
我定义了如下测试Azure Function端点:
public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "projects")] HttpRequestData req) { string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); if (string.IsNullOrWhiteSpace(requestBody)) { // 返回错误请求 } // 执行其他操作 }
在NUnit运行的客户端应用中,调用以下代码会返回错误请求:
var dtoClient = new DtoClient(p1, p2, etc); var response = await _httpClient.PostAsJsonAsync("api/MyAzureFunctionPath", dtoClient);
但调用以下代码则能成功:
var dtoClient = new DtoClient(p1, p2, etc); var content = new StringContent(JsonConvert.SerializeObject(dtoClient), System.Text.Encoding.UTF8, "application/json"); var response = await _httpClient.PostAsync("api/copilot/projects", content);
疑问:
PostAsJsonAsync是否存在问题?为何在微软生态中无法正常工作?- 有资料称这是因为HttpClient将内容大小设为0导致的,这是bug吗?
- 我应该直接避免使用
PostAsJsonAsync还是学习正确的使用方式?
问题原因与解决方案
核心原因:序列化库行为差异
PostAsJsonAsync 默认使用System.Text.Json做序列化,而你手动写的代码用的是Newtonsoft.Json(Json.NET)。两者的序列化规则有明显差异:
- 如果
DtoClient类里有System.Text.Json默认忽略的属性(比如非公开字段、只加了Newtonsoft版[JsonIgnore]的属性,或者类型处理逻辑不同),会导致序列化后的内容为空或不完整,被Azure Function的空白请求校验拦截。 - 另一种可能是
DtoClient实例用System.Text.Json序列化后生成了空JSON(比如所有属性都是默认值且被配置为忽略),直接导致请求体为空。
关于“内容大小设为0”的说法
这不是HttpClient的bug,本质是序列化结果为空导致的。当System.Text.Json无法正确序列化对象时,会生成空内容,此时请求体大小自然为0,触发你Azure Function里的错误请求逻辑。
正确使用方式(无需弃用PostAsJsonAsync)
你可以通过以下方式让它正常工作:
- 统一序列化库:
- 若继续用System.Text.Json,检查
DtoClient的序列化配置:确保需要序列化的属性是公开的,没有被System.Text.Json的[JsonIgnore]标记,或者手动配置序列化选项包含所需内容。 - 或者给
HttpClient扩展一个基于Newtonsoft.Json的PostAsJsonAsync方法,内部逻辑和你手动实现的一致——用JsonConvert.SerializeObject生成JSON后包装成StringContent。
- 若继续用System.Text.Json,检查
- 核对请求路径:注意到你两次调用的路径不同(
api/MyAzureFunctionPathvsapi/copilot/projects),确认PostAsJsonAsync用的路径是否正确指向Azure Function的projects路由(不过你的情况是返回错误请求,更大概率是序列化问题)。 - 调试序列化结果:在客户端提前用System.Text.Json序列化
dtoClient,看看结果是否为空或不符合预期:var json = System.Text.Json.JsonSerializer.Serialize(dtoClient); // 输出json查看内容是否正常
总结
PostAsJsonAsync本身没有问题,问题出在序列化库的差异或对象的序列化配置上。不需要弃用它,只要统一序列化规则或调整对象的序列化配置就能解决问题。
内容的提问来源于stack exchange,提问作者Ama
相关产品推荐
相关产品推荐

