问题描述
您好,
我已按照生成.c |的典型步骤进行操作。 .h文件(用于
的svcutil https://api.betfair.com/global/v3/BFGlobalService.wsdl 然后
wsutil)。然后我写了一个小程序来访问服务公开的登录方法(这将在下面的BFGlobalService_login中发生)。调用此方法时,我会在标题中给出HRESULT。查询WS_ERROR我得到以下详细信息:
I have followed the typical steps for generating the .c | .h files (used svcutil forhttps://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:
- 错误0:读取WS_READ_OPTION为'2',名称为'loginResponse'和命名空间'的元素时发生序列化失败http://www.betfair.com/publicapi/v3/BFGlobalService/'.
- 错误1:使用WS_TYPE '26(0x1A)',WS_FIELD_MAPPING'2',名称读取字段时发生序列化失败'结果'和名称空间'http://www.betfair.com/publicapi/v3/BFGlobalService/'.
- 错误2:使用WS_TYPE '26(0x1A)'读取字段时发生序列化失败, WS_FIELD_MAPPING'2',名称'header'和名称空间''。
- 错误3:不期望名称为"type"且名称空间为"http://www.w3.org/2001/XMLSchema-instance"的属性。
快速整理C#程序尝试同样的事情 按预期工作。
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;
}
推荐答案
我有相同的反序列化问题,除非我试图获取自定义标头(WS_STRUCT_TYPE),WWSAPI是抱怨没有预期属性'mustUnderstand'! 我不知道为什么在
a标题中不会出现这个属性...但是我发现了以下工作。
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.
使用 WsUtil.exe 编译WSDL C文件时,请指定
/ ignoreUnhandledAttributes 标记。 根据使用信息,此标志用于以下目的:
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.
希望这有帮助,
本杰明
这篇关于收到有效响应时反序列化错误(HRESULT:0x803d0000“输入数据不是预期格式或没有预期值”)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!