调用SOAP Web服务序列化请求头报错:临时类生成失败与类型转换错误
关于SOAP调用OTA_HotelRoomListRQ服务的序列化错误排查
问题场景
尝试调用OTA_HotelRoomListRQ Web服务,编写的C#代码如下:
var OTA_HotelRoomListRQ = new MyMapping.OTA_HotelRoomListRQ() { TimeStamp = DateTime.Now, Version = 1, HotelRoomLists = new HotelRoomListType[] { new HotelRoomListType { HotelCode = "12345" } } }; MyMapping.OTA_HotelRoomListRS OTA_HotelRoomListRS = null; var test = MyMapping_PortTypeClient.ReadRoomTypes(securityHeaderType, ref MessageID, ref to, ref from, ref action, OTA_HotelRoomListRQ, out OTA_HotelRoomListRS);
错误信息
调用时抛出序列化错误:
There was an error in serializing one of the headers in message ReadRoomTypesRequest: 'Unable to generate a temporary class (result=1). error CS0030: Cannot convert type 'MySolution.ReadMapping.VendorMessageType[]' to 'MySolution.ReadMapping.VendorMessageType' error CS0030: Cannot convert type 'MySolution.ReadMapping.VendorMessageType[]' to 'MySolution.ReadMapping.VendorMessageType' error CS0029: Cannot implicitly convert type 'MySolution.ReadMapping.VendorMessageType' to 'MySolution.ReadMapping.VendorMessageType[]' error CS0029: Cannot implicitly convert type 'MySolution.ReadMapping.VendorMessageType' to 'MySolution.ReadMapping.VendorMessageType[]' '. Please see InnerException for more details.
原因分析
错误核心是**VendorMessageType数组类型和单个对象类型不匹配**,导致序列化时无法完成转换。这类问题通常源于WSDL生成服务代理类时的映射错误:
- WSDL中某个元素的基数定义(
minOccurs/maxOccurs)与生成的C#类型不匹配,比如WSDL标记为可重复的元素(maxOccurs="unbounded"),代理类却错误生成了单个对象类型;反之亦然。 - 错误发生在消息头序列化阶段,说明
securityHeaderType或其他传入的消息头参数中,存在VendorMessageType相关属性的类型赋值错误。
解决方案
重新生成服务代理类
删除当前的服务引用或代理类文件,重新通过WSDL生成代理。生成时可进入高级设置,调整序列化选项(优先选择System.Xml.Serialization序列化器),确保集合类型(数组/列表)的生成逻辑正确。手动修正代理类的类型映射
找到代理类中VendorMessageType相关的属性定义,对照WSDL的元素基数:- 若WSDL中该元素是可重复的(
maxOccurs="unbounded"),确保代理类中对应属性为VendorMessageType[]或List<VendorMessageType>; - 若WSDL中该元素是单个实例(
maxOccurs="1"),则属性应为单个VendorMessageType对象。
- 若WSDL中该元素是可重复的(
检查消息头的赋值逻辑
排查securityHeaderType等消息头参数的赋值代码,确认VendorMessageType相关属性的赋值类型与代理类定义一致:- 如果代理类属性是数组类型,需将单个对象包装为数组(如
new VendorMessageType[] { instance }); - 如果是单个对象类型,直接赋值单个实例即可,不能传入数组。
- 如果代理类属性是数组类型,需将单个对象包装为数组(如
内容的提问来源于stack exchange,提问作者Pine Code
相关产品推荐
相关产品推荐

