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

时间:2010-01-26 17:21:09

标签: c# wcf web-services proxy svcutil.exe

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

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

那么,生成消费此类服务的客户端代码的常规方法是什么?

限制:

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

5 个答案:

答案 0 :(得分:5)

嗯,基本上你可以

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

或者然后:

  • 您必须单独为服务生成每个代理,并且每个服务都将获得“请求”和“响应”类的“副本”

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

答案 1 :(得分:4)

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

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

答案 2 :(得分:2)

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

http://wscfblue.codeplex.com/

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

答案 3 :(得分:0)

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

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

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

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

答案 4 :(得分:0)

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

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