我遇到了这里描述的问题:
我正在使用Web Service
using Office 2003 Web Services Toolkit
。这会为我的 Web 服务返回的所有数据生成类:其中一个类的属性是一个可能为空的数组。
当我调用 Web 服务时,通用类型映射器会引发错误:
array dimensions do not match definition
有谁知道这个问题的解决方案,可以让我继续使用生成的类(我知道我可以只使用原始 XML)?
我遇到了这里描述的问题:
我正在使用Web Service
using Office 2003 Web Services Toolkit
。这会为我的 Web 服务返回的所有数据生成类:其中一个类的属性是一个可能为空的数组。
当我调用 Web 服务时,通用类型映射器会引发错误:
array dimensions do not match definition
有谁知道这个问题的解决方案,可以让我继续使用生成的类(我知道我可以只使用原始 XML)?
由于没有接受者,我将描述我迄今为止所做的事情,以防其他人遇到类似问题。
在我的客户端(使用 Office 2003 Web 服务工具包)上,我想接收一个对象集合,这些对象的属性本身就是对象集合。例如,来自 C# Web 服务的 Customer 对象的集合,其中 Customer 类如下所示:
public class Customer
{
public string Name { get; set; }
public Collection<Address> Addresses { get; }
}
我遇到的问题是 Addresses 属性有时可能是一个空集合,而 SOAP30 GenericTypeMapper 无法处理这个问题。
在我的具体情况下,客户端实际上并不需要地址集合,我只是希望能够获取 Customer 类的其他属性。因此,我并不真正关心由 Web 服务工具包创建的“地址”变体属性中的内容。
我所做的是创建一个 VB6 ActiveX DLL,其中包含一个具有 ISoapMapper 的极简实现的类,该类始终返回一个未初始化的对象引用:
Implements ISoapTypeMapper
Private Function ISoapTypeMapper_Iid() As String
End Function
Private Sub ISoapTypeMapper_Init(ByVal par_Factory As MSOSOAPLib30.ISoapTypeMapperFactory, ByVal par_Schema As MSXML2.IXMLDOMNode, ByVal par_WSMLNode As MSXML2.IXMLDOMNode, ByVal par_xsdType As MSOSOAPLib30.enXSDType)
End Sub
Private Function ISoapTypeMapper_Read(ByVal par_soapreader As MSOSOAPLib30.ISoapReader, ByVal par_Node As MSXML2.IXMLDOMNode, ByVal par_encoding As String, ByVal par_encodingMode As MSOSOAPLib30.enEncodingStyle, ByVal par_flags As Long) As Variant
Set ISoapTypeMapper_Read = Nothing
End Function
Private Function ISoapTypeMapper_SchemaNode() As MSXML2.IXMLDOMNode
Set ISoapTypeMapper_SchemaNode = Nothing
End Function
Private Function ISoapTypeMapper_VarType() As Long
ISoapTypeMapper_VarType = vbObject
End Function
Private Sub ISoapTypeMapper_Write(ByVal par_ISoapSerializer As MSOSOAPLib30.ISoapSerializer, ByVal par_encoding As String, ByVal par_encodingMode As MSOSOAPLib30.enEncodingStyle, ByVal par_flags As Long, par_var As Variant)
End Sub
Private Function ISoapTypeMapper_XsdType() As MSOSOAPLib30.enXSDType
ISoapTypeMapper_XsdType = enXSDUndefined
End Function
然后我修改了由 Web 服务工具包生成的 WSML,以将此实现用于适当的属性:
Dim str_WSML As String
str_WSML = "<servicemapping>"
str_WSML = str_WSML & "<service name='MyService'>"
str_WSML = str_WSML & "<using PROGID='MSOSOAP.GenericCustomTypeMapper30' cachable='0' ID='GCTM'/>"
str_WSML = str_WSML & "<using PROGID='SoapHelper.EmptyArrayMapper' cachable='0' ID='EATM'/>" ' <== Added this line
str_WSML = str_WSML & "<types>"
...
str_WSML = str_WSML & "<type name='ArrayOfAddress' targetNamespace='http://...' uses='EATM' targetClassName='struct_Address'/>" '<== Added this line
str_WSML = str_WSML & "<type name='Address' targetNamespace='http://mynamespace.com/myapp/services/data' uses='GCTM' targetClassName='struct_Address'/>"
...
这实现了我需要的这个应用程序。
在我看来,可以通过以下方式实现 ISoapMapper 来更普遍地实现对空数组的支持:
它检测并处理空数组的情况。
或者,如果数组不是空的,它会委托给标准的 GenericTypeMapper。
我仍然很想知道是否有人解决了一般问题。可能不是因为 SOAP 客户端已过时且 Microsoft 不再支持。