我在IIS / ASP.NET中托管了一个WCF服务,它接受序列化对象的HTTP Post( not form post )。
如果客户端发送格式错误的请求(例如,他们没有正确序列化对象),我想记录发送的消息。
我们已经在使用ELMAH捕获未处理的异常,因此只需附加发布数据就是最简单的选择。
我可以在异常期间获取当前的HttpContext,但是这只包含HTTP标头信息。
我的问题是:有没有办法捕获原始HTTP POST请求正文?或者,失败 - 更好的方法(没有反向代理)捕获导致错误的输入?
编辑:只是为了澄清,始终运行数据包级捕获并不合适。我正在寻找一个可以部署到生产服务器的解决方案,它将拥有我们无法控制或监控能力的客户端。
编辑#2:建议访问Request.InputStream - 如果您在WCF已从流中读取请求后尝试读取,则此操作无效。
这里有一段代码,看看我是如何尝试使用它的。
StringBuilder log = new StringBuilder();
var request = HttpContext.Current.Request;
if (request.InputStream != null)
{
log.AppendLine(string.Format("request.InputStream.Position = \"{0}\"", request.InputStream.Position));
if (request.InputStream.Position != 0)
{
request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
}
using (StreamReader sr = new StreamReader(request.InputStream))
{
log.AppendLine(string.Format("Original Input: \"{0}\"", sr.ReadToEnd()));
}
}
else
{
log.AppendLine("request.Inputstream = null");
}
log.ToString();
log.ToString()的输出是:
request.InputStream.Position = "0" Original Input: ""
答案 0 :(得分:3)
当它到达您的服务时,请求将被处理并且不可用。
然而......你可以附上message inspector。消息检查器允许您在消息到达操作实现之前调整消息。您可以创建消息的缓冲副本,并将其复制到OperationContext.Current。
丑陋的黑客当然,这意味着内存开销,因为现在每个请求都会浮动两个消息副本。
答案 1 :(得分:-1)
你看过System.Web.Request.InputStream属性吗?它应该完全符合你的要求。
如何“回放”InputStream属性。
if (Request.InputStream.Position != 0)
{
Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
}
您应该考虑的另一个选项是在BeginRequest事件上使用HTTPModule捕获此信息。数据应该在BeginRequest事件中存在,因为我不相信WCF在PostAuthenticateEvent之后才接收请求。
答案 2 :(得分:-1)
从ASP.NET(IIS下的ASP Web服务)下面的代码有助于:
if (request.InputStream.Position != 0)
{
request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
}
WCF可能不同(即在读取后将Disposes InputStream)
答案 3 :(得分:-2)
使用fiddler。免于MS。效果很好。