系列導航地址http://www.49028c.com/fzrain/p/3490137.html
經過前2節的介紹,我們已經把數據訪問層搭建好了,從本章開始就是Web Api部分了。在正式開始之前,再一次回顧一下Web Api的應用場景:Web Api可以與 MVC,WebForm結合使用,也可以作為一個單獨的Web服務。在正式討論Web Api的配置以及如何構造我們的URI來消費資源之前,我們必須理解Http方法與我們將要訪問的資源之間的關系。舉個簡單的例子,我們把模型”Course”作為我們訪問的資源,下面就列舉了訪問這個資源的http方法:
Action | HTTP Verb | Relative URI |
獲取所有課程信息 | GET | /api/courses |
根據某個Id獲取單個課程 | GET | /api/courses/id |
新增一個課程 | POST | /api/coursesNew course is sent in POST body |
更新一個課程 | PUT or PATCH | /api/courses/idUpdated course is sent in POST body |
刪除一個課程 | DELETE | /api/courses/id |
右擊解決方案->添加新建項目
下一步:
點擊確定
在創建好項目之后,我們可以在App_Start文件夾下看到“WebApiConfig”類。這個類就是用來配置路由信息的,這個類最終會在“Global.asax”的application_Start()方法中被調用,后面我們會在這個這個類里面配置多條路由信息。
配置第一個路由:
config.Routes.MapHttPRoute( name: "Courses", routeTemplate: "api/courses/{id}", defaults: new {controller="courses", id = RouteParameter.Optional } );
分析一下上面這段代碼:我們創建了一個Courses的路由規則,這個路由模板會匹配到“api/courses/{id}”的URI,在這個模板定義了2個默認值(api,courses)以及一個可選值(id)。對于“/api/courses or /api/courses/5”URI就會被我們的路由模板匹配到,同時“/api/courses”URI也會被匹配到,因為Id是可選的。
Web Api中的Controller是用來處理客戶端Http請求的(與MVC中的Controller類似),首先,創建Controller——右擊Controller文件夾->新建項->控制器
然后出現下面窗口:
選擇Web API 2控制器-空,并命名為CoursesController。然后確定
打開剛才創建的Controller,可以看到我們創建的類繼承自“ApiController”。同時對于這個類的類名必須是“CoursesController”,因為在Web Api中默認的控制器選擇方式是尋找所有繼承自“ApiController”類并且這個類是以“Courses”開頭(這是在我們的路由規則中配置的)的控制器。
首先,我們創建上述表格列舉到的前2個方法(GetAllCourses,GetCourseById)
方法的選擇是智能的,如果我們創建了2個方法Get()和GetCourse(int id),假設我們發送一個GET請求并且URI是“/api/courses/5”,那么“GetCourse(int id)”方法就會被選擇執行,這是因為方法是以Get開頭而且URI中包含Id的值。這種選擇方式同樣適用以其他的Http方法(put,delete,post),下面上代碼:
public class CoursesController : ApiController { public List<Course> Get() { ILearningRepository repository = new LearningRepository(new LearningContext()); return repository.GetAllCourses().ToList(); } public Course GetCourse(int id) { ILearningRepository repository = new LearningRepository(new LearningContext()); return repository.GetCourse(id); } }
當我們創建一個Get請求并且URI是“http://localhost:{your_port}/api/courses”時候,Get()方法會被選擇調用,下面是相應的部分代碼:
[ { "Id": 1, "Name": "History Teaching Methods 1", "Duration": 3, "DescrOutlook.com", "UserName": "AhmadJoudeh", "PassWord": "SWDQNPSE", "FirstName": "Ahmad", "LastName": "Joudeh", "Gender": 0 }, "CourseSubject": { "Courses": [], "Id": 1, "Name": "History" }, "Enrollments": [] }, { "Id": 2, "Name": "History Teaching Methods 2", "Duration": 3, "Description": "The course will talk in depth about: History Teaching Methods 2", "CourseTutor": { "Courses": [], "Id": 1, "Email": "Ahmad.Joudeh@outlook.com", "UserName": "AhmadJoudeh", "Password": "SWDQNPSE", "FirstName": "Ahmad", "LastName": "Joudeh", "Gender": 0 }, "CourseSubject": { "Courses": [], "Id": 1, "Name": "History" }, "Enrollments": [] },
如果你發送一個Get請求并且URI是“http://localhost:{your_port}/api/courses/5”。那么GetCourse(int id)將會被選擇調用執行。但是很遺憾在調用這個方法之后就會產生一個異常,這個異常信息簡單來說就是“序列化對象的時候出現了循環依賴”,換句話說就是對象間循環引用(Course>Enrollment>Course>Enrollment>etc…)
到目前為止我們已經讓Web Api跑起來了,但仍然有很多不足之處:
返回對象時出現循環依賴,可以通過模型工廠模式解決。
我們返回了領域模型中所有的字段給客戶端,然而有一些敏感信息不應該返回(例如:password字段),解決方案:模型工廠模式
每一個返回給客戶端的資源都應該包含一個URI以便客戶端查詢,解決方案依舊是模型工廠模式。
對于返回單個資源,我們應當返回相應的狀態碼(例如:成功200,資源未找到404等),解決方案:HttpResponseMessage對象
在每個方法里我們都實例化了一個repository,這個對象包含了一些昂貴的操作(例如:數據庫連接),解決方案:依賴注入模式
對于返回的Json對象格式是以“帕斯卡”風格的(例如“FirstName”),然而我們的Api有很大的可能被帶有javascript的客戶端消費,對于JS開發者來說可能更適合“駝峰”風格(例如”firstName”)的數據。解決方案:配置Json格式。
ok,下一章我們就著重解決上述的問題
本章代碼:http://yun.baidu.com/share/link?shareid=2010367762&uk=17559114&third=0
新聞熱點
疑難解答