I want to read the Body of incoming requests with the help of my HttpRequestTelemetryInitializer class. Although my GetRequestHeader method works successfully, I get the following error on the
var body = reader.ReadToEndAsync().Result;
line of my GetRequestBody method.
**
ERROR: Cannot access a disposed object. Object name:
‘HttpRequestStream’.
**
What should I do about this error? Can you help me?
public class HttpRequestTelemetryInitializer : ITelemetryInitializer
{
private const string _requestBody = "RequestBody";
private const string _requestHeaders = "RequestHeaders";
private readonly List<string> _skipBodyLoggingOnErrorApiList;
private readonly List<string> _skipHeaderLoggingOnErrorApiList;
private readonly IHttpContextAccessor _httpContextAccessor;
public HttpRequestTelemetryInitializer(IHttpContextAccessor httpContextAccessor, IConfiguration configuration)
{
_httpContextAccessor = httpContextAccessor;
_skipBodyLoggingOnErrorApiList = configuration.GetSection("HttpRequestTelemetryInitializerConfig:SkipBodyLoggingOnError").Get<List<string>>();
_skipHeaderLoggingOnErrorApiList = configuration.GetSection("HttpRequestTelemetryInitializerConfig:SkipHeaderLoggingOnError").Get<List<string>>();
}
public void Initialize(ITelemetry telemetry)
{
try
{
if (telemetry == null)
return;
if (telemetry is RequestTelemetry requestTelemetry)
{
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null || httpContext.Request == null)
return;
var request = httpContext.Request;
if (request.Method == HttpMethod.Post.Method ||
request.Method == HttpMethod.Put.Method ||
request.Method == "PATCH")
{
if (!_skipBodyLoggingOnErrorApiList.Any(url => request.Path.Value.Contains(url)))
{
requestTelemetry.Properties.Add(_requestBody, GetRequestBody(request));
}
if (!_skipHeaderLoggingOnErrorApiList.Any(url => request.Path.Value.Contains(url)))
{
requestTelemetry.Properties.Add(_requestHeaders, GetRequestHeaders(request));
}
}
}
}
catch
{
}
}
private string GetRequestHeaders(HttpRequest request)
{
using var writer = new StringWriter();
foreach (var header in request.Headers)
{
writer.WriteLine($"{header.Key}: {header.Value}");
}
writer.WriteLine();
return writer.ToString();
}
private string GetRequestBody(HttpRequest request)
{
request.EnableBuffering();
var reader = new StreamReader(request.Body);
var body = reader.ReadToEndAsync().Result;
request.Body.Position = 0;
return body;
}
}
Startup.cs:
services.AddApplicationInsightsTelemetry();
services.AddSingleton<ITelemetryInitializer, HttpRequestTelemetryInitializer>();
2
Answers
@Sures Chikkam
The result still is the same. Does not work your code.
It occurs because the
HttpRequestStream
is disposed of before you’re trying to read it again.Problem arises when you try to read the body synchronously with
ReadToEndAsync().Result
, which can lead to issues if the stream is disposed prematurely.Firstly, check that the request body is read asynchronously.
Initialize
method to call theGetRequestBodyAsync
method asynchronously.Result: