Trong bài này Tui sẽ hướng dẫn chi tiết cách tạo Web API, cách cấu hình IIS, cách sử dụng công cụ Postman(với những ai dùng chrome), cách sử dụng HttpRequester (với những ai dùng Firefox). Postman và HttpRequester là một trong những công cụ hiệu quả nhất để TEST coding của ta, nếu code của ta pass qua được công cụ này thì có thể kết luận rằng Webservice của ta chắc chắn hoạt động tốt.
Để cho có cảm giác Tui sẽ tạo một cơ sở dữ liệu SQL Server, WebAPI sẽ tương tác dữ liệu này bằng cách sử dụng LinQ to SQL:
Bước 1: Tạo cơ sở dữ liệu tên “dbFood”, có một bảng “Food” gồm 4 cột (id để auto) như dưới đây:
Các bạn có thể tải SQL Script ở đây để tạo CSDL cho lẹ: http://www.mediafire.com/download/48dkwoqka2e1w07/dbFood.sql
Bước 2: Tiến hành viết Web API
Để tạo Project sử dụng Web API có nhiều cách tạo, ở đây Tui sử dụng cách đơn giản nhất để các bạn bớt rối.
Từ Visual Studio 2013 vào menu File/chọn new/ chọn Project:
Project mặc định ban đầu như sau:
Bấm chuột phải vào Project/ chọn :
(chú ý đôi khi bạn sẽ không thấy LINQ to SQL Classes ở màn hình này), nếu không thấy thì chọn New Item:
Ta chọn các mục giống như bên dưới, tìm tới LINQ to SQL Classes rồi đặt tên DBFood tương tự như trên:
Bạ mở Server Explorer (vào menu View/Server Explorer), bấm chọn theo các bước như bên dưới (lệ thuộc vào Server của bạn mà chọn Server name, User đăng nhập cho phù hợp):
Tiếp theo bạn tạo 1 thư mục (tên gì cũng được), ở đây Tui đặt đại tên Controllers (bấm chuột phải vào Project/chọn Add/chọn New Folder):
Sau khi thư mục Controllers được tạo ra, bạn bấm chuột phải vào Thư Mục này rồi chọn Add/Controller..:
Ta chọn Web API 2 Controller – Empty rồi bấm Add, Visual sẽ hiển thị màn hình đặt tên cho Controller:
Mặc định là chữ Default, bây giờ bạn đổi lại thành Food (thường ta làm API cho bảng nào thì lấy tên bảng đó), đó là lý do vì sao Tui đặt là Food:
Tập tin FoodController.cs sẽ được tạo ra, nhưng ta chỉ lấy Food(bỏ chữ Controller đằng sau đi) để tương tác (đây là cơ chế hoạt động). Ta xem cấu trúc Controller được tạo ra:
- File WebApiConfig.cs được sinh ra trong thư mục App_Start, bạn để ý routeTemplate: “api/{controller}/{id}”, tức là khi ta dùng thì viết: “api/food” để lấy toàn bộ danh sách, hay “api/food/3” để lấy chi tiết 1 Food có mã là 3.
- File FoodController.cs kế thừa từ ApiController
Bây giờ ta tiến hành viết các chức năng (viết trong file FoodController.cs) :
- HttpGet: Truy vấn thông tin
- HttpPost: Thêm mới thông tin
- HttpPut: Thay đổi thông tin
- HttpDelete: Xóa thông tin
Trước tiên ta làm HttpGet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; namespace FoodServer.Controllers { public class FoodController : ApiController { /// <summary> /// Dịch vụ lấy toàn bộ Food /// </summary> /// <returns></returns> [HttpGet] public List<Food> GetFoodLists() { DBFoodDataContext db = new DBFoodDataContext(); return db.Foods.ToList(); } /// <summary> /// Dịch vụ lấy 1 Food theo khóa chính nào đó /// </summary> /// <param name="id"></param> /// <returns></returns> [HttpGet] public Food GetFood( int id) { DBFoodDataContext db = new DBFoodDataContext(); return db.Foods.FirstOrDefault(x => x.id == id); } } } |
Chú ý là Web API nó không quan tâm tới tên phương thức (viết tên gì cũng được, nó tự động lấy chính xác Service yêu cầu), (không cho phép trùng tên biến). Ví dụ nếu bạn cố tình tạo thêm 1 hàm:
1
2
3
4
5
6
| [HttpGet] public Food GetFood_test( int id) { DBFoodDataContext db = new DBFoodDataContext(); return db.Foods.FirstOrDefault(x => x.id == id); } |
Khi chạy sẽ báo lỗi ngày (vì hệ thống không quan tâm tên hàm), nó thấy 2 biến id giống nhau ở trên 2 hàm nó sẽ không biết dùng cái nào (vì chúng cùng nhóm HttpGet). Cụ thể là lỗi sau:
“Multiple actions were found that match the request:
GetFood on type FoodServer.Controllers.FoodController
GetFood_test on type FoodServer.Controllers.FoodController”
GetFood on type FoodServer.Controllers.FoodController
GetFood_test on type FoodServer.Controllers.FoodController”
Tiếp theo ta viết HttpPost (thêm mới):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| /// <summary> /// Dịch vụ này để thêm mới 1 Food, các thông số gửi từ client lên /// </summary> /// <param name="name">tên </param> /// <param name="type">loại-nhóm</param> /// <param name="price">đơn giá</param> /// <returns>true thành công, false thất bại</returns> [HttpPost] public bool InsertNewFood( string name, string type, int price) { try { DBFoodDataContext db = new DBFoodDataContext(); Food food = new Food(); food.name = name; food.type = type; food.price = price; db.Foods.InsertOnSubmit(food); db.SubmitChanges(); return true ; } catch { return false ; } } |
Để chỉnh sửa thông tin ta viết HttpPut:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| /// <summary> /// Dịch vụ chỉnh sửa thông tin /// </summary> /// <param name="id">mã food muốn sửa</param> /// <param name="name">tên mới</param> /// <param name="type">loại mới</param> /// <param name="price">giá mới</param> /// <returns></returns> [HttpPut] public bool UpdateFood( int id, string name, string type, int price) { try { DBFoodDataContext db = new DBFoodDataContext(); //lấy food tồn tại ra Food food = db.Foods.FirstOrDefault(x=>x.id==id); if (food == null ) return false ; //không tồn tại false food.name = name; food.type = type; food.price = price; db.SubmitChanges(); //xác nhận chỉnh sửa return true ; } catch { return false ; } } |
Cuối cùng để xóa 1 Food ta viết HttpDelete như sau:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| /// <summary> /// Dịch vụ dùng để xóa Food có id /// </summary> /// <param name="id">id muốn xóa</param> /// <returns></returns> [HttpDelete] public bool DeleteFood( int id) { DBFoodDataContext db = new DBFoodDataContext(); //lấy food tồn tại ra Food food = db.Foods.FirstOrDefault(x => x.id == id); if (food == null ) return false ; db.Foods.DeleteOnSubmit(food); db.SubmitChanges(); return true ; } |
Sau cùng ta có coding tổng hợp của FoodController như sau:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
| using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; namespace FoodServer.Controllers { public class FoodController : ApiController { /// <summary> /// Dịch vụ lấy toàn bộ Food /// </summary> /// <returns></returns> [HttpGet] public List<Food> GetFoodLists() { DBFoodDataContext db = new DBFoodDataContext(); return db.Foods.ToList(); } /// <summary> /// Dịch vụ lấy 1 Food theo khóa chính nào đó /// </summary> /// <param name="id"></param> /// <returns></returns> [HttpGet] public Food GetFood( int id) { DBFoodDataContext db = new DBFoodDataContext(); return db.Foods.FirstOrDefault(x => x.id == id); } /// <summary> /// Dịch vụ này để thêm mới 1 Food, các thông số gửi từ client lên /// </summary> /// <param name="name">tên </param> /// <param name="type">loại-nhóm</param> /// <param name="price">đơn giá</param> /// <returns>true thành công, false thất bại</returns> [HttpPost] public bool InsertNewFood( string name, string type, int price) { try { DBFoodDataContext db = new DBFoodDataContext(); Food food = new Food(); food.name = name; food.type = type; food.price = price; db.Foods.InsertOnSubmit(food); db.SubmitChanges(); return true ; } catch { return false ; } } /// <summary> /// Dịch vụ chỉnh sửa thông tin /// </summary> /// <param name="id">mã food muốn sửa</param> /// <param name="name">tên mới</param> /// <param name="type">loại mới</param> /// <param name="price">giá mới</param> /// <returns></returns> [HttpPut] public bool UpdateFood( int id, string name, string type, int price) { try { DBFoodDataContext db = new DBFoodDataContext(); //lấy food tồn tại ra Food food = db.Foods.FirstOrDefault(x=>x.id==id); if (food == null ) return false ; //không tồn tại false food.name = name; food.type = type; food.price = price; db.SubmitChanges(); //xác nhận chỉnh sửa return true ; } catch { return false ; } } /// <summary> /// Dịch vụ dùng để xóa Food có id /// </summary> /// <param name="id">id muốn xóa</param> /// <returns></returns> [HttpDelete] public bool DeleteFood( int id) { DBFoodDataContext db = new DBFoodDataContext(); //lấy food tồn tại ra Food food = db.Foods.FirstOrDefault(x => x.id == id); if (food == null ) return false ; db.Foods.DeleteOnSubmit(food); db.SubmitChanges(); return true ; } } } |
Bây giờ ta tiến hành cấu hình Port để test trên IIS express hoặc bạn cấu hình IIS full. Trong bài này Tui hướng dẫn cách sử dụng IIS Express.
Bạn bấm chuột phải vào FoodServer Project/ chọn Properties:
Bạn cấu hình như trên, Port tui chỉnh là 8888, bạn chọn Port nào cũng được, nhưng thường là 4 chữ số.
Sau đó bấm Create Virtual Directory:
Bây giờ ta thử chức năng HttpGet để lấy toàn bộ Food và lấy 1 Food theo id bất kỳ:
F5 để chạy Project:
Bạn chỉnh lại: http://localhost:8888/api/food để lấy toàn bộ Food:
Ví dụ: Lấy Food có mã id=15: http://localhost:8888/api/food/15
Bài kế tiếp Tui sẽ hướng dẫn cách dùng công cụ Postman và HttpRequester để xử lý 4 tác vụ trên.
Bây giờ các bạn hãy làm theo hướng dẫn này để có thể tạo được 1 Web API hoàn chỉnh, test trước phần HttpGet mà Tui đã trình bày ở trên trước.
Các bạn tải source code FoodServer ở đây: http://www.mediafire.com/download/c24sm4hg19v8grz/FoodServer.rar
Chúc các bạn thành công.
0 comments: