You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 Web API读取请求体为空?求正确获取方法

ASP.NET Core 8.0 Web API读取请求体为空的解决方法

问题原因

当Action方法包含CreateResponseWADto类型的参数时,ASP.NET Core的模型绑定机制会优先读取请求体完成对象反序列化,此时请求体流的位置已经移到末尾。后续即使调用Request.EnableBuffering()和Request.Body.Position = 0,也无法读到内容——因为这两个操作是在模型绑定之后执行的,流已经被消费过。

解决方法

方法一:移除自动模型绑定,直接读取请求体

如果不需要自动将请求体映射到DTO,可以去掉Action参数,直接读取原始请求体:

[Authorize]
[ApiController]
[Route("api/[controller]/[action]")]
public class StatusWAController : ControllerBase
{
    private readonly ILogger<StatusWAController> _logger;
    private readonly IstatusMensajeWAService _statusMensajeWAService;

    public StatusWAController(ILogger<StatusWAController> logger, IstatusMensajeWAService statusMensajeWAService)
    {
        _logger = logger;
        _statusMensajeWAService = statusMensajeWAService;
    }

    [HttpPost(Name = "CreateResponseWA")]
    public async Task<IActionResult> CreateResponseWA()
    {
        _logger.LogWarning("Request started: ");

        Request.EnableBuffering();
        Request.Body.Position = 0;

        using var reader = new StreamReader(Request.Body);
        var body = await reader.ReadToEndAsync();
        _logger.LogWarning("Request finished: " + body);

        // 若需使用DTO,可手动反序列化
        // var dto = JsonSerializer.Deserialize<CreateResponseWADto>(body);

        return Ok(body);
    }
}

方法二:全局启用请求体缓冲,保留模型绑定

如果需要同时使用模型绑定和读取原始请求体,需在模型绑定前启用请求体缓冲。在Program.cs中添加中间件配置:

var builder = WebApplication.CreateBuilder(args);

// 添加控制器服务
builder.Services.AddControllers();

var app = builder.Build();

// 启用请求体缓冲中间件(必须在MapControllers之前)
app.Use(async (context, next) =>
{
    context.Request.EnableBuffering();
    await next();
});

app.MapControllers();
app.Run();

修改后的Action代码:

[HttpPost(Name = "CreateResponseWA")]
public async Task<IActionResult> CreateResponseWA(CreateResponseWADto createResponseWADto)
{
    _logger.LogWarning("Request started: ");

    // 重置流位置到开头
    Request.Body.Position = 0;

    using var reader = new StreamReader(Request.Body);
    var body = await reader.ReadToEndAsync();
    _logger.LogWarning("Request finished: " + body);

    // 读完后重置流位置,避免影响后续中间件
    Request.Body.Position = 0;

    return Ok(body);
}

方法三:使用内置中间件简化操作

ASP.NET Core提供了HttpRequestRewindMiddleware,可以一键启用请求体缓冲并重置位置。在Program.cs中替换中间件:

// 替换之前的自定义缓冲中间件
app.UseRewind();

此时Action中无需额外调用EnableBuffering(),直接重置位置读取即可。

内容的提问来源于stack exchange,提问作者Andres Camacho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:40:15