7

I'd like to see what the request body of my HTTP request contained for debugging purposes. Here's what I've got right now:

var httpResponseMessage = await _httpClient.PostAsync(uri, objectToInsert, jsonFormatter);

//This throws an exception
var thisDoesntWork = await httpResponseMessage.RequestMessage.Content.ReadAsStringAsync();

This throws an ObjectDisposedException. How can I view the request body to make sure the JSON being sent is correct?

Justin Helgerson
  • 24,900
  • 17
  • 97
  • 124
  • 5
    Use [fiddler](http://www.telerik.com/fiddler) ...? – rene Aug 25 '16 at 18:06
  • 1
    @rene - I know I could use Fiddler or Wireshark or plenty of other tools, but this isn't a one time curiosity question. I may want to log the request body for auditing purposes so I need to determine the request body programatically. – Justin Helgerson Aug 25 '16 at 18:30
  • @JustinHelgerson then use [FiddlerCore](http://www.telerik.com/fiddler/fiddlercore) :) – L.B Aug 25 '16 at 18:34
  • @L.B While I appreciate having options (I had never heard of FiddlerCore before) I'd prefer to use something available in the plain ol' .NET framework. Where there's a will there's a way? Maybe? :) – Justin Helgerson Aug 25 '16 at 18:37
  • The only thing that might work is setting up an `System.Net.Http` tracesource in your app.config but you might only end up with the [first 1024 characters of the content](http://stackoverflow.com/a/38190983/578411) – rene Aug 25 '16 at 19:09

3 Answers3

5

The short answer is you can't after the request has already been sent. HttpClient disposes the content body after the request is made as a convenience to the developer. See Why do HttpClient.PostAsync and PutAsync dispose the content? for some detail.

As an alternative, you could inherit from an existing HttpContent implementation, override the Dispose method, and log the body of the content prior to disposal.

Or, as suggested, use an external tool to monitor the request in flight.

Community
  • 1
  • 1
villecoder
  • 13,323
  • 2
  • 33
  • 52
0

You'd need to first create a HttpRequestMessage to pass to the HttpClient. Then you can just evaluate/log the content.

    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
    request.Content=JsonSerializer.Serialize(objectToInsert);
    Console.WriteLine(request.Content.ReadAsStringAsync().Result);
    HttpResponseMessage response = await httpClient.SendAsync(request);
gjutras
  • 65
  • 1
  • 8
-1

ObjectDisposedException is thrown because you're disposing the HttpRequestMessage and HttpClient before Content.ReadAsStringAsync() finishes.

Note that Content.ReadAsStringAsync() is an asynchronous method. You need to wait for it to complete before disposing the HttpClient.

If you are not wanting to use async you can add .Result to force the code to execute synchronously:

var response = httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters)).Result;

var contents = response.Content.ReadAsStringAsync().Result;
  • I'm not disposing the `HttpClient` until much later. Obviously `PostAsync` is automatically disposing of the `HttpRequestMessage` in some fashion which is why I'm asking the question. Also, if you look at my question I already am awaiting the `ReadAsStringAsync` method. – Justin Helgerson Aug 25 '16 at 18:32
  • 1
    Try this and let me know what is the response from: httpResponseMessage.EnsureSuccessStatusCode(); This will throw an exception if the IsSuccessStatusCode property for the HTTP response is false. – Diogo Menezes Aug 25 '16 at 18:53
  • Other thing you could do is send json as string to test. ....PostAsync(uri, new StringContent(data)); – Diogo Menezes Aug 25 '16 at 18:58