HTTP不單單用於提供網頁。HTTP也是構建公開服務和數據的API強大平臺。HTTP簡單靈活且無處不在。幾乎任何你能想到的平臺都有一個HTTP庫,所以HTTP服務能夠覆蓋普遍的客戶端,包括瀏覽器,移動設備和傳統的桌面應用程序。web
ASP.NET Web API 是一個框架,基於.NET Framework 或.NET Core 之上構建 Web API。sql
從本章開始學習Web API系列時,先從一個示例開始,下面使用ASP.NET Core MVC 建立 Web API。經過本次演示將瞭解到一個基礎的Web API應用。環境使用vs 2017 +sql server 2012。示例主要知識點包括:數據庫
(1)建立 Web API 項目。json
(2)添加模型類。api
(3)建立數據庫上下文。瀏覽器
(4)註冊數據庫上下文。服務器
(5)添加控制器。框架
(6)添加 CRUD 方法。asp.net
(7)配置路由和 URL 路徑。async
(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 。 等等
下面簡單使用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調用的配置和注意事項,請查看官網介紹。
參考文獻: