iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
自我挑戰組

30天開啟.NET後端工程師的旅程系列 第 27

Day27 使用Dapper實現ASP.NET Core Web API中的CRUD操作 (part 2 Controller 建立)

  • 分享至 

  • xImage
  •  

前言

Day 26 使用了Dapper實現CRUD,再來就是到Controller的地方要可以執行這些。

API的方法使用了以下幾個

  • GET:獲得資源
  • POST:新增資源
  • PUT:修改資源(若原本無資料則新增)
  • PATCH:修改資源(只修改部分資源)
  • DELETE:刪除資源

首先先講解甚麼是async跟Task??
非同步程式設計的核心是建立非同步作業模型的 Task 和 Task<T> 物件。 它們是受 async 和 await 關鍵字所支援。

以5歲小孩也能理解的方式來解釋:

Task(工作) 就像是一個小任務,你需要完成它。這個任務可以是做家庭作業、畫一幅畫,或者做任何你需要做的事情。當你完成這個任務時,你會得到一個答案或者獎勵。

async 像是一個特殊的指示,它告訴電腦說:“嘿,這個任務可能需要一些時間,所以不用一直等著,你可以做別的事情。當我完成這個任務時,我會通知你。”

所以,當你看到 "async Task",這就像是告訴電腦說:“嗨,這是一個需要時間的任務,我們會在完成後告訴你。” 這可以幫助我們在處理一些需要等待的事情時,不必浪費太多時間,而是可以繼續做其他有趣的事情。

再來是路由規則
路由規則的意思是,當收到一個 URL 請求時,MVC 框架會嘗試將該 URL 映射到一個控制器的動作方法。
路由的目的是將傳入的 URL 映射到相應的處理程序,以便執行所需的操作。
路由規則中的 {controller}{action}{id} 等占位符會根據 URL 的不同部分進行填充。

在 ASP.NET Core 中,你可以使用路由來定義如何處理不同的 HTTP 請求。路由通常包括以下兩個主要元素:

路由模板(Route Template):這是一個 URL 模式,用於匹配傳入的 URL。路由模板可以包含靜態部分(例如 /api/)和動態部分(例如 {id},其中 {} 括號內的部分表示動態的路由參數)。例如,/api/articles/{id} 是一個路由模板,它匹配 /api/articles/1、/api/articles/2 等 URL。

處理程序(Controller Action):這是一個方法或函式,它處理特定路由模板所匹配的 URL。處理程序通常位於控制器類別中,並根據 HTTP 請求的類型(GET、POST、PUT、DELETE 等)執行相應的邏輯。例如,當用戶訪問 /api/articles/1 時,可能會調用一個名為 GetArticle 的處理程序方法,該方法會處理獲取文章的操作。

下面是預設的路由(預設的Controller叫Home,預設的action叫做Index,Index後面預設的是參數)

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

在Controller中使用ArticleRepository 來執行資料庫操作,可以看到Controller中的每個動作方法都是使用建立的ArticleRepository 透過Dapper來執行資料庫操作,而不是使用Entity Framework Core的DbContext。:

[Route("api/[controller]")]
[ApiController]
public class ArticleController : ControllerBase
{
		//這是一個私有的 **ArticleRepository** 實例,用於處理與文章相關的資料庫操作。
    private readonly ArticleRepository _articleRepository;

		//看到跟控制器同名,也就是控制器的建構函式。接受一個 **IConfiguration** 對象,通常用於讀取設定檔中的資料庫連接字串。
    public ArticleController(IConfiguration configuration)
    {
				//在建構函式中,建立了一個 **ArticleRepository** 實例,並使用我們設定的連接字串名字初始化它。
        _articleRepository = new ArticleRepository(configuration.GetConnectionString("ironDay"));
    }

    // GET: api/Article
    [HttpGet]
    public async Task<ActionResult<IEnumerable<Article>>> GetArticles()
    {
        var articles = await _articleRepository.GetAllArticlesAsync();
        return Ok(articles);
    }

    // GET: api/Article/5
    [HttpGet("{id}")]
    public async Task<ActionResult<Article>> GetArticle(int id)
    {
        var article = await _articleRepository.GetArticleByIdAsync(id);
        if (article == null)
        {
            return NotFound();
        }
        return Ok(article);
    }

