Asked by:
Deserializing error when receiving a valid response (HRESULT : 0x803d0000 "The input data was not in the expected format or did not have the expected value")

Question
-
Hi,
I have followed the typical steps for generating the .c | .h files (used svcutil for https://api.betfair.com/global/v3/BFGlobalService.wsdl then wsutil). Then I wrote a small program to access the login method exposed by the service (that would happen in the BFGlobalService_login below). When this method is invoked I get the HRESULT given in the title. Querying the WS_ERROR I get the following details:
- Error 0: Serialization failure occurred when reading an element with WS_READ_OPTION '2', name 'loginResponse' and namespace 'http://www.betfair.com/publicapi/v3/BFGlobalService/'.
- Error 1: Serialization failure occurred when reading a field with WS_TYPE '26 (0x1A)', WS_FIELD_MAPPING '2', name 'Result' and namespace 'http://www.betfair.com/publicapi/v3/BFGlobalService/'.
- Error 2: Serialization failure occurred when reading a field with WS_TYPE '26 (0x1A)', WS_FIELD_MAPPING '2', name 'header' and namespace ''.
- Error 3: The attribute with name 'type' and namespace 'http://www.w3.org/2001/XMLSchema-instance' was not expected.
Trying the same thing from a quickly put together C# program works as expected.
Any help would be much appreciated.
class WsError { WS_ERROR* m_h; public: WsError() : m_h(0) {} ~WsError() { if (0 != m_h) WsFreeError(m_h); } HRESULT Create(__in_ecount_opt(propertyCount) const WS_ERROR_PROPERTY* properties, __in ULONG propertyCount) { ASSERT(0 == m_h); return WsCreateError(properties, propertyCount, &m_h); } HRESULT GetProperty(__in WS_ERROR_PROPERTY_ID id, __out_bcount(bufferSize) void* buffer, __in ULONG bufferSize) { ASSERT(0 != m_h); ASSERT(0 != buffer); return WsGetErrorProperty(m_h, id, buffer, bufferSize); } template <typename T> HRESULT GetProperty(__in WS_ERROR_PROPERTY_ID id, __out T* buffer) { return GetProperty(id, buffer, sizeof(T)); } HRESULT GetString(__in ULONG index, __out WS_STRING* string) { ASSERT(0 != m_h); ASSERT(0 != string); return WsGetErrorString(m_h, index, string); } operator WS_ERROR*() const { return m_h; } }; class WsHeap { WS_HEAP* m_h; public: WsHeap() : m_h(0) { } ~WsHeap() { if (0 != m_h) WsFreeHeap(m_h); } HRESULT Create(__in SIZE_T maxSize, __in SIZE_T trimSize, __in_opt const WS_HEAP_PROPERTY* properties, __in ULONG propertyCount, __in_opt WS_ERROR* error) { ASSERT(0 == m_h); return WsCreateHeap(maxSize, trimSize, properties, propertyCount, &m_h, error); } operator WS_HEAP*() const { return m_h; } }; class WsServiceProxy { WS_SERVICE_PROXY* m_h; public: WsServiceProxy() : m_h(0) {} ~WsServiceProxy() { if (0 != m_h) { Close(0, 0); WsFreeServiceProxy(m_h); } } HRESULT Open(__in const WS_ENDPOINT_ADDRESS* address, __in_opt const WS_ASYNC_CONTEXT* asyncContext, __in_opt WS_ERROR* error) { ASSERT(0 != m_h); return WsOpenServiceProxy(m_h, address, asyncContext, error); } HRESULT Close(__in_opt const WS_ASYNC_CONTEXT* asyncContext, __in_opt WS_ERROR* error) { ASSERT(0 != m_h); return WsCloseServiceProxy(m_h, asyncContext, error); } WS_SERVICE_PROXY** operator&() { ASSERT(0 == m_h); return &m_h; } operator WS_SERVICE_PROXY*() const { return m_h; } }; class WsServiceHost { WS_SERVICE_HOST* m_h; public: WsServiceHost() : m_h(0) {} ~WsServiceHost() { if (0 != m_h) { Close(0,0); WsFreeServiceHost(m_h); } } HRESULT Create(__in_ecount_opt(endpointCount) const WS_SERVICE_ENDPOINT** endpoints, __in const USHORT endpointCount, __in_ecount_opt(servicePropertyCount) const WS_SERVICE_PROPERTY* properties, __in ULONG propertyCount, __in_opt WS_ERROR* error) { ASSERT(0 == m_h); return WsCreateServiceHost(endpoints, endpointCount, properties, propertyCount, &m_h, error); } HRESULT Open(__in_opt const WS_ASYNC_CONTEXT* asyncContext, __in_opt WS_ERROR* error) { ASSERT(0 != m_h); return WsOpenServiceHost(m_h, asyncContext, error); } HRESULT Close(__in_opt const WS_ASYNC_CONTEXT* asyncContext, __in_opt WS_ERROR* error) { ASSERT(0 != m_h); return WsCloseServiceHost(m_h, asyncContext, error); } operator WS_SERVICE_HOST*() const { return m_h; } };
#define HR(expr) { hr = expr; if (FAILED(hr)) return hr; }
#include "stdafx.h" #include "..\BFGlobalService.wsdl.h" #include "..\WsHelpers.h" HRESULT Login(__in PCWSTR url, __in PCWSTR user, __in PCWSTR password, __out WCHAR** token, __in_opt WS_ERROR* error) { ASSERT(nullptr != url ); ASSERT(nullptr != user); ASSERT(nullptr != password); ASSERT(nullptr != token); HRESULT hr = S_OK; WsHeap heap; HR(heap.Create(8192, 512, nullptr, 0, error)); WsServiceProxy serviceProxy; WS_SSL_TRANSPORT_SECURITY_BINDING sslBinding = {}; sslBinding.binding.bindingType = WS_SSL_TRANSPORT_SECURITY_BINDING_TYPE; WS_SECURITY_BINDING* securityBindings[1] = { &sslBinding.binding }; WS_SECURITY_DESCRIPTION securityDescription = { securityBindings, ARRAYSIZE(securityBindings) , nullptr, 0}; WS_ENCODING encoding = WS_ENCODING_XML_UTF8; WS_ENVELOPE_VERSION soapVersion = WS_ENVELOPE_VERSION_SOAP_1_1; WS_ADDRESSING_VERSION addressingVersion = WS_ADDRESSING_VERSION_TRANSPORT; WS_CHANNEL_PROPERTY channelProperties[3] = { {WS_CHANNEL_PROPERTY_ENVELOPE_VERSION, &soapVersion, sizeof(soapVersion)}, {WS_CHANNEL_PROPERTY_ADDRESSING_VERSION, &addressingVersion, sizeof(addressingVersion)}, {WS_CHANNEL_PROPERTY_ENCODING, &encoding, sizeof(encoding)}, }; //HR(BFGlobalService_CreateServiceProxy(0, nullptr, 0, &serviceProxy, error)); HR(WsCreateServiceProxy( WS_CHANNEL_TYPE_REQUEST, WS_HTTP_CHANNEL_BINDING, &securityDescription, nullptr,0, channelProperties, ARRAYSIZE(channelProperties), &serviceProxy, error)); WS_ENDPOINT_ADDRESS address = { {static_cast<ULONG>(wcslen(url)), const_cast<PWSTR>(url)}}; HR(serviceProxy.Open(&address, nullptr, error)); LoginReq loginRequest= {nullptr, 0, const_cast<PWSTR>(password), 0, const_cast<PWSTR>(user), 82}; LoginResp* response = nullptr; HR(BFGlobalService_login(serviceProxy, &loginRequest, &response,heap, nullptr, 0, nullptr,error)); if(response) delete response; HR(serviceProxy.Close(nullptr, error)); return S_OK; } int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr = S_OK; WsError error; HR(error.Create(0, 0)); WCHAR* token(nullptr); hr = Login(L"https://api.betfair.com/global/v3/BFGlobalService",L"someuser", L"somepassword",&token,error); if(token) { delete[] token; } if(FAILED(hr)) { ULONG stringCount = 0; HR(error.GetProperty(WS_ERROR_PROPERTY_STRING_COUNT, &stringCount)); for (ULONG i = 0; i < stringCount; ++i) { WS_STRING string; HR(error.GetString(i, &string)); wprintf(L"Error %d: %.*s\n", i, string.length, string.chars); } } return 0; }
- Edited by stepib Sunday, March 25, 2012 10:50 PM
All replies
-
Hi,
I had the same deserialization issue, except whenever I was trying to get a custom header (WS_STRUCT_TYPE), WWSAPI was complaining that the attribute 'mustUnderstand' was not expected! I do not know why this attribute would not be expected in a header... but I discovered the following work around.
When compiling your WSDL C files with WsUtil.exe, specify the /ignoreUnhandledAttributes flag. From the usage information, this flag serves the following purpose:
"Specify the unhandled attributes for generated structures to be ignored during deserialization."
After I specified this flag, I no longer experienced the deserialization error.
Hope this helps,
Benjamin
- Proposed as answer by razneb Monday, November 25, 2013 5:32 AM