2010-06-16 155 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