[转]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教程(六) 安全与身份认证 摘要: 在实际的项目应 ...
随机推荐
- 纸壳CMS的插件加载机制
纸壳CMS是一个开源的可视化设计CMS,通过拖拽,在线编辑的方式来创建网站. GitHub https://github.com/SeriaWei/ZKEACMS.Core 欢迎Star,Fork,发 ...
- python--面向对象(02)
1.类的成员 在类中你能写的所有内容都是类的成员 class 类名: # 方法 def __init__(self, 参数1, 参数2....): # 属性变量量 self.属性1 = 参数1 sel ...
- Help Jimmy(动态规划)
点击打开链接 Help Jimmy Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12168 Accepted: 402 ...
- C语言 从头学起了
1,我用的是VC6.0++编译器 具体安装使用教程 去网上找 2,刚写hello world时候 就遇到一个坑. #网上 hello world 代码 #include<stdio.h> ...
- npm 常用配置
npm config list/ls 显示配置信息npm config list/ls -l 更详细npm -h 显示帮助信息,建议多查看npm -l display full usage info ...
- [java实现]常见算法之字符串操作
一.字符串反转 把一个句子中的打次进行反转,比如“how are you” ,变为 “you are how” // 字符串反转 public class StringTest { // 字符反转的方 ...
- Centos7.4下安装Redis5.0
一.下载Redis Redis下载地址:https://redis.io/download 二.安装依赖包 安装Redis之前需要安装c++命令 yum install gcc-c++ 三.上传并解压 ...
- 对HTTP和TCP的理解
1.TCP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上. ...
- Angular Material 按钮图标系列
工做中经常用到Angular Material 中的好多按钮素材,奈何官网经常上不去,所以只能自己把这些常用的按钮扒下来了,留给自己同时也留给大家方便查看. Angular material mat- ...
- Android的启动模式(下)
Android中的启动模式(下) 在这篇文章中,我会继续跟大家分享有关于Android中启动模式的相关知识.当然,如果对这个启动模式还不完全了解或者没有听过的话,可以先看看我之前写的有关于这个知识点的 ...