C# SOAP代理调用WebService createAccount接口返回null问题
问题成因
返回值始终为null的核心原因是SOAP序列化格式不匹配:
- 你当前代理类方法上标记的
SoapDocumentMethod特性,会让.NET使用*文档/文字(Doc/Literal)规则做XML反序列化,但服务端实际返回的是RPC/编码(RPC/Encoded)*格式的响应:响应根节点明确带了SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"属性,内部还存在SOAP-ENC:Struct这类SOAP编码专属的类型标记。Doc/Literal序列化器无法识别这种编码格式的节点结构,反序列化时会直接跳过返回内容,也不会抛出显式异常,最终拿到的返回值就是null。 - 你之前调整命名空间、修改
SoapDocumentMethod参数的操作,都没有改变序列化的核心模式,所以无法解决问题。另外响应中xsi:type="CreateAccountSuccess"没有携带服务的目标命名空间,也会加剧类型匹配失败的问题。
修复步骤
- 替换方法的序列化特性
把createAccount方法上的SoapDocumentMethod替换为SoapRpcMethod,原有Action、请求/响应命名空间参数保持不变即可。SoapRpcMethod是.NET专门为适配RPC/Encoded格式SOAP接口提供的特性,修改后的方法代码如下:/// <remarks/> [System.Web.Services.Protocols.SoapRpcMethod("https://ocs-api-v2-3-sandbox.outbox.de/account#createAccount", RequestNamespace= "https://ocs-api-v2-3-sandbox.outbox.de/account", ResponseNamespace="https://ocs-api-v2-3-sandbox.outbox.de/account")] [return: System.Xml.Serialization.SoapElementAttribute("return")] public CreateAccountSuccess createAccount(string transactionId, Person person, Address address, bool checkHousenumberAdditive, string resellerId, Contract contract) { object[] results = this.Invoke("createAccount", new object[] { transactionId, person, address, checkHousenumberAdditive, resellerId, contract}); return ((CreateAccountSuccess)(results[0])); } - 补全实体类的类型标记
给CreateAccountSuccess、Person、Address、Contract以及emergencycoding对应的所有自定义实体类,添加[System.Xml.Serialization.SoapType(Namespace = "https://ocs-api-v2-3-sandbox.outbox.de/account")]特性,确保序列化器可以正确匹配响应中的类型,不受节点上xsi:type命名空间缺失的影响。 - 固定代理的SOAP版本
在代理类的构造函数中添加如下配置,强制使用SOAP1.1协议通信,避免版本协商带来的解析问题:this.SoapVersion = System.Web.Services.Protocols.SoapProtocolVersion.Soap11;
注意:不要在修改Reference.cs后执行“更新Web引用”操作,自动生成逻辑会覆盖你所有的手动修改。可以把生成好的代理类代码复制到项目内的自定义代码文件中维护,避免被覆盖。
内容的提问来源于stack exchange,提问作者cddimari
相关产品推荐
相关产品推荐

