1

我正在尝试将一些 SOAP 消息记录功能添加到一个旧的、旧的 ATL Server Web 服务,该服务在 Windows Server 2008 机器上的 IIS 7.5 中以集成模式运行,但遇到了一个奇怪的问题。对于进一步的背景知识,我已将包含 HttpModule 的程序集添加到 ATL Server Web 服务的 web.config 的 modules 元素中。

我一直在关注 此处提供的答案,并且日志记录本身效果很好。

但是,每当我使用此日志记录功能时,服务都会以“SOAP 无效请求”进行响应,而日志文件中包含预期的 SOAP 消息。我已经对它进行了很多摆弄,并发现只有当我在 BeginRequest 事件的处理程序中访问请求对象的 InputStream 属性时才会发生这种情况。如果我什至像这样简单地将变量设置为 InputStream 的长度,它将失败:

private void OnBegin(object sender, EventArgs e)
   {
   var request = _application.Request;
   //this will blow up
   var foo = request.InputStream.Position;
   }

如果我不触摸我的处理程序中的 InputStream(显然,当我这样做是为了记录请求的内容时,这并没有多大用处),请求就会完美地通过。

我可以访问 Request 对象中的标头值以及所涉及的 HttpApplication 的各种其他属性,但访问 InputStream 会导致服务阻塞。

ATL Server 是否有一些内在的东西会阻止我执行此日志记录?我是否需要在 BeginRequest 处理程序中添加某种锁定或其他保护措施以确保其正常运行?我的处理程序是否以某种方式占用 InputStream 导致它无法用于服务?

解决这个问题的另一种方法是询问是否有办法在请求到达我的服务时查看请求(即在此 HttpModule 执行之后)?

值得注意的是,我正在使用 SoapUI 来测试服务。

编辑:我现在在 IIS 中完成了一些失败的请求跟踪,并收到以下错误消息:

ModuleName IsapiModule 
Notification 128 
HttpStatus 500 
HttpReason Internal Server Error 
HttpSubStatus 0 
ErrorCode 0 
ConfigExceptionInfo  
Notification EXECUTE_REQUEST_HANDLER 
ErrorCode The operation completed successfully. (0x0) 

这来自 ATL Server Web 服务的处理程序(即服务的 DLL)。在这之前是“GENERAL_READ_ENTITY_START”和“GENERAL_READ_ENTITY_END”消息,“END”有这个消息:

BytesReceived 0 
ErrorCode 2147942438 
ErrorCode Reached the end of the file. (0x80070026) 

这是否意味着我认为的意思?处理程序没有获取任何数据?这是指向我的 HttpModule 与请求的 InputStream 混淆的更多证据吗?

4

2 回答 2

0

您确定您的请求对象有效吗?您在此处所做的事情与您引用的示例略有不同。他们正在从 sender 参数中提取流,而您显然依赖于成员变量。

于 2012-05-18T00:26:48.063 回答
0

所以我最终确定这不是一个可行的方法:我根本无法在 IIS 6 中触发 HttpModule(我需要让它成为一个可接受的解决方案)。我尝试在 Request 对象上设置 Filter 属性和各种其他疯狂的想法,但没有一个能让我能够在 HttpModule 中记录请求正文并让服务仍然工作。

所以我做了更多的挖掘,并在codeproject上找到了这篇关于ATL Server 内部工作的文章,特别是 atlsoap.h 中的 HandleRequest 方法。我在那里闲逛了一段时间,想出了一种方法来获取那里的请求正文,从那里手动将其写入文件非常简单。

对于那些好奇的人,这是我添加到 HandleRequest() 的最终代码:

//****************************************REQUEST LOGGING**********************************************************
        BYTE* bytes = pRequestInfo->pServerContext->GetAvailableData();
        FILE* pFile;
        pFile = fopen("C:\\IISLog\\ATL.txt", "a");
        fwrite(bytes, 1, pRequestInfo->pServerContext->GetAvailableBytes(), pFile);
        fclose(pFile);
//****************************************REQUEST LOGGING********************************************************** 

我仍然会多玩一点,但我有一个似乎可行的解决方案。

于 2012-05-18T20:11:33.653 回答