多个WCF服务引用相同的数据契约

19

我正在构建一组WCF服务,它们共享公共数据合同(或实体,如果您喜欢这样称呼)。这些是带有DataContract和DataMember属性的简单数据传输对象。我明确指定名称和命名空间。为了遵循IDesign建议的每个服务契约平均12个成员的原则,我将我的服务项目拆分为多个服务。

我的数据合同位于一个单独的程序集中,如果客户端使用.Net,则可以提供给他们。他们可以告诉他们的服务引用在引用的程序集中重用类型。但是如果他们没有使用.Net,并且他们使用了两个使用相同实体的服务,那么我认为他们会收到模棱两可的引用消息。如果我不引用数据合同dll,在Visual Studio中可以看到这一点。

我的问题是,我的服务是否有什么可以做的,或者客户端应用程序可以做些什么来避免不得不限定数据合同来自哪个代理的限制?


我遇到了同样的问题。我尝试使用下面文章中的建议,但是没有成功。然而,我正在使用WCF RESTful服务(这可能与下面的方法不起作用有关),所以我最终只是引用了一个包含我的数据契约的公共DLL,并且完全放弃了服务引用。由于我使用简单的HTTP Web请求调用我的服务,因此实际上不需要在项目中使用服务引用。 - Nick
6个回答

11

2

我也倾向于将所有的数据契约保存在一个程序集中,然后让多个服务和客户端应用程序引用它。这种方式非常有效,但我从未尝试在 .NET 之外使用这个服务。

了解他们在除了 .NET 以外使用什么技术来消费服务可能会有所帮助。是什么导致了歧义引用消息呢?


你可以在.NET中完成它,只需不引用数据契约DLL并观察结果。创建一个测试项目,添加两个使用共同数据契约作为引用的服务,你将会得到模糊的消息。 - Paul Speranza

0

我恰好有多个在我的端口共享对象的服务。我不确定您为什么会遇到这个问题。在我的情况下,我可以通过以下方式访问这些对象。

SERVICE1客户端 = new SERVICE1()

客户端.CommonLibrary.Address. . .

SERVICE2客户端2 = newSERVICE2()

客户端2.CommonLibrary.Address. . . .


这对我也适用。关键是它们是两个不同的对象。消费应用程序不能只说CommonLibrary.Address,它必须用服务名称限定。这并不是真正的问题,我只是想知道服务引用是否会检测到共享相同命名空间的公共数据契约。 - Paul Speranza

0

0

根据我的理解和使用WCF,只要客户端应用程序使用的数据契约之一具有相同的完全限定名称并且具有相同的数据成员,则任何一个数据契约都不会有影响。在内部,它只是动态创建对象并使用公共setter重新分配这些数据成员属性。

我认为更好的方法是重构您的数据契约,以便将所有跨多个服务的公共内容放入一个程序集中,并引用它们,因此无论客户端应用程序使用多少个服务,都不会出现歧义或冲突问题。


Fadrian,我的所有数据契约都在一个程序集中。问题是如果两个服务引用相同的数据契约,则每个服务都会获得其自己的命名空间版本。 - Paul Speranza
Paul,你尝试在DataContract属性中明确指定命名空间了吗?你是如何创建数据契约程序集的?你尝试使用svcutil工具并手动生成带有/namespace参数的数据控件了吗?我个人没有遇到过这个问题,所以可能不是很确定,只是在这里分享一些想法。 - Fadrian Sudaman

0
我们不通过Visual Studio助手生成服务代理,而是通过调用slsvcutil.exe的自定义批处理文件来生成(因为我们使用Silverlight)。在那里,您可以使用/n参数指定命名空间映射,例如:
"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v5.0\tools\slsvcutil.exe "^
 http://ServiceUrl/MyService.svc^
 **/n:http://youruri.org/CustomerService/DataContracts,CLR.Namespace.CustomerService^**
 /n:*,CLR.Namepsace.MyService^
 /r:"%ProgramFilesFolder%\Reference Assemblies\Microsoft\Framework\Silverlight\v5.0\System.Windows.dll"^
 /ct:System.Collections.ObjectModel.ObservableCollection`1^
 /edb^

因此,所有具有命名空间http://youruri.org/CustomerService/DataContracts的数据契约都会在代理文件中生成到clr命名空间CLR.Namespace.CustomerService中。假设您已经提前在同一代理程序集中生成了此代理,您可以将整个命名空间从第二个文件中剪切掉,一切都能正常工作 - 我们为最后一步编写了一个小工具。所有其他契约命名空间都将生成到CLR.Namepsace.MyService namspace(请参见星号表示捕获所有内容)

这个过程有些麻烦,因为您必须手工制作批处理文件,但一旦完成,它就可以很好地工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接