使用WSE Web服务导入键入重新定义

时间:2011-03-07 20:47:26

标签: c# .net visual-studio-2008 wse wse3.0

考虑以下Visual Studio项目结构

  • ProjectA.csproj
    • AClass.cs
  • ProjectB.csproj
    • 参考
      • 项目A
    • 网络参考
      • AWebService
  • AWebService.csproj
    • 参考
      • 项目A
    • ReturnAClassViaWebService.asmx

当ProjectB将Web引用添加到AWebService并自动生成用于访问AWebService的所有代理代码(包括新的AClass实现)时,会出现此问题。由于我们所有其他代码都需要使用ProjectA中定义的AClass,因此我们不得不将从服务返回的AWebService.AClass转换为我们可以使用的内容。

我们目前正在考虑两种解决方案,这两种解决方案都不理想。

  • 手动编辑生成的Reference.cs以删除新的AClass定义
  • 将AWebService.AClass序列化为流然后反序列化为ProjectA.AClass

有没有人有更好的解决方案?对于其他开发人员来说,这似乎已经足够了。

理想情况下,我们希望在ProjectB中生成代理代码以引用ProjectA.AClass,而不是生成一个全新的实现。

我们的环境是使用.NET 2.0的VS 2008。

3 个答案:

答案 0 :(得分:2)

我遇到了你所描述的同样的问题,我已经尝试了你指定的两个选项而没有对它们中的任何一个完全满意。

我们都有这个问题的原因至少部分是因为共享库 - 消费者和提供商的网络服务 - 解决方案违反了公认的模式和web service design的做法。在消费者方面,它足以知道在WSDL中发布的接口。

但是,如果您准备接受Web服务提供商和Web服务使用者之间的紧密耦合,并且您知道以确定您的当前客户端永远不会被其他客户端替换(可能没有能力引用共享库),那么我理解为什么提出的解决方案看起来像一个整洁的方式来构建您的应用程序。重要提示:我们真的可以诚实地对这两个问题回答是吗?可能不是。

回顾一下:

  1. 当您在某种共享库中定义类(例如强类型数据集)时会出现此问题(在客户端和服务器上都使用)。
  2. 您的某些共享类在您的Web服务定义的界面中使用。
  3. 添加Web引用时,Web引用命名空间中定义了(对于共享类)的代理类。
  4. 由于名称空间不同,代理类及其在共享库中的实际副本不兼容。
  5. 如果您想继续使用共享库设置,可以尝试以下四种解决方案:

    1. 别。在客户端使用代理类。这就是它的意图。除非您同时希望利用Web服务WSDL未公开的共享库的各个方面,否则它可以正常工作。
    2. 实现或使用类的提供的复制/复制功能(例如,您可以尝试将一个强类型数据集合并到另一个中)。铸造是不可能的,并且复制选项通常不是一个非常好的解决方案,因为它往往具有不良的副作用。例如。将数据集合并到另一个数据集时,目标数据集中的所有行都将标记为“已更改”。这可以通过AcceptChanges()重新启动,但如果接收到的几行 实际上已更改,那该怎么办呢。
    3. 将所有内容(除基本数据类型外)序列化为字符串(并在消费者方面再次返回)。类型安全性的丧失是这种方法的一个重要缺点。
    4. 删除Reference.cs中共享类的显式声明,并从Reference.cs中提到的任何位置剥离共享类中的命名空间。这可能是最好的选择。你得到真正想要的东西。共享类由Web服务返回。此解决方案唯一令人恼火的缺点是,每当您更新Web引用时,对reference.cs文件的修改都将丢失。相信我:这可能会非常烦人。
    5. 以下是指向similar discussion的链接:

答案 1 :(得分:0)

您可以通过单击“添加服务引用”表单上的“高级”按钮,在客户端和服务之间重用现有的引用类型。确保选中“在引用的程序集中重用类型”复选框,并且在生成服务客户端时,它应该重用项目A中的所有类型。

在以前的版本中,这并不总是正常工作,我必须通过选择“在指定的引用程序集中重用类型”选项,然后在列表框中检查相应的程序集来显式选择共享类型程序集。但是,我刚刚使用VS 2008 SP1测试了它,它似乎按预期工作。显然,您需要确保服务和客户端项目使用的类型都来自项目A.

希望这会有所帮助。

答案 2 :(得分:-1)

我们的一个项目遇到了类似的问题。因为我们有几个依赖项,所以我们最终创建了一个循环引用,因为项目1需要项目2中的对象,但项目2无法在项目3之前构建,项目3依赖于项目1来构建。

为了解决这个问题,我们从两个项目中提取了所有公共独立类,并将它们放在一个库中。最后我们创建了这样的东西:

  • Framework.Objects
  • Framework.Interface
  • Framework.Implementation
  • 的WebService

WebService将链接到我们案例中的所有项目,而外部方只会链接到要使用的对象和接口类。实时实现在运行时通过反射耦合。

希望这有帮助