    // POST: api/Article
    [HttpPost]
    public async Task<IActionResult> PostArticle(Article article)
    {
        var result = await _articleRepository.InsertArticleAsync(article);
        if (result > 0)
        {
            return CreatedAtAction(nameof(GetArticle), new { id = article.Id }, article);
        }
        return BadRequest();
    }

    // PUT: api/Article/5
    [HttpPut("{id}")]
    public async Task<IActionResult> PutArticle(int id, Article article)
    {
        if (id != article.Id)
        {
            return BadRequest();
        }
        var result = await _articleRepository.UpdateArticleAsync(article);
        if (result > 0)
        {
            return NoContent();
        }
        return NotFound();
    }

    // DELETE: api/Article/5
    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteArticle(int id)
    {
        var result = await _articleRepository.DeleteArticleAsync(id);
        if (result > 0)
        {
            return NoContent();
        }
        return NotFound();
    }
}

上面的程式碼定義了一個 ASP.NET Core Web API 控制器,一樣參考了我們在Day23講到的API動作,這個控制器處理關於文章(Article)資源的 HTTP 請求:

  1. [Route("api/[controller]")][ApiController]:這些是控制器屬性。[Route] 屬性指定了路由模板,表示這個控制器處理的請求應該以 /api/ 開頭,並使用控制器名稱(在這種情況下是 "Article")作為路由的一部分。
  2. [ApiController] 屬性表示這是一個 Web API 控制器。
  3. [HttpGet]public async Task<ActionResult<IEnumerable<Article>>> GetArticles():這是一個 HTTP GET 請求的處理程序。當用戶端對 /api/Article 發出 GET 請求時,這個方法會被呼叫。
    使用 _articleRepository 從資料庫中獲取所有文章,並以 IEnumerable<Article> 的形式返回。如果成功取得文章,它將返回 HTTP 200 OK 狀態碼,並返回文章清單。否則,它可能返回 HTTP 404 Not Found 狀態碼。
  4. [HttpGet("{id}")]public async Task<ActionResult<Article>> GetArticle(int id):這是另一個 HTTP GET 請求的處理程序。當用戶端對 /api/Article/{id} 發出 GET 請求時,這個方法會被呼叫,其中 {id} 是文章的識別碼。它使用 _articleRepository 從資料庫中根據文章識別碼獲取特定文章,如果找到文章,則返回 HTTP 200 OK 狀態碼和文章。如果文章不存在,則返回 HTTP 404 Not Found 狀態碼。
  5. [HttpPost]public async Task<IActionResult> PostArticle(Article article):這是 HTTP POST 請求的處理程序。當用戶端對 /api/Article 發出 POST 請求時,這個方法會被呼叫,用於新增文章。它使用 _articleRepository 嘗試插入一篇文章,如果成功插入,則返回 HTTP 201 Created 狀態碼和文章的詳細資訊。如果插入失敗,則返回 HTTP 400 Bad Request 狀態碼。
  6. [HttpPut("{id}")]public async Task<IActionResult> PutArticle(int id, Article article):這是 HTTP PUT 請求的處理程序。當用戶端對 /api/Article/{id} 發出 PUT 請求時,這個方法會被呼叫,用於更新文章。它使用 _articleRepository 嘗試根據文章識別碼更新文章,如果成功更新,則返回 HTTP 204 No Content 狀態碼。如果更新失敗或文章不存在,則返回 HTTP 400 Bad Request 或 HTTP 404 Not Found 狀態碼。
  7. [HttpDelete("{id}")]public async Task<IActionResult> DeleteArticle(int id):這是 HTTP DELETE 請求的處理程序。當用戶端對 /api/Article/{id} 發出 DELETE 請求時,這個方法會被呼叫,用於刪除文章。它使用 _articleRepository 嘗試根據文章識別碼刪除文章,如果成功刪除,則返回 HTTP 204 No Content 狀態碼。如果刪除失敗或文章不存在,則返回 HTTP 404 Not Found 狀態碼。

這個控制器允許用戶端執行各種與文章資源相關的操作,包括獲取文章清單、獲取特定文章、新增文章、更新文章和刪除文章。

使用的結果跟Day24,25兩天是一樣的喔(一樣執行之後就可以進行增刪查改的動作了~)


第27天挑戰完成~~


上一篇
Day26 使用Dapper實現ASP.NET Core Web API中的CRUD操作 (part 1)
下一篇
加強安全性 - 使用BCrypt和JWT實現強大的身分驗證
系列文
30天開啟.NET後端工程師的旅程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言