我正在努力从 webservice/webclient 架构迁移到 WCF 架构。该对象非常复杂,有很多嵌套的 xsd 和不同的命名空间。通过将 Web 引用添加到具有 30 多个 Web 方法的原始 wsdl 并使用 xsd.exe 生成缺少的 SOAPFault 对象来生成代理类。我的试点 WCF 服务仅包含 1 个与原始方法之一的确切语法匹配的 web 方法:1 个对象作为参数,返回 1 个其他对象作为结果值。我使用这些代理类创建了一个 WCF 接口,使用属性:XMLSerializerFormat
并ServiceContract
在接口OperationContract
上,使用原始 wsdl 指定的一种方法Action
,ReplyAction
,都具有适当的命名空间。我使用 SoapUI 创建传入的客户端消息;我从原始 WSDL 文件生成了一个项目(导致 SoapUI 项目有 30 多个方法),并在一个实现的 WebMethod 上创建了一个新请求,将 URL 更改为我的 wcf Web 服务并发送消息。由于 中指定的 (Reply-)Action OperationContractAttribute
,消息实际上被接收并正确反序列化为对象。
为了做到这一点(40 小时的谷歌搜索),很多挫折使我使用了一个自定义端点,在该端点中删除了 WCF“包装标签”,更正了嵌套类型的命名空间,并且生成的 wsdl 得到了展平(为了更好与其他工具的兼容性,然后是 MS VisualStudio)。
接口代码是这样的:
[XmlSerializerFormat(Use = OperationFormatUse.Literal, Style = OperationFormatStyle.Document, SupportFaults = true)]
[ServiceContract(Namespace = Constants.NamespaceStufZKN)]
public interface IOntvangAsynchroon
{
[OperationContract(Action = Constants.NamespaceStufZKN + "/zakLk01", ReplyAction = Constants.NamespaceStufZKN + "/zakLk01", Name = "zakLk01")]
[FaultContract(typeof(Fo03Bericht), Namespace = Constants.NamespaceStuf)]
Bv03Bericht zakLk01([XmlElement("zakLk01", Namespace = Constants.NamespaceStufZKN)] ZAKLk01 zakLk011);
当我在代码中使用 Web 客户端发送消息时,一切正常。我的问题是,当我使用 WCF 客户端时。我ChannelFactory<IOntvangAsynchroon>
用来发信息。但是生成的 xml 看起来不同:它包含方法的参数名!我花了很多时间来解决这个问题,但这是发生的事情:
正确的 xml(剥离的肥皂信封):
<soap:Body>
<zakLk01 xmlns="http://www.egem.nl/StUF/sector/zkn/0310">
<stuurgegevens>
<berichtcode xmlns="http://www.egem.nl/StUF/StUF0301">Bv01</berichtcode>
<zender xmlns="http://www.egem.nl/StUF/StUF0301">
<applicatie>ONBEKEND</applicatie>
</zender>
</stuurgegevens>
<parameters>
</parameters>
</zakLk01>
</soap:Body>
错误的xml:
<soap:Body>
<zakLk01 xmlns="http://www.egem.nl/StUF/sector/zkn/0310">
<zakLk011>
<stuurgegevens>
<berichtcode xmlns="http://www.egem.nl/StUF/StUF0301">Bv01</berichtcode>
<zender xmlns="http://www.egem.nl/StUF/StUF0301">
<applicatie>ONBEKEND</applicatie>
</zender>
</stuurgegevens>
<parameters>
</parameters>
</zakLk011>
</zakLk01>
</soap:Body>
注意zakLk011
元素?它是我界面中方法的参数名称!所以现在是zakLk011
,但是当我的参数名称是时zakLk01
,xml 似乎包含上面标记的一些神奇副本,但没有命名空间。当然,你可以想象我在发现它是参数名之前对发生的事情发疯了!
我现在实际上已经创建了一个 WCF 服务,我无法再使用 WCF 客户端发送消息。为清楚起见:该方法确实在我的 Web 服务上使用 WCF 客户端调用,但参数对象为空。因为我使用自定义端点来记录传入的 xml,所以我可以看到消息接收良好,但语法错误!
WCF 客户端代码:
ZAKLk01 stufbericht = MessageFactory.CreateZAKLk01();
ChannelFactory<IOntvangAsynchroon> factory = new ChannelFactory<IOntvangAsynchroon>(new BasicHttpBinding(), new EndpointAddress("http://localhost:8193/Roxit/Link/zkn0310"));
factory.Endpoint.Behaviors.Add(new LinkEndpointBehavior());
IOntvangAsynchroon client = factory.CreateChannel();
client.zakLk01(stufbericht);
我没有使用生成的客户端,我只是像以前那样引用 Web 服务(共享库)。
编辑:生成服务参考时,它会生成重复的类(不知道为什么..)。但是,当删除这些重复项时,客户端会使用正确的 xml 发送消息。但是我的架构需要共享库,所以这对我没有帮助。
谁能帮帮我吗?我无法在此搜索任何内容...