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

时间:2015-06-04 12:34:09

标签: c#

鉴于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的属性树,但我无法弄清楚如何以监视窗口中的方式将其内容作为常规字符串。

有什么建议吗?

1 个答案:

答案 0 :(得分:7)

使用System.Net.Http.dll v2.2.29.0分析ILSpy表明System.Net.Http.HttpClientHandler.CreateResponseMessage(初始化HttpResponse个对象)对相应的HttpRequest&#做任何事情都没有39; s .Content。这意味着,如果它首先不是null,那么内容对象本身应该仍然可用。

当对已处置的对象执行操作时,

System.ObjectDisposedException被抛出"" "处置对象"意思? System.Net.Http.StringContent通过其祖先System.IDisposable实现了System.Net.Http.HttpContent。 因此,在调用IDisposable方法后,它实际上意味着" .Dispose()。"

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

现在,关于该怎么做。 HttpContent.Dispose()所做的就是关闭对象的流并设置一个标志。但是,StreamContent(或者更确切地说是其父级ByteArrayContent会将数据保存在.content字段中 - 这不会被处置所触及!< / p>

唉,直接读取它的两种方法都是protected,所有使用它们的公共方法都会先检查标记。 因此,阅读它的唯一方法是使用反射(插图在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)
<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]>,
<...>

在C#中,这看起来像是:

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