我们有一组实现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 Build上制动。这应该在开机前在开发人员的机器上解决。
6)我们严格控制服务器和客户端部分。这组Web服务充当Click Once Windows Forms应用程序的后端。一切都在内联网上运行。每次合同更改时,都会与新版本的客户端应用程序一起完成。
7)WCF在短期内不是这组Web服务的选项。当我在一年前加入该项目时,我被赋予了创建一组新的Web服务的任务,以便与其他内部系统进行互操作。这些Web服务是预先设计的,一旦上层管理人员允许我们使用WCF,就可以轻松升级到WCF。我将不得不看一下svcutil.exe,但是如果它能够满足我们的需要,那么我将有另一点试图说服高层管理人员采用WCF。
答案 0 :(得分:4)
嗯,经典的ASMX Web服务和现代WCF服务都能够为您自动生成WSDL。如果转到Web服务端点的URL,只需将WSDL添加到URL的末尾即可获得WSDL。您通常不希望从服务本身的代码生成代理... Web服务的目的是将您与实现分离,并允许您绑定到契约(这是WSDL的......合同。)您可以通过几种方式生成客户端代理...使用wsdl.exe,svcutil.exe或通过visual studio的“添加Web引用”或“添加服务引用”选项。
如果你真的需要,你可以写你自己的代理生成器。我最近编写了一个动态代理生成器,它允许在运行时使用轻量级代码生成(ILEmit)通过Castle Windsor IOC容器生成WCF服务代理。有各种各样的选项,但关键是你绑定到WSDL(你的合同),而不是服务的实际C#代码。最理想的选择是编写WSDL,并从WSDL生成客户端代理和服务契约接口以及数据/消息契约。这称为契约优先服务开发,并且有一些.NET产品允许合同优先开发。
编辑:
您评论说我没有真正回答您的问题。也许这是真的,但是,对你的问题没有真正好的答案。您正尝试在构建上自动生成客户端代理。这确实不是一个好主意,并且当您的服务发生变化时,可能会导致一些重大的构建问题。
一个示例场景。假设你有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服务时,最好手动处理代理生成。如果需要重新生成代理(如果您正确地对服务进行了版本设置,那么一旦合同固化后应该很少),那么您不能简单地生成而不会破坏某些内容。您将需要生成代理,然后更新消耗它的任何内容以符合新接口。我想不出任何我想在构建时生成代理的情况,也不想在每次构建时重新生成代理。我也不能向任何人推荐这样的场景。我为没有直接回答你的问题而道歉,但我希望我的解释会帮助你建立一个更好的解决方案。
答案 1 :(得分:1)
您可以使用ServiceDescriptionReflector从程序集构建WSDL文件。
请参阅本指南:http://www.pluralsight.com/community/blogs/craig/archive/2004/10/18/2877.aspx
修改强>
使用ServiceDescriptionReflector生成WSDL后,您可以使用WSDL.exe工具生成代理类。
答案 2 :(得分:1)
我创建了一个工具,可以从包含一个或多个WebServices的已编译c#程序集(dll)生成WSDL文件。通常,您需要一个运行服务(IIS或其他)来托管.asmx,以便您可以使用/MyWebService.asmx?wsdl
检索WSDL。此工具使用反射生成WSDL文件,以从程序集(dll)中检索所有信息。
找到答案 3 :(得分:-1)
使用ASMX Web服务无法做到这一点。
但是,自Microsoft says: ASMX Web Services are a “Legacy Technology”起,这可能是您考虑Migrating ASP.NET Web Services to WCF的好时机。
原因是svcutil.exe
可以使用svcutil.exe
从已编译的程序集中导出元数据,然后您可以转而使用它来创建代理代码。
我同意jrista的答案:代理代码是一种生成的代码,我不相信它应该在构建期间生成。它应该由开发人员生成,并且实际上应该检查源代码控制。