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 многие методы работают таким вот хитрым образом - полагаются на расположение вложенных структур в оперативной памяти.
Десериализацию структуры я опишу позже. Может быть.