给定HttpResponseMessage,我如何阅读请求的内容?

给定一个System.Net.Http.HttpResponseMessage ,我可以获得很多关于我通过response.RequestMessage做出的请求的信息,例如

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

但是,我无法找到一种方法来获得有用的东西

 response.RequestMessage.Content // a StringContent instance 

我查看了StringContent的属性树,但我无法弄清楚如何以Watch Window中的方式将其内容作为常规字符串。

有什么建议?

使用ILSpy分析System.Net.Http.dll v2.2.29.0显示System.Net.Http.HttpClientHandler.CreateResponseMessage (初始化HttpResponse对象)对相应的HttpRequest.Content没有任何.Content 。 这意味着如果它首先不是null ,那么内容对象本身应该仍然可用。

在对已处置的对象执行操作时,抛出System.ObjectDisposedException “处置对象”是什么意思? System.Net.Http.StringContent通过其祖先System.Net.Http.HttpContent实现System.IDisposable 。 因此,它实际上意味着“在调用其.Dispose()方法之后的IDisposable ”。

当然,搜索HttpContent.Dispose()用户会给我们带来罪魁祸首 – System.Net.Http.HttpClient.SendAsync() ,它在发送数据后调用System.Net.Http.HttpClient.DisposeRequestContent()


现在,关于做什么。 HttpContent.Dispose()所做的就是关闭对象的流并设置一个标志。 但是, StreamContent (或者更确切地说是它的父节点ByteArrayContent将数据保存在.content字段中 – 这个位置没有触及!

唉,两种直接读取它的方法都protected ,所有使用它们的公共方法都首先检查它。 因此,阅读它的唯一方法是使用reflection (插图是在IronPython中,注释是针对C#等效的):

 >>> 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)  # `_' is last result >>> _.GetValue(sc) Array[Byte]((, , , <...> 

在C#中,这看起来像:

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