2

I want trace the response body of my httpclient requests in dependencies table Application Insight. My application runs with .NET framework 4.8 I created an Initializer to trace the Dependencies telemetry with the following code:

public class TrackResponseBody : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        var requestTelemetry = telemetry as DependencyTelemetry;

        if (requestTelemetry == null)
            return;

        if (requestTelemetry.TryGetOperationDetail("HttpResponse", out var responseObj))
        {
            var response = responseObj as HttpWebResponse;

            if (response != null)
            {
                using (var stream = response.GetResponseStream())
                {
                    var reader = new StreamReader(stream);
                    string result = reader.ReadToEnd();
                    requestTelemetry.Properties["ResponseBody"] = result;
                }
            }
        }
    }
}

But when i try to call reader.ReadToEnd(), my code generate this exception: System.NotSupportedException: 'The stream does not support concurrent IO read or write operations.'

This code write correctly in application insight dependencies log, if i don't try to get body response.

This is how I implemented my HttpClient:

            var client_ = new HttpClient();

            client_.BaseAddress = new Uri("https://www.google.com");

            using (var request_ = new HttpRequestMessage())
            {
                request_.Method = new HttpMethod("GET");
                var response_ = await client_.SendAsync(request_).ConfigureAwait(false);
                var responseData_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
            }

Is there a way to get the body response of my HttpClient?

colinD
  • 1,641
  • 1
  • 20
  • 22
  • 1
    Is it a .net core project? And can you please show us the httpclient request related code? – Ivan Glasenberg May 20 '20 at 06:59
  • Hi @IvanYang, I updated the question including the HttpClient example. The target framework is .NET 4.8. Thanks for your support. – user13575485 May 20 '20 at 10:25
  • Hi, I followed your code, but in the TrackResponseBody class -> in this line: var response = responseObj as HttpWebResponse; the response is always null:(. Is there any specific settings in your side? – Ivan Glasenberg May 21 '20 at 03:03
  • I just posted an answer, please let me know if you still have any more issues. – Ivan Glasenberg May 21 '20 at 05:50
  • Hello, if the answer is helpful, could you please accept it as answer as per this [link](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work?answertab=active#tab-top)? Thanks. – Ivan Glasenberg May 22 '20 at 00:33
  • Hi, have found a way to do this? I have the same requierments except that I want the body content of the request instead of the response. I get the same error as you when I try to read the stream. I've also posted a question here: https://stackoverflow.com/questions/67375209/can-i-add-the-post-body-of-an-outgoing-http-request-dependency-to-the-availabl – user2509192 May 05 '21 at 13:35

1 Answers1

0

I try the code by myself, in TrackResponseBody, this line of code returns null: var response = responseObj as HttpWebResponse; , the response variable is always null.

And then I make a small change, instead convert responseObj to HttpWebResponse, I just convert responseObj to string, then add it to the requestTelemetry.Properties. The code is as below:

public class TrackResponseBody: ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        var requestTelemetry = telemetry as DependencyTelemetry;

        if (requestTelemetry == null)
            return;

        if (requestTelemetry.TryGetOperationDetail("HttpResponse", out var responseObj))
        {
            var response = responseObj as HttpWebResponse;

            //convert responseObj to string
            string s = responseObj.ToString();
            requestTelemetry.Properties["ResponseBody"] = s;
        }
    }

}

Test result:

enter image description here

Ivan Glasenberg
  • 29,865
  • 2
  • 44
  • 60
  • Hi Ivan, thanks for the support! I want to get the **response body object** of my APIs ({'a':'xxx','b':'xxx'}). In this way I can't get it, I've only information about my request that already exists in dependencies log :( How can I access to the response content body object? – user13575485 May 22 '20 at 08:12
  • @user13575485, but as I mentioned, when I tried to convert using this line of code `var response = responseObj as HttpWebResponse;`, the `response` is always null:(. Can you try to define a MemoryStream, then use the `CopyTo` method to copy the original stream to the new MemoryStream, then to see that if you can operate on the new MemoryStream? – Ivan Glasenberg May 22 '20 at 08:21
  • 1
    I tried to use MemoryStream, but it generate the same exception :( System.NotSupportedException: 'The stream does not support concurrent IO read or write operations.' – user13575485 May 22 '20 at 13:04