[转]Web Api系列教程第2季(OData篇)(二)——使用Web Api创建只读的OData服务
本文转自:http://www.cnblogs.com/fzrain/p/3923727.html
前言
很久没更新了,之前有很多事情,所以拖了很久,非常抱歉。好了,废话不多说,下面开始正题。本篇仍然使用上一季的的项目背景(系列地址http://www.cnblogs.com/fzrain/p/3490137.html)来演示OData服务,因此我们可以直接使用之前建好的数据访问层。但是不是说一定要看到之前的所有内容,我们只是借用数据库访问层,对于数据库的模型构建移步(使用Entity Framework Code First构建数据库模型)。
有了数据访问的基础,我们可以开始构建OData服务了。
第一步:创建空的Web Api项目
打开项目的解决方案,新建web项目,选择空的web api项目(如上图所示),记得选择.Net Framework 4.5。建好项目之后需要添加对“EntityFramework”和“Learning.Data”(我们的数据访问层)的引用。
第二步:添加OData引用
在默认的情况下,Web Api是无法支持OData的,因此我们需要添加对“Microsoft.ASP.NET Web API 2.1 OData”的引用——打开NuGet如下图所示:
第三步:配置OData路由
打开“App_Start”文件夹中系统帮我们创建的“WebApiConfig”类,在这里有一个Register方法并注册路由规则。我们需要配置的OData也是写在这里,代码如下:

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务 // Web API 路由
config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapODataRoute("elearningOData", "OData", GenerateEdmModel());
}
private static IEdmModel GenerateEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.EntitySet<Course>("Courses");
builder.EntitySet<Enrollment>("Enrollments");
builder.EntitySet<Subject>("Subjects");
builder.EntitySet<Tutor>("Tutors"); return builder.GetEdmModel();
}
}

虽然我们只是使用OData服务,但我并没有移除默认的配置因为这两种路由规则是可以共存的。
上面为我们的OData服务配置了路由规则以及实体数据模型(EDM)
EDM主要是定义数据类型、导航属性和方法来适应OData的格式。有2种方式来定义EDM,第一种是基于公约的方式,我们将使用“ODataConventionModelBuilder”类,另一种则是使用“ODataModelBuilder”。
在这里我们将使用“ODataConventionModelBuilder ”因为它会根据我们定义的导航属性来生成关联集合的链接。相比来说写的代码比较少。如果你想在关联集合间有更多的控制,那么你可以使用“ODataModelBuilder”。
我们在builder对象中添加了4个不同的实体,注意:字符串参数“Courses”定义的实体集合名字必须与Controller的名字保持一致,也就是说我们的controller的名字必须是“CoursesController”。
“MapODataRoute”是一个扩展方法,当我们添加对OData引用时就可以使用了。它主要为OData服务来定义路由规则的:第一个参数指定一个名字,这个名字客户端是不会用到的;第二个参数是指对应OData终结点的URI前缀(在我们的案列中访问Courses资源的URI就应该是:http://hostname/odata/Courses)。你可以在同一个应用程序中拥有多个OData终结点,只需要调用“MapODataRoute”方法指定不同的前缀就行了。
第四步:添加第一个只读的OData控制器
现在我们创建一个Web Api控制器来处理OData URI类似“/odata/Courses”的HTTP请求。右击controller文件夹->新增->选择“空的API控制器”模板并命名“CoursesController”。
创建好之后,首先将我们的基类改成“System.Web.Http.OData.EntitySetController”。这个泛型基类需要2个参数:第一个指映射到这个controller对应的实体类型;第二个参数是指这个实体主键的类型,下面上代码:

public class CoursesController : EntitySetController<Course, int>
{
LearningContext ctx = new LearningContext(); [Queryable(PageSize = 10)]
public override IQueryable<Course> Get()
{
return ctx.Courses.AsQueryable();
} protected override Course GetEntityByKey(int key)
{
return ctx.Courses.Find(key);
}
}

“EntitySetController”类定义了很多抽象和可重写的方法来更新和查询实体,因此你会发现你可以重写很多的方法例如:Get(),GetEntityByKey(),CreateEntrty(),PatchEntity(),UpdateEntity(),etc…
正如我前面提到的,我们将创建一个只读的控制器,这就意味着我们只实现读取的操作,解释一下上面代码的实现:
1.重写Get()方法并附上[Queryable]特性,这意味着我们允许客户端发送HTTP的Get到我们的终结点并在URI参数值支持filter,order by,pagination的操作。Queryable特性是一个action过滤器,主要转换和校验查询的URI及相应参数,当客户端查询将花费很多时间或者大量数据时候这个特性将会有意想不到的作用(举个例子:设置PageSize属性,这样一次性只会给客户端返回10条数据)
2.重写GetEntityByKey(int key)方法将支持客户端发送HTTP访问单个资源,形式类似于“/odata/Courses(5)”。注:这里的key代表对应实体的主键。
第五步:测试Courses控制器
现在我们开始测试我们的controller,对于所有的请求我们都将accept header指定为“application/json”,因此我们将获得轻量JSON数据,你也可以去指定accept header为“application/json;odata=verbose”或者“application/atom+xml”来查看结果。
我们演示一下场景:
1.$filter:我们查询所有时长超过4小时的课程:发送Get请求http://{hostname}/OData/Courses?$filter=Duration gt 4
2.$orderby, $take:我们需要根据课程名排序并获取前5条记录:发送Get请求http://{hostname}/OData/Courses?$orderby=Name&$top=5
3.$select:我们仅需要获取Name和Duration字段的值:发送Get请求http://{hostname}/OData/Courses?$select=Name,Duration
4.$expand:我们需要获取每个课程对应的主题和讲师并根据课程名倒序排列:发送Get请求http://{hostname}/OData/Courses?$expand=CourseTutor,CourseSubject&$orderby=Name desc
通过刚刚4个例子我们可以看到在我们的返回结果中包含了UserName和Password这两个字段,但个信息是没必要给客户端的。,
十分幸运的是我们只需要去配置一下EDM就可以在返回结果中不包含这两个字段了,具体做法在WebApiConfig类中的GenerateEdmModel()方法里加入如下代码:

private static IEdmModel GenerateEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.EntitySet<Course>("Courses");
builder.EntitySet<Enrollment>("Enrollments");
builder.EntitySet<Subject>("Subjects");
builder.EntitySet<Tutor>("Tutors");
var tutorsEntitySet = builder.EntitySet<Tutor>("Tutors"); tutorsEntitySet.EntityType.Ignore(s => s.UserName);
tutorsEntitySet.EntityType.Ignore(s => s.Password); return builder.GetEdmModel();
}

