WCF - 自定义客户端请求/响应XML

时间:2011-02-25 17:57:59

标签: .net xml wcf

我正在尝试使用WCF客户端使用供应商提供的AXIS Web服务。该服务期望将请求/响应元素<TXLife>作为SOAP主体的根元素(没有包装它的操作元素)。我正在使用XmlSerializer,因为我的数据协定有一些自定义的ACORD模式特性。例如,服务器想要看到以下内容(...和是,“service”是操作的名称......):

...<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。在我看来,没有简单的方法来“装饰”我的方式围绕这个问题。

BTW:根据这个建议,我的服务合同,数据合同和代理客户都在不同的项目中,这对我来说非常可靠: blog post by Miguel Castro

UPDATE2:

我创建了使用MessageContract / MessageBodyMember标签修饰的Request / Response包装类。现在,XML按预期生成。仍然在响应中得到空对象......

UPDATE3:

我的响应中的“null”对象实际上存在于XML响应中,但没有被反序列化,因为序列化程序正在将它们作为限定对象进行查找。我将它们改为不合格,之后我的对象就显得很好了。

1 个答案:

答案 0 :(得分:3)

您是否尝试使用IsWrapped = false的MessageContract而不是使用[MessageParameter]?