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();

}