[转]Web Api系列教程第2季(OData篇)(二)——使用Web Api创建只读的OData服务的更多相关文章
- Web Api系列教程第2季(OData篇)(二)——使用Web Api创建只读的OData服务
前言 很久没更新了,之前有很多事情,所以拖了很久,非常抱歉.好了,废话不多说,下面开始正题.本篇仍然使用上一季的的项目背景(系列地址http://www.cnblogs.com/fzrain/p/34 ...
- Web Api系列教程第2季(OData篇)(一)——OData简介和一个小应用
第一季的链接以及系列导航:http://www.cnblogs.com/fzrain/p/3490137.html 在这里,首先要感谢Taiseer Joudeh不断的为我们带来最新的技术分享,楼主对 ...
- ASP.NET Web API系列教程目录
ASP.NET Web API系列教程目录 Introduction:What's This New Web API?引子:新的Web API是什么? Chapter 1: Getting Start ...
- ASP.NET Web API系列教程(目录)(转)
注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP.NET Web API.这是一个用来在.NET平台上建立HTTP服务的Web API框架,是微软的又一项令人振奋的技术.目前,国内 ...
- [转]ASP.NET Web API系列教程(目录)
本文转自:http://www.cnblogs.com/r01cn/archive/2012/11/11/2765432.html 注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP ...
- Web攻防系列教程之文件上传攻防解析(转载)
Web攻防系列教程之文件上传攻防解析: 文件上传是WEB应用很常见的一种功能,本身是一项正常的业务需求,不存在什么问题.但如果在上传时没有对文件进行正确处理,则很可能会发生安全问题.本文将对文件上传的 ...
- 源码学习系列之SpringBoot自动配置(篇二)
源码学习系列之SpringBoot自动配置(篇二)之HttpEncodingAutoConfiguration 源码分析 继上一篇博客源码学习系列之SpringBoot自动配置(篇一)之后,本博客继续 ...
- SpringBoot系列之profles配置多环境(篇二)
SpringBoot系列之profles配置多环境(篇二) 继续上篇博客SpringBoot系列之profles配置多环境(篇一)之后,继续写一篇博客进行补充 写Spring项目时,在测试环境是一套数 ...
- 【转】ASP.NET WEB API系列教程
from: 西瓜小强 http://www.cnblogs.com/risk/category/406988.html ASP.NET Web API教程(六) 安全与身份认证 摘要: 在实际的项目应 ...
随机推荐
- .Net MVC5路由机制与扩展
新建一个MVC项目启动后,首先访问的地址是http://localhost:xxx/Home/Index,这时候我们也明白因为在程序中有个叫做Home的控制器,并且在这个控制器下面有个叫做Index的 ...
- windows server 2008 站点系列--AD的站点建立与子网的管理(zhuanzai)
本次课程将给大家介绍AD中站点和子网的功能.站点和子网之间的关联,以及相关的设置步骤. 应用背景介绍: contoso公司的总部在西安(Xian),陕南的汉中(Shannan)和陕北的榆林(Shanb ...
- 索引+sql优化
索引的概念: 索引是提高查询速度的一种手段.索引有很多种,以下是索引树的结构 要求查询出薪资大于5000的雇员信息,只要在树中找到5000的节点,直接查询该节点右边的数据即可,左边就不用管了,这样提高 ...
- jquery点击页面其他位置隐藏div
$("#btnAdd").on('click', function (e) { $("#setUp").toggle(); $(document).one('c ...
- ajax1—php(27)
一 简介 web程序工作原理图: 传统的web程序工作原理图: Ajax工作原理图: 1. 关于Ajax l Asynchronous 异步 l JavaScript l And l XML ...
- CAS客户端整合(二) Zabbix
Zabbix是一个强大的服务器/交换机监控应用,有zabbix-server, zabbix-client, zabbix-web 三部分.zabbix-web管理端是用php写的. 前文参考:CAS ...
- Windows server 2008启动remote dosktop services服务报错1079
原创 欢迎转载,届时请注明出处 报错场景 今天,刚开始启动win server的远程连接服务(remote desktop services)时 该服务可以正常启动,然后选择了 “计算机--> ...
- Metasploit渗透某高校域服务器
本文作者:i 春秋签约作家——shuteer 前期准备:1. 使用Veil生成免杀PAYLOAD: 2. 有一个外网IP的服务器,安装好metasploit,方便操作. 一.SHELL反弹meterp ...
- Linux 中排除掉筛选的文件
以下命令以网站目录www为例做介绍,有时候更新网站的时候需要保留比如图片目录,或者其他目录就需要这样的操作 实例一: 删除文件夹内所有文件只保留一个文件命令 [root@linuxzgf www]# ...
- MQ 消息队列的比较
目前业界有很多MQ产品,我们作如下对比: RabbitMQ 是使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP, STOMP,也正是如此,使的它变的非常重量 ...