我遇到了这里描述的问题:
我正在使用Web Service
消费Office 2003 Web Services Toolkit
。这会为我的Web服务返回的所有数据生成类:其中一个类的属性是一个可能为空的数组。
当我调用Web服务时,Generic Type Mapper会引发错误:
array dimensions do not match definition
有没有人知道这个问题的解决方案,它允许我继续使用生成的类(我知道我可以只使用原始XML)?
答案 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支持。