.net-core - StreamReader 上的 EnableRewind 和 leaveOpen 不会停止处理请求
问题描述
我正在使用 ApplicationInsights,我想将请求和响应添加到日志记录属性。
为了实现这一点,我正在实施我自己的ITelemetryInitializer
. 它看起来就像这样。
public class MyInitializer : ITelemetryInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor;
public MyInitializer(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public void Initialize(ITelemetry telemetry)
{
var requestTelemetry = telemetry as RequestTelemetry;
if (requestTelemetry == null || _httpContextAccessor?.HttpContext?.Request == null
|| requestTelemetry.Properties.ContainsKey("RequestBody"))
{
return;
}
var request = _httpContextAccessor?.HttpContext?.Request;
request?.EnableRewind();
if (request.Method.Equals(HttpMethod.Post.ToString(), StringComparison.InvariantCultureIgnoreCase)
|| request.Method.Equals(HttpMethod.Put.ToString(), StringComparison.InvariantCultureIgnoreCase))
{
using (var reader = new StreamReader(request.Body, Encoding.UTF8, true, 1024, true))
{
var requestBody = reader.ReadToEnd();
requestTelemetry.Properties.Add("RequestBody", requestBody);
}
}
}
}
在启动时我添加了这个
services.AddHttpContextAccessor();
services.AddSingleton<ITelemetryInitializer, MyInitializer>();
services.AddApplicationInsightsTelemetry();
我得到的错误是:
ObjectDisposedException: Cannot access a disposed object.
Object name: FileBufferingReadStream.
Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.ThrowIfDisposed()
我已经使用.EnableRewind
并指示StreamReader
将文件保持打开状态。尽管如此,当我的请求实际到达我的控制器时,或者甚至当它再次到达我的初始化程序以进行第二次传递(设置响应信息)时,我的请求仍然为空。
欢迎任何建议。
此外,我尝试添加一个中间件以确保.EnableRewind
一切正常,但这没有任何作用。我不希望添加任何额外的中间件,因为我希望没有其他依赖项。
app.Use(async (context, next) =>
{
context.Request.EnableRewind();
await next();
});
谢谢。
解决方案
与往常一样,解决方案最终只是一行代码。我要感谢 Gunnar Peipman 先生的博文阅读 ASP.NET Core 中的请求正文。
该行:
request.Body.Seek(0, SeekOrigin.Begin);
编码
public class MyInitializer : ITelemetryInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor;
public MyInitializer(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public void Initialize(ITelemetry telemetry)
{
var requestTelemetry = telemetry as RequestTelemetry;
if (requestTelemetry == null || _httpContextAccessor?.HttpContext?.Request == null
|| requestTelemetry.Properties.ContainsKey("RequestBody"))
{
return;
}
var request = _httpContextAccessor?.HttpContext?.Request;
request?.EnableRewind();
if (request.Method.Equals(HttpMethod.Post.ToString(), StringComparison.InvariantCultureIgnoreCase)
|| request.Method.Equals(HttpMethod.Put.ToString(), StringComparison.InvariantCultureIgnoreCase))
{
using (var reader = new StreamReader(request.Body, Encoding.UTF8, true, 1024, true))
{
var requestBody = reader.ReadToEnd();
request.Body.Seek(0, SeekOrigin.Begin);
requestTelemetry.Properties.Add("RequestBody", requestBody);
}
}
}
}
推荐阅读
- ios - 为私有 GitHub 存储库设置 Codecov
- reactjs - 如何在 React 中访问不同 reducer 的状态
- three.js - 将视频纹理一分为二
- html - 在列表标签中将圆盘对齐到中心
- yii2 - Yii2 为什么 PhpStorm 不自动完成单元测试方法
- c - 根据 fgetc(FILE*) 实现,我找不到 FILE 结构的 ungetcflag 成员
- git - 无法使用本地文件夹克隆 git repo
- azure - 使用 Azure AD 对本地(集成 Windows 身份验证)应用程序进行身份验证
- flutter - Flutter:ListView.builder 中的自动垂直高度
- hyperledger-fabric - 超级账本结构链代码:从链代码中调用另一个函数的函数?