【问题标题】:Are there any tools to build ASMX proxies from server side assemblies?是否有任何工具可以从服务器端程序集构建 ASMX 代理?
【发布时间】:2010-11-21 13:04:59
【问题描述】:

我们有一组实现 Web 服务操作的程序集。

为了构建客户端代理,我们首先在服务器上构建和部署 Web 服务(程序集和 ASMX 文件)。

然后我们使用 wsdl.exe 指向 ASMX 端点并为客户端代理生成类。

我发现可以使用 wsdl.exe 或 disco.exe 从 wsdl 文件(而不是 asmx 端点)创建代理。


是否有工具可以直接从服务器程序集生成 wsdl 文件或代理类,而无需使用 Web 服务器?


更新:

首先我想说,我感谢你们抽出宝贵的时间来做这件事。我还想说,我知道在不了解给定场景的所有细节的情况下提供建议是多么困难。也就是说,让我详细说明一下场景并解决你们提出的一些观点:

1) 这是一个相当大的项目,已经开发了几年。使用 ASMX Web 服务的决定是在 WCF 出现之前做出的。

2) 我已经考虑过编写我们自己的代理生成器,如果我们没有找到可以做到这一点的工具,这可能是一个选择。

3) 我们仍然想绑定到 WSDL 契约。我试图避免的是在构建过程中对 Web 服务器的依赖。

4) 我们已经在 TFS Build 中运行的自动构建中自动生成代理,这本身不是问题。正如我被告知的那样,这个问题必须将构建分为两部分:服务器和客户端。可能有其他方法可以避免使用一些花哨的 MSBUILD 任务进行拆分,但我对这件事的了解有限。

5) 如果客户端代码和服务器端代码在编译期间不匹配,我确实希望构建在 TFS 构建时停止。这应该在签入前在开发者的机器上解决。

6) 我们对服务器和客户端部分有严格的控制。这组 Web 服务用作 Click Once Windows 窗体应用程序的后端。一切都在 Intranet 上运行。每次合约更改时,都会与客户端应用程序的新版本同步完成。

7) WCF 在短期内不是这组 Web 服务的选项。一年多前,当我加入该项目时,我的任务是创建一组新的 Web 服务,以实现与其他内部系统的互操作性。这些 Web 服务是预先设计的,一旦高层管理人员允许我们使用 WCF,就可以轻松升级到 WCF。我将不得不查看 svcutil.exe,但如果它满足我们的需要,我将尝试说服高层管理人员采用 WCF。

【问题讨论】:

标签: c# .net vb.net proxy wsdl


【解决方案1】:

嗯,经典的 ASMX Web 服务和现代的 WCF 服务都能够为您自动生成 WSDL。如果您访问 Web 服务端点的 URL,则只需将 ?WSDL 添加到 URL 的末尾即可获取 WSDL。您通常不希望从服务本身的代码生成代理...Web 服务的重点是将您与实现分离,并允许您绑定到合同(这就是 WSDL 是什么...合同。)您可以通过几种方式生成客户端代理...使用 wsdl.exe、svcutil.exe 或通过 Visual Studio 的“添加 Web 引用”或“添加服务引用”选项。

如果您真的需要,您可以编写自己的代理生成器。我最近编写了一个动态代理生成器,它允许通过 Castle Windsor IOC 容器使用轻量级代码生成 (ILEmit) 在运行时生成 WCF 服务代理。有多种选择,但关键是您绑定到 WSDL(您的合同),而不是服务的实际 C# 代码。最理想的选择是编写 WSDL,并从 WSDL 生成客户端代理和服务合同接口以及数据/消息合同。这称为契约优先服务开发,有一些 .NET 产品允许契约优先开发。

编辑:

您评论说我没有真正回答您的问题。也许这是真的,但是,您的问题没有真正好的答案。您正尝试在 build 上自动生成客户端代理。这确实不是一个好主意,并且可能会在您的服务更改时导致一些重大的构建问题。

一个示例场景。假设您有 IServiceA,它有一个将数据协定作为参数传入的方法,并因此返回不同的数据协定:

[ServiceContract]
public interface IServiceA
{
    [OperationContract]
    SecureOutput SomeSecureOperation(SecureInput input);
}

public class SecureInput
{
    public UserCredentials Credentials { get; set; }
    public byte[] EncryptedData { get; set; }
}

public class SecureOutput
{
    public byte[] EncryptedData { get; set; }
}

假设上述服务使用同步加密来加密和解密数据,但后来被确定为不安全。所以你改变了数据合同:

[ServiceContract]
public interface IServiceA
{
    [OperationContract]
    SecureOutput SomeSecureOperation(SecureInput input);

    [OperationContract]
    byte[] GetPublicKey();
}

