2016-06-21 106 views
1

我正面临着WCF和命名空间的一些问题。情况是这样的:我的webservice(我们称之为“WS-A”)应该作为另一个(更复杂的)web服务(“WS-B”)的代理。 WS-A为我们开发的应用程序公开了更简单的接口,因此它简单地“隐藏”了一些我们不想在我们的应用程序中结束的业务逻辑。我们获得了WS-B的WSDL和XSD模式,并使用svcutil将它们导入到C#中。显然它继承了WS-B的命名空间(http://ws.source.com)。对于WS-A,我们使用一些其他名称空间(http://ws.example.com)。一些数据结构必须在两个Web服务之间共享,但我无法重用相同的数据合同。 AFAIK WCF要求数据和服务合约的名称空间是“静态的”,并且不能在运行时决定。有没有办法与WCF做到这一点,或者我应该改变我的策略?在不同命名空间中共享数据合同

编辑:这里是一个例子,试图澄清我需要什么。

 
            Namespace A  V  Namespace B 
           +--------------+ | +--------------+ 
           |    | | |    | 
      Application >-------+ Webservice A +-------+ Webservice B | 
           |    | | |    | 
           +--------------+ | +--------------+ 

应用程序调用WS-A的操作“GiveMeData”,该操作使用名称空间A,如其WSDL中所述。响应所包含的类别“数据”,这实际上是使用命名空间B.

[DataContract(Namespace="http://namespaceB")] 
public class Data { 
...  
} 

所以响应将数据绑定到错误的命名空间从WS-B中得到的数据结构的引用。

+0

您是否考虑将共享数据合同移动到可以在服务之间共享的独立程序集中?您可以在代码中设置命名空间 - 例如'[DataContract(Namespace =“http://some.namespace.com/”)''。 – Tim

+0

问题是共享XSD命名空间而不是程序集命名空间之间的数据契约。我有一个对象,我想从/到/两个名称空间的序列化。 –

+0

如果我正确理解你的问题,我会改变这种策略。您可能会从不紧密耦合的数据合同中受益。 (当你每次签订合同B时都想改变合同A?) 我会使用单独的名称空间,但可能会通过继承通用接口或类似工具来在WCF之外共享数据合同。 – Guran

回答

2

所以你想减少系统中重复代码的数量,以及可能跳过一些似乎毫无意义的对象深层复制操作?

对问题的评论表明这是一个坏主意,我同意。无论您或后端Web服务是否需要更改合同(即使只是一点点),无论如何您都无法或将最终收到两个数据联系人类。

相反,即使结构相同,也应该保留两个POCO类定义,并用类似http://automapper.org的方式管理克隆/复制过程。这样,您可以利用映射器中的一些转换缓存,并保持代码清洁。

如果您坚持在代理服务的两端使用相同的POCO,您可能只想使用后端POCO进行编码。但是,在序列化响应之后(在进入线程之前)以及在反序列化请求之前(在它变成POCO之前),您需要在WCF管道中操作消息。前者有点破解,您可以考虑它就像使用正则表达式替换名称空间中的响应来重新编写信息一样,当你控制序列化的响应流时,这不是太难,但是你不控制发送到你的代理服务的东西,所以正则表达式来处理请求将会成比例地变得更加复杂,并且很容易出错。看看这个WCF自定义消息编码器的例子:https://social.msdn.microsoft.com/Forums/en-US/0da33309-ec07-47d6-8ddb-15290a80977f/wcf-hook-in-after-serialization?forum=wcf

该答案的作者有一些关于这个主题的其他博客文章,有不同的方法。 ,完成你的愿望的代码变得非常奇怪,真的很快。

+0

我对数据合同变化不大:我相当有信心:如果这些变化不是向后兼容的话,它们会打破数百个政府电子支付系统的客户。但是如果他们破坏了某些东西(我们都知道政府的系统是天生的),我*必须*尽快更新我的代码,以避免重复的代码/类将帮助我实现可维护性(DRY原则)。 这就是说,我也同意重复的POCO是我得到的最好的选择,automapper实际上是一个非常好的工具,可以帮助我的代码保持整洁,所以谢谢。 ;) –