无法序列化接口:添加ISerializable后SoapClient实现报错
调用SAP Web Service的序列化冲突问题解决
问题背景
调用SAP的Z_WS_DELIVERY_DOC_GET_DETAIL Web Service时,误听建议给服务接口添加ISerializable接口,导致新错误:‘SoapClient’未实现接口成员‘ISerializable.GetObjectData’。此前调用其他Web Service无异常,且已给所有实体类添加[DataContract]特性,问题仍未解决。
相关代码
服务契约接口
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.3")] [System.ServiceModel.ServiceContractAttribute(Namespace="urn:sap-com:document:sap:rfc:functions", ConfigurationName="ServiceReference1.Z_WS_DELIVERY_DOC_GET_DETAIL")] public interface Z_WS_DELIVERY_DOC_GET_DETAIL { [System.ServiceModel.OperationContractAttribute(Action = "", ReplyAction = "*")] [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults = true)] System.Threading.Tasks.Task<ServiceReference1.Z_WS_DELIVERY_DOC_GET_DETAILResponse1> Z_WS_DELIVERY_DOC_GET_DETAILAsync(ServiceReference1.Z_WS_DELIVERY_DOC_GET_DETAILRequest request); }
已添加DataContract的实体类
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.3")] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:sap-com:document:sap:soap:functions:mc-style")] [DataContract] public partial class Z_WS_DELIVERY_DOC_GET_DETAIL1 { // .... }
解决步骤
移除接口的ISerializable继承
WCF的ServiceContract接口不需要实现ISerializable,这是针对.NET对象序列化的接口,和Web Service的契约序列化无关。直接去掉接口上的ISerializable声明,回到原始生成的代码状态。统一序列化配置
接口使用了XmlSerializerFormatAttribute指定用XmlSerializer序列化,但实体类添加了[DataContract](对应DataContractSerializer),两种序列化机制混用导致冲突:- 方案一:保留XmlSerializer。移除所有实体类的
[DataContract]和[DataMember]特性,保留原有的[XmlType]、[XmlElement]等Xml序列化特性。 - 方案二:切换到DataContractSerializer。将接口上的
XmlSerializerFormatAttribute替换为DataContractFormatAttribute,确保实体类的[DataContract]特性生效。
- 方案一:保留XmlSerializer。移除所有实体类的
重新生成服务引用
手动修改生成的代码容易引入错误,建议删除当前服务引用,重新生成:- 使用Svcutil工具时,若SAP服务要求XmlSerializer,添加参数
/serializer:XmlSerializer;默认使用DataContractSerializer,无需额外参数。 - 生成后不要随意修改自动生成的接口和客户端类。
- 使用Svcutil工具时,若SAP服务要求XmlSerializer,添加参数
恢复自动生成的客户端类
报错的SoapClient是自动生成的客户端实现,默认继承ClientBase<Z_WS_DELIVERY_DOC_GET_DETAIL>,不需要实现ISerializable。如果之前修改了它的继承关系,改回默认即可。
内容的提问来源于stack exchange,提问作者albert
相关产品推荐
相关产品推荐

