.net core读取Response.Body

读取请求体流的demo
public static async Task<string> GetBodyForm(this HttpContext http)
{
var content = string.Empty;
var request = http.Request;
try
{
request.Body.Position = 0;
using var reader = new StreamReader(request.Body, Encoding.UTF8, leaveOpen: true);
var strRequestBody = await reader.ReadToEndAsync();
Console.WriteLine("ok");
Console.WriteLine(strRequestBody == null ? "null" : strRequestBody);
request.Body.Position = 0;
}
catch (Exception ex)
{
Console.WriteLine("err");
Console.WriteLine(ex);
}
return content;
}

在ActionFilter中读取Request.Body

public class ActionFilterTestA : ActionFilterAttribute
{
public override async void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine("From Request Body---->");
Console.WriteLine(await context.HttpContext.GetBodyForm());
Console.WriteLine("From Request Body---->");
}
}

报错,一般是在Request.Body处报NotSupportedException

解决方案

在自定义中间件中调用EnableBuffering()

app.Use(async (context, next) =>
{
context.Request.EnableBuffering();
await next();
});

疑问

(移除以上正确方案代码) 为什么在ActionFilterTestA中调用context.HttpContext.Request.EnableBuffering();没有效果?(没有报错,但是内容为空字符串)

猜测

请求体流在ActionFilter之前,在自定义中间件之后被消耗。 中间件执行顺序

测试

// 取消模型绑定
builder.Services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressInferBindingSourcesForParameters = true;
});

Request.Body的内容打印成功。

推论

绑定模型时会消耗掉请求体流。

其他资料

https://markb.uk/asp-net-core-read-raw-request-body-as-string.html

结语

推荐还是通过中间件调用EnableBuffering解决问题

注意事项:

  1. 避免关闭StreamReader导致关闭了Stream,可以通过leaveOpen: true解决
  2. 重置Position = 0
posted @   复制粘贴机器人  阅读(317)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示