最近在俱樂部做win8和winphone8相關的一些應用,當然選擇的是C#語言以及XAML,剛剛起步,邊學邊做,一直在各大博客以及MSDN官方學習網站進行學習,並開始開發手頭的win8程序,而這么一個異常真的是花費了我一天一夜才完成的東西,只能表示微軟所出的VS2012及其組件完全是在折騰人。
之前沒有太多PC設備的開發經驗,對C#的了解也不夠,只是做過一些很簡單的winphone7以及安卓上的一些移動程序,不過開發的架構都差不多,這里我不一一贅述。
當然,之前我所使用的技術基本都基於本地,甚至SQLite都沒怎么用到,更不用說訪問服務器數據了。
之后我開始了解一部分關於數據傳輸方面的內容,隊友也開始着手用Webservice進行后台的編寫,然而當他簡單的部署了一個局域網內的Web時,問題出現了。
首先,給各位介紹一下如何在C#窗口程序下進行服務器的訪問。
當web服務被部署后,屬於同源的C#窗口程序和webservice程序讓我們有了更加便捷的訪問方式。直接在solution窗體下的ServiceReference初右鍵引用,輸入webservice部署生成的URL,即可獲得webservice傳過來的SOAP。
在C#窗口程序下,直接以同步方式即可調用。代碼如下:
ServiceReference1.WebServiceSoapClient wss = new WebServiceSoapClient();
string s = wss.HelloWorld();
再用一個textblock即可顯示返回的服務器數據。
然而在win8應用商店程序下,為了保證程序的主界面不會被卡死,強制使用了異步類型訪問服務器數據,而無法使用上述的方法來調用。
這樣的話程序會較為復雜,不易編寫,不過微軟也提供了相應方法,即引入了async、await來實現異步方法。其原理是將你要異步操作的代碼通過await方法實現程序的托管,這一過程不會阻塞其他進程,使得win8的使用更為流暢。代碼如下:
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
ServiceReference1.WebServiceSoapClient wta = new WebServiceSoapClient();
ServiceReference1.HelloWorldResponse s = await wta.HelloWorldAsync();
string x = s.Body.HelloWorldResult;
……//輸出x內容
}
注意到在定義Button_Click_1事件時,添加async,表示該事件內存在await異步操作。
代碼無錯,編譯成功,然而點擊運行的時候卻發生了異常EndpointNotFoundException。
報錯情況是There was no endpoint listening at http://192.168.1.8/WaterService.asmx that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
通過try,catch抓住異常,奇怪的是所謂的Endpoint,其實就是WebService傳過來的Soap。
調試了很久還是出現這樣的異常,沒辦法去處理它,於是我想了想,是不是win8的問題,就在之前的窗口程序里復制粘貼了這段代碼,運行是正常的。
這時候就知道了,的確是Win8開發的默認值有問題。並不是VS2012怎樣,因為都是用它創建的Project。然后就想到關於Win8的一些改進,比如用戶權限降低了,很多程序不得不用管理員身份打開。於是我這樣嘗試,結果行不通。
這個情況是不是說發展到Win8的微軟體系連WebService的數據都沒辦法方便的獲取呢?
無奈之下我在各大國外論壇搜索,結果發現了一個答案。他告訴我在manifest,即清單設計器當中的功能選項里可以指定應用程序可使用的系統功能或設備。
仔細查看列表果然Internet(客戶端和服務器)以及私有網絡(客戶端和服務器)是默認未勾選的。
打上勾之后,問題迎刃而解,在win8程序中異步獲取服務器數據完成。