转: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