问:我想在.NET中在运行时给一个Web服务绑定一个指定的实现,请问您可否给我提供一个参考?请问我能不能用一个WSDL工具在编译时来产生一个代理,然后在运行时修改该代理的URL(与/或该代理的其他属性)来存取该服务的一个特定的实现?是不是有其他的技术或工具更适合用来做这个?
答:首先,我先来回答在运行时动态调用一个服务终端的问题。你可以通过设置代理类的URL属性来轻而易举地实现这个。这是所有Proxy类的基类System.Web.Services.Protocols.SoapHttpClientProtocol的一个公共的可存取的属性。它在构造函数中赋值,如下:
public MyService() {
this.Url = "http://localhost/MyService/service1.asmx";
}
而你可以在调用任何方法前重新给它赋值。
我建议你不要修改代理类里面的任何东西——如果你可以避免的话,你不应该修改自动生成的代码。这能让你很灵活地重新生成代理,例如添加了新的方法,你可以直接重新生成代理类,而如果你修改了其中的代码,如URL,你不能不重新设置。而用BeginXXX()和EndXXX()之类的方法,你可以异步地调用代理类的任何公共方法。每个Web服务的方法都可以通过它的.NET代理来被同步或异步地调用。这有一个异步调用Web服务的例子。
回到运行时选择服务终端的问题,你应该考虑这些终端必须对应了Web服务的WSDL绑定。这意味着你只能设置URL属性为那些准确地实现了代理的WebServiceBindingAttribute指定的每个方法的服务终端。多个对同一个WSDL绑定的服务实现可能是以下情况之一:
1、它们是服务的精确复制,可能是为了在多个机器上的负载平衡——因此它们在不同的终端上发布,但是语义上是一样的。
2、使用基于接口的WSDL绑定,多个服务实现了同一个WSDL定义的部分或所有方法。例如,如果一个工业标准WSDL设计成提供了服务们应该支持的命名空间和消息定义,那么为了一致性,可能很多个公司实现一个公用的服务绑定。这样,一个消息可以被发送到在不同公司上部署的服务终端。你可以根据一个公共的WSDL定义,在你的服务中实现一个消息(方法),或者根据多个公共的WSDL定义实现多个消息(方法)。
综上所述,你可以动态地修改服务终端的URL,但关键是你要知道在什么情况下这样做是可取的,那就是:代理所希望的WSDL绑定,将被这个服务实现。