如何为具有共享类型的多个 WCF 服务生成客户端代码

Posted

技术标签:

【中文标题】如何为具有共享类型的多个 WCF 服务生成客户端代码【英文标题】:How to generate client-side code for multiple WCF services with shared types 【发布时间】:2011-01-09 14:48:22 【问题描述】:

我有多个共享一些数据协定的 WCF 服务,并且需要使用 svcutil.exe 生成客户端代码。我在使用两种最明显的方法时遇到了错误,需要一些帮助。

但首先,这里是服务:

[ServiceContract( Namespace = "http://www.me.com/services/" )]
public interface IFooService 
    [OperationContract]
    Response RunFoo( Request request );

[ServiceContract( Namespace = "http://www.me.com/services/" )]
public interface IBarService 
    [OperationContract]
    Response RunBar( Request request );

Response 和 Request 在单独的程序集中定义:

[DataContract( Namespace = "http://www.me.com/shared/" )]
public class Request 
    [DataMember]
    public int Input  get; set; 

[DataContract( Namespace = "http://www.me.com/shared/" )]
public class Response 
    [DataMember]
    public int Result  get; set; 

服务以某种简单的方式实现、编译、发布 - 现在让我们切换到客户端。

在 svcutil 命令行中包含这两个服务 - 像这样:

svcutil /o:Client.cs http://hostname.com/FooService.svc http://hostname.com/BarService.svc

将导致大量关于重复数据类型的错误消息,以

开头

错误:导出期间生成的架构出现验证错误: 资源: 行:1 列:9087 验证错误:已声明全局元素“http://schemas.microsoft.com/2003/10/Serialization/:anyType”。

结尾

错误:导出期间生成的架构出现验证错误: 资源: 行:1 列:12817 验证错误:complexType 'http://www.me.com/shared/:Response' 已被声明。

为每个服务单独生成一个客户端文件可以避免这些错误:

svcutil /o:Foo.cs http://hostname.com/FooService.svc
svcutil /o:Bar.cs http://hostname.com/BarService.svc

但是共享类型(如Request和Response)的定义会在Foo.cs中重复,然后在Bar.cs中,显然会导致编译器错误。

那么,生成使用此类服务​​的客户端代码的常规方法是什么

限制:

无法向客户端发送包含共享类型的程序集(以便他们可以使用 svcutil.exe 的 /r 选项) 无法在 Visual Studio 中使用“添加服务引用...”命令 - 需要 svcutil 命令行(或其他命令行工具)。

【问题讨论】:

【参考方案1】:

嗯,基本上你可以

或者将您的共享类型放入一个单独的程序集中,供客户端在生成客户端代码时使用(您已经将其视为不可能)

然后:

您必须分别为服务生成每个代理,每个服务将获得自己的“请求”和“响应”类的“副本”

可以共享通用程序集 - 或者您不能 - 我真的没有其他选择。

【讨论】:

但这不是非此即彼的情况。通过在命令行上为 svcutil 指定多个端点,您可以生成一组输出文件,这些文件在多个服务中重用 DTO。无需从服务端重用程序集,也无需每个服务拥有自己的相同对象的副本。【参考方案2】:

由于您排除了共享 DTO 程序集(为什么,顺便说一句?),在这种情况下,看起来最简单的选择是在不同的 C# 命名空间中生成类型(即两次调用 @987654321 @),并在两者之间映射数据。本质上:将来自两个服务的 DTO 视为巧合相似。

您可以使用自动映射器之类的东西来减少工作,或者您可以从类型 A 序列化并反序列化为类型 B(假设实际的 data 命名空间等是相同的)。

【讨论】:

服务器和客户端在不同的组织中。因此,我必须联系每个客户并为他们提供 DLL,或者将其转换为可下载或开源的产品。无论如何,与开发人员简单地选择正确的命令行选项组合相比,这将涉及更多的人,并且是一个更加困难和昂贵的决定。【参考方案3】:

如果您还没有找到解决方案,WSCF Blue 可能会让您更接近解决方案。

http://wscfblue.codeplex.com/

它可以为每种类型生成单独的文件,覆盖后续操作。

【讨论】:

【参考方案4】:

当您运行客户端实用程序后,您将获得一个 XXXXService.cs 和一个 output.config 文件。

如果您观察 XXXXService 类,您将所有内容都放在一个文件中。您可以将它们拆分为单独的 IXXXService 和 XXXService 文件以及 datacontracts 文件。

然后您可以为第二个服务运行该实用程序并添加 IXXXService1.cs 和 1XXXService.cs 文件以及可用于共享这两个服务的相同数据合约。

我不确定这是否可以回答您的问题。我有 an example 可以帮助你。 您可以看到更多与 MVC 和 WCF 相关的示例 here。

【讨论】:

【参考方案5】:

请从以下链接下载 WSCFblue-v1-Walkthrough zip,它可能会帮助您实现它。

http://wscfblue.codeplex.com/releases/view/48529

【讨论】:

以上是关于如何为具有共享类型的多个 WCF 服务生成客户端代码的主要内容,如果未能解决你的问题,请参考以下文章

从服务参考共享类型/模型到客户端

在 WCF 服务及其 .net 客户端之间共享类型

WCF 服务代理中伪装的类型?

如何为 WCF REST API 生成提到的 json 格式

如何为 Azure Blob 存储中的文件夹生成共享访问签名?

RPA如何为财务共享中心(FSSC)带来新的赋能