jsp网站安全性,网站外链发布,学校网站建设方案论文,深圳住房建设局网站首页概要
本文主要介绍如何在ASP.NET Core的中间件中#xff0c;读取Response.Body的方法#xff0c;以便于我们实现更多的定制化开发。本文介绍的方法适用于.Net 3.1 和 .Net 6。
代码和实现
现象解释
首先我们尝试在自定义中间件中直接读取Response.Body#xff0c;代码如…概要
本文主要介绍如何在ASP.NET Core的中间件中读取Response.Body的方法以便于我们实现更多的定制化开发。本文介绍的方法适用于.Net 3.1 和 .Net 6。
代码和实现
现象解释
首先我们尝试在自定义中间件中直接读取Response.Body代码如下
public class GlobalRequestManagementMiddleware : IMiddleware{public async Task InvokeAsync(HttpContext context, RequestDelegate next){try{await next(context);var reader new StreamReader(context.Response.Body, Encoding.UTF8);var bodyText await reader.ReadToEndAsync();}catch (Exception){throw;}}}我们会得到一个异常消息表示Response.Body是一个不可读的Stream流。 我们添加更多的调试信息查看Response.Body的具体属性 public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{try{await next(context);Console.WriteLine(CanRead is context.Response.Body.CanRead);Console.WriteLine(CanSeek is context.Response.Body.CanSeek);Console.WriteLine(CanWrite is context.Response.Body.CanWrite);var reader new StreamReader(context.Response.Body, Encoding.UTF8);var bodyText await reader.ReadToEndAsync();}catch (Exception){throw;}
}输出结果如下 Response.Body是一个不可读不可查找但是可写的StreamCanReadCanSeek和CanWrite全部是只读属性不可修改。
解决方案
从Response.Body本身来解决这个问题已经基本不可能了。因为该Stream已经被标记为不可读并且不可修改。
我们变换解决思路既然这个Stream无法使用那我们就在其进入其它中间件过滤器和Action之前将其替换为可读和可写的普通内存流。代码如下
public async Task InvokeAsync(HttpContext context, RequestDelegate next){using ( var bodyStream new MemoryStream()){Stream originalBody context.Response.Body;context.Response.Body bodyStream ;await next(context);bodyStream.Position 0;var reader new StreamReader(context.Response.Body, Encoding.UTF8);var bodyText await reader.ReadToEndAsync();Console.WriteLine(bodyText is bodyText);bodyStream.Position 0;await bodyStream.CopyToAsync(originalBody);context.Response.Body originalBody;}}用普通的MemoryStream替代原有Response.Body中的Stream使用MemoryStream 去接收中间件后面操作产生的操作结果读取MemoryStream中的操作结果重置MemoryStream以方便后面的操作读取Response.Body虽然是不可读的但是可写我们可以将中间件后续操作中的操作结果写入最初的Response.Body中将context.Response.Body替换为最初的Stream流。
用上述方法我们就可以读取甚至修改Response.Body中的内容。
我们调用一个Post请求查看我们自定义的Middleware和后面的操作是否可以正常完成
[HttpPost({id})]
public Student Post([FromBody] Student student)
{return student;
}执行结果如下 Body的内容在中间件中被成功读出Post请求成功的将Student对象返回。
附录 public class Student{public int Id { get; set; }public string Name { get; set; }}