public class SecureInput
{
    public UserCredentials Credentials { get; set; }
    public byte[] UserPublicKey { get; set; }
    public byte[] EncryptedData { get; set; }
}

public class SecureOutput
{
    public byte[] EncryptedData { get; set; }
}

该服务现在使用异步加密,并使用用户公钥加密返回数据。该服务还具有一项新操作,允许客户端获取服务的公钥,以便他们可以加密输入数据。您的服务的合同已更改,需要您更新客户端代码。您应该对您的服务进行版本控制...但是我们正在处理安全问题,并且必须弃用旧版本以支持新版本以维护安全性。如果您在构建时自动生成您的客户端代理,您将遇到严重的问题。您的客户端代码不再与新代理兼容,并且您的构建失败。

在处理 Web 服务时,最好手动处理代理生成。如果需要重新生成代理(如果您正确地对服务进行版本化,一旦合同固化,这种情况应该很少见),那么您不能简单地生成而不破坏某些东西。您将需要生成代理,然后更新使用它的任何内容以符合新接口。我想不出我想在构建时生成代理的任何场景,也不想在每次构建时重新生成代理。我也不能向任何人推荐这样的场景。对于没有直接回答您的问题,我深表歉意,但我希望我的解释能帮助您建立更好的解决方案。

【讨论】:

  • 这真的不能回答我的问题。正如您在我的帖子中看到的,今天我已经将 wsdl.exe 与 ASMX 端点一起使用。我想要的是能够有一个单一的 MSBUILD 项目,一次编译服务器和客户端程序集。如果 ASP.NET 能够从程序集的类型和成员生成 WSDL,我猜另一个工具也可以做到这一点 - 甚至可能是直接生成代理类的捷径。
  • 嗯,您的问题确实没有很好的答案。为服务自动生成代理的问题在于,如果服务发生更改,并且您在编译整个系统之前没有更新代理,那么每当您的服务更改时,您可能会遇到严重的构建问题。请参阅我的答案以获取更新的场景。
  • 我在问题更新中添加了有关我们方案的更多信息。
【解决方案2】:

您可以使用 ServiceDescriptionReflector 从程序集构建 WSDL 文件。

请参阅本指南:http://www.pluralsight.com/community/blogs/craig/archive/2004/10/18/2877.aspx

编辑:

使用 ServiceDescriptionReflector 生成 WSDL 后,您可以使用 WSDL.exe 工具生成代理类。

【讨论】:

    【解决方案3】:

    我创建了一个工具,它可以从包含一个或多个 Web 服务的已编译 c# 程序集 (dll) 生成 WSDL 文件。通常,您需要一个正在运行的服务(IIS 或其他)托管 .asmx,以便您可以使用 /MyWebService.asmx?wsdl 检索 WSDL

    此工具使用反射生成 WSDL 文件以从程序集 (dll) 中检索所有信息。

    下载地址为http://wsdlgenerator.codeplex.com

    【讨论】:

      【解决方案4】:

      ASMX Web 服务无法做到这一点。

      但是,由于Microsoft says: ASMX Web Services are a “Legacy Technology”,这可能是您考虑Migrating ASP.NET Web Services to WCF 的好时机。

      原因是svcutil.exe 可以从已编译的程序集中导出元数据,然后您应该能够转过来并使用它来创建代理代码,也可以使用svcutil.exe

      我同意jrista 的回答:代理代码是一种生成代码,我认为它不应该在构建过程中生成。它应该由开发人员生成,实际上应该检查到源代码管理中。

      【讨论】:

      • 我必须同意约翰的观点......从 ASMX 迁移到 WCF 将是最好的主意。 WCF 提供了更丰富的框架来构建服务,并且 svcutil.exe 实用程序比 wsdl.exe 实用程序更灵活。
      • 如果您遵循迁移指南的建议,并且坚持使用 basicHttpBinding 绑定,这也不是很困难,这只是 SOAP over HTTP,就像 ASMX。
      • 我已更新问题以解释我们为什么不使用 WCF。
      • -1.前 2 个陈述在很多方面都不正确,您甚至与您的第一个与您的第三段相矛盾(这是正确的)。但是“遗产”意味着它已经在所有方面都被更好的东西所取代,不再需要它。 WCF 并不总是能够使用,并且比 ASMX 更复杂。对我来说,这并没有让它变得更好。如果它在 2009 年被标记为过时,为什么我可以在 VS 2013 中创建一个新的 ASMX Web 服务?我们不应该用“它已经过时,不要打扰”来解决问题,尤其是。即使在今天也可以创建构造的新实例。
      • @vapcguy 大多数人更喜欢它通过一些努力正常工作,而不是永远无法工作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-29
      • 1970-01-01
      • 2011-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多