Given the HttpResponseMessage, how can I read the content of the request?

Given System.Net.Http.HttpResponseMessage

, I can get quite a lot of information about the request I made through response.RequestMessage

, for example

response.RequestMessage.RequestUri // the url of the request
response.RequestMessage.Method     // the HTTP method

      

However, I cannot find a way to get something useful from

response.RequestMessage.Content    // a StringContent instance

      

I've looked at the property tree StringContent

, but I can't figure out how to get its contents as a regular string in a way that works in the viewport.

Any suggestions?

+3


source to share


1 answer


Analysis System.Net.Http.dll v2.2.29.0

with ILSpy shows that the System.Net.Http.HttpClientHandler.CreateResponseMessage

(initializing object HttpResponse

) does nothing with the corresponding one HttpRequest

.Content

. This means that if it was not null

in the first place, the content object itself should be available.

System.ObjectDisposedException

selected when an operation is performed on a placed object. What does "located facility" mean? System.Net.Http.StringContent

It is realized System.IDisposable

through their ancestor System.Net.Http.HttpContent

. So it actually means "a IDisposable

after the method call .Dispose()

.

Naturally, searching for users HttpContent.Dispose()

leads us to the culprit -System.Net.Http.HttpClient.SendAsync()

which calls System.Net.Http.HttpClient.DisposeRequestContent()

after the data is sent.


Now what to do. All it HttpContent.Dispose()

does is close the object streams and set a flag. However StreamContent

(or rather, its parent ByteArrayContent

) stores the data in a field.Content

- which is not affected by the layout!



Alas, both methods that read it directly are this protected

, and all public methods that use them check the flag first. So, the only way to read this with reflection (illustration in IronPython, notes are given for C # equivalents):

>>> sc=System.Net.Http.StringContent("abcdefghijklmnopqrstuvwxyz")
#in C#, the following is `type(StringContent)' (this is what it actually does)
>>> scd=System.Reflection.TypeDelegator(System.Net.Http.StringContent)
>>> print scd.GetField("content",System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Instance)
None     #because the field is in ByteArrayContent and is private
>>> bacd=System.Reflection.TypeDelegator(System.Net.Http.ByteArrayContent)
>>> bacd.GetField("content",System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Instance)
<System.Reflection.RtFieldInfo object at 0x000000000000002C [Byte[] content]>
# `_' is last result
>>> _.GetValue(sc)
Array[Byte]((<System.Byte object at 0x000000000000002D [97]>, <System.Byte objec
t at 0x000000000000002E [98]>, <System.Byte object at 0x000000000000002F [99]>,
<...>

      

In C # it would look like this:

type(ByteArrayContent)
    .GetField("content",BindingFlags.NonPublic|BindingFlags.Instance)
    .GetValue(content)

      

+7


source







All Articles