轉:http://www.cnblogs.com/shanyou/archive/2013/06/11/3131583.htmlhtml
在SOA的世界中,最重要的一個概念就是契約(contract)。在雲計算的世界中,有關通訊的最重要的概念也是契約。XML具備強大對數據的描述能力,Atom格式和AtomPub都創建在XML之上,在Google和微軟的推進下,也已經成爲標準。可是,Atom/AtomPub和ODBC/OLEDB這樣的真正數據交互協議相比較,還有着根本上的欠缺:缺少數據類型的具體描述,下降了交互性能。缺少對數據查詢的控制能力,好比返回特定的數據集合的區間,或者說分頁能力等等。微軟基於EDM模型釋出了:OData,這裏也能夠看出Entity Framework對於NHibernate這樣的ORM的工具不一樣的戰略考慮。web
在.NET中,早期是用Remoting/Webservice來處理全部程序間的通訊,從.NET 3.0開始使用WCF統一了通訊模型,ASP.NET MVC4的推出,造成大的One ASP.NET戰略,增長了WebAPI和SingalR做爲通訊服務:json
開放數據協議(OData)是一個查詢和更新數據的Web協議。OData應用了web技術如HTTP、Atom發佈協議(AtomPub)和JSON等來提供對不一樣應用程序,服務和存儲的信息訪問。除了提供一些基本的操做(像增刪改查),也提供了一些高級的操做相似過濾數據和實體的導航。OData擴展了上述的協議可是不是取代他們。他能夠被XML(ATOM)或者JSON取代可是OData的重要在於它符合REST原則。在某種意義上,它創建在'簡單'的REST HTTP 服務上,而且有着清晰的目標——簡化和標準化咱們操做和查詢數據的方式。若是你過去在給你的REST服務建立搜索、過濾、或者分頁API的時候感受很麻煩,那麼OData將是一個不錯的選擇。api
目前不少接口,不管是基於SOAP、REST仍是別的都在交換數據時使用不一樣的模式。這種方法隨後返回一大堆客戶記錄。你隨後能夠決定添加分頁支持。你但願將結果捆綁在一個網格中,並對數據排序。最後,決定想要查詢的東西,經過好比郵政編碼來查詢。app
首先是,沒有建立泛型客戶端的途徑,而這些和API緊密聯繫,由於它不知道參數的順序或者模式被使用的順序。由於不能建立泛型客戶端,你必須爲每個你但願暴露的API建立客戶端。簡單的基礎HTTP API能夠實現,但其仍舊很昂貴。逐漸增多的多樣性客戶端與這些API通訊加重了這個問題。框架
這種模式的第二個問題是它迫使開發人員進行很艱難的權衡。我應該暴露多少個查詢?你必要在暴露每個你能想到內容和少暴露一些,從而削弱服務之間協調。前者致使API 須要管理的界面的增長,後者會致使咱們一般所說的「數據豎井」,也就是關鍵數據在特定模式中鎖定,其餘應用不可以簡單應用,由於它沒有以一種須要的方式暴露給這個應用。服務試圖比單一應用要得到更長久一些,所以你須要以一種方式設計API,使其可以持久,因此若是你發現你須要添加服務藉口的新版本可不太好辦,好比建立新的客戶端。在不少案例中,服務開發者和客戶端開發者並非同一我的,於是改變服務接口簡直就是不可能的事情。asp.net
經過OData,咱們採起不一樣的方法。取代建立客戶端簽名和參數,咱們問了以下的問題:「若是你將數據集做爲源處理,併爲最頻繁使用的操做定義模式,像查詢、分頁、排序、新建、刪除和更新,服務接口因該是什麼樣子的?」 這也就致使OData的建立。OData解決了上面提到的關鍵服務設計挑戰。函數
咱們來看一下啓用OData協議的WebAPI的例子:工具
http://localhost:8080/api/meetings性能
http://localhost:8080/api/meetings?$filter=(Leader eq ‘Mark Nichols’)
http://localhost:8080/api/meetings?$top=2
http://localhost:8080/api/meetings?$filter=MeetingDate eq datetime’2013-01-17′
在項目中啓用OData查詢,首先在項目加入Web API的OData支持,經過Nuget 查找ASP.NET Web API OData
Microsoft.AspNet.WebApi.OData提供可一系列的類擴展了Web API。
在項目中啓用OData查詢:
public static void Register(HttpConfiguration config)
{
// ...
config.EnableQuerySupport();
// ...
}
若是是使用self-hosting方式,在HttpSelfHostConfiguration上啓用EnableQuerySupport():
var config = new HttpSelfHostConfiguration(new Uri("http://localhost:8080"));
config.EnableQuerySupport();
而後將Controls上的Action的返回結果更改成IQueryable,並打上標籤[Queryable()]:
// GET api/Meeting
[Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
public IQueryable<Meeting> Get() { return _scheduledMeetings.AsQueryable(); } 須要添加 using System.Web.Http.OData.Query; 咱們下AllowedQueryOptions 看支持那些OData的類型:
// Summary:
// OData query options to allow for querying. [Flags] public enum AllowedQueryOptions { // Summary: // A value that corresponds to allowing no query options. None = 0, // // Summary: // A value that corresponds to allowing the $filter query option. Filter = 1, // // Summary: // A value that corresponds to allowing the $expand query option. Expand = 2, // // Summary: // A value that corresponds to allowing the $select query option. Select = 4, // // Summary: // A value that corresponds to allowing the $orderby query option. OrderBy = 8, // // Summary: // A value that corresponds to allowing the $top query option. Top = 16, // // Summary: // A value that corresponds to allowing the $skip query option. Skip = 32, // // Summary: // A value that corresponds to allowing the $inlinecount query option. InlineCount = 64, // // Summary: // A value that corresponds to the default query options supported by System.Web.Http.QueryableAttribute. Supported = 121, // // Summary: // A value that corresponds to allowing the $format query option. Format = 128, // // Summary: // A value that corresponds to allowing the $skiptoken query option. SkipToken = 256, // // Summary: // A value that corresponds to allowing all query options. All = 511, }
上面有個Format,咱們能夠進行格式化輸出。使用下面的代碼對Format進行數據格式化:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );
config.Formatters.JsonFormatter.AddQueryStringMapping("$format", "json", "application/json"); config.Formatters.XmlFormatter.AddQueryStringMapping("$format", "xml", "application/xml");
config.EnableQuerySupport(); }
另外須要注意的一點是OData查詢是大小寫敏感的。
我將使用Fiddler去測試這個服務
咱們沒有寫任何一個特別的邏輯去支持這些功能,所有都由框架來提供的。是否是OData爲你的搜索、過濾、或者分頁API的時候提供了一個很好的選項。
然而,若是要向組織外部公開可查詢的操做,能夠利用查詢驗證添加一個保護層以保護咱們的服務。微軟的程序經理Hongmei Ge介紹了幾種在Queryable API中添加驗證的場景。
Hongmei指出的第一個場景是,使用AllowedQueryOptions屬性,只容許包含$top和$skip的查詢。以下所示:
[Queryable(AllowedQueryOptions = AllowedQueryOptions.Skip | AllowedQueryOptions.Top)]
public IQueryable Get(int projectId)
還可使用MaxTop和MaxSkip屬性將$top和$skip的最大值限制在100和200:
[Queryable(MaxTop = 100)]
public IQueryable Get(int projectId)
[Queryable(MaxSkip = 200)]
public IQueryable Get(int projectId)
利用AllowedOrderByProperties,能夠將結果按Id屬性排序,由於按其餘屬性排序可能會很慢:
[Queryable(AllowedOrderByProperties = "Id")]
public IQueryable Get(int projectId)
若是容許客戶端在$filter內使用相等比較,應該使用AllowedLogicalOperators對其進行驗證:
[Queryable(AllowedLogicalOperators = AllowedLogicalOperators.Equal)]
public IQueryable Get(int projectId)
將AllowedArithmeticOperators設置爲None,就能夠關閉$filter中的算術操做:
[Queryable(AllowedArithmeticOperators = AllowedArithmeticOperators.None)]
public IQueryable Get(int projectId)
你還可使用AllowedFunctions屬性來限制$filter中的函數使用:
[Queryable(AllowedFunctions = AllowedFunctions.StartsWith)]
public IQueryable Get(int projectId)
上面的代碼意味着只能在$filter中使用StartsWith函數。
Hongmei還演示了高級場景中的查詢驗證,如爲$skip、$top、$orderby、$filter自定義默認驗證邏輯,以及使用ODataQueryOptions來驗證查詢。
相關文章:
OData Developers Reference: http://www.odata.org/developers/
OData in ASP.NET: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api
Limiting OData Query Options: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options
OData Security: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-security-guidance
Add an OData Feed to Your App Using Web API:http://marknic.net/2013/03/02/add-an-odata-feed-to-your-app-using-web-api/
Working with OData Queries in ASP.NET Web API:http://www.codeguru.com/csharp/.net/working-with-odata-queries-in-asp.net-web-api.htm
在ASP.NET Web API OData中利用Queryable API進行驗證: http://www.infoq.com/cn/news/2013/02/queryable-api
一個建立 OData 的新選項: Web API:http://msdn.microsoft.com/zh-cn/magazine/dn201742.aspx
Building OData Service using ASP.Net Web API Tutorial – Part 1
示例代碼下載 : 原例子有點小問題,堪正以下: http://files.cnblogs.com/files/HouZhiHouJueBlogs/WebApiOData.zip