我想通过调用ChannelFactory.CreateChannel()
方法访问使用WCF的旧ASMX webservice。使用WCF访问asmx WebService
如果Web服务是由WCF创建的,则一切都很简单。我可以实例化由svcutil工具生成的代理客户端,或手动调用ChannelFactory.CreateChannel()
方法。之后,我可以在两种情况下都以相同的方式调用Web服务方法。
但是,如果Web服务是旧的ASMX品种,我仍然可以实例化代理,但我无法调用相同的Web服务方法。
例如,假设这个基本WCF Web服务接口:
[ServiceContract]
public interface IWebService
{
[OperationContract]
string HelloWorld();
}
使用svcutil
生成代理后,我可以叫HelloWorld()
的2种方法之一:
WebServiceClient proxy = new ServiceReference.WebServiceClient();
textBox1.Text += proxy.HelloWorld();
或:
ChannelFactory<ServiceReference.IWebService2> cfactory =
new ChannelFactory<ServiceReference.IWebService>("BasicHttpBinding_IWebService");
ServiceReference.IWebService proxy = cfactory.CreateChannel();
((IClientChannel)proxy).Open();
textBox1.Text += proxy.HelloWorld();
现在假设这个ASMX网络服务:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
public WebService() { }
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
使用svcutil
工具生成的SoapClient
几乎是一样的,如果它是一个WCF Web服务调用HelloWorld()
:
WebServiceSoapClient proxy = new ServiceReference.WebServiceSoapClient();
textBox1.Text += proxy.HelloWorld();
但试图调用HelloWorld()
如果创建频道你自己,你会得到一个错误:
ChannelFactory<ServiceReference.WebServiceSoap> cfactory =
new ChannelFactory<ServiceReference.WebServiceSoap>("WebServiceSoap");
ServiceReference.WebServiceSoap proxy = cfactory.CreateChannel();
((IClientChannel)proxy).Open();
textBox1.Text += proxy.HelloWorld();
的错误是“没有重载方法的HelloWorld取0参数”。
看起来是因为自动生成的接口(ServiceReference.WebServiceSoap)
中的HelloWorld
方法接受了ServiceReference.HelloWorldRequest
类型的参数。
所以,我只能够使它工作通过了svcutil
生成的代码寻找和改变我实现这个:
ChannelFactory<ServiceReference.WebServiceSoap> cfactory =
new ChannelFactory<ServiceReference.WebServiceSoap>("WebServiceSoap");
ServiceReference.WebServiceSoap proxy = cfactory.CreateChannel();
((IClientChannel)proxy).Open();
ServiceReference.HelloWorldRequest inValue =
new WCFConsumeWebServices.ServiceReference.HelloWorldRequest();
inValue.Body = new WCFConsumeWebServices.ServiceReference.HelloWorldRequestBody();
ServiceReference.HelloWorldResponse retVal = proxy.HelloWorld(inValue);
textBox1.Text += retVal.Body.HelloWorldResult;
这是它是如何假设是?
对于一种基本的http web服务,我们可以使用几乎相同的代码来调用一个方法,但是对于另一种我们需要通过生成的代理代码来实现,并根据打开通道的方式有不同的实现。
发布整个服务? 以上代码是整个asmx webservice实现(WebService.cs文件)。 asmx文件只有一行: 它只有一个webmethodHelloWorld(),它不接受任何一个webmethod HelloWorld()参数并返回字符串“Hello World”。 问题是自动生成的代理服务器代码(来自svcutil)有一个接口,它没有一个不带参数的HelloWorld方法,即使实际的web服务也是如此。 – Buma 2010-06-16 18:29:59
@Buma:请做**不**将冗长的代码片段发布到评论中 - 那些不清晰。请**通过编辑更新**您的原始问题 - 谢谢。 – 2010-06-16 18:33:46
是的,这种行为似乎是它的工作方式 - 不确定是否有任何特别的原因(可能有)。 – 2010-06-16 18:34:31