Azure APIM导入含SOAP编码数组类型的WSDL失败及修改咨询
问题场景
尝试通过WSDL在Azure APIM中创建API时,导入步骤触发解析错误,提示soapenc:Array类型未定义,且该类型被用作复杂类型限制的基类。已知该Array类型不符合WSI标准,无法直接被APIM解析。由于不拥有后端服务,但服务方允许修改WSDL以完成导入,需调整WSDL的同时保证APIM代理转发请求正常运行。
错误提示
Error: Parsing error : Line 17, position 22: Unable to import API from WSDL: Undefined
complexType 'http://schemas.xmlsoap.org/soap/encoding/:Array' is used as a base for
complex type restriction.
精简后的目标WSDL代码
<?xml version="1.0"?> <definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s0="urn:ChestersCopperpotsServiceSoap" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:atls="http://tempuri.org/vc/atl/server/" targetNamespace="urn:ChestersCopperpotsServiceSoap" xmlns="http://schemas.xmlsoap.org/wsdl/" > <types> <s:schema targetNamespace="urn:ChestersCopperpotsServiceSoap" attributeFormDefault="qualified" elementFormDefault="qualified"> <s:import namespace="http://schemas.xmlsoap.org/soap/encoding/"/> <s:complexType name="CMessage"> <s:sequence> <s:element name="Code" type="s:int"/> <s:element name="Text" type="s:string"/> </s:sequence> </s:complexType> <s:complexType name="GetMessages_return_Array"> <s:complexContent> <s:restriction base="soapenc:Array"> <s:attribute ref="soapenc:arrayType" wsdl:arrayType="s0:CMessage[]"/> </s:restriction> </s:complexContent> </s:complexType> <s:complexType name="MyHeader"> <s:sequence> <s:element name="m_SessionID" type="s:string"/> </s:sequence> </s:complexType> </s:schema> </types> <message name="GetMessagesIn"> </message> <message name="GetMessagesOut"> <part name="return" type="s0:GetMessages_return_Array"/> </message> <message name="m_Header"> <part name="m_Header" type="s0:MyHeader"/> </message> <portType name="ChestersCopperpotsServiceSoap"> <operation name="GetMessages"> <input message="s0:GetMessagesIn"/> <output message="s0:GetMessagesOut"/> </operation> </portType> <binding name="ChestersCopperpotsServiceSoap" type="s0:ChestersCopperpotsServiceSoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/> <operation name="GetMessages"> <soap:operation soapAction="#GetMessages" style="rpc"/> <input> <soap:body use="encoded" namespace="urn:ChestersCopperpotsService" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> <soap:header message="s0:m_Header" part="m_Header" use="encoded" namespace="urn:ChestersCopperpotsService" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </input> <output> <soap:body use="encoded" namespace="urn:ChestersCopperpotsService" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> <soap:header message="s0:m_Header" part="m_Header" use="encoded" namespace="urn:ChestersCopperpotsService" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation> </binding> <service name="ChestersCopperpotsService"> <port name="ChestersCopperpotsServiceSoap" binding="s0:ChestersCopperpotsServiceSoap"> <soap:address location="http://localhost:80/ChestersCopperpots/ccSOAP.dll?Handler=Default"/> </port> </service> </definitions>
Azure APIM完整错误栈
Informational: ParsingXMLStarted : Started parsing XML Informational: ParsingXMLComplete : Completed parsing XML Verbose: WsdlImportRuleVerifyWadl11Schema : WSDL validated against XML Schema Informational: WsdlPrecheckComplete : Completed WSDL verification. WSDL is considered valid. Informational: WsdlParsingStarted : Service : Endpoint : Informational: WsdlIdentification : WsdlVersion: 'Wsdl11' TargetNamespace: 'urn:ChestersCopperpotsServiceSoap'. Informational: LoadedSchema : Target Namespace: 'urn:ChestersCopperpotsServiceSoap'. Informational: LoadedSchemas : Loaded '1' schemas. Informational: LoadedTypes : Loaded '0' types. Informational: LoadedMessages : Loaded '3' messages. Informational: LoadedInterfaces : Loaded '1' interfaces. Informational: LoadedBindings : Loaded '1' bindings. Informational: LoadedServices : Loaded '1' services. Informational: WsdlParsingComplete : Parsed 1 operations and 3 messages Informational: ApiType : Creating SOAP Passthrough API Informational: APICreated : Name : chesterscopperpotsservice Service Url: http://localhost:80/ChestersCopperpots/ccSOAP.dll?Handler=Default Informational: XsdParsing : Starting to parse urn:ChestersCopperpotsServiceSoap Error: Parsing error : Line 17, position 22: Unable to import API from WSDL: Undefined complexType 'http://schemas.xmlsoap.org/soap/encoding/:Array' is used as a base for complex type restriction.
修改方案
核心问题
Azure APIM无法识别SOAP编码规范中的soapenc:Array类型,该类型不属于WSI标准,且APIM解析器默认不加载对应的SOAP编码Schema定义。
具体修改步骤
1. 替换soapenc:Array的限制定义
将基于soapenc:Array的限制类型,改为使用标准XML Schema的序列数组定义,同时保留原类型名称以兼容现有消息结构:
<!-- 替换原GetMessages_return_Array定义 --> <s:complexType name="GetMessages_return_Array"> <s:sequence> <s:element name="item" type="s0:CMessage" minOccurs="0" maxOccurs="unbounded"/> </s:sequence> </s:complexType>
2. 兼容SOAP编码属性(可选)
如果后端服务严格依赖SOAP编码的arrayType属性,可在修改后的类型中添加该属性声明,确保运行时请求转发时属性存在:
<s:complexType name="GetMessages_return_Array"> <s:sequence> <s:element name="item" type="s0:CMessage" minOccurs="0" maxOccurs="unbounded"/> </s:sequence> <s:attribute ref="soapenc:arrayType" wsdl:arrayType="s0:CMessage[]"/> </s:complexType>
3. 导入SOAP编码Schema(备选方案)
若上述修改仍有问题,可在<s:schema>标签中添加SOAP编码Schema的具体引用,确保APIM能加载到Array类型定义:
<s:import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/"/>
注意:部分环境可能无法外部加载Schema,优先推荐第一种修改方式。
验证标准
修改后的WSDL需满足两个条件:
- 能成功导入Azure APIM,无解析错误
- 运行时APIM转发的请求/响应结构与原WSDL定义兼容,后端服务能正常处理
内容的提问来源于stack exchange,提问作者Matt Felzani

