WebAPI无强类型模型接收任意结构JSON时参数为空的问题咨询
问题原因
- 给动作参数加
[FromBody]时,ASP.NET 会自动匹配对应输入格式化器完成反序列化。默认 JSON 格式化器处理string类型参数时,仅能将JSON 字符串字面量(即入站内容为"xxx"这种带外层引号的合法 JSON 字符串值)反序列化为 C# string。如果客户端传的是裸 JSON 对象/数组(比如{"name":"test"}这种常规接口入参),格式化器无法将其转换为 string,最终就会得到 null。 - 用
HttpRequestMessage当参数拿不到内容,是因为请求正文的流式读取默认是单向的,一旦被其他中间件/格式化器读过一次,后续再读就会因为流位置已到末尾得到空内容,直接从参数取值没有主动重置流位置、也没有显式读流的话,自然拿不到有效值。
修正方案
方案1:用动态JSON对象接收(最常用,无需手动读流)
内置 Newtonsoft.Json 的环境下,直接把参数类型换成JObject即可,该类型兼容任意结构的JSON入参,无需预定义强类型模型(使用前需引入Newtonsoft.Json.Linq命名空间):
[Post] public async Task<HttpResponseMessage> myWebApiMethod([FromBody] JObject Request) { // 按 key 取值,或转成动态对象处理 var param1 = Request["key1"]?.ToString(); dynamic dynamicReq = Request; var param2 = dynamicReq.key2; }
ASP.NET Core 3.0+ 默认使用 System.Text.Json 的环境,可替换为JsonElement,核心用法逻辑一致。
方案2:需要获取未反序列化的原始JSON字符串
如果必须拿到原始请求文本,不要给参数加[FromBody],直接从当前请求的正文流中读取即可:
ASP.NET Core 环境
[Post] public async Task<HttpResponseMessage> myWebApiMethod() { // 重置流位置到开头,适配流已被其他组件读取过的场景 Request.Body.Position = 0; using var reader = new StreamReader(Request.Body); string rawJson = await reader.ReadToEndAsync(); }
旧版 ASP.NET Web API(非Core)环境
[Post] public async Task<HttpResponseMessage> myWebApiMethod() { string rawJson = await Request.Content.ReadAsStringAsync(); }
内容的提问来源于stack exchange,提问作者bilpor
相关产品推荐
相关产品推荐

