系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html

前言

这一篇文章主要介绍一下资源间的关联——例如在学生和课程之间就存在这样的关联:每一个课程都会有多个学生来选,如何获取这些有关联的信息?如何实现选课的业务?对于客户端应该怎么来调用呢?下面给出解决方案:

配置对应的路由

对于上面的需求,我们可以先定制一个URI模板:”api/courses/courseid/students/{userName}“,如果我们打算查询所有选了courseId为5的学生,那么客户端就应该发送Get请求”api/courses/5/students/”.如果我们打算为用户名为”TaiseerJoudeh“的学生选择课程CourseId为5的课程,那么就应该发送Post请求”api/courses/5/students/TaiseerJoudeh“。

为了实现上面说的,我们首先要在”WebApiConfig“中添加如下一条路由信息:

config.Routes.MapHttpRoute(
name: "Enrollments",
routeTemplate: "api/courses/{courseId}/students/{userName}",
defaults: new { controller = "Enrollments", userName = RouteParameter.Optional }
);

可以看到在这里courseId是必选的,而userName是可选的

创建响应的控制器

正如上面路由配置的,我们应该有一个“EnrollmentsController”,在这个控制器中我们应该包含2个方法:Get用来返回对应的学生信息,Post用来实现学生选课,下面上代码:

public class EnrollmentsController : BaseApiController
{
public EnrollmentsController(ILearningRepository repo)
: base(repo)
{
} public IEnumerable<StudentBaseModel> Get(int courseId)
{
IQueryable<Student> query; query = TheRepository.GetEnrolledStudentsInCourse(courseId).OrderBy(s => s.LastName); var totalCount = query.Count(); System.Web.HttpContext.Current.Response.Headers.Add("X-InlineCount", totalCount.ToString()); var results = query .ToList()
.Select(s => TheModelFactory.Create(s)); return results; } public HttpResponseMessage Post(int courseId, [FromUri]string userName, [FromBody]Enrollment enrollment)
{
try
{ if (!TheRepository.CourseExists(courseId)) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Could not find Course"); var student = TheRepository.GetStudent(userName);
if (student == null) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Could not find Student"); var result = TheRepository.EnrollStudentInCourse(student.Id, courseId, enrollment); if (result == )
{
return Request.CreateResponse(HttpStatusCode.Created);
}
else if (result == )
{
return Request.CreateResponse(HttpStatusCode.NotModified, "Student already enrolled in this course");
} return Request.CreateResponse(HttpStatusCode.BadRequest); }
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
}

在Post方法中我们使用了FormURL和FormBody的特性,这样就表明我们将从请求的什么地方来获得参数(从URL中获取UserName,从Body中获取enrollment),对于enrollment对象来说只要包含一个日期即可(详情参看系列数据库及模型的构建:http://www.cnblogs.com/fzrain/p/3491804.html),同时我们要发送“courseId”以及“UserName”。

下面测试一下我们的Post方法:我们打算为“TaiseerJoudeh”选择CourseId为5的课程:

在之前已经介绍过,我们使用http状态码来响应请求的不同结果(从这次开始看的朋友可以参考:http://www.cnblogs.com/fzrain/p/3520442.html),请求成功则返回201(Resource Created),如果该选课记录已存在则返回304(Not modified)

总结

对于资源间的关联就这么点到为止了,具体的应用在以后慢慢感悟了。对于之前给出的Get方法,有一个明显的瑕疵:对于大量的数据,服务器会全部返回给客户端,这是非常不好的,那么下一章我们就来实现分页。

本章源码:http://yun.baidu.com/share/link?shareid=1470307710&uk=17559114&third=0

使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【六】——实现资源间的关联的更多相关文章

  1. ASP.NET Web Api构建基于REST风格的服务实战系列教程

    使用ASP.NET Web Api构建基于REST风格的服务实战系列教程[十]——使用CacheCow和ETag缓存资源 系列导航地址http://www.cnblogs.com/fzrain/p/3 ...

  2. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【开篇】【持续更新中。。。】

    最近发现web api很火,园内也有各种大神已经在研究,本人在asp.net官网上看到一个系列教程,原文地址:http://bitoftech.net/2013/11/25/detailed-tuto ...

  3. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【五】——在Web Api中实现Http方法(Put,Post,Delete)

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在Web Api中,我们对资源的CRUD操作都是通过相应的Http方法来实现——Post(新 ...

  4. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【九】——API变了,客户端怎么办?

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 一旦我们将API发布之后,消费者就会开始使用并和其他的一些数据混在一起.然而,当新的需求出现 ...

  5. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【八】——Web Api的安全性

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 这一篇文章我们主要来探讨一下Web Api的安全性,到目前为止所有的请求都是走的Http协议 ...

  6. [转]使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【八】——Web Api的安全性

    本文转自:http://www.cnblogs.com/fzrain/p/3552423.html 系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html ...

  7. 使用ASP.NET WEB API构建基于REST风格的服务实战系列教程(一)——使用EF6构建数据库及模型

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 使用Entity Framework Code First模式构建数据库对象 已经决定使用EF C ...

  8. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【二】——使用Repository模式构建数据库访问层

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在数据访问层应用Repository模式来隔离对领域对象的细节操作是很有意义的.它位于映射层 ...

  9. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【外传】——Attribute Routing

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 题外话:由于这个技术点是新学的,并不属于原系列,但借助了原系列的项目背景,故命名外传系列,以后也可 ...

随机推荐

  1. Ueditor 上传图片 如何设置只显示 本地上传

    我这个是自问自答,其实很简单.只要按照以下方式修改就可以了. 找到image.html 将以下代码 <div id="tabHeads" class="tabhea ...

  2. extjs5 一个容器中有几个组件公用一个控制器和一个模型

    Ext.define('TestViewModel', { extend: 'Ext.app.ViewModel', alias: 'viewmodel.test', // connects to v ...

  3. Install marvel and head plugin for ealsticsearch

    安装ES插件 marvel marvel是ES的供开发者免费使用的管理工具,他内置了一款叫做Sense的控制台,Sense是运行在浏览器中的,基于Sense可以很方便的和ES进行通讯.官方文档中的很多 ...

  4. js类型转换的坑

    JS的灵活 说好听是说JS灵活, 说不好听就是JS的坑太多, JS类型转换就是一个大坑, JS的类型包括了原始类型的[null, undefined, String ,Number, Boolean] ...

  5. Canvas是什么

    Canvas 是通过 JavaScript 来绘制 2D 图形,是 HTML 5 中新增的元素. Canvas 有如下特点: 绘制的是位图,图像放大后会失真. 不支持事件处理器. 能够以 .png 或 ...

  6. Git一套简流

    一.前奏 1.凡是记忆性的问题都不是问题! 如果你曾大致了解了Git这一门技术,你会发现这是属于"记忆型"的,所以,这门技术对我们来说不是问题,是一门熟能生巧的哲学. 有了这个前奏 ...

  7. 【ACdream 1187】Rational Number Tree(树,递归)

    有理数的树,根节点是1/1,左儿子是1/2,右儿子是2/1....求给定的分数是第几个,或者给定n求第n个分数.递归.给定的分数,每次递归,如果分子比较小,就用分母减去分子,并且这是左儿子.反之是右儿 ...

  8. Quality Trimming Via Trimmomatic

    已经去除接头(adapter) java -jar trimmomatic.jar PE -threads 20 -phred33 \ left.fastq.gz right.fastq.gz \ l ...

  9. 又爱又恨系列之枚举enum

    其实枚举挺简单的,只不过以前没好好学,所以不知道这个东西,恩,现在梳理一下 整体而言,首先枚举是一个数据类型,这个数据类型和结构体有点像 可以分为三个层次 1.枚举数据类型定义 第一种:enum 枚举 ...

  10. 74.Android之四种启动模式

    转载:http://www.cnblogs.com/meizixiong/archive/2013/07/03/3170591.html 一.启动模式介绍 启动模式简单地说就是Activity启动时的 ...