在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