一.概述 HTTP不僅僅用於提供網頁。HTTP也是構建公開服務和數據的API強大平臺。HTTP簡單靈活且無處不在。幾乎任何你能想到的平臺都有一個HTTP庫,因此HTTP服務可以覆蓋廣泛的客戶端,包括瀏覽器,移動設備和傳統的桌面應用程式。 ASP.NET Web API 是一個框架,基於.NET Fr ...
一.概述
HTTP不僅僅用於提供網頁。HTTP也是構建公開服務和數據的API強大平臺。HTTP簡單靈活且無處不在。幾乎任何你能想到的平臺都有一個HTTP庫,因此HTTP服務可以覆蓋廣泛的客戶端,包括瀏覽器,移動設備和傳統的桌面應用程式。
ASP.NET Web API 是一個框架,基於.NET Framework 或.NET Core 之上構建 Web API。
從本章開始學習Web API系列時,先從一個示例開始,下麵使用ASP.NET Core MVC 創建 Web API。通過本次演示將瞭解到一個基礎的Web API應用。環境使用vs 2017 +sql server 2012。示例主要知識點包括:
(1)創建 Web API 項目。
(2)添加模型類。
(3)創建資料庫上下文。
(4)註冊資料庫上下文。
(5)添加控制器。
(6)添加 CRUD 方法。
(7)配置路由和 URL 路徑。
(8)指定返回值。
(9)使用Fiddle調用 Web API。
(10)使用 jQuery 調用 Web API。
在開發Web API之前,先制定幾個有針對性的API 介面,至於api 介面業務很簡單,主要是演示如何應用Web API。
API介面 |
說明 |
請求報文 |
響應報文 |
GET /api/todo |
獲取所有待辦事項 |
無 |
待辦事項的數據 |
GET /api/todo/{id} |
按 ID 獲取項 |
無 |
待辦事項 |
POST /api/todo |
添加新項 |
待辦事項 |
待辦事項 |
PUT /api/todo/{id} |
更新現有項 |
待辦事項 |
無 |
DELETE /api/todo/{id} |
刪除項 |
無 |
無 |
1.1 創建web項目
(1)從“文件”菜單中選擇“新建” > “項目”。
(2)選擇“ASP.NET Core Web 應用程式”模板。 將項目命名為 TodoApi,然後單擊“確定”。
(3)在“新建 ASP.NET Core Web 應用程式 - TodoApi”對話框中,選擇 ASP.NET Core 版本。 選擇“API”模板,然後單擊“確定”。 請不要選擇“啟用 Docker 支持”。
項目模板會創建 values
API。 控制器方法中預設的Http[Verb] 屬性路由包括GET,POST, PUT, DELETE介面
1.2 添加模型類
在項目中,添加Models文件夾,新建一個 TodoItem
類,如下所示:
public class TodoItem { //主鍵 public long Id { get; set; } //待辦事項名稱 public string Name { get; set; } //是否完成 public bool IsComplete { get; set; } }
1.3 添加資料庫上下文
在“Models”文件夾,然後選擇“添加” > “類”。 將類命名為 TodoContext,如下所示:
//using Microsoft.EntityFrameworkCore; public class TodoContext: DbContext { public TodoContext(DbContextOptions<TodoContext> options) : base(options) { } public DbSet<TodoItem> TodoItems { get; set; } }
1.4 註冊上下文
在 ASP.NET Core 中,服務(如資料庫上下文)必須向依賴關係註入 (DI) 容器進行註冊。 該容器向控制器提供服務。這裡使用Microsoft.EntityFrameworkCore.SqlServer數據提供程式。再根據模型生成資料庫表(庫名Todo,有一個表TodoItem)。關於如何安裝數據提供程式,以及如何用模型生成資料庫表,請參考“asp.net core 系列第 20 篇” 。使用遷移生成資料庫後,如下所示:
1.5 添加控制器
在Controllers 文件夾中,選擇“API 控制器類”模板。將類命名為 TodoController.cs, 代碼如下所示:
[Route("api/[controller]")] [ApiController]//添加特性,代表是一個Web API控制器類 public class TodoController : Controller { private readonly TodoContext _context; /// <summary> /// 實例化一個EF上下文,進行資料庫操作。開始初始入庫一條數據 /// </summary> /// <param name="context"></param> public TodoController(TodoContext context) { _context = context; if (_context.TodoItems.Count() == 0) { // Create a new TodoItem if collection is empty, // which means you can't delete all TodoItems. _context.TodoItems.Add(new TodoItem { Name = "Item1" }); _context.SaveChanges(); } } }
1.6 添加GET方法
通過GET方法來查詢待辦事項的 API,將以下方法添加到 TodoController 類中。關於路由知識,請參考asp.net core 系列第5篇。
/// <summary> /// 獲取所有事項 /// GET: api/Todo /// </summary> /// <returns></returns> [HttpGet] public async Task<ActionResult<IEnumerable<TodoItem>>> GetTodoItems() { //using Microsoft.EntityFrameworkCore; return await _context.TodoItems.ToListAsync(); } /// <summary> /// 根據id,獲取一條事項 /// GET: api/Todo/5。 id 是參數,代表路由合併 /// </summary> /// <param name="id"></param> /// <returns></returns> [HttpGet("{id}")] public async Task<ActionResult<TodoItem>> GetTodoItem(long id) { var todoItem = await _context.TodoItems.FindAsync(id); if (todoItem == null) { return NotFound(); } return todoItem; }
啟動vs,測試結果,如下所示,註意請求wep api 地址與action的方法名沒有關係,是根據方法名之上的Http[Verb]特性來確定url地址的:
1.7 路由和URL路徑
(1) Route特性
Route是用來制定路由模板的,在第5章中也講到。[Route("api/[controller]")]中是以api開頭,替換[controller]
為控制器的名稱, 按照慣例,控制器類名稱減去“Controller”尾碼, 因此控制器名稱為“todo” ,路由不區分大小寫。
(2) HttpGet
如果[HttpGet]
屬性具有路徑模板,例如:[HttpGet("{id}")]
,
則將其
附加到路徑
(如:api/todo/1)
。在這個示例中
,
"{id}"
是占位符變數,用於待辦事項的唯一標識符。
1.8 返回值
上面的GetTodoItems和GetTodoItem方法的返回類型是ActionResult <T>類型。ASP.NET Core自動將對象序列化為JSON,並將JSON寫入響應消息的正文中。假設沒有異常,此返回類型的響應代碼為200。未處理的異常被轉換為5xx錯誤。
ActionResult
返回類型可以表示各種HTTP狀態代碼,例如在上面的GetTodoItem
方法中
可以返回兩個不同的狀態值:一個是成功的200, 一個是404未到找。所有的HTTP狀態代碼可以在ControllerBase中找到,例如下圖中的Forbid() 是Http狀態碼403,NoContent()是Http 狀態碼204 。 等等
二.測試Web API
下麵簡單使用Fiddler來測試一下增刪改增。先在本機vs 2017中啟動該項目,地址為http://localhost:62271。
2.1 查詢
在Fiddler工具中,選擇GET,輸入查詢的http地址,右邊是響應的http 狀態碼200, 以及查詢的json結構對象。
2.2 新增
下麵創建方法,添加以下 PostTodoItem 方法,在新增方法中調用了CreatedAtAction內置方法,如果新增成功,則返回 HTTP 201 狀態代碼。HTTP 201是HTTP POST方法的標準響應,該方法在伺服器上創建新資源。
//POST: api/Todo [HttpPost] public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem item) { _context.TodoItems.Add(item); await _context.SaveChangesAsync(); return CreatedAtAction(nameof(GetTodoItem), new { id = item.Id }, item); }
2.3 修改
添加以下 PutTodoItem
方法, PutTodoItem 與 PostTodoItem 類似,但是使用的是 HTTP PUT。 響應是 204(無內容)。 根據 HTTP 規範,PUT 請求需要客戶端發送整個更新的實體,而不僅僅是更改。若要支持部分更新,請使用HttpPatch特性。
// PUT: api/Todo/1 [HttpPut("{id}")] public async Task<IActionResult> PutTodoItem(long id, TodoItem item) { if (id != item.Id) { //http 403 return BadRequest(); } //當前傳過來的實體添加到上下文,並設置為修改 _context.Entry(item).State = EntityState.Modified; await _context.SaveChangesAsync(); return NoContent(); }
2.4 刪除
// DELETE: api/Todo/2 [HttpDelete("{id}")] public async Task<IActionResult> DeleteTodoItem(long id) { var todoitem = await _context.TodoItems.FindAsync(id); if (todoitem == null) { return NotFound(); } _context.TodoItems.Remove(todoitem); await _context.SaveChangesAsync(); return NoContent(); }
最後:關於jQuery 調用 Web API,不再演示,jQuery調用的配置和註意事項,請查看官網介紹。
參考文獻: