【发布时间】:2011-02-25 17:57:58
【问题描述】:
我正在尝试使用供应商提供的带有 WCF 客户端的 AXIS Web 服务。该服务期望将请求/响应元素 <TXLife> 作为 SOAP 主体的根元素(没有操作元素包装它)。我正在使用 XmlSerializer,因为我的数据合同有一些自定义 ACORD 架构特性。例如,服务器希望看到以下内容(...是的,“服务”是操作的名称...):
...<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><TXLife><TXLifeRequest xmlns="">...
我的客户正在生成 XML,操作序列化为包装元素,如下所示:
...<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><service xmlns="urn:example.servicecontract"><TXLife><TXLifeRequest xmlns="">...
使用“extra”标签指示请求中的操作,服务无法处理请求和错误。如果我删除 <service> 标记,Web 服务会愉快地处理请求。
不幸的是,该服务还以未包装的<TXLife> 标记作为根元素向下发送响应:
...<soapenv:Body><TXLife xmlns=""><TXLifeResponse>...
我的反序列化程序没有正确处理响应,我得到了一个 null 对象。我假设是因为我的客户期望一个服务操作响应包装器标签而没有得到一个。在反序列化级别,我没有从调试器那里得到太多帮助。
我正在考虑实现 IClientMessageFormatter 甚至 IClientMessageInspector 来修改请求/响应(例如,从请求消息中删除操作标记并在响应消息中添加响应标记)。我知道 Formatter 是作为 OperationalBehavior 注入的,但我不确定 MessageInspector 适合堆栈的位置。也许我会以错误的方式解决这个问题...... 任何见解或建议将不胜感激。原谅我,这是我第一次尝试 WCF 服务,我正在慢慢摸索。不幸的是,关于这项服务的一切似乎都是“定制的”。
我的服务合同:
[XmlSerializerFormat]
[ServiceContract(Namespace="urn:example.servicecontract")]
public interface IPayoutServiceContract
{
[OperationContract]
TXLife service([MessageParameter(Name = "TXLife")]TXLife request);
}
服务 WSDL 的一部分:
<wsdl:types><schema targetNamespace="urn:Tx103Service" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><import id="tx" namespace="http://ACORD.org/Standards/Life/2" schemaLocation="../acord/TXLife2.8.92.xsd" /></schema></wsdl:types><wsdl:message name="serviceRequest"><wsdl:part element="tx:TXLife" name="acordRequest" /></wsdl:message><wsdl:message name="serviceResponse"><wsdl:part element="tx:TXLife" name="acordResponse" /></wsdl:message><wsdl:portType name="LifeWebService"><wsdl:operation name="service"><wsdl:input message="impl:serviceRequest" name="serviceRequest" /><wsdl:output message="impl:serviceResponse" name="serviceResponse" /></wsdl:operation></wsdl:portType>
更新:
我首先尝试在代理类上使用MessageContract(isWrapped=false) 装饰器(接口不允许这样做)。那什么也没做。我还尝试了BodyStyle = WebMessageBodyStyle.Bare 的口味,也没有。我认为这是由于我正在使用的 XMLSerializer。在我看来,解决这个问题没有简单的方法来“装饰”我的方式。
顺便说一句:我的服务合同、数据合同和代理客户端都根据这个建议在不同的项目中,这对我来说听起来很可靠: blog post by Miguel Castro
更新2:
我创建了用 MessageContract/MessageBodyMember 标签装饰的请求/响应包装类。现在 XML 已按预期生成。仍然在响应中获取 null 对象...
更新3:
我的响应中的“null”对象实际上存在于 XML 响应中,但没有被反序列化,因为序列化程序正在寻找它们作为合格的对象。我将它们更改为不合格,之后我的对象就正常显示了。
【问题讨论】: