C# 给定HttpResponseMessage,如何读取请求的内容?
例如,给定一个C# 给定HttpResponseMessage,如何读取请求的内容?,c#,C#,例如,给定一个System.Net.Http.HttpResponseMessage,我就可以通过response.RequestMessage获得很多关于请求的信息 response.RequestMessage.RequestUri // the url of the request response.RequestMessage.Method // the HTTP method 然而,我想不出一个方法来从中获得有用的东西 response.RequestMessage.Cont
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
的属性树,但我不知道如何以在监视窗口中工作的方式将其内容作为常规字符串获取
有什么建议吗?分析表明,System.Net.Http.HttpClientHandler.CreateResponseMessage
(初始化HttpResponse
对象)与相应的HttpRequest
的内容没有任何关系。这意味着,如果它不是null
,那么内容对象本身应该仍然可用
在对已处置对象执行操作时抛出。“已处置对象”是什么意思System.Net.Http.StringContent
最终通过其祖先System.Net.Http.HttpContent
实现了System.IDisposable
。
因此,它实际上意味着“在调用了.Dispose()
方法之后,调用了IDisposable
。
当然,搜索HttpContent.Dispose()
用户会让我们找到罪魁祸首-System.Net.Http.HttpClient.sendsync()
,它在发送数据后调用System.Net.Http.HttpClient.DisposeRequestContent()
现在,关于该做什么。HttpContent.Dispose()
所做的就是关闭对象的流并设置标志。但是,StreamContent
(或者更确切地说,它的父项,ByteArrayContent
)将数据保存在.content
字段中,该字段不会被处置所触及
唉,两种直接读取它的方法都受到保护
,所有使用这些方法的公共方法都会首先检查标志因此,阅读它的唯一方法是使用反射(图中使用了IronPython,为C#等价物提供了注释):
ReadAsStringAsync()
@jeroenvanevel:在监视窗口中执行此操作会引发一个System.ObjectDisposedException
。不过谢谢你的提示!处理完后你还在看吗?那么,我希望这会发生。您无法查看已处理的对象,尽管其中可能有一些复制值的技巧。但是表达式本身不能再次求值。您正在使用VS2015吗?我记得读过一篇文章,说现在更好地支持watch表达式。@jeroenvanevel:VS2013,我在响应返回后观察它,所以请求对象很可能已经处理了它的内容。。。关于如何从HttpResponseMessage
获取请求正文的内容有什么想法吗?我正在使用VS2015,在msg.Content.ReadAsStringAsync().Result
上放置了一个手表并处理了该消息之后,我仍然可以在手表窗口中看到该值(但显示为灰色)。我尝试的示例代码是:OK。对于我的用例(调试…)来说,反射无疑是过火了,所以我就不谈这个了。不过,感谢您的深入挖掘和解释!您也可以在调试器中读取该字段。如果您不知道,它会使用反射来探索对象;-)
>>> 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]>,
<...>
type(ByteArrayContent)
.GetField("content",BindingFlags.NonPublic|BindingFlags.Instance)
.GetValue(content)