Odata简介和Demo
转:http://www.cnblogs.com/shanyou/archive/2013/06/11/3131583.html
在SOA的世界中,最重要的一个概念就是契约(contract)。在云计算的世界中,有关通信的最重要的概念也是契约。XML具有强大对数据的描述能力,Atom格式和AtomPub都建立在XML之上,在Google和微软的推动下,也已经成为标准。但是,Atom/AtomPub和ODBC/OLEDB这样的真正数据交互协议相比较,还有着根本上的欠缺:缺乏数据类型的具体描述,降低了交互性能。缺乏对数据查询的控制能力,比如返回特定的数据集合的区间,或者说分页能力等等。微软基于EDM模型释出了:OData,这里也可以看出Entity Framework对于NHibernate这样的ORM的工具不同的战略考虑。
在.NET中,早期是用Remoting/Webservice来处理所有程序间的通信,从.NET 3.0开始使用WCF统一了通信模型,ASP.NET MVC4的推出,形成大的One ASP.NET战略,增加了WebAPI和SingalR作为通信服务:

开放数据协议(OData)是一个查询和更新数据的Web协议。OData应用了web技术如HTTP、Atom发布协议(AtomPub)和JSON等来提供对不同应用程序,服务和存储的信息访问。除了提供一些基本的操作(像增删改查),也提供了一些高级的操作类似过滤数据和实体的导航。OData扩展了上述的协议但是不是取代他们。他可以被XML(ATOM)或者JSON取代但是OData的重要在于它符合REST原则。在某种意义上,它建立在'简单'的REST HTTP 服务上,并且有着清晰的目标——简化和标准化我们操作和查询数据的方式。如果你过去在给你的REST服务创建搜索、过滤、或者分页API的时候感觉很麻烦,那么OData将是一个不错的选择。
目前很多接口,无论是基于SOAP、REST还是别的都在交换数据时使用不同的模式。这种方法随后返回一大堆客户记录。你随后可以决定添加分页支持。你希望将结果捆绑在一个网格中,并对数据排序。最后,决定想要查询的东西,通过比如邮政编码来查询。
首先是,没有创建泛型客户端的途径,而这些和API紧密联系,因为它不知道参数的顺序或者模式被使用的顺序。因为不能创建泛型客户端,你必须为每一个你希望暴露的API创建客户端。简单的基础HTTP API可以实现,但其仍旧很昂贵。逐渐增多的多样性客户端与这些API通信加剧了这个问题。
这种模式的第二个问题是它迫使开发人员进行很艰难的权衡。我应该暴露多少个查询?你必要在暴露每一个你能想到内容和少暴露一些,从而削弱服务之间协调。前者导致API 需要管理的界面的增加,后者会导致我们通常所说的“数据竖井”,也就是关键数据在特定模式中锁定,其他应用不能够简单应用,因为它没有以一种需要的方式暴露给这个应用。服务试图比单一应用要获得更长久一些,因此你需要以一种方式设计API,使其能够持久,所以如果你发现你需要添加服务借口的新版本可不太好办,比如创建新的客户端。在很多案例中,服务开发者和客户端开发者并不是同一个人,因而改变服务接口简直就是不可能的事情。
通过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
Odata简介和Demo的更多相关文章
- Web Api系列教程第2季(OData篇)(一)——OData简介和一个小应用
		第一季的链接以及系列导航:http://www.cnblogs.com/fzrain/p/3490137.html 在这里,首先要感谢Taiseer Joudeh不断的为我们带来最新的技术分享,楼主对 ... 
- Disruptor并发框架(一)简介&上手demo
		框架简介 Martin Fowler在自己网站上写了一篇LMAX架构的文章,在文章中他介绍了LMAX是一种新型零售金融交易平台,它能够以很低的延迟产生大量交易.这个系统是建立在JVM平台上,其核心是一 ... 
