Silverlight初探(三) - 使用WCF存取資料庫篇
本文要示範如何在Silverlight當中使用WCF,何謂WCF,簡單的說就是WebService,詳細說明請參閱本文下方連結,首先我先簡單的示範如何寫一個正常的WCF,我根據了Steven的心得筆記寫出了下面語法的WCF。
WCF的設定很多,會發生很多錯誤,但是這一開始接觸新的技術都會發生的事,相信把錯誤訊息拿去Google一下應該很快就會解開了,而且自己查過才更容易知道錯的原因,因此我就不再列舉我發生的錯誤了,到了這裡你應該已經可以讓Silverlight呼叫WCF了Method了,因此我們只需要在幾個步驟就可以完成我們的需求了,我們需要存取資料庫的資料,WCF方面的寫法就如同正常的Method,只是我們這次要把回傳的值改成DataSet,至於為什麼不使用DataTable?
想在WCF傳資料一定要有XmlSerialize的資料包裝動作,DataTabel 沒有包裝資料的能力,所以不能傳輸。DataSet 有包裝資料的能力,所以可以傳輸。
網路上有些人說WCF可以回傳DataTable型態的資料,只需要給DataTable命名即可,我本人試過是沒有成功,有興趣的人請自己嘗試吧。
最後一切都完成了,我卻發現一個重大的問題就是,我的WCF竟然不允許跨域存取【嘗試向 URI http://xxx 進行要求時發生錯誤。這可能是因為嘗試以跨網域方式存取服務,而沒有適當的跨網域原則所造成,或是由不適用於 SOAP 服務的原則所造成。您可能需要連絡服務的擁有者,以發佈跨網域原則檔案,並確定它允許傳送 SOAP 相關的 HTTP 標頭。這項錯誤也可能是在 Web 服務 Proxy 中使用內部型別而沒有使用 InternalsVisibleToAttribute 屬性所造成。如需詳細資訊,請查看內部例外狀況。】。好在有Google,一樣馬上找到解決辦法,只需要在網站根目錄加入已下兩支檔案(二擇一),還有拜託一下貼語法之前請先參考一下MSDN怎麼說的不要亂貼一通,安全性問題還是要注意。
clientaccesspolicy.xml
crossdomain.xml
何謂WCF & 如何使用WCF
Steven的心得筆記
MSDN WCF線上教學
namespace WCFService { [ServiceContract] public interface IHelloWord { //為每個 operation 指定唯一的別名,這樣就可以使用相同名稱的方法 [OperationContract(Name = "MyHello")] string MyHello(string text); //為每個 operation 指定唯一的別名,這樣就可以使用相同名稱的方法 [OperationContract(Name = "MyHello1")] int MyHello(int text); //沒有加上[OperationContact]的method,就不會成為合約的一部份。 string MyOtherHello(string text); } class HelloWord : IHelloWord { public string MyHello(string text) { return "Hello " + text; } public int MyHello(int text) { MyOtherHello(text.ToString()); return 0; } public string MyOtherHello(string text) { return "這個method非合約的部份,無法透過WCF呼叫!"; } } }測試一下執行畫面正常(如下圖),可是使用Silverlight呼叫的時候卻出現【在 ServiceModel 用戶端組態區段中找不到參照合約 'ServiceReference1.IHelloWord' 的預設端點項目。可能是因為找不到應用程式的組態檔,或是用戶端項目中找不到符合此合約的端點項目。】(呼叫方式請參閱下面語法,但是前提必須將此WCF加入專案參考),網路Google一下原來WCF如果要給Silverlight讀取,使用方式是不相同的,必須啟用給ASP.NET專用的服務,由於這個項目啟用後會使Web.Config改變很多東西,我就不再解釋了,想要知道怎麼啟用此服務,可以參閱這個阿六仔的Blog。必須要啟用順便提一下,將此WCF掛到IIS下面去執行記得要把NET.Framework版本改成4.0,否則會出現【404 - 找不到檔案或目錄】。
// Executes when the user navigates to this page. protected override void OnNavigatedTo(NavigationEventArgs e) { ServiceReference1.HelloWordClient proxy = new ServiceReference1.HelloWordClient(); proxy.MyHelloCompleted += new EventHandler<servicereference1 .myhellocompletedeventargs="">(proxy_MyHelloCompleted); //以非同步方式呼叫WCF服務功能 proxy.MyHelloAsync("Lawrence"); proxy.CloseAsync(); } void proxy_MyHelloCompleted(object sender, ServiceReference1.MyHelloCompletedEventArgs e) { Dispatcher.BeginInvoke(delegate() { MessageBox.Show(e.Result); }); }
WCF的設定很多,會發生很多錯誤,但是這一開始接觸新的技術都會發生的事,相信把錯誤訊息拿去Google一下應該很快就會解開了,而且自己查過才更容易知道錯的原因,因此我就不再列舉我發生的錯誤了,到了這裡你應該已經可以讓Silverlight呼叫WCF了Method了,因此我們只需要在幾個步驟就可以完成我們的需求了,我們需要存取資料庫的資料,WCF方面的寫法就如同正常的Method,只是我們這次要把回傳的值改成DataSet,至於為什麼不使用DataTable?
想在WCF傳資料一定要有XmlSerialize的資料包裝動作,DataTabel 沒有包裝資料的能力,所以不能傳輸。DataSet 有包裝資料的能力,所以可以傳輸。
網路上有些人說WCF可以回傳DataTable型態的資料,只需要給DataTable命名即可,我本人試過是沒有成功,有興趣的人請自己嘗試吧。
最後一切都完成了,我卻發現一個重大的問題就是,我的WCF竟然不允許跨域存取【嘗試向 URI http://xxx 進行要求時發生錯誤。這可能是因為嘗試以跨網域方式存取服務,而沒有適當的跨網域原則所造成,或是由不適用於 SOAP 服務的原則所造成。您可能需要連絡服務的擁有者,以發佈跨網域原則檔案,並確定它允許傳送 SOAP 相關的 HTTP 標頭。這項錯誤也可能是在 Web 服務 Proxy 中使用內部型別而沒有使用 InternalsVisibleToAttribute 屬性所造成。如需詳細資訊,請查看內部例外狀況。】。好在有Google,一樣馬上找到解決辦法,只需要在網站根目錄加入已下兩支檔案(二擇一),還有拜託一下貼語法之前請先參考一下MSDN怎麼說的不要亂貼一通,安全性問題還是要注意。
clientaccesspolicy.xml
<access-policy> <cross-domain-access> <policy> <allow-from http-request-headers="SOAPAction"> <domain uri="*"/> </allow-from> <grant-to> <resource path="/" include-subpaths="true"/> </grant-to> </policy> </cross-domain-access> </access-policy>
crossdomain.xml
<cross-domain-policy> <allow-http-request-headers-from domain="*" headers="SOAPAction,Content-Type" /> </cross-domain-policy>
何謂WCF & 如何使用WCF
Steven的心得筆記
MSDN WCF線上教學
留言
張貼留言
您好,我是 Lawrence,這裡是我的開發筆記的網誌,如果你對我的文章有任何疑問或者有錯誤的話,歡迎留言讓我知道。