asp.net core系列 36 WebAPI 搭建詳細示例

一.概述

HTTP不僅僅用于提供網(wǎng)頁。HTTP也是構(gòu)建公開服務和數(shù)據(jù)的API強大平臺。HTTP簡單靈活且無處不在。幾乎任何你能想到的平臺都有一個HTTP庫,因此HTTP服務可以覆蓋廣泛的客戶端,包括瀏覽器,移動設(shè)備和傳統(tǒng)的桌面應用程序。

ASP.NET Web API 是一個框架,基于.NET Framework 或.NET Core 之上構(gòu)建 Web API。

從本章開始學習Web API系列時,先從一個示例開始,下面使用ASP.NET Core MVC 創(chuàng)建 Web API。通過本次演示將了解到一個基礎(chǔ)的Web API應用。環(huán)境使用vs 2017 +sql server 2012。示例主要知識點包括:
(1)創(chuàng)建 Web API 項目。
(2)添加模型類。
(3)創(chuàng)建數(shù)據(jù)庫上下文。
(4)注冊數(shù)據(jù)庫上下文。
(5)添加控制器。
(6)添加 CRUD 方法。
(7)配置路由和 URL 路徑。
(8)指定返回值。
(9)使用Fiddle調(diào)用 Web API。
(10)使用 jQuery 調(diào)用 Web API。
在開發(fā)Web API之前,先制定幾個有針對性的API 接口,至于api 接口業(yè)務很簡單,主要是演示如何應用Web API。

API接口 說明 請求報文 響應報文
GET /api/todo 獲取所有待辦事項 待辦事項的數(shù)據(jù)
GET /api/todo/{id} 按 ID 獲取項 待辦事項
POST /api/todo 添加新項 待辦事項 待辦事項
PUT /api/todo/{id} 更新現(xiàn)有項 待辦事項
DELETE /api/todo/{id} 刪除項
1.1 創(chuàng)建web項目

(1)從“文件”菜單中選擇“新建” > “項目”。

(2)選擇“ASP.NET Core Web 應用程序”模板。 將項目命名為 TodoApi,然后單擊“確定”。

(3)在“新建 ASP.NET Core Web 應用程序 - TodoApi”對話框中,選擇 ASP.NET Core 版本。 選擇“API”模板,然后單擊“確定”。 請不要選擇“啟用 Docker 支持”。

項目模板會創(chuàng)建 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 添加數(shù)據(jù)庫上下文

在“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 中,服務(如數(shù)據(jù)庫上下文)必須向依賴關(guān)系注入 (DI) 容器進行注冊。 該容器向控制器提供服務。這里使用Microsoft.EntityFrameworkCore.SqlServer數(shù)據(jù)提供程序。再根據(jù)模型生成數(shù)據(jù)庫表(庫名Todo,有一個表TodoItem)。關(guān)于如何安裝數(shù)據(jù)提供程序,以及如何用模型生成數(shù)據(jù)庫表,請參考“asp.net core 系列第 20 篇” 。使用遷移生成數(shù)據(jù)庫后,如下所示:


image
1.5 添加控制器

在Controllers 文件夾中,選擇“API 控制器類”模板。將類命名為 TodoController.cs, 代碼如下所示:

[Route("api/[controller]")]
    [ApiController]//添加特性,代表是一個Web API控制器類
    public class TodoController : Controller
    {
        private readonly TodoContext _context;

        /// <summary>
        /// 實例化一個EF上下文,進行數(shù)據(jù)庫操作。開始初始入庫一條數(shù)據(jù)
        /// </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 類中。關(guān)于路由知識,請參考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>
        /// 根據(jù)id,獲取一條事項
        /// GET: api/Todo/5。  id 是參數(shù),代表路由合并
        /// </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,測試結(jié)果,如下所示,注意請求wep api 地址與action的方法名沒有關(guān)系,是根據(jù)方法名之上的Http[Verb]特性來確定url地址的: 


image
1.7 路由和URL路徑

(1) Route特性

Route是用來制定路由模板的,在第5章中也講到。[Route("api/[controller]")]中是以api開頭,替換[controller] 為控制器的名稱, 按照慣例,控制器類名稱減去“Controller”后綴, 因此控制器名稱為“todo” ,路由不區(qū)分大小寫。
(2) HttpGet

如果[HttpGet]屬性具有路徑模板,例如:[HttpGet("{id}")], 則將其附加到路徑(如:api/todo/1)。在這個示例中, "{id}"是占位符變量,用于待辦事項的唯一標識符。

1.8 返回值

上面的GetTodoItems和GetTodoItem方法的返回類型是ActionResult <T>類型。ASP.NET Core自動將對象序列化為JSON,并將JSON寫入響應消息的正文中。假設(shè)沒有異常,此返回類型的響應代碼為200。未處理的異常被轉(zhuǎn)換為5xx錯誤。

ActionResult返回類型可以表示各種HTTP狀態(tài)代碼,例如在上面的GetTodoItem方法中可以返回兩個不同的狀態(tài)值:一個是成功的200, 一個是404未到找。所有的HTTP狀態(tài)代碼可以在ControllerBase中找到,例如下圖中的Forbid() 是Http狀態(tài)碼403,NoContent()是Http 狀態(tài)碼204 。 等等 


image

二.測試Web API

下面簡單使用Fiddler來測試一下增刪改增。先在本機vs 2017中啟動該項目,地址為http://localhost:62271。

2.1 查詢

在Fiddler工具中,選擇GET,輸入查詢的http地址,右邊是響應的http 狀態(tài)碼200, 以及查詢的json結(jié)構(gòu)對象。


image
2.2 新增

下面創(chuàng)建方法,添加以下 PostTodoItem 方法,在新增方法中調(diào)用了CreatedAtAction內(nèi)置方法,如果新增成功,則返回 HTTP 201 狀態(tài)代碼。HTTP 201是HTTP POST方法的標準響應,該方法在服務器上創(chuàng)建新資源。

//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);
        }
image
2.3 修改

添加以下 PutTodoItem 方法, PutTodoItem 與 PostTodoItem 類似,但是使用的是 HTTP PUT。 響應是 204(無內(nèi)容)。 根據(jù) HTTP 規(guī)范,PUT 請求需要客戶端發(fā)送整個更新的實體,而不僅僅是更改。若要支持部分更新,請使用HttpPatch特性。

// PUT: api/Todo/1
        [HttpPut("{id}")]
        public async Task<IActionResult> PutTodoItem(long id, TodoItem item)
        {
            if (id != item.Id)
            {
                //http 403
                return BadRequest();
            }
            //當前傳過來的實體添加到上下文,并設(shè)置為修改
            _context.Entry(item).State = EntityState.Modified;
            await _context.SaveChangesAsync();

            return NoContent();
        }
image
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();
        }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容