2010-06-16 105 views
1

我想通过调用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服务,我们可以使用几乎相同的代码来调用一个方法,但是对于另一种我们需要通过生成的代理代码来实现,并根据打开通道的方式有不同的实现。

回答

1

副手,我不知道为什么,但WCF似乎在与您的ASMX服务通话时使用消息合约。你有没有发布整个服务?

+0

发布整个服务? 以上代码是整个asmx webservice实现(WebService.cs文件)。 asmx文件只有一行: 它只有一个webmethodHelloWorld(),它不接受任何一个webmethod HelloWorld()参数并返回字符串“Hello World”。 问题是自动生成的代理服务器代码(来自svcutil)有一个接口,它没有一个不带参数的HelloWorld方法,即使实际的web服务也是如此。 – Buma 2010-06-16 18:29:59

+0

@Buma:请做**不**将冗长的代码片段发布到评论中 - 那些不清晰。请**通过编辑更新**您的原始问题 - 谢谢。 – 2010-06-16 18:33:46

+0

是的,这种行为似乎是它的工作方式 - 不确定是否有任何特别的原因(可能有)。 – 2010-06-16 18:34:31