如果我們自己新建一個WCF服務庫,生成了dll文件。那我們需要創建一個宿主程序,在本例中我們新建一個Winform程序作為WCF的宿主程序。
在網上很多教程里對創建過程寫的很模糊,錯誤也很多。本文是作者在嘗試了網上各種失敗方法之后,經過自己的改正,總結出的可以正確運行的解決方案。
1. 創建wcf服務庫。
打開vs, 新建一個 WCF服務庫。 什么都不用改,直接生成。 此時會在bin目錄下生成一個dll文件(默認名WcfServiceLibrary1.dll)。
2. 創建宿主程序。
1). 打開vs,新建一個Windows窗體應用程序。
2). 添加引用,System.ServiceModel和 剛剛生成的WcfServiceLibrary1.dll。
3). 創建一個button,在button.click的事件里添加如下代碼:
- private void button1_Click(object sender, EventArgs e)
- {
- if (Host == null)
- {
- Host = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
- System.ServiceModel.Channels.Binding httpbinding = new BasicHttpBinding();
- Host.AddServiceEndpoint(typeof(WcfServiceLibrary1.Service1), httpbinding, "http://localhost:8002");
- if (Host.Description.Behaviors.Find<System.ServiceModel.Description.ServiceMetadataBehavior>() == null)
- {
- ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
- behavior.HttpGetEnabled = true;
- behavior.HttpGetUrl = new Uri("http://localhost:8002/Service1");
- Host.Description.Behaviors.Add(behavior);
- Host.Open();
- MessageBox.Show("OK");
- }
- }
- }
private void button1_Click(object sender, EventArgs e) { if (Host == null) { Host = new ServiceHost(typeof(WcfServiceLibrary1.Service1)); System.ServiceModel.Channels.Binding httpbinding = new BasicHttpBinding(); Host.AddServiceEndpoint(typeof(WcfServiceLibrary1.Service1), httpbinding, "http://localhost:8002"); if (Host.Description.Behaviors.Find<System.ServiceModel.Description.ServiceMetadataBehavior>() == null) { ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); behavior.HttpGetEnabled = true; behavior.HttpGetUrl = new Uri("http://localhost:8002/Service1"); Host.Description.Behaviors.Add(behavior); Host.Open(); MessageBox.Show("OK"); } } }
注意本句:
- Host.AddServiceEndpoint(typeof(WcfServiceLibrary1.IService1), httpbinding, "http://localhost:8002");
Host.AddServiceEndpoint(typeof(WcfServiceLibrary1.IService1), httpbinding, "http://localhost:8002");
.IService1 為網絡教程中出錯經作者修改的部分,此處如果寫成Service1的話會報如下的錯:
協定類型WcfServiceLibrary1.Service1不具有ServiceContractAttribute特性。若要定義有效協定(協定接口或服務類)必須具有ServiceContractAttribute特性。
4). 在窗口關閉的事件里添加如下代碼:
- if (Host != null)
- {
- Host.Close();
- }
if (Host != null) { Host.Close(); }
5). 生成,運行。
3. 創建客戶端程序。
1). 打開vs,新建一個Windows窗體應用程序。
2). 右鍵點擊引用,然后選擇添加服務引用,在地址欄中輸入 http://localhost:8002/Service1 ,即剛剛代碼中的behavior的uri,注意不是http://localhost:8002/。
3). 點擊前往,然后點確定即可。
注意:在網上的好些教程里都寫的是在宿主程序用用WCF配置工具生成app.config然后運行宿主程序,那樣生成的app.config是有問題的,在客戶端程序引用的時候會報錯。錯誤提示:
下載“http://localhost:8082/wcf2”時出錯。 請求因 HTTP 狀態 400 失敗: Bad Request。 元數據包含無法解析的引用:“http://localhost:8082/wcf2”。 服務 http://localhost:8082/wcf2 不支持內容類型 application/soap+xml; charset=utf-8。客戶端和服務綁定可能不匹配。 遠程服務器返回錯誤: (415) Cannot process the message because the content type 'application/soap+xml; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'.。 如果該服務已在當前解決方案中定義,請嘗試生成該解決方案,然后再次添加服務引用。
此問題絕對會發生,但那些教程里並沒有指出錯誤並告知解決辦法。困擾我許久之后我終於發現本文中的方法。
4). 創建一個button,button的click事件中填寫如下代碼:
- private void button1_Click(object sender, EventArgs e)
- {
- using (ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client())
- {
- sc.Open();
- MessageBox.Show(sc.GetData(10));
- sc.Close();
- }
- }
private void button1_Click(object sender, EventArgs e) { using (ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client()) { sc.Open(); MessageBox.Show(sc.GetData(10)); sc.Close(); } }
5).生成,運行即可。