[水煮 ASP.NET Web API2 方法论](12-3)OData 查询
问题
Web API 怎么支持通用的 OData 系统查询项,例如 $select 或 $filter。
解决方案
为了在 Web API 中启用查询项,我们需要在 Action 上使用 EnableQueryAttribute。
如果 Action 没有返回集合,而是返回单个对象的实例,调用端仍然可以使用 $expand 和 $select 两个查询语句,要达到这个目的,我们必须将返回对象包装在 SingleResult<T> 中。集合和单个对象实例作为返回值的例子如订单 12-7 所示
清单 12-7. 在两个路由上启用查询语句
public class PlayersController : ODataController
{
private readonly PlayersContext playersDbContext = new PlayersContext();
[EnableQuery]
public IQueryable<Player> GetAllPlayers()
{
Return playersDbContext;
}
[EnableQuery]
public SingleResult<Player> GetSinglePlayers(int key)
{
return SingleResult.Create(playersDbContext.Where(x => x.Id == key).AsQueryable());
}
}
工作原理
OData 查询选项是被定义在 OData 规范中,如,查询字符串的参数控制的是返回资源的数量和顺序。ASP.NET Web API 几乎支持所有的标准查询项:
- $expand:允许响应给客户端的信息包含关联资源(导航属性)
- $select:限制返回的属性
- $filter:过滤 Api 暴露出来的资源
- $count:获取集合中实体的总数
- $orderby:指定集合的排序 key
- $skip:获取集合跳过的数量
- $top:限制集合返回集合的数量
- $format:请求特定的响应格式
唯一不支持的是 $search 查询参数。
小提示 可以查看 OData 4.0 支持的完整的文档地址:http://docs.oasis-open.org/OData/new-in-OData/v4.0/cn01/new-in-OData-v4.0-cn01.html
查询项是在 ASP.NET Web API 中被 ODataQueryOption 类所描述的。EnableQueryAttribute 的工作方式实际是非常简单的。因为他是 Action 的 Filter,在 OnActionExecuted 方法中会获取 Action 的响应,并转换 HttpContent 为ObjectContent<T>。然后根据 HttpRequest 基于客户端的参数构造 ODataQueryOptions 实例,并返回相应的响应给客户端。如果响应是集合的话,可以响应客户端所有的查询项。如果响应不是集合,就会通过 ObjectContent 包装成 SingleResult<T>。这些时候,$expand 和 $select 都是可用的。
不使用 EnableQueryAttribute,也可以使用 ODataQueryOptions,他是可以接受 Action 的参数的。这种方式是通过自定义 HttpParameterBinding 类型的 ODataQueryParameterBinding 来支持的。我们也可以使用 ODataQueryOptions 实例中的信息手动执行相关查询。
在 Web API 中我们不需要完全掌握 OData 就可以体会到查询项给我们带来的便利。就算不是基于 ODataCotrollers,只要 Action 上使用了 EnableQueryAttribute 属性标签,我们还是可以在 Web API 上使用一些基础查询项,例如,$top,$skip,$select。
代码演示
在 Controller 的 Action 上使用 EnableQueryAttribute,这样的请求就可以使用 OData 查询项,如清单 12-7
- Host/Plays(1)$select=Name,Team:使用 Player 实体的 Id 进行过滤,仅仅返回 Name 和 Team 两个属性。这个例子的响应,如清单 12-8.
清单 12-8. 从 OData 的 Web API 查询响应例子
{
"@OData.context":"http://localhost:43539/OData/$metadata#Players(Name,Team)/$entity","Name":"Name1","Team":"Team"
}
- Host/Players?skip=1&$top=2:忽略集合中第一个实体,然后再剩下的实体中获取两个返回(可以理解为分页的第二页数据,每页大小是 2)。具体响应,如清单 12-9 所示。
清单 12-9. 从 OData 的 Web API 查询响应例子
{
"@OData.context":"http://localhost:43539/OData/$metadata#Players","value":[
{
"Id":1,"Name":"Name1","Team":"Team"
},{
"Id":2,"Name":"Name11","Team":"Team"
}
]
}
- Host/Players?$format=application/json;OData.metadata=full&$filter=Team%20eq%20%27Team2%27:请求条件你为 Team 属性值为 Whales,以 json 格式返回 ,包含 OData 元数据的所有信息,包含类型和导航链接。具体响应结果,如清单 12-10 所示
{
"@OData.context":"http://localhost:43539/OData/$metadata#Players","value":[
{
"@OData.type":"#BoiledCode.WebApi.Recipe.ODataDemo.Models.Player","@OData.id":"http://localhost:43539/OData/Players(3)","@OData.editLink":"http://localhost:43539/OData/Players(3)","Id":3,"Name":"Name2","Team":"Team2"
},{
"@OData.type":"#BoiledCode.WebApi.Recipe.ODataDemo.Models.Player","@OData.id":"http://localhost:43539/OData/Players(4)","@OData.editLink":"http://localhost:43539/OData/Players(4)","Id":4,"Name":"Name21","Team":"Team2"
}
]
}
就像上面提到的,我们可以通过在 Action 方法中使用 ODataQueryOptions 参数,来手动的实现询项。ODataQueryParameterBinding 会帮我完成将对象传入到 Action 的操作,这样我们就可以 Action 内部提取 OData 相关的查询项了。
清单 12-11. 在 Action 中使用 ODataQueryOptions
public IQueryable<Player> GetAllPlayers(ODataQueryOptions queryOptions)
{
// 客户端传入的 top 和 skip
var filtered = db.Players.Skip(queryOptions.Skip.Value);
if (queryOptions.Top.Value > )
{
filtered = filtered.Take(queryOptions.Top.Value);
}
return filtered.AsQueryable();
}
[水煮 ASP.NET Web API2 方法论](12-3)OData 查询的更多相关文章
- [水煮 ASP.NET Web API2 方法论](3-9)空气路由的设置
阅读导航 问题 解决方案 工作原理 代码演示 在此解释一下,空气路由,是本人臆想出来,觉着更能表达 IgnoreRoute 的意图,如果看着辣眼睛^^,请见谅. 问题 我们在之定义过集中式路由,集中式 ...
- [水煮 ASP.NET Web API2 方法论](1-2)在 WebForm 应用程序中添加 ASP.NET Web API
问题 怎么样将 Asp.Net Web Api 加入到 Asp.Net Web From 应用程序中 解决方案 在 Visual Studio 2013 中,创建新的 Web From,可以直接在&q ...
- [水煮 ASP.NET Web API2 方法论](1-5)ASP.NET Web API Scaffolding(模板)
问题 我们想快速启动一个 ASP.NET Web API 解决方案. 解决方案 APS.NET 模板一开始就支持 ASP.NET Web API.使用模板往我们的项目中添加 Controller,在我 ...
- [水煮 ASP.NET Web API2 方法论](1-4)从 MVC Controller 链接到 API Controller 以及反向链接
问题 想创建一个从 ASP.NET MVC controller 到 ASP.NET Web API controller 的直接链接,或者反向链接. 解决方案 可以使用 System.Web.Htt ...
- [水煮 ASP.NET Web API2 方法论](1-1)在MVC 应用程序中添加 ASP.NET Web API
问题 怎么样将 Asp.Net Web Api 加入到现有的 Asp.Net MVC 项目中 解决方案 在 Visual Studio 2012 中就已经把 Asp.Net Web Api 自动地整合 ...
- [水煮 ASP.NET Web API2 方法论](1-3)如何接收 HTML 表单请求
问题 我们想创建一个能够处理 HTML表单的 ASP.NET Web API 应用程序(使用 application/x-www-form-urlencoded 方式提交数据). 解决方案 我们可以创 ...
- [水煮 ASP.NET Web API2 方法论](1-6)Model Validation
问题 想要 ASP.NET Web API 执行模型验证,同时可以和 ASP.NET MVC 共享一些验证逻辑. 解决方案 ASP.NET Web API 与 ASP.NET MVC 支持一样的验证机 ...
- [水煮 ASP.NET Web API2 方法论](1-7)CSRF-Cross-Site Request Forgery
问题 通过 CSRF(Cross-Site Request Forgery)防护,保护从 MVC 页面提交到ASP.NET Web API 的数据. 解决方案 ASP.NET 已经加入了 CSRF 防 ...
- [水煮 ASP.NET Web API2 方法论](1-8)添加 Session 状态
问题 ASP.NET Web API 构建 Web 应用程序时,要求使用 Session 在服务器存储一些用户特定的信息 解决方案 ASP.NET Web API 不支持 Session,因为 API ...
- [水煮 ASP.NET Web API2 方法论](12-1)创建 OData
问题 怎样用在 Web API 中创建 OData 服务. 解决方案 对于我们来说,在 Web API 中使用 OData最简单的方式就是使用 ASP.NET 模板来创建Odata Controlle ...
随机推荐
- Chrome浏览器的使用技巧
查询Chrome浏览器自身的DNS缓存 在浏览器的地址栏输入:chrome://net-internals/#dns 在左侧的菜单栏,点击对应菜单可以查看对应选项的相关内容. 在Chrome浏览器中输 ...
- Mybatis手工写sql语句及Mapper.xml方法
首先在项目中 建一个mapper包,然后在spring集合mybatis的配置文件中设置扫描这个mapper包 然后,建 封装查询结果需要的 pojo 然后,在 mapper包中创建 Mapper接口 ...
- Codeforces Round #337 (Div. 2) A水
A. Pasha and Stick time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- mysql中的case when 与if else
大神说:在sql中,能用if else 就不用case when 下面来看看,具体为什么,没有搞清楚,如果有大神知道的提供下资料: Mysql的if既可以作为表达式用,也可在存储过程中作为流程控制 ...
- matlab求一个矩阵中各元素出现的个数(归一化)
function [m,n] = stamatrix(a) %网上找到的方法,感觉很巧妙 x=a(:); x=sort(x); d=diff([x;max(x)+1]); count = diff(f ...
- 搜索:BFS
如果题目真的要考察宽度优先搜索,那么这类题目往往具有比较大的编码难度,换个说法,就是细枝末节特别多,状态特别复杂.. 剥茧抽丝,这里以一个比较“裸”的BFS作为例子,了解一下实现BFS的一些规范. 直 ...
- vijos 1180 选课 树形DP
描述 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修了这M门课并考核通过就能获得 ...
- [SDOI2011] 染色(Luogu 2486)
题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例#1: 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C ...
- 安装在Linux下的jenkins执行windows下的bat命令
launch method里面没有 launch agent via java web start 默认是disable 需要改成random 转载自: http://blog.csdn.net/so ...
- [BZOJ2754] [SCOI2012]喵星球上的点名解题报告|后缀数组
a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串来点名,每次读出一个串的 ...