Hungry Mind , Blog about everything in IT - C#, Java, C++, .NET, Windows, WinAPI, ...

Показаны сообщения с ярлыком SOAP. Показать все сообщения
Показаны сообщения с ярлыком SOAP. Показать все сообщения

WWS - How to read SOAP Fault

Сервера веб служб возвращают ошибки в элементе SOAP Fault. Здесь я объясню, как прочитать эту информацию.

Как узнать, что произошел сбой? Проверить код возврата на равенство WS_E_ENDPOINT_FAULT_RECEIVED. Дальше начинается магия.

WS_FAULT *pFault;
hr = WsGetFaultErrorProperty(pError, WS_FAULT_ERROR_PROPERTY_FAULT, &pFault, sizeof(pFault));

Структура определена следующим образом:

//  Faults structure
//
//   A Fault is a value carried in the body of a message which conveys a
//  processing failure.  Faults are modeled using the WS_FAULT structure.
//  See Faults for more information.
//
struct _WS_FAULT {
    WS_FAULT_CODE* code;
    WS_FAULT_REASON* reasons;
    ULONG reasonCount;
    WS_STRING actor;
    WS_STRING node;
    WS_XML_BUFFER* detail;
};

Наибольший интерес вызывает информация, заложенная в элементе <detail/>. WCF определяет специальные сущности с названием Fault Contract. Мы хотим их получить в удобном виде. Текущая версия WWS не генерирует код для Fault Contract-ов. Можно прочитать голый XML или вручную написать эти структуры вместе с метаданными, которые их описывают.

WS_XML_WRITER *pWriter;
hr = WsCreateWriter(NULL, 0, &pWriter, pError);

WS_XML_WRITER_TEXT_ENCODING textEncoding;
textEncoding.charSet = WS_CHARSET_UTF8;
textEncoding.encoding.encodingType = WS_XML_WRITER_ENCODING_TYPE_TEXT;

LPVOID pBuf;
ULONG nBufSize;
hr = WsWriteXmlBufferToBytes(pWriter, pFault->detail, &textEncoding.encoding, NULL, 0, _pWsHeap, &pBuf, &nBufSize, _pWsError);

WsFreeWriter(pWriter);

Этот код запишет XML в буффер pBuf (там будет строка в кодировке UTF-8). Кстати, метод WsWriteXmlBufferToBytes хочет в 3-м параметре __in_opt const WS_XML_WRITER_ENCODING* encoding, а мы ему передаем указатель на член структуры WS_XML_WRITER_TEXT_ENCODING. Учитывая значение WS_XML_WRITER_ENCODING_TYPE_TEXT в поле encodingType, WWS предполагает, что дальше в памяти содержится WS_CHARSET. В WWS многие методы работают таким вот хитрым образом - полагаются на расположение вложенных структур в оперативной памяти.

Десериализацию структуры я опишу позже. Может быть.

C++ SOAP Client

Мне было интересно - а чем и как пишут proxy-классы для Web-служб на C++?! Я раньше наткнулся на интересную C++ библиотеку gSOAP и больше ничего подобного не встречал.

Оказалось, в Visual Studio 2005 есть встроенная возможность генерировать проксяки через Add Web Reference для C++, правда нужен ATL проект. Не порадовала куча ограничений на WSDL, т.е. будет работать только с простейшими службами.

Порадовало сравнение производительности gSOAP VS Apache Axis.

Copyright 2007-2011 Chabster