Web Api中实现Http方法(Put,Post,Delete)
在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 > 0)
{
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
Web Api中实现Http方法(Put,Post,Delete)的更多相关文章
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【五】——在Web Api中实现Http方法(Put,Post,Delete)
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在Web Api中,我们对资源的CRUD操作都是通过相应的Http方法来实现——Post(新 ...
- Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化
9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...
- ASP.NET Web API中的Controller
虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...
- Web APi 2.0优点和特点?在Web APi中如何启动Session状态?
前言 曾几何时,微软基于Web服务技术给出最流行的基于XML且以扩展名为.asmx结尾的Web Service,此服务在.NET Framework中风靡一时同时也被.NET业界同仁所青睐,几年后在此 ...
- ASP.NET Web API 提升性能的方法实践
ASP.NET Web API 是非常棒的技术.编写 Web API 十分容易,以致于很多开发者没有在应用程序结构设计上花时间来获得很好的执行性能. 在本文中,我将介绍8项提高 ASP.NET Web ...
- Web Api中的get传值和post传值
GET 方式 get方式传参 我们一般用于获取数据做条件筛选,也就是 “查” 1.无参 var look = function () { $.ajax({ type: "GET", ...
- WEB API 中HTTP的get、post、put,delete 请求方式
一.WEB API 中HTTP 请求方式的四个主要方法 (GET, PUT, POST, DELETE), 按照下列方式映射为 CURD 操作: 1.POST 用于新建资源,服务端在指定的URI 上创 ...
- Web Api 中Get 和 Post 请求的多种情况分析
转自:http://www.cnblogs.com/babycool/p/3922738.html 来看看对于一般前台页面发起的get和post请求,我们在Web API中要如何来处理. 这里我使用J ...
- Web Api 中返回JSON的正确做法
在使用Web Api的时候,有时候只想返回JSON:实现这一功能有多种方法,本文提供两种方式,一种传统的,一种作者认为是正确的方法. JSON in Web API – the formatter b ...
随机推荐
- printf交替使用
今天附带printf一些替代实现. 转载请注明出处:http://blog.csdn.net/u010484477谢谢^_^ 我们总是用printf做各种输出语句: printf("%d&q ...
- 最新Oracle 和 mysql 的对比参照----开发篇(转)
Oracle mysql 对比版本 Release 10.2.0.1.0 XE windowsXP 5.0.45-community-nt-log MySQL Community Edition ( ...
- XStream 用法汇总
XStream是一家Java对象和XML转换工具,很好很强大.它提供了所有的基本型.排列.收集和其他类型的支持,直接转换.因此XML在数据交换经常使用.对象序列化(和Java对象的序列 ...
- HTML5游戏开发引擎Pixi.js完全入门手册(二)元素对象属性解析
下面,我们来解释下PIXI里面对象的各个属性.. 首先我们来看看这个各个元素对象里面到底长啥样.. alpha Number 整个舞台对象的透明度. buttonMode Boolean 渲染是否作为 ...
- hdu Max Sum Plus Plus(dp+滚动数组)
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1024 m为段,要深刻理解题意,并没有说是段与段要连接. 题解链接:http://blog.csdn.n ...
- android如何在代码中设置margin
1.首先看你要设置组件的父容器是什么. 例如,我是FrameLayout其中包括组件.如果调用bottomLayout这是: FrameLayout.LayoutParams lp = new Fra ...
- shell 命名管道,进程间通信
命名管道基础 命名管道也被称为FIFO文件, 在文件系统中是可见的,并且跟其它文件一样可以读写! 命名管道特点: 当写进程向管道中写数据的时候,如果没有进程读取这些数据,写进程会堵塞 当读取管道中的数 ...
- crawler_微信采集方案
仅供参考
- cscope的使用
转自:http://easwy.com/blog/archives/advanced-vim-skills-cscope/ 本节所用命令的帮助入口: :help cscope 在前面的文章中介绍了利用 ...
- asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证
原文:asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证 在前面的文章中我们曾经涉及到ControllerActionInvoker类GetPara ...