给定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)