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

发布于 2024-10-21 00:33:46 字数 803 浏览 3 评论 0原文

考虑以下 Visual Studio 项目结构

  • ProjectA.csproj
    • AClass.cs
  • ProjectB.csproj
    • 参考文献
      • 项目A
    • 网络参考
      • WebService
  • AWebService.csproj
    • 参考文献
      • 项目A
    • 返回AClassViaWebService.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。

Consider the following Visual Studio project structure

  • ProjectA.csproj
    • AClass.cs
  • ProjectB.csproj
    • References
      • ProjectA
    • Web References
      • AWebService
  • AWebService.csproj
    • References
      • ProjectA
    • ReturnAClassViaWebService.asmx

The issue occurs when ProjectB adds the web reference to AWebService and automatically generates all the proxy code for accessing AWebService including a new implementation of AClass. Since all of our other code needs to use the AClass defined in ProjectA, we're forced to convert the AWebService.AClass returned from the service into something we can use.

We're currently considering two solutions, neither of which are ideal.

  • Manually editing the generated Reference.cs to remove new definitions of AClass
  • Serializing AWebService.AClass to a stream then deserializing to ProjectA.AClass

Does anyone have any better solutions? This seems like something common enough for other developers to have experienced it.

Ideally we would like to have the proxy code generated in ProjectB to reference ProjectA.AClass rather than generating a whole new implementation.

Our environment is VS 2008 using .NET 2.0.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

那小子欠揍 2024-10-28 00:33:46

我遇到了与您描述的相同的问题,并且我尝试了您指定的两个选项,但对其中任何一个都不满意。

我们都遇到这个问题的原因至少部分是因为在消费者和网络服务提供者之间共享库解决方案违反了公认的模式和实践Web 服务设计。在消费者方面,了解 WSDL 中发布的接口应该就足够了。

尽管如此,如果您准备接受 Web 服务提供商和 Web 服务使用者之间的紧密耦合,并且您知道确信您当前的客户端永远不会被其他客户端(可能无法引用共享库),那么我就明白为什么所提出的解决方案似乎是构建应用程序的一种巧妙方法。重要提示:我们真的可以诚实地回答这两个问题吗?可能不会。

回顾一下:

  1. 当您在某种共享库(在客户端和服务器上使用)中定义了类(例如强类型数据集)时,就会出现此问题。
  2. 您的一些共享类在您的 Web 服务定义的接口中使用。
  3. 添加 Web 引用后,会在 Web 引用命名空间内定义代理类(为您的共享类)。
  4. 由于命名空间不同,代理类与其在共享库中的实际对应类不兼容。

如果您想继续进行共享库设置,可以尝试以下四种解决方案:

  1. 不。在客户端使用代理类。这就是它打算如何完成的。它工作得很好,除非您同时想要利用 Web 服务 WSDL 未公开的共享库的各个方面。
  2. 实现或使用该类提供的复制/复制功能(例如,您可以尝试将一个强类型数据集 Merge() 到另一个数据集中)。强制转换显然是不可能的,并且复制选项通常也不是一个很好的解决方案,因为它往往会产生不良的副作用。例如,当您将一个数据集合并到另一个数据集时,目标数据集中的所有行将被标记为“已更改”。这可以通过 AcceptChanges() 来恢复,但是如果接收到的几行实际上发生了变化怎么办?
  3. 将所有内容(基本数据类型除外)序列化为字符串(并在消费者端再次返回)。类型安全性的丧失是这种方法的一个重要弱点。
  4. 删除 Reference.cs 中共享类的显式声明,并从 Reference.cs 中提及的共享类中删除命名空间。这可能是最好的选择。您得到了真正想要的东西。共享类由 Web 服务返回。此解决方案唯一令人恼火的缺点是,每当您更新 Web 引用时,对 reference.cs 文件的修改都会丢失。相信我:这可能会非常烦人。

以下是类似讨论的链接:

I have had the same problem that you are describing and I have tried both of the options you specify without being entirely happy about either of them.

The reason we both have this issue is at least partly because the shared-library-between-consumer-and-provider-of-a-web-service-solution is in violation of accepted patterns and practices for web service design. On the consumer side, it should be sufficient to know the interface published in the WSDL.

Still, if you are prepared to accept a tight coupling between your web service provider and web service consumer and you know for certain that your current client will never be replaced by a different client (which might not be capable of referencing the shared library), then I understand why the proposed solution seems like a neat way to structure your app. IMPORTANT NOTE: Can we really honestly answer yes to both of these questions? Probably not.

To recap:

  1. The issue appears when you have classes (e.g. a strongly typed dataset) defined in some sort of shared library (used on both client and server).
  2. Some of your shared classes are used in the interface defined by your web service.
  3. When the web reference is added there are proxy classes defined (for your shared classes) within the web reference namespace.
  4. Due to the different namespaces the proxy class and its actual counterpart in the shared library are incompatible.

Here are four solutions that can be tried if you want to go ahead with the shared library setup:

  1. Don't. Use the proxy class on the client side. This is how it is intendend to be done. It works fine unless you simultaneously want to leverage aspects of the shared library that are not exposed by the web service WSDL.
  2. Implement or use a provided copy/duplication feature of the class (e.g. you could try to Merge() one strongly typed dataset into another). A Cast is obviosuly not possible, and the copy option is usually not a very good solution either since it tends to have undesirable side-effects. E.g. When you Merge a dataset into another, all the rows in the target dataset will be labeled as 'changed'. This could be resurrected with AcceptChanges(), but what if a couple of the received rows were actually changed.
  3. Serialize everything - except for elementary data types - into strings (and back again on the consumer side). Loss of type safety is one important weakness of this approach.
  4. Remove the explicit declaration of the shared class in Reference.cs and strip the namespace from the shared class wherever it is mentioned within Reference.cs. This is probably the best option. You get what you really wanted. The shared class is returned by the web service. The only irritating drawback with this solution is that your modifications to the reference.cs file is lost whenever you update your web reference. Trust me: It can be seriously annoying.

Here is a link to a similar discussion:

烟火散人牵绊 2024-10-28 00:33:46

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

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

希望这会有所帮助。

You can reuse existing referenced types between the client and service by clicking on the 'Advanced' button on the 'Add Service Reference' form. Make sure the 'Reuse types in referenced assemblies' checkbox is checked and when the service client is generated it should reuse all types from project A.

In past versions this has not always worked correctly and I've had to explicitly select the shared type assemblies by selecting the 'Reuse types in specified referenced assemblies' option and then checking the appropriate assemblies in the list box. However, I just tested this with VS 2008 SP1 and it appears to work as expected. Obviously, you need to make sure that the types that are being used by the service and client projects are both from project A.

Hope that this helps.

巨坚强 2024-10-28 00:33:46

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

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

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

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

希望这有帮助

We encountered a similar problem with one of our projects. Because we had several dependencies, we ended up creating a circular reference because project 1 required objects from project 2, but project 2 could not be build before project 3, which relied on project 1 to be build.

To solve this problem, we extracted all the public standalone classes from both projects and placed them inside a single librarie. In the end we created something like this:

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

The WebService would be linked to all projects in our case, whereas external parties would only be linking to the objects and interface classes to work with. The actuall implementation was coupled at runtime through reflection.

Hope this helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文