如何创建接收动态JSON的C# ASP.NET Core WebAPI端点?
ASP.NET Core WebAPI 动态JSON接收问题解决
问题场景
- 需实现WebAPI端点接收结构不固定的JSON(如产品信息、人员信息等不同操作类型),识别类型后做对应处理
- 使用Postman发送
Content-Type: application/json的Raw JSON数据时,控制器方法无法获取传入的JSON内容 - 尝试用
JsonElement作为参数接收时,触发错误:
"The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. Path: $ | LineNumber: 0 | BytePositionInLine: 0."
错误原因
项目中自定义中间件读取了Request.Body流,但读取完成后未重置流的位置,导致后续模型绑定(如绑定到JsonElement)时,流指针处于末尾,无法读取到任何JSON数据。
默认情况下,Request.Body是不可重读的单向流,一旦被读取过,后续操作无法再获取内容。
解决方法
1. 中间件中处理流重读
在中间件读取Request.Body前,先调用EnableBuffering()启用流缓冲,读取完成后重置流位置到开头:
public async Task InvokeAsync(HttpContext context) { // 启用缓冲,让请求流支持重读 context.Request.EnableBuffering(); // 读取整个请求体内容,leaveOpen设为true避免关闭流 using var streamReader = new StreamReader(context.Request.Body, leaveOpen: true); var requestBody = await streamReader.ReadToEndAsync(); // 重置流位置到起始处,供后续模型绑定使用 context.Request.Body.Position = 0; // 执行后续中间件逻辑 await _next(context); }
2. 控制器接收动态JSON
使用JsonElement作为参数(配合[FromBody]特性),即可接收任意结构的JSON,然后通过属性判断处理不同类型:
[HttpPost("process-dynamic")] public IActionResult ProcessDynamicJson([FromBody] JsonElement payload) { // 判断是否为产品信息 if (payload.TryGetProperty("productId", out JsonElement productIdElem) && productIdElem.ValueKind == JsonValueKind.Number) { int productId = productIdElem.GetInt32(); // 执行产品相关处理逻辑 return Ok($"已处理产品,ID: {productId}"); } // 判断是否为人员信息 else if (payload.TryGetProperty("personName", out JsonElement personNameElem) && personNameElem.ValueKind == JsonValueKind.String) { string personName = personNameElem.GetString(); // 执行人员相关处理逻辑 return Ok($"已处理人员,姓名: {personName}"); } return BadRequest("无法识别的JSON数据类型"); }
验证方式
用Postman发送Raw JSON请求:
- 请求方法:POST
- 请求地址:
https://your-api-url/process-dynamic - Headers:
Content-Type: application/json - Body:选择Raw,输入任意结构的JSON(如
{"productId": 1001}或{"personName": "张三"}),即可正常接收并处理。
内容的提问来源于stack exchange,提问作者DrGriff
相关产品推荐
相关产品推荐

