Это выглядит как решение Тима Картер не работает, если вызов веб-ссылка вызывает исключение. Я пытался получить исходный веб-ответ, поэтому я могу проверить его (в коде) в обработчике ошибок после исключения исключения. Тем не менее, я обнаружил, что журнал ответов, написанный методом Тима, пуст, когда вызов вызывает исключение. Я не совсем понимаю код, но похоже, что метод Тима разрезает процесс после того, как .Net уже недействителен и отменил веб-ответ.
Я работаю с клиентом, который разрабатывает веб-сервис вручную с низким уровнем кодирования. На этом этапе они добавляют свои собственные сообщения об ошибках внутреннего процесса в сообщениях в формате HTML в ответ перед ответом в формате SOAP. Конечно, автоматическая веб-ссылка .Net взрывается. Если бы я мог получить необработанный HTTP-ответ после того, как генерируется исключение, я мог бы искать и анализировать любой ответ SOAP в смешанном ответе HTTP-ответа и знать, что они получили мои данные в порядке или нет.
Позже ...
Вот решение, которое делает работу, даже после execption (обратите внимание, что я только после ответа - может получить запрос тоже):
namespace ChuckBevitt
{
class GetRawResponseSoapExtension : SoapExtension
{
//must override these three methods
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
return null;
}
public override object GetInitializer(Type serviceType)
{
return null;
}
public override void Initialize(object initializer)
{
}
private bool IsResponse = false;
public override void ProcessMessage(SoapMessage message)
{
//Note that ProcessMessage gets called AFTER ChainStream.
//That's why I'm looking for AfterSerialize, rather than BeforeDeserialize
if (message.Stage == SoapMessageStage.AfterSerialize)
IsResponse = true;
else
IsResponse = false;
}
public override Stream ChainStream(Stream stream)
{
if (IsResponse)
{
StreamReader sr = new StreamReader(stream);
string response = sr.ReadToEnd();
sr.Close();
sr.Dispose();
File.WriteAllText(@"C:\test.txt", response);
byte[] ResponseBytes = Encoding.ASCII.GetBytes(response);
MemoryStream ms = new MemoryStream(ResponseBytes);
return ms;
}
else
return stream;
}
}
}
Вот как настроить его в конфигурационном файле:
<configuration>
...
<system.web>
<webServices>
<soapExtensionTypes>
<add type="ChuckBevitt.GetRawResponseSoapExtension, TestCallWebService"
priority="1" group="0" />
</soapExtensionTypes>
</webServices>
</system.web>
</configuration>
«TestCallWebService» Шоуда быть заменено на имя библиотеки (что случилось быть имя приложения тест консоли я работал в).
Вам действительно не нужно ехать в ChainStream; Вы должны быть в состоянии сделать это более просто из ProcessMessage как:
public override void ProcessMessage(SoapMessage message)
{
if (message.Stage == SoapMessageStage.BeforeDeserialize)
{
StreamReader sr = new StreamReader(message.Stream);
File.WriteAllText(@"C:\test.txt", sr.ReadToEnd());
message.Stream.Position = 0; //Will blow up 'cause type of stream ("ConnectStream") doesn't alow seek so can't reset position
}
}
Если вы посмотрите SoapMessage.Stream, он должен быть только для чтения поток, который можно использовать для проверки данных в этой точке. Это завинчивание, потому что если вы читаете поток, последующие обработки бомб без ошибок, обнаруженных данными (поток был в конце), и вы не можете сбросить позицию до начала.
Интересно, что если вы используете оба метода, пути ChainStream и ProcessMessage, метод ProcessMessage будет работать, потому что вы изменили тип потока из ConnectStream на MemoryStream в ChainStream, а MemoryStream позволяет выполнять операции поиска. (Я попробовал лить ConnectStream в MemoryStream - не разрешался.)
Итак ..... Microsoft должна либо разрешить операции поиска по типу ChainStream, либо сделать SoapMessage.Stream действительно копией только для чтения, как предполагается быть. (Напишите своего конгрессмена и т. Д.)
Еще один пункт. После создания способа отвлечения необработанного HTTP-ответа после исключения я все равно не получил полный ответ (как определено с помощью сниффера HTTP). Это было связано с тем, что, когда веб-служба разработки добавила сообщения об ошибках HTML в начало ответа, она не корректировала заголовок Content-Length, поэтому значение Content-Length было меньше размера фактического тела ответа. Все, что у меня было, это количество символов Content-Length символов - остальные отсутствовали. Очевидно, что когда .Net считывает поток ответов, он просто считывает количество символов Content-Length и не допускает, чтобы значение Content-Length было возможно неправильным. Это так и должно быть; но если значение заголовка Content-Length неверно, единственный способ получения всего тела ответа - с помощью сниффера HTTP (пользовательский HTTP-анализатор пользователя от http://www.ieinspector.com).
Да, пробовал проводку, он может отображать только информацию заголовка, содержимое мыла зашифровано. – 2008-11-19 22:08:27
Возможно, потому, что вы используете https. Расширения SOAP, насколько я помню, работают на более высоком уровне, чтобы вы могли видеть данные после их дешифрования. – nzpcmad 2008-11-19 22:15:52
Используйте Fiddler вместо Wireshark, он расшифровывает https из коробки. – 2013-02-05 09:18:39