.NET Core 3.1下Post请求Body为空但ContentLength正常问题求助
嘿,这个问题我之前也碰到过!在.NET Core 3.1里确实有这个请求体读取的坑,主要是因为默认情况下Request.Body是非缓冲流,如果没启用缓冲,直接读取很容易出现空内容的情况,哪怕ContentLength显示正确。我给你几个靠谱的解决方案:
1. 在单个Action里启用缓冲(最直接的解决办法)
你需要在接收请求的Action里先调用Request.EnableBuffering(),并且重置流的位置到开头,这样才能正确读取内容。注意要引用Microsoft.AspNetCore.Http命名空间(默认项目已包含,除非手动移除):
using Microsoft.AspNetCore.Http; // 确保有这个引用 [HttpPost] public async Task<IActionResult> Post() { // 启用请求体缓冲,允许多次读取流 Request.EnableBuffering(); // 把流指针重置到起始位置,避免因中间件提前读取导致指针在末尾 Request.Body.Position = 0; // 现在可以正常读取请求体了 using var streamReader = new StreamReader(Request.Body); var requestBody = await streamReader.ReadToEndAsync(); // 这里处理你的requestBody即可 return Ok($"Received content: {requestBody}"); }
2. 优化发送端代码细节
你的发送端代码有个小优化点:StringContent的构造函数可以直接指定ContentType和编码,不用单独设置Header,避免编码不一致导致的读取异常(虽然你说ContentLength正确,但编码问题也可能让内容看起来为空):
// 显式指定UTF-8编码和application/json类型,和接收端保持一致 var httpContent = new StringContent("test Data", Encoding.UTF8, "application/json"); var response = await myHttpClient.PostAsync(destUrl, httpContent);
3. 用[FromBody]自动绑定(更简洁的方式)
如果接收的是JSON格式内容,直接用[FromBody]属性让框架自动绑定模型即可,框架会自动处理缓冲和读取,不用手动操作Request.Body:
// 接收字符串的情况 [HttpPost] public async Task<IActionResult> Post([FromBody] string content) { // content就是请求体的内容,直接使用即可 return Ok(content); } // 接收复杂对象的情况 public class MyRequestModel { public string Data { get; set; } } [HttpPost] public async Task<IActionResult> Post([FromBody] MyRequestModel model) { return Ok(model.Data); }
4. 全局启用请求体缓冲(适合全应用需求)
如果你的整个应用都需要多次读取请求体,可以在Startup.cs里全局配置:
public void ConfigureServices(IServiceCollection services) { // 配置表单选项,启用缓冲 services.Configure<FormOptions>(options => { options.BufferBody = true; // 根据需求调整最大请求大小,这里设为最大值 options.MultipartBodyLengthLimit = long.MaxValue; }); // 或者在控制器配置里全局启用缓冲 services.AddControllers(options => { // 设置最大请求体大小 options.MaxRequestBodySize = int.MaxValue; }).AddNewtonsoftJson(); // 如果用Newtonsoft.Json替代System.Text.Json的话 }
按照上面的方法操作,应该就能解决你遇到的Request.Body为空的问题了!
内容的提问来源于stack exchange,提问作者Chen Ben Hamo
相关产品推荐
相关产品推荐

