C# Can';t获取响应主体以将其登录到应用程序洞察中
为了将C# Can';t获取响应主体以将其登录到应用程序洞察中,c#,.net-core,middleware,azure-application-insights,C#,.net Core,Middleware,Azure Application Insights,为了将响应主体从HttpContext记录到app insights中,我应该开发一个中间件,它截取每个请求和响应并提取HttpContext,在我的例子中是response.body,然后使用遥测客户端将其发送到app insights中 问题是,当我调试和提取响应体时,响应体总是空的 这是我的中间件类 public class ResponseBodyInitializer { private readonly IHttpContextAccessor _httpContextAcc
响应主体
从HttpContext
记录到app insights中,我应该开发一个中间件
,它截取每个请求和响应并提取HttpContext
,在我的例子中是response.body
,然后使用遥测客户端将其发送到app insights中
问题是,当我调试和提取响应体时,响应体总是空的
这是我的中间件类
public class ResponseBodyInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly RequestDelegate _next;
public ResponseBodyInitializer(IHttpContextAccessor httpContextAccessor, RequestDelegate next)
{
_httpContextAccessor = httpContextAccessor;
_next = next;
}
public async Task Invoke(HttpContext context)
{
string resBody = await GetResponseBodyForTelemetry(context);
SendDataToTelemetryLog(resBody, context);
}
private static void SendDataToTelemetryLog(string respBody, HttpContext context)
{
if (context.Request.Method == "POST" || context.Request.Method =="PUT")
{
var telemetryClient = new TelemetryClient();
var traceTelemetry = new TraceTelemetry
{
Message = respBody,
SeverityLevel = SeverityLevel.Information
};
//Send a trace message for display in Diagnostic Search.
telemetryClient.TrackTrace(traceTelemetry);
}
}
private async Task<string> GetResponseBodyForTelemetry(HttpContext context)
{
var originalBody = context.Response.Body;
try
{
using (var memStream = new MemoryStream())
{
context.Response.Body = memStream;
//await the responsebody
await _next(context);
if (context.Response.StatusCode == 204)
{
return null;
}
memStream.Position = 0;
var responseBody = new StreamReader(memStream).ReadToEnd();
memStream.Position = 0;
await memStream.CopyToAsync(originalBody);
return responseBody;
}
}
finally
{
context.Response.Body = originalBody;
}
}
}
或者是否有其他方法在app insights中记录响应?以下是您必须执行的步骤:-
1) 您必须实现ITelemetryInitializer
2) 将IHttpContextAccessor注入类,并在Initialize方法中读取响应流
3) 确保传递的ITelemetry对象来自RequestTelemetry类型,并且HttpRequest是Post或Put
4) 然后,可以使用IHttpContext.HttpContext.response.Body属性读取响应,并使用Application Insight记录它
最后,在Startup.cs中的ConfigureService方法中注册类
我明白了,您没有实现ITelemetryInitializer,还需要在Initialize方法中读取流
尝试以下步骤,看看是否有帮助。以下是您必须执行的步骤:-
1) 您必须实现ITelemetryInitializer
2) 将IHttpContextAccessor注入类,并在Initialize方法中读取响应流
3) 确保传递的ITelemetry对象来自RequestTelemetry类型,并且HttpRequest是Post或Put
4) 然后,可以使用IHttpContext.HttpContext.response.Body属性读取响应,并使用Application Insight记录它
最后,在Startup.cs中的ConfigureService方法中注册类
我明白了,您没有实现ITelemetryInitializer,还需要在Initialize方法中读取流
尝试这些步骤,看看是否有帮助。我尝试过这种方法,但我得到了错误“流不可读”。问题是,当您使用初始值设定项时,您还没有响应,因此您必须以某种方式等待。我无法插入RequestDelegate
来等待上下文。您的方式非常适合阅读HttpContext.Request
,这对我来说非常适合。我尝试过这种方式,但我得到了错误“流不可读”。问题是,当您使用初始值设定项时,您还没有响应,因此您必须以某种方式等待。我无法插入RequestDelegate
来等待上下文。您的方式非常适合阅读HttpContext.Request
,这对我来说非常合适。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
_loggerFactory = loggerFactory;
app.UseDefaultFiles()
.UseStaticFiles()
.UseMiddleware<ResponseBodyInitializer>()
.UseBotFramework();
}