快速變動的資訊時代,除了 DevOps,你更需要融入 Security!
作者:唐任威 精誠資訊 恆逸教育訓練中心 資深講師
一、加速軟體交付速度,減少開發到生產的時間,提高產品上線的效率和靈活性;二、提高系統的可靠性和穩定性,減少系統故障和問題,提升用戶體驗和滿意度;三、增強團隊的合作和溝通,打破功能部門間的隔閡,促進跨部門的協作和共享知識。
作者:唐任威 精誠資訊 恆逸教育訓練中心 資深講師
恆逸學員曾子維從研究所進修第一堂白帽駭客課程CEH開啟了他的資安旅程,學生時代半工半讀,一路當上上市櫃公司的首席資安工程師,再到創業當老闆,8年來考了7張資安認證與多張雲端認證,累積了堅強的實務經驗與資安技術,一起來看看他的進修心路歷程!
案例分析:
在網域中受管理的電腦安裝LAPS工具
Fluent UI Blazor 是一個由微軟開發的開源元件庫,可以讓程式開發人員在 Blazor 應用程式中使用 Fluent UI 來設計系統。Fluent UI 是一種設計套件,可幫助開發人員建立美觀、一致且易於使用的使用者介面。
Fluent UI Blazor 元件庫目前包含了超過 40 幾個元件,涵蓋了應用程式或網站中常見的使用者介面元素,例如按鈕、文字方塊、下拉式選單、表格、圖表等等。這些元件經過精心設計,可與 Fluent UI 設計系統的其餘部分無縫整合。
Fluent UI Blazor 元件庫的主要功能包括:
• 豐富的元件庫:包含超過 40 幾個常用元件,可滿足各種使用者介面需求。
• 易於使用:元件採用簡單易懂的 API,可快速上手,學習曲線短。
• 允許客製化:元件可根據需要進行客製化,以符合特定的設計的要求。
• 無障礙性:元件遵循無障礙性最佳做法,可供所有人使用。
Fluent UI Blazor 元件庫適用於以下場景:
• 建立新的 Blazor 應用程式。
• 將 Fluent UI 設計系統到用到現有的 Blazor 應用程式之中。
• 加速 Blazor 應用程式的使用者介面設計動作。
使用 Fluent UI Blazor 元件庫的優點包括:
• 可提高開發效率:使用現成的元件可節省開發時間和精力。
• 提升使用者體驗:Fluent UI 設計系統可幫助建立美觀、一致且易於使用的使用者介面。
• 降低維護成本:元件經過良好測試和維護,可降低應用程式的維護成本。
在這一篇文章中,我們將介紹一些適用於.NET 8,可在Blazor應用程式使用的Fluent UI元件基本功能。
安裝 Microsoft.FluentUI.AspNetCore.Templates套件
想要在Blazor應用程式之中開始使用 Fluent UI Blazor 元件進行設計的最簡單方法,就是利用官方提供的專案範本。專案範本可從以下網址下載:
https://www.nuget.org/packages/Microsoft.FluentUI.AspNetCore.Templates
請參考下圖所示:
PMP認證與ACP認證3年需要更新一次。3年內PMP認證需累積60PDU學分,ACP認證需累積30PDU學分,就可以更新;若3年沒有更新,有1年緩衝期,在緩衝期間達到累積學分即可更新認證,若超過緩衝期則要重考該認證。
若您100.1.1考上PMP認證(以證書日期為主),103.1.1前需要更新PMP認證,若無,103.1.1~104.1.1則為您的緩衝期,緩衝期間您的認證是無效的,PMI官網查詢到您的證書狀態為Suspend(暫停),若您在這一年內更新完成,您的第二張PMP證書的日期則為103.1.1~106.1.1;換言之,緩衝期的一年是不會影響您的證書起訖時間。
恆逸PDU系列課程為您提供全面的培訓,包含專案管理實務課程、敏捷管理課程、商業分析課程,也提供ITIL系列課程、藍隊資安、駭客資安、資安專家系列課程、國際標準系列課程,讓您在專業領域中脫穎而出。
作者:許薰尹 精誠資訊/恆逸教育訓練中心資深講師
本文將延續本站《使用Visual Studio Code設計ASP.NET Core Web API - 1》一文的情境,介紹如何在ASP.NET Core Web API專案中設計資料模型、資料服務,以及控制器的程式碼,以處理各種不同的HTTP請求,例如使用 CRUD 操作(新增、讀取、更新、刪除)處理資料。
在設計 Web API 之前,我們需要提供執行作業的資料暫存區,通常會使用模型類別來代表,我們將加入一個「Book」類別代表圖書資料。 模型中定義代表圖書特性的屬性。 模型將應用在 Web API 中傳遞資料,以及用來將圖書資料保存在資料存放區中,在這個文章中我們會將資料放在本機記憶體內部快取之中。
接下來來設計設計「Book」模型。先在終端機視窗執行下列命令,建立「Models」資料夾:
1 | mkdir Models |
在 Visual Studio Code 開發工具中選取「Models」資料夾,並按下「New File」按鈕,新增一個名為「Book.cs」的新檔案。
圖 1:新增「Book.cs」檔案。
新增下列程式碼到「Book.cs」之中:
1 2 3 4 5 6 7 8 9 10 11 12 | namespace MyWebAPI.Models { public class Book { public int Id { get ; set ; } public string Title { get ; set ; } public decimal Price { get ; set ; } public DateTime PublishDate { get ; set ; } public bool InStock { get ; set ; } public string Description { get ; set ; } } } |
在終端機視窗執行下列命令來建立「Services」資料夾:
1 | mkdir Services |
在 Visual Studio Code 開發工具中選取「Services」資料夾,並新增一個名為「BookService.cs」的新檔案。然後加入下列程式碼,建立圖書資料服務:
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 | using System; using System.Collections.Generic; using MyWebAPI.Models; namespace MyWebAPI.Services { public static class BookService { public static List<Book> Books { get ; private set ; } static BookService() { Books = new List<Book>() { new Book() { Id = 1 , Title = " Essential Programming Language " , Price = 250 , PublishDate = new DateTime( 2019 ,1,2 ) , InStock = true , Description = "Essential Programming Language " , }, new Book() { Id = 2 , Title = " Telling Arts " , Price = 245 , PublishDate = new DateTime( 2019 , 4 , 15 ) , InStock = true , Description = " Telling Arts " , }, new Book() { Id = 3 , Title = " Marvel " , Price = 150 , PublishDate = new DateTime( 2019 , 2, 21 ) , InStock = true , Description = " Marvel " , }, new Book() { Id = 4 , Title = " The Beauty of Cook" , Price = 450 , PublishDate = new DateTime( 2019 ,12,2 ) , InStock = true , Description = " The Beauty of Cook " , } }; } public static List<Book> GetAllBooks() { return Books; } public static Book? GetBookById( int id ) { return Books.Find( book => book.Id == id ); } public static void AddBook( Book book ) { int newId = Books.Count + 1; book.Id = newId; Books.Add( book ); } public static void DeleteBookById( int id ) { Book bookToRemove = Books.Find( book => book.Id == id ); if ( bookToRemove != null ) { Books.Remove( bookToRemove ); } } public static void UpdateBook( int id, Book book ) { Book bookToUpdate = Books.Find( book => book.Id == id ); if ( bookToUpdate != null ) { bookToUpdate.Title = book.Title; bookToUpdate.Price = book.Price; bookToUpdate.PublishDate = book.PublishDate; bookToUpdate.InStock = book.InStock; bookToUpdate.Description = book.Description; } } } } |
在終端機視窗命令提示字元執行下列命令,以建置應用程式:
1 | dotnet build |
這個命令的執行結果請參考下圖所示:
圖 2:建置應用程式。
在ASP.NET Core Web API中,控制器是一個用來處理來自用戶端的HTTP請求的類別。每個控制器可以包含一個或多個動作(方法),這些動作負責處理各種不同的HTTP請求,例如GET、POST、PUT等。
在 Visual Studio Code 開發工具中選取「Controllers」資料夾,並新增一個名為「BookController.cs」的新檔案,依照慣例,控制器類別名稱的字尾會加上 「Controller」字串。在「BookController.cs」檔案中加入以下程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 | using System; using Microsoft.AspNetCore.Mvc; namespace MyWebAPI.Controllers { [ApiController] [Route( "[controller]" )] public class BookController : ControllerBase { } } |
控制器是一個公開類別,通常繼承自「ControllerBase」類別,類別上方套用[ApiController] 和 [Route]。
控制器類別包含處理不同HTTP請求的方法,這些方法稱為「動作」,它們是公開方法,用來對應特定的HTTP請求。
我們要撰寫的第一個REST指令動詞為「GET」,讓用戶端能夠從API獲取所有圖書的資訊。我們可以利用內建的[HttpGet]屬性,來定義一個方法,負責從服務取回圖書清單,在「BookController」類別加入以下程式碼:
1 2 3 4 5 6 | //Get All Books [HttpGet] public IActionResult GetAll() { return Ok( MyWebAPI.Services.BookService.GetAllBooks() ); } |
上述程式具有以下特點:
用戶端可能會需要查詢特定圖書的詳細資料,而不是整個圖書清單。為此,我們可以設計一個帶有「id」參數的「GET」動作。使用內建的[HttpGet("{id}")]屬性定義一個方法,從服務中取回特定的圖書資料。在「BookController」類別加入以下程式碼:
1 2 3 4 5 6 7 | //Get Book by Id [HttpGet( "{id}" )] public ActionResult<Book> Get( int id ) { var book = MyWebAPI.Services.BookService.GetBookById( id ); return book != null ? Ok( book ) : NotFound( ); } |
Web API的路由系統會根據是否提供id,來決定叫用[HttpGet](無id)和[HttpGet("{id}")](帶有id)兩個方法。
在終端機視窗命令提示字元執行下列命令以執行Web API程式:
1 | dotnet run |
這個命令的執行結果請參考下圖所示:
圖 3:執行Web API程式。
開啟 「MyWebAPI.http」檔案,在分隔符「###」下方加入以下兩個「GET」程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @MyWebAPI_HostAddress = http: //localhost:5052 GET {{MyWebAPI_HostAddress}}/weatherforecast/ Accept: application/json ### GET {{MyWebAPI_HostAddress}}/Book/ Accept: application/json ### GET {{MyWebAPI_HostAddress}}/Book/1 Accept: application/json ### |
選取「GET」上方的 「Send Request」命令傳送要求,此命令將會以 JSON 格式傳回所有圖書的清單,這個命令的執行結果請參考下圖所示:
圖 4:送出GET請求取回所有圖書資料。
按相同的方式測試最後一個「GET」請求,取回一本圖書資料,這個命令的執行結果請參考下圖所示:
圖 5:送出「GET」請求取「id」相符的圖書資料。
我們的 API 也會處理資料不存在的情況。 若再次呼叫 API,故意使用下列命令傳入無效的圖書id編號:
1 2 3 4 5 6 | @MyWebAPI_HostAddress = http: //localhost:5052 ### GET {{MyWebAPI_HostAddress}}/Book/100 Accept: application/json ### |
這時將會傳回 「404 Not Found」錯誤,請參考下圖所示:
圖 6:「404 Not Found」 錯誤。
在 Visual Studio Code 開發工具中選擇「 Terminal 」> 「New Terminal」開啟一個新的整合式終端機,在其中輸入並執行命令,以 .NET HTTP REPL 命令列工具,來送出HTTP 請求:
1 | connect http: //localhost:5052 |
這個命令的執行結果請參考下圖所示:
圖 7:使用.NET HTTP REPL命令測試控制器。
執行下列命令,查看端點:
1 |
執行下列命令,以前往「Book」端點:
1 | cd Book |
使用下列命令,透過「HttpRepl」送出「GET」請求:
1 | Get |
這些命令的執行結果請參考下圖所示:
圖 8:使用HTTP REPL 命令測試控制器。
我們的圖書服務提供支援圖書清單的 CRUD(建立、讀取、更新、刪除)操作。這些操作是透過不同的HTTP指令動詞來實現的,並且在ASP.NET Core中,這些動詞由特定的屬性來對應。例如從服務取得一個或多個項目的HTTP GET指令動詞,會透過使用[HttpGet]屬性來標示相應的動作方法。同樣的道理,[HttpPost]可用來標示資料新增的動作方法;[HttpPut] 可用來標示資料修改的動作方法;[HttpDelete] 可用來標示資料刪除的動作方法;
我們已經看過「GET」動作的運作方式, 現在就來深入了解「POST」、「PUT」和 「DELETE」動作。我們先使用「POST」方法,透過 Web API 新增圖書資料,在「BookController」類別加入以下程式碼:
1 2 3 4 5 6 7 | // Add Book [HttpPost] public IActionResult AddBook( Book book ) { MyWebAPI.Services.BookService.AddBook( book ); return Created( $ "/book/{book.Id}" , book ); } |
「AddBook」方法上標註 [HttpPost],用來處理發送到 Book API 的 HTTP「POST」請求。和「Get」方法回傳圖書清單不同的是,這方法會回傳「IActionResult」。「IActionResult」使用戶端能夠了解請求是否執行成功,若成功便提供新建立的圖書「ID」。利用標準的 HTTP 狀態碼,「IActionResult」確保無論用戶端使用的程式語言或開發平台是什麼,都能夠輕鬆地實現與用戶端的整合。
修改或更新我們圖書的程式類似於之前實作的「POST」方法,但需要搭配使用[HttpPut]屬性。除此之外,除了需要更新的「Book」物件之外,還需要一個「id」參數。接著,使用「PUT」方法,透過 Web API 更新圖書。在「BookController」類別加入以下程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Update Book [HttpPut( "{id}" )] public IActionResult UpdateBook( int id, Book book ) { var existingBook = MyWebAPI.Services.BookService.GetBookById( id ); if (existingBook == null ) { return NotFound(); } book.Id = id; MyWebAPI.Services.BookService.UpdateBook( id, book ); return NoContent(); } |
Web API其中一個較簡單要實作的動作是「DELETE」動作,只接受圖書的「id」參數,以便從記憶體內部快取中移除。在「BookController」類別加入以下程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 | // Delete Book [HttpDelete( "{id}" )] public IActionResult DeleteBook( int id ) { var existingBook = MyWebAPI.Services.BookService.GetBookById( id ); if ( existingBook == null ) { return NotFound(); } MyWebAPI.Services.BookService.DeleteBookById( id ); return NoContent(); } |
我們已經完成Web API的設計了,現在讓我們來測試看看。在終端機視窗命令提示字元執行下列命令,建立並啟動 Web API:
1 | dotnet run |
然後使用「.HTTP」檔案測試已完成的 Web API,重新開啟「MyWebAPI.http」 檔案,使用下列命令來送出「POST」要求,以新增圖書:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @MyWebAPI_HostAddress = http: //localhost:5052 POST {{MyWebAPI_HostAddress}}/Book/ Content-Type: application/json Accept: application/json { "id" : 100, "title" : "Book 100" , "price" : 100, "PublishDate" : "2021-01-01T00:00:00" , "InStock" : true , "Description" : "Book 100 Description" } ### |
上述命令會傳回新建立的圖書,執行結果請參考下圖所示:
圖 9:新增圖書。
在終端機視窗命令提示字元執行下列命令,以 「PUT」要求來更新圖書:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @MyWebAPI_HostAddress = http: //localhost:5052 PUT {{MyWebAPI_HostAddress}}/Book/1 Content-Type: application/json Accept: application/json { "id" : 1, "title" : "New Book 1" , "price" : 100, "PublishDate" : "2021-01-01T00:00:00" , "InStock" : false , "Description" : "New Book 1 Description" } ### |
上述命令會傳回下列訊息,表示成功:
1 2 3 4 | HTTP/1.1 204 No Content Connection: close Date: Thu, 29 Feb 2024 05:51:06 GMT Server: Kestrel |
這個命令的執行結果請參考下圖所示:
圖 10:修改資料。
在終端機視窗命令提示字元執行下列命令,以透過「DELETE」動作來刪除圖書:
1 2 3 4 5 | @MyWebAPI_HostAddress = http: //localhost:5052 ### DELETE {{MyWebAPI_HostAddress}}/Book/1 |
上述命令會傳回下列訊息,表示成功,請參考下圖所示:
圖 11:刪除圖書。
先在專案根目錄加入一個「data.json」檔案,包含要新增的資料,使用JSON格式:
1 | { "id" : 100, "title" : "Book 100" , "price" : 100, "PublishDate" : "2021-01-01T00:00:00" , "InStock" : true , "Description" : "Book 100 Description" } |
在 Visual Studio Code 開發工具 中選擇 >「 Terminal 」> 「New Terminal」開啟一個新的整合式終端機,在其中輸入並執行命令:
1 | httprepl http: //localhost:5052 |
執行下列命令,查看端點:
1 |
這些命令的執行結果請參考下圖所示:
圖 12:httprepl連線到服務。
執行下列命令,以前往「Book」端點:
1 | cd Book |
使用下列命令,透過「HttpRepl」送出 POST請求,利用「-f」參數指定資料所在的檔案:
1 | POST -f data.json |
這些命令的執行結果請參考下圖所示:
圖 13:新增資料。
接著我們修改「data.json」檔案,修改編號「1」的圖書「title」等資料:
1 | { "id" : 1, "title" : "Book 101" , "price" : 100, "PublishDate" : "2021-01-01T00:00:00" , "InStock" : true , "Description" : "Book 101 Description" } |
重複之前的動作,在 Visual Studio Code 開發工具 中選擇 >「 Terminal 」> 「New Terminal」開啟一個新的整合式終端機,在其中輸入並執行命令:
1 | httprepl http: //localhost:5052 |
執行下列命令,查看端點:
1 |
圖 14:httprepl連線到服務。
執行下列命令,以前往「Book」端點:
1 | cd Book |
1 |
圖 15:{id}端點。
使用下列命令,透過「HttpRepl」中送出「PUT」請求:
1 | Put -f data.json |
使用「get」命令取回修改結果,比對資料是否正確被修改:
1 | get |
圖 16:修改資料。
重複之前的動作,在終端機視窗輸入並執行命令,刪除編號為「1」的資料:
1 | delete 1 |
1 | get |
這些命令的執行結果請參考下圖所示:
圖 17:刪除資料。
在這一系列文章,我們介紹了如何在 .NET 平台上建立一個運行ASP.NET Core Web API的應用程式。這個Web API利用快取來建立、讀取、修改和刪除圖書資料。現在你已掌握了以下使用ASP.NET Core建立Web API的關鍵步驟: