使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【五】——在Web Api中实现Http方法(Put,Post,Delete)
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html
前言
在Web Api中,我们对资源的CRUD操作都是通过相应的Http方法来实现——Post(新增),Put(修改),Delete(删除),Get(查询)。查询在前几章我们已经实现了,本章就在我们的案列(CourseController)中实现put,post和delete方法。
使用Http Post方法创建一个Course
首先,在“CourseController”中创建Post(CourseModel courseModel)方法,具体代码如下:
public HttpResponseMessage Post([FromBody] CourseModel courseModel)
{
try
{
var entity = TheModelFactory.Parse(courseModel); if (entity == null) Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Could not read subject/tutor from body"); if (TheRepository.Insert(entity) && TheRepository.SaveAll())
{
return Request.CreateResponse(HttpStatusCode.Created, TheModelFactory.Create(entity));
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Could not save to the database.");
}
}
catch (Exception ex)
{ return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
上面的代码主要做了以下的事:
1.方法名为Post因此客户端发起的Http请求必须也是Post
2.方法接受一个CourseModel类型的参数,对于复杂类型的参数Web Api会从Http请求的Body部分反序列化出来,因此客户端必须发送一个代表CourseModel类型的对象参数(我觉得就是一些Key Value键值对——key对应CourseModel的属性名,Value就是属性值)
3.对于新增操作,我们在操作成功之后返回201(资源创建)的同时,把 新创建的资源返回也是必要的,因为这个这个资源包含了一个在服务器端自动生成的Id。
4.我们在ModelFactory中新增了一个Parse方法用来将我们的CourseModel转化为domain model(“Course”),这个方法代码就不贴了,在本章代码中给出。
ok,我们测试一下:发送一个Post请求到(http://localhost:{your_port}/api/courses/)请求部分如下图所示:

解释下这个请求:
1.设置header部分“content-type”属性为“application/json”因为我们发送的数据格式是JSON格式。
2.设置header部分“accept”属性为“application/json”因为我们希望接受的数据格式也是JSON格式。
3.请求的Body部分是一个以JSON格式序列化的“CourseModel”,正如我们之前说的——一个课程对应一个科目同时对应一个导师(具体模型之间的关系,可以参考:http://www.cnblogs.com/fzrain/p/3491804.html),所以在新增课程的时候我们需要指定科目的Id和导师的Id,在我们的Parse方法中就会根据这些Id来创建有效的领域模型——Course,最终通过Repository存入数据库。
如果这个post请求执行成功,那么一个新的Course即被创建,我们接受到的响应报文应该如下图所示:

使用Http Put方法更新一个Course
在“CourseController”中创建Put(int Id CourseModel courseModel)方法,具体代码如下:
[HttpPatch]
[HttpPut]
public HttpResponseMessage Put(int id, [FromBody] CourseModel courseModel)
{
try
{ var updatedCourse = TheModelFactory.Parse(courseModel); if (updatedCourse == null) Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Could not read subject/tutor from body"); var originalCourse = TheRepository.GetCourse(id); if (originalCourse == null || originalCourse.Id != id)
{
return Request.CreateResponse(HttpStatusCode.NotModified, "Course is not found");
}
else
{
updatedCourse.Id = id;
} if (TheRepository.Update(originalCourse, updatedCourse) && TheRepository.SaveAll())
{
return Request.CreateResponse(HttpStatusCode.OK, TheModelFactory.Create(updatedCourse));
}
else
{
return Request.CreateResponse(HttpStatusCode.NotModified);
} }
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
解释一下上面的代码:
1.方法名为Put,因此需要客户端发送put请求,但是在我们的方法上打了Patch特性,那就说明put和patch请求都将执行这个方法。对于put和patch请求的区别在于——当我们需要更新CourseModel所有字段时用“put”,只更新部分字段时用“Patch”,但在我们的put方法中无需区分这2者。
2.在我们的put方法中需要接受2个参数(Id和CourseModel),Id是包含在URL中,而CourseModel则应该在请求的Body中。
3.对于更新成功我们返回200状态码和更新过的Course,没成功返回304(Not Modified)。
ok,我们测试一下:发送一个Put请求到(http://localhost:{your_port}/api/courses/1003)请求部分如下图所示:

解释下这个请求:
1.设置header部分“content-type”属性为“application/json”因为我们发送的数据格式是JSON格式。
2.设置header部分“accept”属性为“application/json”因为我们希望接受的数据格式也是JSON格式。
3.请求的Body部分是一个以JSON格式序列化且需要更新的“CourseModel“。
如果put方法执行成功,那么我们会获得200的响应状态码以及更新过的Course。
使用Http Delete方法删除一个Course
在“CourseController”中创建Delete(int Id )方法,具体代码如下:
public HttpResponseMessage Delete(int id)
{
try
{
var course = TheRepository.GetCourse(id); if (course == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
} if (course.Enrollments.Count > )
{
return Request.CreateResponse(HttpStatusCode.BadRequest, "Can not delete course, students has enrollments in course.");
} if (TheRepository.DeleteCourse(id) && TheRepository.SaveAll())
{
return Request.CreateResponse(HttpStatusCode.OK);
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
} }
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
}
}
解释一下上面代码:
1.方法名为delete,所以对应的http请求应该是delete。
2.方法接收一个参数Id,而Id应该在URL中设置,所以请求正文的内容为空。
3.如果删除成功,我们返回200状态码,删除失败时返回400(BadRequest)的同时把错误内容也返回给客户端
ok,我们测试一下:发送一个Delete请求到(http://localhost:{your_port}/api/courses/1003)请求部分如下图所示:

在项目中添加StudentController
studentController用于对Students实现CRUD,主要涉及以下功能:
1.使用Get请求获取所有学生信息。
2.发送Get请求获取单个学生信息(注:在这里我们将UserName作为参数传递到服务器,这个方法是基于Basic authentication,因此只有提供用户名的密码才能查询到相应的信息,在讲Web Api安全性的时候我们着重来说这里)。
3.通过Post请求新增一个学生。
4.通过Put或Patch请求修改一个学生。
5.通过Delete删除一个学生。
这里就不给出StudentController中的详细代码了,和CourseController中的基本相似,大家可以在本章最后给的代码链接中获得,这里列举一下在WebApiConfig中添加的路由代码:
config.Routes.MapHttpRoute(
name: "Students",
routeTemplate: "api/students/{userName}",
defaults: new { controller = "students", userName = RouteParameter.Optional }
);
总结
到此为止,我们已经将Http方法所对应操作资源的CRUD介绍完了,下一章我们将介绍资源间的关联,敬请期待。
本章代码:http://yun.baidu.com/share/link?shareid=4231221159&uk=17559114&third=0
使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【五】——在Web Api中实现Http方法(Put,Post,Delete)的更多相关文章
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【九】——API变了,客户端怎么办?
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 一旦我们将API发布之后,消费者就会开始使用并和其他的一些数据混在一起.然而,当新的需求出现 ...
- ASP.NET Web Api构建基于REST风格的服务实战系列教程
使用ASP.NET Web Api构建基于REST风格的服务实战系列教程[十]——使用CacheCow和ETag缓存资源 系列导航地址http://www.cnblogs.com/fzrain/p/3 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【开篇】【持续更新中。。。】
最近发现web api很火,园内也有各种大神已经在研究,本人在asp.net官网上看到一个系列教程,原文地址:http://bitoftech.net/2013/11/25/detailed-tuto ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【外传】——Attribute Routing
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 题外话:由于这个技术点是新学的,并不属于原系列,但借助了原系列的项目背景,故命名外传系列,以后也可 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【七】——实现资源的分页
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 这篇文章我们将使用不同的方式实现手动分页(关于高端大气上档次的OData本文暂不涉及,但有可 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【八】——Web Api的安全性
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 这一篇文章我们主要来探讨一下Web Api的安全性,到目前为止所有的请求都是走的Http协议 ...
- [转]使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【八】——Web Api的安全性
本文转自:http://www.cnblogs.com/fzrain/p/3552423.html 系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html ...
- 使用ASP.NET WEB API构建基于REST风格的服务实战系列教程(一)——使用EF6构建数据库及模型
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 使用Entity Framework Code First模式构建数据库对象 已经决定使用EF C ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【二】——使用Repository模式构建数据库访问层
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在数据访问层应用Repository模式来隔离对领域对象的细节操作是很有意义的.它位于映射层 ...
随机推荐
- 【CodeVS 5032】【省队集训2016 Day5 T1】Play with array
一开始我用分块大法,分成$\sqrt{n}$块,每个块上维护一个Splay,然后balabala维护一下,时间复杂度是$O(n\sqrt{n}logn)$.后来对拍的时候发现比$O(n^2)$的暴力跑 ...
- Doccms 中新闻列表排序无效bug的修复
手动修改 content/index/list.php 37 为 $sql="Select * FROM ".TB_PREFIX."list Where channelI ...
- 【BZOJ-1441】Min 裴蜀定理 + 最大公约数
1441: Min Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 471 Solved: 314[Submit][Status][Discuss] De ...
- 【SDOI2010题集整合】BZOJ1922~1927&1941&1951&1952&1972&1974&1975
BZOJ1922大陆争霸 思路:带限制的单源最短路 限制每个点的条件有二,路程和最早能进入的时间,那么对两个值一起限制跑最短路,显然想要访问一个点最少满足max(dis,time) 那么每次把相连的点 ...
- 【bzoj1178】 Apio2009—CONVENTION会议中心
http://www.lydsy.com/JudgeOnline/problem.php?id=1178 (题目链接) 题意 给出n个区间,问在区间两两不相交的情况下最多能选出多少区间,并输出字典序最 ...
- css选择器(选择<div>内所有<p>元素)
情况1:<div><p></div> 情况2:<div><a><p></p></a></div&g ...
- 什么是ECMA标准
是1961年成立的旨在建立统一的电脑操作格式标准,包括程序语言和输入输出的组织. 官方ECMA标准列表: http://www.ecma-international.org/publications/ ...
- CCTray配置如何添加远程服务器
前提: Windows防火墙必须开通的TCP端口 或者直接把防火墙关闭(不建议) 或者直接在防火墙规则增加CCNET的服务进去 总者,只要确保能telnet ip 21234能通即可 建议全部软件都装 ...
- Visual Studio 2015出现Cannot find one or more components. Please reinstall the application.的问题解决
cd C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE devenv.exe /resetuserdata devenv. ...
- [NOIP2012] 提高组 洛谷P1084 疫情控制
题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都, 也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散 ...