使用ASP.NET Web Api構建基於REST風格的服務實戰系列教程【三】——Web Api入門


系列導航地址http://www.cnblogs.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

 

第一步:創建Web Api項目

右擊解決方案->添加新建項目

image

下一步:

image

點擊確定

第二步:配置第一個路由

在創建好項目之后,我們可以在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是可選的。

第三步:添加第一個控制器(courses controller)

Web Api中的Controller是用來處理客戶端Http請求的(與MVC中的Controller類似),首先,創建Controller——右擊Controller文件夾->新建項->控制器

然后出現下面窗口:

image

選擇Web API 2控制器-空,並命名為CoursesController。然后確定

打開剛才創建的Controller,可以看到我們創建的類繼承自“ApiController”。同時對於這個類的類名必須是“CoursesController”,因為在Web Api中默認的控制器選擇方式是尋找所有繼承自“ApiController”類並且這個類是以“Courses”開頭(這是在我們的路由規則中配置的)的控制器。

第四步:在Controller中添加Action

首先,我們創建上述表格列舉到的前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,
        "Description": "The course will talk in depth about: History Teaching Methods 1",
        "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": []
    },
    {
        "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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM