看WCF Web API的第一印象
每隔幾天,就會打開http://aspnet.codeplex.com去看看有什么動態,前兩天無意間打開后發現了一個新東西,WCF Web API,本來我對WWW(WCF,WF,WPF)沒有啥好印象,雖然在各大招聘網站上好像需求量倒不小,但是我發現這個Web API貌似是有關REST的內容,于是就多看了兩眼,發現果不其然。
不幸的是,現在Web API還是preview版本,文檔少的可憐,只有源代碼和一個幾乎沒有什么用的Sample,上網搜索也沒有結果。前兩天看到一句話,大概意思是:前兩年大家都在考慮要不要REST,現在已經開始考慮如何REST了。
盡管如些,但是在.NET平臺上,REST好像還只是一種概念,研究的人都很少,更不要說投入生產了。關于WCF,剛問世時我倒是學習過一段時間,也做了幾個例子,但是引用WCF服務的那種方式我一直不喜歡,在客戶端中生成一堆代碼,然后再使用那個蹩腳的***Client來調用服務,這就讓我產生一個疑問:在兩個客戶端中調用同一個服務,難道需要生兩個Client不成?再則,既然是服務,那就應該是一個“開放”的東西,雖然WSDL名聲顯赫,然則過于龐大繁復,如果你想用瀏覽器來調用WCF的服務,從現實上來說似乎不太可能,如果從瀏覽器不能調用一個Web服務(當然是GET),那這個Web服務似乎就不太純粹;最后,HTTP是一個完善的協議 ,對于操作數據尤為如此,無論多么復雜的需求,最終對于數據而言無外乎增刪改查耳,HTTP都具有了,作為一個真正開放、通用的服務來說,使用HTTP的基本方法,幾乎沒有不能完成的任務。于是對于操作"用戶"數據而言,使用GET、POST、PUT、DELETE足已,實在沒有必要再自定義一些諸如GetUser,CreateUser之類的RPC方法,為啥一定得要人花一番工夫才能知道添加一個用戶到底是用Create還是Add呢?從某種意義來說,每一個網站實際上都是一個Web服務,不是嗎?基于HTTP,提供數據,只要你輸入對URL,它永遠都會將你想要的結果呈現在你的眼前,如果這樣一個服務,你要使用類似WCF的框架去提供,使用這個Web服務的人會如何評價呢?他永遠不知道在你的“服務”后面是加一個View還是Get抑或是Display...
然而,做技術的人往往喜歡把一個簡單的問題想的無限大,然后再整出一個周身毛病的解決方案,等引誘人家去上當,到最終滿頭包時,才回歸到問題本質,推出一個兼顧的方案,如果這還說的不透徹,那么試想,你現在需要剪刀,然而很快專家們就設計出了瑞士軍刀,因為他們想到你以后很可能還會需要用...,到最后,你發現你使用幾乎天天用剪刀,那些掏耳勺,鑷子,起瓶器之類的幾乎不用,最后,手里還是拿了把張小泉。記得以前看過一句話:請把牛B還給牛,我想說的是,請把HTTP還給HTTP,無論是在前端還是在服務端。
這兩天映入眼簾的東西較多,有IronJS,MongoDB,還有就是正在說的這個WCF Web API了,其實這段時間我正在做一個類似的框架,是在ASP.NET MVC上開發一個輕量級的REST框架(說框架好像有點抬舉自已了),基本思路是使用MVC的Action作為數據服務,使用M$的Syndication來做數據傳遞格式,使用WebRequest以及WebResponse來手工向服務發起請求以及回傳響應,目前支持Atom和JSON格式的內容,核心部分已經完工了,本來打算投入使用后寫幾篇說明和各位兄弟探討,但是現在又發現了WCF Web API,這讓我很糾結,不知道該是繼續呢還是先研究下Web API。昨天把那本《MongoDB權威指南》算是粗讀了一遍,今天晚上閑來無事,又把那個WCF Web API的源碼包打開看了看,了解下這個所謂的Web API到底是怎么回事,內容不多,但是由于下周有個項目有新需求要增加,而從下下周開始要休假一段時間,因此有必須把今天看的東西記錄下來,以免再過20來天,又不知丟到哪里去了。
要了解一個ASP.NET應用的原理,還是得看Global、HttpHandler、HttpModel,在Web API的示例(ContactManager_Advanced)中,沒有發現顯示使用HttpHandler和HttpModel,那就只能看Global了:
- protected void Application_Start(object sender, EventArgs e)
- {
- // use MEF for providing instances
- var catalog = new AssemblyCatalog(typeof(Global).Assembly);
- var container = new CompositionContainer(catalog);
- var config = HttpHostConfiguration.Create().
- AddFormatters(
- new ContactPngFormatter(),
- new ContactFeedFormatter("http://localhost:9000/Contact"),
- new VCardFormatter(),
- new CalendarFormatter()).
- SetResourceFactory(new MefResourceFactory(container)).
- AddMessageHandlers(typeof (LoggingChannel), typeof (UriFormatExtensionMessageChannel));
- SetMappings();
- RouteTable.Routes.MapServiceRoute<ContactResource>("Contact", config);
- RouteTable.Routes.MapServiceRoute<ContactsResource>("Contacts", config);
- }
有意義的顯然是這段了,
catalog變量是指MEF用于導入的目錄,container是組合容器,有了這兩個對象實例后,就開始創建一個HttpHostConfiguration的實例,使用一些自定義的Formatter,Formatter是啥用通呢?如果你了解AtomEntry,那就知道,AtomEntry里面實際是一種格式,它定義了一些固定的內容(屬性),比如:Id,Title,Summary,Link之類的,對于一個User實體來說,UserName如何表示呢,當能只能去擴展這個AtomEntry了,而這個Formatter就是擴展這個AtomEntry的。SetResourceFactory,這個方法的作用是定義一個資源工廠,啥是資源?在REST中,把用戶需要請求操作的服務即稱為資源,http://localhost/User,這是一個Url,沒錯,但是這個Url就代表User服務,它就是個資源,每一個Url就代表一個資源,但是http://localhost/User?id=think8848和http://localhost/User是同一個資源,這其中的道理不難理解,但是設計可訪問的資源也是一個比較復雜的話題,這里不做詳細說明了,有興趣的朋友可以參考《RESTful Web Service》一書。
那么在這段代碼中,到底是如何設置資源,又是如何使用資源的呢?這里使用M$的MEF,MEF是一個比較復雜的框架,簡單的說吧,它有點類似于依賴注入,M$對于它定義如下:“Managed Extensibility Framework 或 MEF 是一個用于創建可擴展的輕型應用程序的庫。 應用程序開發人員可利用該庫發現并使用擴展,而無需進行配置。 擴展開發人員還可以利用該庫輕松地封裝代碼,避免生成脆弱的硬依賴項。 通過 MEF,不僅可以在應用程序內重用擴展,還可以在應用程序之間重用擴展。”。也就是說,使用MEF,可以獲取某些符合條件(通過特性Attribute檢索的)的接口實例。在這里設置一個ResourceFactory,當調用到達時,就會在這個ResourceFactory中去找服務的實例,在我們自已的程序中,可以使用其他方法達到資源工廠的功能,比如Ioc框架。AddMessageHandlers這個名字看起來比較直觀,以我現在的觀察,之前我們使用HttpRequest好像都變成了HttpRequestMessage了,于是我們姑且把這個Message看成是Request,這樣,就可以很清楚的看到,AddRequestHandler就是在添加請求的處理程序。初步猜測,在這個處理程序中,應該能做諸如權限控制之類的工作。
最后兩句,關鍵詞是MapServiceRoute,這其實是一個擴展方法,就定義在WCF Web API中,方法是為泛型參數類型的服務注冊一個UrlRouting的規則,至此,事情就回到了MVC的范疇之類了。
對于WCF Web API,調試了源代碼,感覺比MVC框架要復雜的多,今天發現的東西實在很多,還得以后慢慢消化了。
原文鏈接:http://www.cnblogs.com/think8848/archive/2011/07/23/2115127.html
【編輯推薦】