7

我有一个托管在 IIS/ASP.NET 中的 WCF 服务,它接受序列化对象的 HTTP Post(而不是表单 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"
    原始输入:“”
4

4 回答 4

3

当它为您提供服务时,请求已被处理,您无法使用。

但是...您可以附加一个消息检查器。消息检查器允许您在消息到达您的操作实现之前对其进行处理。您可以创建消息的缓冲副本,并将其复制到 OperationContext.Current。

当然是丑陋的 hack,这将意味着内存开销,因为现在每个请求都有两个消息副本浮动。

于 2009-05-25T17:04:07.717 回答
-1

你看过 System.Web.Request.InputStream 属性吗?它应该有你想要的。

如何“倒带” InputStream 属性。

    if (Request.InputStream.Position != 0)
    {
        Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
    }

您应该研究的另一个选项是在 BeginRequest 事件上使用 HTTPModule 捕获此信息。数据应该在 BeginRequest 事件中存在,因为我不相信 WCF 会在 PostAuthenticateEvent 之后接收请求。

于 2009-05-25T13:56:28.690 回答
-1

在 ASP.NET(IIS 下的 ASP Web 服务)下,以下代码有帮助:

if (request.InputStream.Position != 0)
{
  request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
}

WCF 可能不同(即在读取后 Dispose InputStream)

于 2013-01-03T12:46:20.277 回答
-2

使用提琴手。免于 MS。效果很好。

于 2009-05-25T13:45:16.280 回答