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


我有多个共享一些数据协定的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 );
}

响应和请求在单独的程序集中定义:

[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

但是,共享类型(例如请求和响应)的定义将在Foo.cs中重复,然后在Bar.cs中重复,从而导致编译器错误。

所以, 什么是生成消费此类服务的客户端代码的传统方法

限制:

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

2330
2018-01-26 17:21


起源



答案:


好吧,基本上你可以

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

或者:

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

不管你 能够 分享共同集会 - 或者你 不能  - 我真的没有看到任何其他选择。


5
2018-01-26 17:26



但这不是一种或两种情况。通过在命令行上为svcutil指定多个端点,您可以生成一组输出文件,这些文件可以跨多个服务重用DTO。无需从服务端重用程序集,也不需要每个服务都拥有相同对象的自己副本。 - Bevan


答案:


好吧,基本上你可以

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

或者:

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

不管你 能够 分享共同集会 - 或者你 不能  - 我真的没有看到任何其他选择。


5
2018-01-26 17:26



但这不是一种或两种情况。通过在命令行上为svcutil指定多个端点,您可以生成一组输出文件,这些文件可以跨多个服务重用DTO。无需从服务端重用程序集,也不需要每个服务都拥有相同对象的自己副本。 - Bevan


既然你有一个共享DTO程序集的规则(为什么,顺便说一下?),在这种情况下最简单的选项 容貌 要在不同的C#名称空间中生成类型(即两次调用 svcutil),并在两者之间映射数据。基本上:将这两种服务中的DTO视为巧合相似。

您可以使用诸如automapper之类的东西来减少工作,或者您可以从类型A开始序列化并反序列化为类型B(假设实际 数据 名称空间等是相同的)。


4
2018-01-26 17:26



服务器和客户端位于不同的组织中。因此,我必须联系每个客户端并向他们提供DLL或将其转换为可下载或开源产品。在任何情况下,与开发人员只选择正确的命令行选项组合相比,这将涉及更多人并且是一个更加困难和昂贵的决策。 - azheglov


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

http://wscfblue.codeplex.com/

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


2
2017-08-05 11:58





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

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

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

我不确定这是否可以回答你的问题。我有 一个例子 哪个可以帮到你。 你可以看到更多的例子 这里 与一些MVC和WCF相关的东西。


0
2018-01-26 17:40





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

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


0
2018-02-28 00:55