HttpModule ATL Server Служба Ошибка InputStream
Я пытаюсь добавить некоторые возможности ведения журнала сообщений SOAP в старую, старую веб-службу ATL Server, которая работает в интегрированном режиме в IIS 7.5 на Windows Server 2008, но сталкивается со странной проблемой. Для получения дополнительной информации я добавил сборку, содержащую модуль HttpModule, в модуль modules файла web.config для веб-службы сервера ATL.
Я следил за ответом, представленным здесь, и сама регистрация отлично работает.
Однако всякий раз, когда я использую эту возможность ведения журнала, служба отвечает "Неверный запрос SOAP", в то время как файл журнала имеет ожидаемое сообщение SOAP. Я много поиграл с этим и понял, что это происходит, только если / когда я получаю доступ к свойству InputStream объекта запроса в моем обработчике для события BeginRequest. Это не удастся, если я даже просто установлю переменную на длину 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 (т.е. DLL для службы). Непосредственно перед этим появляются сообщения "GENERAL_READ_ENTITY_START" и "GENERAL_READ_ENTITY_END", а "END" содержит следующее сообщение:
BytesReceived 0
ErrorCode 2147942438
ErrorCode Reached the end of the file. (0x80070026)
Значит ли это, что я думаю, что это значит? Что обработчик не получает никаких данных? Является ли это еще одним доказательством того, что мой HttpModule работает с InputStream запроса?
2 ответа
Таким образом, я окончательно определил, что это нереальный подход: я не мог заставить HttpModule вообще запускаться в IIS 6 (что мне понадобится, чтобы это было приемлемым решением). Я попытался установить свойство Filter для объекта Request и всевозможных других безумных идей, но ни одно из них не позволило мне одновременно записать тело запроса в HttpModule и по-прежнему работать с сервисом.
Поэтому я стал больше копаться и наткнулся на эту статью о codeproject, в которой рассказывается о внутренней работе ATL Server, в частности о методе HandleRequest в atlsoap.h. Я немного покопался там и нашел способ найти там тело запроса, и было довольно просто записать его в файл вручную оттуда.
Для тех, кому интересно, это последний код, который я добавил в 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**********************************************************
Я собираюсь еще немного поиграть с этим, но у меня есть то, что кажется приемлемым решением.
Вы уверены, что ваш объект запроса действителен? Вы делаете вещи немного иначе, чем образец, на который вы ссылаетесь. Они извлекают поток из аргумента отправителя, тогда как вы, очевидно, полагаетесь на переменную-член.