可以说服通用类型映射器(MSSOAP工具包)来处理空数组

时间:2008-10-06 14:31:39

标签: vba soap

我遇到了这里描述的问题:

http://groups.google.com/group/microsoft.public.xml.soap/browse_thread/thread/029ee5b5d4fa2440/0895d73c5c3720a1

我正在使用Web Service消费Office 2003 Web Services Toolkit。这会为我的Web服务返回的所有数据生成类:其中一个类的属性是一个可能为空的数组。

当我调用Web服务时,Generic Type Mapper会引发错误:

array dimensions do not match definition

有没有人知道这个问题的解决方案,它允许我继续使用生成的类(我知道我可以只使用原始XML)?

1 个答案:

答案 0 :(得分:0)

由于没有参与者,我将描述我迄今为止所做的事情,以防其他人遇到类似问题。

在我的客户端上(使用Office 2003 Web Services Toolkit)我希望收到一个对象集合,这些对象的属性本身就是对象的集合。例如,来自C#Web服务的Customer对象集合,其中Customer类看起来像:

public class Customer
{
    public string Name { get; set; }

    public Collection<Address> Addresses { get; }
}

我遇到的问题是Addresses属性有时可能是一个空集合,而SOAP30 GenericTypeMapper无法处理它。

在我的具体情况下,客户端实际上并不需要地址集合,我只是希望能够获得Customer类的其他属性。所以我并不关心Web Services Toolkit创建的“Addresses”变体属性中的内容。

我所做的是创建一个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 Services Toolkit生成的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支持。