標籤:sharp ram 刪除 取數 啟動 doc from gui 路由
在Mac下建立ASP.NET Core Web API在Mac下建立ASP.NET Core Web API
這系列文章是參考了.NET Core文檔和源碼,可能有人要問,直接看官方的英文文檔不就可以了嗎,為什麼還要寫這些文章呢?
原因如下:
- 官方文檔涉及的內容相當全面,屬於那種大而全的知識倉庫,不太適合初學者,很容易讓人失去重要,讓人掉入到具體的細節之中。
- 對於大多數人來講開發語言只是工具,程式員都有一個通病,就是死磕工具,把工具學深。我認為在工具上沒有必要投入太多時間,以能高效地完成日常的工作項目> 目為準即可。要需求驅動學習,你需要什麼學什麼。如果你學的新技術新特性只是屠龍之技或者只需要用到的時候去查一下即可的話,這種死磕這又有什麼用。沒有必> 要花120%的時間去學100%的知識,你只需要花20%的時間去學習80%的知識就可以了,剩下的等實際的項目中用到的時候去查就可以了,工具只是工具,不是工作本身。
- 目前基本所有的文章都是基於Windows平台的Visual Studio IDE來介紹的。而我用的是一台Mac,所以我將基於Mac平台的Visual Studio Code講解適合我們實際項目中遇到的知識。
- 還有一點,就是這是我個人的學習總結。
這系列文章就是讓你去花20%的時間去學80%的東西,剩下的20%再去看官方文檔。
在.NET Core裡面MVC和WebAPI兩者被整合成一個架構,分享同一套代碼和管線。這樣我們就可以更方便地開發MVC應用程式和Web API介面。
建立項目
在這篇文章中我們將要建立的API如下:
| API |
描述 |
| GET /api/user |
擷取所有的使用者資訊 |
| GET /api/user/{id} |
根據ID擷取指定的使用者 |
| POST /api/user |
添加新的使用者 |
| PUT /api/user/{id} |
更新使用者資訊 |
| PATCH /api/user/{id} |
更新使用者資訊 |
| DELETE /api/user/{id} |
刪除使用者資訊 |
根據上一篇文章,我們通過Yeoman建立一個WebAPI項目,命名為UserWebAPI:
添加模型類
然後在項目根目錄下面建立一個Models檔案夾,在該檔案夾下面利用yo aspnet:class UserItem建立一個UserItem類。
namespace UserWebAPI.Models{ public class UserItem { public string Key { get; set; } public string Name { get; set; } public int Age { get; set; } }}
添加倉儲類
Repository類是封裝了資料層的對象,包含了擷取資料、並映射到實體模型類的商務邏輯。
首先我們在Models檔案夾下面定義一個IUserRepositoryrepository介面。
通過運行yo aspnet:interface IUserRepository命令來建立該介面。
namespace UserWebAPI.Models{ public interface IUserRepository { void Add(UserItem item); IEnumerable<UserItem> GetAll(); UserItem Find(string key); UserItem Remove(string key); void Update(UserItem item); }}
接著再添加一個UserRepository類來實現IUserRepository介面。
namespace UserWebAPI.Models{ public class UserRepository : IUserRepository { private static ConcurrentDictionary<string, UserItem> _users = new ConcurrentDictionary<string, UserItem>(); public UserRepository() { Add(new UserItem { Name = "Charlie", Age = 18 }); } public void Add(UserItem item) { item.Key = Guid.NewGuid().ToString(); _users[item.Key] = item; } public UserItem Find(string key) { UserItem user; _users.TryGetValue(key, out user); return user; } public IEnumerable<UserItem> GetAll() { return _users.Values; } public UserItem Remove(string key) { UserItem user; _users.TryRemove(key, out user); return user; } public void Update(UserItem item) { _users[item.Key] = item; } }}
註冊倉儲
通過定義一個repository介面,我們從使用它的MVC Controller來解耦該repository類。我們在此將通過注入一個UserRepository來代替直接在Controller裡面執行個體化一個UserRepository類。
為了注入一個repository到controller,我們必須通過DI容器來註冊它,開啟Startup.cs檔案,在ConfigureServices方法添加如下代碼:
添加控制器
控制器是用於處理HTTP請求並建立HTTP響應的對象,這裡通過運行yo aspnet:webapicontroller UserController命令產生UserController控制器。
namespace UserWebAPI.Controllers{ [Route("api/[controller]")] public class UserController : Controller { public IUserRepository UserItems { get; set; } public UserController(IUserRepository userItems) { UserItems = userItems; } }}
擷取使用者資訊
[HttpGet]public IEnumerable<UserItem> GetAll(){ return UserItems.GetAll();}[HttpGet("{id}", Name = "GetUser")]public IActionResult GetById(string id){ var item = UserItems.Find(id); if (item == null) { return NotFound(); } return new ObjectResult(item);}
上述兩個方法實現了兩個GET方法:
GET /api/user
GET /api/user/{id}
運行dotnet restore、dotnet run之後,應用程式將會在本機啟動,並在http://localhost:5000上開啟監聽服務。
然後在Postman上測試你的API介面是否能正確運行。
在GetById方法中:
[HttpGet("{id}", Name = "GetTodo")]public IActionResult GetById(string id)
其中"{id}"是UserItem的ID預留位置,當GetById被調用時,URL中的“{id}”值會被分配給該方法的id參數。
Name = "GetTodo"建立了一個命名的路由,並允許你在HTTP響應中連結到該路由。
GetAll方法返回了一個IEnumerable,MVC會自動將對象序列化成JSON並將JSON寫入到響應訊息的本文中。該方法的響應狀態代碼為200,假設沒有發生任何未處理異常。
而GetById方法返回的是一個更為通用的IActionResult類型。該方法有兩種不同的傳回型別:
- 如果沒有項匹配指定的請求ID,該方法通過返回
NotFound表示一個404錯誤。
- 否則,該方法返回一個JSON響應本文和200響應碼,通過返回
ObjectResult來表示。
添加新使用者
[HttpPost]public IActionResult Create([FromBody]UserItem item){ if (item == null) { return BadRequest(); } UserItems.Add(item); return CreatedAtRoute("GetUser", new { id = item.Key }, item);}
通過[HttpPost] attribute 標明這個一個HTTP POST方法,[FromBody] attribute 告訴MVC從HTTP 要求的本文中擷取使用者UserItem值。
CreatedAtRoute方法返回一個201響應狀態代碼(實際上是CreatedAtRouteResult對象),201狀態代碼是通過POST方法在伺服器上成功建立了一個新的資源時的標準響應碼。CreateAtRoute也在響應裡面添加了一個Location頭資訊,這個頭資訊指定了最新建立的User URI。
/// <summary>/// Creates a <see cref="CreatedAtRouteResult"/> object that produces a Created (201) response./// </summary>/// <param name="routeName">The name of the route to use for generating the URL.</param>/// <param name="routeValues">The route data to use for generating the URL.</param>/// <param name="value">The content value to format in the entity body.</param>/// <returns>The created <see cref="CreatedAtRouteResult"/> for the response.</returns>[NonAction]public virtual CreatedAtRouteResult CreatedAtRoute(string routeName, object routeValues, object value){ return new CreatedAtRouteResult(routeName, routeValues, value);}
/// <summary>/// Initializes a new instance of the <see cref="CreatedAtRouteResult"/> class with the values/// provided./// </summary>/// <param name="routeName">The name of the route to use for generating the URL.</param>/// <param name="routeValues">The route data to use for generating the URL.</param>/// <param name="value">The value to format in the entity body.</param>public CreatedAtRouteResult(string routeName, object routeValues, object value) : base(value){ RouteName = routeName; RouteValues = routeValues == null ? null : new RouteValueDictionary(routeValues); StatusCode = StatusCodes.Status201Created;}
通過查看CreatedAtRouteResult的建構函式可以看到StatusCode(從ObjectResult對象繼承而來)被直接設定成了Status201Created枚舉值。
201狀態代碼是當你在用POST/PUT在伺服器端成功建立了一個新的資源時,伺服器就應當返回201 Created同時在回應標頭添加一個Location來指定剛剛建立好的資源的URI。
通過Postman來發送Create請求
剛伺服器接收到請求,會在VS Code的控制台顯示出相應的資訊:
點擊Headers tab可以看到Location的值顯示剛剛建立好的資源的URI。
更新使用者資訊(HTTP PUT)
[HttpPut("{id}")]public IActionResult Update(string id, [FromBody] UserItem item){ if (item == null || item.Key != id) { return BadRequest(); } var user=UserItems.Find(id); if(user==null) { return NotFound(); } UserItems.Update(item); return new NoContentResult();}
採用了HTTP PUT標記Update方法,並且響應狀態代碼設定為204(No Content)。根據HTTP規範,PUT請求要求用戶端發送整個被更新實體,而不是累加式更新部分。如果要支援局部更新,則需要使用HTTP PATCH。
204(No Content)狀態代碼表示伺服器已經成功處理了你的請求,但不需要返回具體的資料。瀏覽器不用重新整理頁面,也不用重新導向到新的頁面,會保留髮送了該請求的頁面,不產生任何文檔視圖上的變化,只停留在當前頁面。由於204響應被禁止包含任何訊息體,因此它始終以訊息頭後的第一個空行結尾。對提交到伺服器進行處理的資料,如果只需要返回是否成功的話,可考慮使用狀態代碼204來作為返回資訊,從而減少多餘的資料轉送。
NoContentResult類在建構函式中調用了父類的建構函式並把Status204NoContent傳給了該類。
namespace Microsoft.AspNetCore.Mvc{ public class NoContentResult : StatusCodeResult { public NoContentResult() : base(StatusCodes.Status204NoContent) { } }}
更新使用者資訊(HTTP PATCH)
[HttpPatch("{id}")]public IActionResult Update([FromBody] UserItem item, string id){ if (item == null) { return BadRequest(); } var user = UserItems.Find(id); if (user == null) { return NotFound(); } item.Key = user.Key; UserItems.Update(item); return new NoContentResult();}
刪除使用者
[HttpDelete("{id}")]public IActionResult Delete(string id){ var user = UserItems.Find(id); if (user == null) { return NotFound(); } UserItems.Remove(id); return new NoContentResult();}
這個響應狀態代碼同樣是204(No Content)。
個人部落格
我的個人部落格
在Mac下建立ASP.NET Core Web API