ASP.NET Core 3.0如何获取原始JSON字符串(无需改客户端Content-Type)
解决ASP.NET Core 3.0 ApiController获取原始JSON字符串的问题
这个问题我之前也碰到过,确实挺头疼的——明明客户端已经按要求发了application/json格式的数据,却因为默认的序列化规则触发验证错误。好在有几种不用修改客户端请求的办法,能直接在ApiController里拿到原始的JSON字符串:
方法一:直接读取HttpRequest的Body流
这是最直接的方式,跳过默认的模型绑定,手动从请求体里读取原始内容:
[HttpPost] public async Task<IActionResult> ReceiveRawJson() { // 启用请求体缓冲,允许多次读取(默认只能读一次) Request.EnableBuffering(); // 读取整个请求体内容 using var streamReader = new StreamReader(Request.Body); var rawJsonString = await streamReader.ReadToEndAsync(); // 重置流的位置,方便后续中间件或逻辑读取 Request.Body.Position = 0; // 这里就可以使用rawJsonString做后续处理了 return Ok($"Received raw JSON: {rawJsonString}"); }
这种方法不需要额外配置,适合临时或者简单的场景,缺点是没法用[FromBody]的简洁写法,需要手动处理流。
方法二:自定义InputFormatter实现全局支持
如果你的多个Action都需要接收原始JSON字符串,可以自定义一个输入格式化器,让它优先处理application/json类型的字符串绑定:
1. 实现自定义InputFormatter
public class RawJsonStringInputFormatter : InputFormatter { public RawJsonStringInputFormatter() { // 声明支持application/json媒体类型 SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json")); } // 只处理string类型的绑定 protected override bool CanReadType(Type type) { return type == typeof(string); } // 读取请求体并返回原始字符串 public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context) { using var streamReader = new StreamReader(context.HttpContext.Request.Body); var rawJson = await streamReader.ReadToEndAsync(); return await InputFormatterResult.SuccessAsync(rawJson); } }
2. 在Startup中注册格式化器
在ConfigureServices方法里,把自定义的格式化器添加到MVC的输入格式化器列表最前面,确保它优先被使用:
public void ConfigureServices(IServiceCollection services) { services.AddControllers(options => { // 插入到第一个位置,覆盖默认的JSON格式化器对string类型的处理 options.InputFormatters.Insert(0, new RawJsonStringInputFormatter()); }); }
3. 在Action中使用[FromBody]
现在就可以像平时一样用[FromBody]来接收原始JSON字符串了:
[HttpPost] public IActionResult ReceiveJson([FromBody] string rawJson) { // rawJson就是客户端发送的原始JSON内容 return Ok(rawJson); }
这个方法一劳永逸,适合多个Action都需要这个功能的场景,保持代码的简洁性。
内容的提问来源于stack exchange,提问作者Poul K. Sørensen
相关产品推荐
相关产品推荐

