Skip to main content

 none
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") RRS feed

  • 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
    Sunday, March 25, 2012 10:48 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
    Monday, November 25, 2013 5:31 AM