- 【JSONCpp】简介及demo
		一.JSON简介 JSON 一种轻量级的数据交换格式,易于阅读.编写.解析,全称为JavsScript ObjectNotation. JSON由两种基本结构组成 ① 名字/值 对的集合,可以理解 ... 
- PyQt5简介及demo
		PyQt5说明 pyqt5是一套Python绑定Digia QT5应用的框架.它可用于Python 2和3.本教程使用Python 3.Qt库是最强大的GUI库之一.pyqt5的官方网站http:// ... 
- 国外源码精品-Android-PullToRefresh 简介与DEMO导入
		转载地址:http://my.oschina.net/cuitongliang/blog/170708 (一)&&http://my.oschina.net/cuitongliang/ ... 
- Flask简介,安装,demo,快速入门
		1.Flask简介 Flask是一个相对于Django而言轻量级的Web框架. 和Django大包大揽不同,Flask建立于一系列的开源软件包之上,这其中 最主要的是WSGI应用开发库Werkzeug ... 
- JWT令牌简介及demo
		一.访问令牌的类型 二.JWT令牌 1.什么是JWT令牌  JWT是JSON Web Token的缩写,即JSON Web令牌,是一种自包含令牌. JWT的使用场景: 一种情况是webapi,类似之 ... 
- bluebird-api简介及demo
		var Promise = require("bluebird"); var fs = require("fs"); //方法Promise化 var read ... 
- 轻量级通信引擎StriveEngine —— C/S通信demo(附源码)
		前段时间,有几个研究ESFramework的朋友对我说,ESFramework有点庞大,对于他们目前的项目来说有点“杀鸡用牛刀”的意思,因为他们的项目不需要文件传送.不需要P2P.不存在好友关系.也不 ... 
随机推荐
- mysql--mysql的安装与目录介绍
			一.mysql的下载安装 1.下载安装 1.windows10下安装 我们采用绿色免安装版, 打开你的mysql文件夹中的bin目录,我的是这个样子的 将这个路径添加入系统环境变量,首先右键此电脑-- ... 
- html页面pc显示正常,在手机端适配也可以看整个页面
			<meta name="viewport" content="width=1250,initial-scale=0,maximum-scale=2"/&g ... 
- 如何在WS系统的DOS命令台打印JAVA_HOME变量
			echo %JAVA_HOME% 查看环境变量 path 新增临时环境变量 path D:\test;%path% 注意是反斜杆 cls 清空 F7 显示历史CMD指令 
- S2-052复现过程(附POC利用)
			漏洞编号:CVE-2017-9805(S2-052) 影响版本:Struts 2.5 - Struts 2.5.12 漏洞概述:问题出现在struts2-rest-plugin插件XStreamHan ... 
- 搭建一个ES6开发环境
			一.首先先建立一个项目工程目录,并在目录下建立两个文件夹:src和dist src:书写ES6代码的文件夹,写的js程序都放在这里. dist:利用Babel编译成的ES5代码的文件夹,在HTML页面 ... 
- 【FAQ】Maven 本地仓库明明有jar包,pom文件还是报错解决办法
			方法一: 找到出错的jar包文件位置,删掉_maven.repositories文件 方法二: maven中的本地仓库的index索引没有更新导致 解决方案: 在eclipse中打开菜单 window ... 
- maven指定本地的文件包
			maven指定本地的文件包 案例: <!-- CKFinder begin --> <dependency> <groupId>net.coobird</gr ... 
- URL的组成和含义
			1.URL - Uniform Resource Locator 当您点击 HTML 页面中的某个链接时,对应的 <a>标签指向万维网上的一个地址. 统一资源定位器(URL)用于定位万维网 ... 
- Android跳转淘宝、京东APP商品详情页
			import Android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; imp ... 
- 一次完整的http请求全程
			当我们在打开浏览器的时候,在地址栏输入诸如 http://www.baidu.com时,几秒后浏览器打开百度页面,几秒钟内到底发生了哪些事情. 一.解析URL: 浏览器首先会对输入的URL进行检查,如 ... 
