一、開篇引入
在當(dāng)今的 Web 應(yīng)用開發(fā)領(lǐng)域,前后端分離開發(fā)模式已成為主流趨勢。這種模式就像是一場高效的接力賽,前端專注于打造用戶界面,為用戶帶來絕佳的視覺與交互體驗;而后端則承擔(dān)起數(shù)據(jù)處理、業(yè)務(wù)邏輯實現(xiàn)以及服務(wù)提供的重任,是整個應(yīng)用的堅實后盾。就好比建造一座高樓,前端是這座樓華麗的外觀與精致的內(nèi)飾,而后端則是穩(wěn)固的地基和承重結(jié)構(gòu)。
后端開發(fā)技術(shù)的重要性不言而喻,它直接關(guān)系到應(yīng)用程序的性能、穩(wěn)定性和安全性。打個比方,后端開發(fā)就如同餐廳的廚房,前端展示的是精致的菜品,而后端則是在幕后精心準(zhǔn)備食材、烹飪美食的地方。沒有一個高效、穩(wěn)定的廚房(后端),前端即便再吸引人,也無法持續(xù)為用戶提供優(yōu)質(zhì)的服務(wù)。
在眾多后端開發(fā)技術(shù)中,.NET Core WebApi 脫穎而出,它憑借自身的眾多優(yōu)勢,成為了開發(fā)者們構(gòu)建強大后端服務(wù)的得力工具。接下來,就讓我們一起深入探索.NET Core WebApi 的精彩世界。
二、.NET Core WebApi 是什么
(一).NET Core 簡介
.NET Core 是微軟開發(fā)的一個開源、通用的開發(fā)框架,旨在為開發(fā)者提供一個高效、靈活且跨平臺的開發(fā)環(huán)境。它就像是一個萬能的工具箱,里面裝滿了各種工具和組件,能幫助開發(fā)者輕松打造出各種類型的應(yīng)用程序。
其最顯著的特性之一便是跨平臺能力。以往,基于.NET Framework 開發(fā)的應(yīng)用往往被限制在 Windows 系統(tǒng)中運行,就如同被束縛在一個小圈子里。而.NET Core 打破了這一限制,它可以在 Windows、Linux 和 macOS 等多種操作系統(tǒng)上運行,就像一位自由的旅行者,可以在不同的土地上自由穿梭。這使得開發(fā)者能夠更廣泛地部署應(yīng)用,滿足不同用戶群體的需求,無論是企業(yè)級的服務(wù)器應(yīng)用,還是個人開發(fā)的小型項目,.NET Core 都能完美適配。
在實際應(yīng)用場景中,.NET Core 被廣泛應(yīng)用于云服務(wù)、微服務(wù)架構(gòu)以及各類 Web 應(yīng)用的開發(fā)。以云服務(wù)為例,許多企業(yè)將業(yè)務(wù)遷移到云端,.NET Core 憑借其高效的性能和跨平臺特性,能夠輕松部署在各種云平臺上,如 Microsoft Azure、AWS 等,為企業(yè)提供穩(wěn)定可靠的服務(wù)。在微服務(wù)架構(gòu)中,各個微服務(wù)可以獨立開發(fā)、部署和擴展,.NET Core 的輕量級和模塊化設(shè)計使其非常適合構(gòu)建這種分布式的系統(tǒng)架構(gòu),每個微服務(wù)都可以專注于自己的業(yè)務(wù)邏輯,通過高效的通信機制協(xié)同工作,就像一個精密的機器,各個零部件各司其職,共同推動整個系統(tǒng)的運轉(zhuǎn)。
(二)WebApi 在開發(fā)中的角色
WebApi 在前后端分離開發(fā)模式中扮演著至關(guān)重要的數(shù)據(jù)交互橋梁角色。簡單來說,前端負(fù)責(zé)呈現(xiàn)精美的界面,與用戶進行交互,而后端則負(fù)責(zé)處理業(yè)務(wù)邏輯和數(shù)據(jù)存儲。WebApi 就像是連接前后端的高速公路,讓數(shù)據(jù)能夠在兩者之間快速、準(zhǔn)確地傳輸。
想象一下,你在手機上使用一款購物 APP,當(dāng)你點擊查看商品詳情時,前端界面會向 WebApi 發(fā)送請求,WebApi 接收到請求后,會在后端的數(shù)據(jù)庫中查詢相關(guān)商品信息,然后將這些信息以特定的格式(如 JSON)返回給前端,前端再根據(jù)這些數(shù)據(jù)將商品詳情展示在你的屏幕上。這個過程中,WebApi 提供了一系列的數(shù)據(jù)接口,這些接口就像是高速公路上的一個個出口,前端可以根據(jù)不同的需求,通過相應(yīng)的接口獲取或操作數(shù)據(jù)。
在實際開發(fā)中,WebApi 通常會定義各種不同的 API 端點,每個端點對應(yīng)著不同的業(yè)務(wù)功能。比如,一個用戶管理系統(tǒng)的 WebApi 可能會有 “/api/users/login” 用于用戶登錄,“/api/users/register” 用于用戶注冊,“/api/users/{id}” 用于獲取特定用戶的信息等接口。通過這些清晰明確的接口,前端開發(fā)者可以方便地與后端進行交互,而無需關(guān)心后端復(fù)雜的業(yè)務(wù)邏輯和數(shù)據(jù)處理過程,就像你只需要知道如何使用高速公路上的出口到達目的地,而不需要了解高速公路的建設(shè)和維護細節(jié)一樣。
三、開發(fā)環(huán)境搭建
(一)開發(fā)工具推薦
在進行.NET Core WebApi 開發(fā)時,選擇一款合適的開發(fā)工具能讓你的開發(fā)之旅更加順暢。以下是幾款常用的開發(fā)工具及其優(yōu)勢:
Visual Studio
:這是一款由微軟開發(fā)的功能強大的集成開發(fā)環(huán)境(IDE),就像是一個超級工具箱,里面應(yīng)有盡有。它對.NET Core 有著原生的支持,提供了豐富的代碼編輯、調(diào)試和項目管理功能。在代碼編輯方面,它擁有智能代碼提示功能,就像你的私人助手,能根據(jù)你的輸入自動提示可能需要的代碼,大大提高了編碼效率。調(diào)試功能更是強大,你可以設(shè)置斷點,逐行執(zhí)行代碼,查看變量的值,輕松定位和解決代碼中的問題,就像拿著一個放大鏡,仔細檢查代碼中的每一個細節(jié)。下載安裝也很簡單,你可以在微軟官網(wǎng)(https://visualstudio.microsoft.com/zh-hans/downloads/)下載,根據(jù)安裝向?qū)У奶崾?,一步步完成安裝。安裝過程中,你可以根據(jù)自己的需求選擇安裝的組件,比如你主要進行.NET Core WebApi 開發(fā),就可以選擇安裝相關(guān)的 Web 開發(fā)組件等。
Visual Studio Code
:這是一款輕量級但功能強大的源代碼編輯器,它的特點是跨平臺,無論你使用的是 Windows、macOS 還是 Linux 系統(tǒng),都可以流暢使用。它擁有豐富的插件生態(tài)系統(tǒng),這就像是一個巨大的插件超市,你可以根據(jù)自己的開發(fā)需求安裝各種插件。比如,安裝 C# 插件后,它就能很好地支持.NET Core 開發(fā),提供代碼高亮、智能補全等功能。你可以在官網(wǎng)(https://code.visualstudio.com/)下載安裝包,安裝完成后,在擴展商店中搜索并安裝 C# 插件,即可開始.NET Core WebApi 的開發(fā)。
Rider
:這是 JetBrains 公司開發(fā)的一款跨平臺的.NET IDE,它以其智能的代碼分析和豐富的代碼導(dǎo)航功能而受到開發(fā)者的喜愛。它能快速分析你的代碼,找出潛在的問題和優(yōu)化建議,就像一個專業(yè)的代碼醫(yī)生,為你的代碼健康保駕護航。在代碼導(dǎo)航方面,你可以輕松跳轉(zhuǎn)到定義、查看引用等,方便你理解和管理代碼結(jié)構(gòu)。你可以在 JetBrains 官網(wǎng)(https://www.jetbrains.com/rider/)下載安裝,安裝完成后,就可以創(chuàng)建.NET Core WebApi 項目進行開發(fā)了。
(二)創(chuàng)建第一個.NET Core WebApi 項目
接下來,我們以 Visual Studio 為例,一步步創(chuàng)建一個.NET Core WebApi 項目。
打開 Visual Studio
:安裝完成后,在開始菜單中找到 Visual Studio 并打開它。第一次打開時,可能會進行一些初始化設(shè)置,比如選擇主題、設(shè)置環(huán)境等,你可以根據(jù)自己的喜好進行選擇。
創(chuàng)建新項目
:點擊 “創(chuàng)建新項目”,在彈出的 “創(chuàng)建新項目” 窗口中,你會看到各種各樣的項目模板。在搜索框中輸入 “ASP.NET Core Web API”,然后在搜索結(jié)果中選擇 “ASP.NET Core Web API” 模板,這個模板就是專門用于創(chuàng)建.NET Core WebApi 項目的,就像你找到了一把專門打開 WebApi 項目大門的鑰匙。點擊 “下一步”。
配置項目信息
:在這一步,你需要給項目命名,比如 “FirstWebApiProject”,同時選擇項目的存儲位置,建議選擇一個空間較大且便于管理的磁盤目錄,比如 D 盤的某個文件夾。還可以根據(jù)需要設(shè)置解決方案名稱,解決方案是一個容器,它可以包含多個項目,這里我們可以保持默認(rèn)與項目名稱相同。設(shè)置完成后,點擊 “下一步”。
選擇框架和其他配置
:在這個界面,你可以選擇.NET Core 的版本,比如選擇最新穩(wěn)定版本,以獲得更好的性能和功能支持。還可以配置身份驗證類型、是否配置 HTTPS 等。對于初學(xué)者,我們可以先保持默認(rèn)設(shè)置,這些配置在后續(xù)的開發(fā)中也可以根據(jù)實際需求進行調(diào)整。點擊 “創(chuàng)建” 按鈕。
等待項目創(chuàng)建完成
:Visual Studio 會根據(jù)你選擇的模板和配置,自動創(chuàng)建項目。這個過程可能需要一些時間,就像在搭建一座房子,需要逐步構(gòu)建各個部分。創(chuàng)建完成后,你會看到一個完整的項目結(jié)構(gòu),其中包含了各種文件和文件夾,如 Controllers 文件夾用于存放控制器,Models 文件夾用于存放數(shù)據(jù)模型,Program.cs 是項目的入口文件,它負(fù)責(zé)啟動應(yīng)用程序等。
四、核心開發(fā)技術(shù)解析
(一)控制器與路由
在.NET Core WebApi 中,控制器就像是交通樞紐的調(diào)度員,負(fù)責(zé)接收客戶端發(fā)送的 HTTP 請求,并根據(jù)請求的內(nèi)容來執(zhí)行相應(yīng)的操作,然后將處理結(jié)果返回給客戶端。它是整個 WebApi 的核心組件之一,將業(yè)務(wù)邏輯與外部請求進行了有效的連接。
以一個簡單的用戶管理系統(tǒng)為例,我們來創(chuàng)建一個控制器。首先,在 Controllers 文件夾下創(chuàng)建一個名為 UserController.cs 的文件。在這個文件中,我們定義一個類,讓它繼承自 ControllerBase 類,這樣它就具備了 WebApi 控制器的能力。
using Microsoft.AspNetCore.Mvc;
namespace FirstWebApiProject.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
// 獲取所有用戶
[HttpGet]
public IActionResult GetAllUsers()
{
// 這里可以編寫從數(shù)據(jù)庫獲取所有用戶的邏輯,暫時返回一個簡單的模擬數(shù)據(jù)
var users = new[] { new { Name = "張三", Age = 20 }, new { Name = "李四", Age = 22 } };
return Ok(users);
}
// 根據(jù)ID獲取單個用戶
[HttpGet("{id}")]
public IActionResult GetUserById(int id)
{
// 同樣,這里可以編寫從數(shù)據(jù)庫根據(jù)ID查詢用戶的邏輯,這里簡單模擬
var user = new { Name = "模擬用戶", Age = 25 };
return Ok(user);
}
// 添加新用戶
[HttpPost]
public IActionResult AddUser([FromBody] dynamic user)
{
// 處理添加用戶的邏輯,這里簡單返回添加成功的信息
return Ok($"用戶 {user.Name} 添加成功");
}
// 更新用戶信息
[HttpPut("{id}")]
public IActionResult UpdateUser(int id, [FromBody] dynamic user)
{
// 處理更新用戶信息的邏輯,這里簡單返回更新成功的信息
return Ok($"用戶 {id} 的信息更新成功");
}
// 刪除用戶
[HttpDelete("{id}")]
public IActionResult DeleteUser(int id)
{
// 處理刪除用戶的邏輯,這里簡單返回刪除成功的信息
return Ok($"用戶 {id} 刪除成功");
}
}
}
在上述代碼中,我們定義了多個方法,每個方法對應(yīng)一種 HTTP 請求方式和相應(yīng)的業(yè)務(wù)邏輯。比如,GetAllUsers方法用于處理獲取所有用戶的 GET 請求,AddUser方法用于處理添加用戶的 POST 請求等。
路由則決定了客戶端的請求如何被映射到相應(yīng)的控制器和操作方法上。在上面的代碼中,[Route("api/[controller]")]表示該控制器的路由前綴為 “api/” 加上控制器的名稱(去掉 Controller 后綴)。例如,對于 UserController,其路由前綴就是 “api/user”。[HttpGet]、[HttpPost]等特性則進一步指定了方法對應(yīng)的 HTTP 請求方式。[HttpGet("{id}")]表示這個方法處理帶有一個參數(shù)id的 GET 請求,比如 “api/user/1”,這里的 “1” 就是id的值。
不同的路由規(guī)則有著不同的應(yīng)用場景。例如,屬性路由(如上面代碼中使用的)適用于構(gòu)建 RESTful 風(fēng)格的 API,它能讓 API 的 URL 更加直觀和易于理解,通過 URL 就能清晰地知道請求的目的和操作的資源。而傳統(tǒng)路由則更適合一些對 URL 格式有特定要求,或者需要進行復(fù)雜路由匹配的場景。比如,在一個大型的企業(yè)級應(yīng)用中,可能需要根據(jù)不同的模塊、權(quán)限等因素來進行路由匹配,傳統(tǒng)路由可以通過在 Startup.cs 文件中進行詳細的配置來滿足這些需求。
(二)請求與響應(yīng)處理
在 WebApi 中,常見的 HTTP 請求方式有 GET、POST、PUT、DELETE 等,每種請求方式都有其特定的用途。
GET 請求通常用于從服務(wù)器獲取資源。比如,在上面的 UserController 中,GetAllUsers方法和GetUserById方法都是處理 GET 請求的。當(dāng)客戶端發(fā)送一個 GET 請求到 “api/user” 時,GetAllUsers方法會被調(diào)用,返回所有用戶的信息;當(dāng)發(fā)送 GET 請求到 “api/user/1” 時,GetUserById方法會被調(diào)用,返回 ID 為 1 的用戶信息。在實際應(yīng)用中,GET 請求還可以帶有查詢參數(shù),用于對獲取的資源進行篩選、排序等操作。比如 “api/user?age=20”,表示獲取年齡為 20 的用戶信息。
POST 請求一般用于向服務(wù)器提交數(shù)據(jù),以創(chuàng)建新的資源。在AddUser方法中,我們使用[FromBody]特性來獲取客戶端發(fā)送的請求體中的數(shù)據(jù),這些數(shù)據(jù)就是要添加的新用戶的信息。服務(wù)器接收到 POST 請求后,會根據(jù)請求體中的數(shù)據(jù)在數(shù)據(jù)庫中創(chuàng)建一個新的用戶記錄,并返回相應(yīng)的結(jié)果給客戶端,告知客戶端添加操作是否成功。
PUT 請求用于更新服務(wù)器上已有的資源。UpdateUser方法接收一個id參數(shù)和請求體中的更新數(shù)據(jù),根據(jù)id找到對應(yīng)的用戶,然后將請求體中的數(shù)據(jù)應(yīng)用到該用戶上,實現(xiàn)用戶信息的更新。
DELETE 請求自然是用于刪除服務(wù)器上的資源啦。DeleteUser方法根據(jù)傳入的id,在數(shù)據(jù)庫中刪除對應(yīng)的用戶記錄,并返回刪除成功的響應(yīng)給客戶端。
當(dāng) WebApi 接收到客戶端的請求并處理完成后,需要構(gòu)建正確的響應(yīng)返回給客戶端。響應(yīng)通常包括狀態(tài)碼、響應(yīng)頭和響應(yīng)體。狀態(tài)碼用于表示請求的處理結(jié)果,比如 200 表示請求成功,404 表示資源未找到,500 表示服務(wù)器內(nèi)部錯誤等。在上面的代碼中,我們使用Ok方法來返回 200 狀態(tài)碼和相應(yīng)的響應(yīng)體。如果請求處理過程中出現(xiàn)錯誤,我們可以使用BadRequest方法返回 400 狀態(tài)碼,表示客戶端請求錯誤,或者使用NotFound方法返回 404 狀態(tài)碼,表示請求的資源不存在等。響應(yīng)頭則包含了一些關(guān)于響應(yīng)的元信息,比如 Content-Type 用于指定響應(yīng)體的數(shù)據(jù)類型,常見的有 application/json、text/html 等。如果響應(yīng)體是 JSON 格式的數(shù)據(jù),就需要將 Content-Type 設(shè)置為 application/json,這樣客戶端才能正確解析響應(yīng)體中的數(shù)據(jù)。
(三)數(shù)據(jù)訪問與持久化
在實際的 WebApi 開發(fā)中,數(shù)據(jù)訪問與持久化是非常重要的環(huán)節(jié)。接下來,我們簡單介紹一下如何連接常見的數(shù)據(jù)庫(如 SQL Server、MySQL)并進行數(shù)據(jù)的增刪改查操作。
以 SQL Server 為例,我們可以使用ADO.NET來連接數(shù)據(jù)庫。首先,需要在項目中添加對System.Data.SqlClient命名空間的引用。然后,在控制器或數(shù)據(jù)訪問層的代碼中,編寫連接數(shù)據(jù)庫和執(zhí)行操作的代碼。
using System;
using System.Data.SqlClient;
public class UserRepository
{
private readonly string connectionString;
public UserRepository(string connectionString)
{
this.connectionString = connectionString;
}
// 獲取所有用戶
public SqlDataReader GetAllUsers()
{
string query = "SELECT * FROM Users";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(query, connection);
connection.Open();
return command.ExecuteReader();
}
}
// 根據(jù)ID獲取單個用戶
public SqlDataReader GetUserById(int id)
{
string query = "SELECT * FROM Users WHERE Id = @Id";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("@Id", id);
connection.Open();
return command.ExecuteReader();
}
}
// 添加新用戶
public int AddUser(string name, int age)
{
string query = "INSERT INTO Users (Name, Age) VALUES (@Name, @Age); SELECT SCOPE_IDENTITY();";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("@Name", name);
command.Parameters.AddWithValue("@Age", age);
connection.Open();
return Convert.ToInt32(command.ExecuteScalar());
}
}
// 更新用戶信息
public int UpdateUser(int id, string name, int age)
{
string query = "UPDATE Users SET Name = @Name, Age = @Age WHERE Id = @Id";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("@Id", id);
command.Parameters.AddWithValue("@Name", name);
command.Parameters.AddWithValue("@Age", age);
connection.Open();
return command.ExecuteNonQuery();
}
}
// 刪除用戶
public int DeleteUser(int id)
{
string query = "DELETE FROM Users WHERE Id = @Id";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("@Id", id);
connection.Open();
return command.ExecuteNonQuery();
}
}
}
在上述代碼中,UserRepository類封裝了對用戶數(shù)據(jù)的各種操作。通過構(gòu)造函數(shù)傳入數(shù)據(jù)庫連接字符串,然后在各個方法中使用SqlConnection、SqlCommand等類來連接數(shù)據(jù)庫、執(zhí)行 SQL 語句。比如,GetAllUsers方法執(zhí)行一條查詢所有用戶的 SQL 語句,并返回一個SqlDataReader對象,用于讀取查詢結(jié)果;AddUser方法執(zhí)行一條插入新用戶的 SQL 語句,并返回插入的新用戶的 ID。
如果要連接 MySQL 數(shù)據(jù)庫,我們可以使用 MySql.Data.MySqlClient 命名空間。首先,需要在項目中安裝 MySQL 的.NET 驅(qū)動,可以通過 NuGet 包管理器來安裝。安裝完成后,編寫如下代碼:
using System;
using MySql.Data.MySqlClient;
public class UserRepository
{
private readonly string connectionString;
public UserRepository(string connectionString)
{
this.connectionString = connectionString;
}
// 獲取所有用戶
public MySqlDataReader GetAllUsers()
{
string query = "SELECT * FROM Users";
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
MySqlCommand command = new MySqlCommand(query, connection);
connection.Open();
return command.ExecuteReader();
}
}
// 根據(jù)ID獲取單個用戶
public MySqlDataReader GetUserById(int id)
{
string query = "SELECT * FROM Users WHERE Id = @Id";
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
MySqlCommand command = new MySqlCommand(query, connection);
command.Parameters.AddWithValue("@Id", id);
connection.Open();
return command.ExecuteReader();
}
}
// 添加新用戶
public int AddUser(string name, int age)
{
string query = "INSERT INTO Users (Name, Age) VALUES (@Name, @Age); SELECT LAST_INSERT_ID();";
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
MySqlCommand command = new MySqlCommand(query, connection);
command.Parameters.AddWithValue("@Name", name);
command.Parameters.AddWithValue("@Age", age);
connection.Open();
return Convert.ToInt32(command.ExecuteScalar());
}
}
// 更新用戶信息
public int UpdateUser(int id, string name, int age)
{
string query = "UPDATE Users SET Name = @Name, Age = @Age WHERE Id = @Id";
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
MySqlCommand command = new MySqlCommand(query, connection);
command.Parameters.AddWithValue("@Id", id);
command.Parameters.AddWithValue("@Name", name);
command.Parameters.AddWithValue("@Age", age);
connection.Open();
return command.ExecuteNonQuery();
}
}
// 刪除用戶
public int DeleteUser(int id)
{
string query = "DELETE FROM Users WHERE Id = @Id";
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
MySqlCommand command = new MySqlCommand(query, connection);
command.Parameters.AddWithValue("@Id", id);
connection.Open();
return command.ExecuteNonQuery();
}
}
}
這段代碼與連接 SQL Server 的代碼類似,只是使用了 MySql.Data.MySqlClient 命名空間下的類來連接 MySQL 數(shù)據(jù)庫并執(zhí)行操作。通過這些代碼,我們可以在.NET Core WebApi 中實現(xiàn)對 SQL Server 和 MySQL 數(shù)據(jù)庫的基本數(shù)據(jù)訪問與持久化操作。
五、實用開發(fā)技巧
(一)日志記錄
在.NET Core WebApi 開發(fā)中,日志記錄就像是飛機上的黑匣子,它詳細記錄著項目運行過程中的各種信息,對于項目的調(diào)試和問題排查起著至關(guān)重要的作用。通過日志,我們可以了解到請求的處理過程、數(shù)據(jù)的流轉(zhuǎn)情況以及是否發(fā)生了錯誤等。比如,當(dāng)程序出現(xiàn)異常時,日志可以記錄下異常發(fā)生的時間、位置以及詳細的錯誤信息,幫助我們快速定位問題所在。
在.NET Core 中,有多種工具可以幫助我們實現(xiàn)日志記錄功能,其中比較常用的有 Serilog 和 NLog。以 Serilog 為例,我們可以通過以下步驟來配置和使用它。
首先,在項目中安裝 Serilog 相關(guān)的 NuGet 包。打開項目的 “解決方案資源管理器”,右鍵點擊項目名稱,選擇 “管理 NuGet 程序包”,在彈出的窗口中搜索 “Serilog.AspNetCore”,然后點擊安裝。
安裝完成后,在項目的入口文件(通常是 Program.cs)中進行配置。在創(chuàng)建 WebApplicationBuilder 時,添加如下代碼:
using Serilog;
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog((ctx, lc) => lc
.WriteTo.Console()
.WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day));
上述代碼中,我們使用UseSerilog方法來配置 Serilog。WriteTo.Console()表示將日志輸出到控制臺,這樣在開發(fā)過程中,我們可以直接在控制臺看到日志信息,方便調(diào)試。WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day)則表示將日志寫入到文件中,文件名為 “l(fā)ogs/log.txt”,并且每天生成一個新的日志文件,這樣可以避免日志文件過大,同時也便于管理和查看歷史日志。
在控制器中,我們可以通過依賴注入獲取ILogger對象來記錄日志。例如:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
private readonly ILogger<UserController> _logger;
public UserController(ILogger<UserController> logger)
{
_logger = logger;
}
[HttpGet]
public IActionResult Get()
{
_logger.LogInformation("獲取用戶列表的請求被處理");
// 處理業(yè)務(wù)邏輯
return Ok();
}
}
在上述代碼中,_logger.LogInformation("獲取用戶列表的請求被處理")這行代碼記錄了一條信息日志,表示獲取用戶列表的請求被處理,這樣在查看日志時,我們就可以清楚地知道請求的處理情況。
(二)異常處理
在程序運行過程中,異常就像是路上的絆腳石,隨時可能導(dǎo)致程序崩潰。而全局異常處理機制就像是一個保護罩,能夠捕獲這些異常,避免程序崩潰,確保系統(tǒng)的穩(wěn)定性。
在.NET Core WebApi 中,我們可以通過中間件或過濾器來實現(xiàn)全局異常處理。下面以過濾器為例進行講解。
首先,創(chuàng)建一個自定義的異常過濾器。在項目中新建一個文件夾,比如 “Filters”,在該文件夾下創(chuàng)建一個類,例如 “GlobalExceptionFilter.cs”,代碼如下:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
public class GlobalExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
// 記錄異常日志,這里可以使用前面配置的日志記錄工具,如Serilog
// 假設(shè)已經(jīng)在項目中配置好了Serilog,并且可以通過依賴注入獲取到ILogger對象
var logger = context.HttpContext.RequestServices.GetService<ILogger<GlobalExceptionFilter>>();
logger.LogError(context.Exception, "全局異常處理捕獲到異常");
// 根據(jù)異常類型返回不同的響應(yīng)
var statusCode = context.Exception switch
{
// 這里可以根據(jù)自定義的異常類型進行映射,比如自定義了NotFoundException,表示資源未找到
// NotFoundException => StatusCodes.Status404NotFound,
// 這里只是簡單示例,實際應(yīng)用中可以根據(jù)具體需求添加更多的異常類型映射
_ => StatusCodes.Status500InternalServerError
};
context.Result = new ObjectResult(new { error = context.Exception.Message })
{
StatusCode = statusCode
};
// 設(shè)置異常已處理,防止其他異常處理機制再次處理
context.ExceptionHandled = true;
}
}
在上述代碼中,OnException方法會在異常發(fā)生時被調(diào)用。我們首先記錄異常日志,然后根據(jù)異常類型設(shè)置不同的 HTTP 狀態(tài)碼,并返回包含錯誤信息的響應(yīng)。最后,將context.ExceptionHandled設(shè)置為true,表示該異常已經(jīng)被處理,避免其他異常處理機制重復(fù)處理。
接下來,需要將這個自定義的異常過濾器注冊到項目中。在 Startup.cs 文件的ConfigureServices方法中添加如下代碼:
services.AddControllers(options =>
{
options.Filters.Add(typeof(GlobalExceptionFilter));
});
這樣,當(dāng)項目中發(fā)生未處理的異常時,就會被GlobalExceptionFilter捕獲并處理,從而避免程序崩潰,提高系統(tǒng)的穩(wěn)定性。
(三)緩存機制
緩存機制在提升系統(tǒng)性能方面有著神奇的效果,它就像是一個高速緩存區(qū),能夠?qū)⒔?jīng)常訪問的數(shù)據(jù)存儲起來,當(dāng)再次請求相同的數(shù)據(jù)時,直接從緩存中獲取,而不需要再次從數(shù)據(jù)庫或其他數(shù)據(jù)源中讀取,大大減少了數(shù)據(jù)讀取的時間,提高了系統(tǒng)的響應(yīng)速度。
在.NET Core WebApi 中,我們可以使用內(nèi)存緩存(IMemoryCache)來實現(xiàn)簡單的緩存功能。以獲取用戶信息為例,假設(shè)我們有一個方法從數(shù)據(jù)庫中獲取用戶信息,這個操作可能比較耗時?,F(xiàn)在我們使用緩存來優(yōu)化這個過程。
首先,在 Startup.cs 文件的ConfigureServices方法中添加內(nèi)存緩存服務(wù):
services.AddMemoryCache();
然后,在控制器中使用緩存。例如:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
private readonly IMemoryCache _memoryCache;
public UserController(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
[HttpGet("{id}")]
public IActionResult GetUserById(int id)
{
// 定義緩存鍵,通常根據(jù)請求的參數(shù)來生成,確保緩存鍵的唯一性
var cacheKey = $"user_{id}";
// 嘗試從緩存中獲取用戶信息
if (_memoryCache.TryGetValue(cacheKey, out object cachedUser))
{
return Ok(cachedUser);
}
// 緩存中未找到,從數(shù)據(jù)庫中獲取用戶信息(這里假設(shè)存在一個從數(shù)據(jù)庫獲取用戶信息的方法)
var user = GetUserFromDatabase(id);
// 將獲取到的用戶信息添加到緩存中,設(shè)置緩存的過期時間為10分鐘
var cacheOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromMinutes(10));
_memoryCache.Set(cacheKey, user, cacheOptions);
return Ok(user);
}
// 模擬從數(shù)據(jù)庫獲取用戶信息的方法
private object GetUserFromDatabase(int id)
{
// 這里可以編寫實際的數(shù)據(jù)庫查詢邏輯,暫時返回一個簡單的模擬數(shù)據(jù)
return new { Id = id, Name = "模擬用戶", Age = 25 };
}
}
在上述代碼中,首先在控制器的構(gòu)造函數(shù)中注入IMemoryCache對象。在GetUserById方法中,先根據(jù)緩存鍵嘗試從緩存中獲取用戶信息,如果獲取到了,直接返回緩存中的數(shù)據(jù);如果緩存中沒有,則從數(shù)據(jù)庫中獲取用戶信息,然后將其添加到緩存中,并設(shè)置緩存的過期時間為 10 分鐘,最后返回獲取到的用戶信息。通過這種方式,下次再請求相同id的用戶信息時,就可以直接從緩存中獲取,大大提高了系統(tǒng)的響應(yīng)性能。
六、項目部署發(fā)布
(一)發(fā)布前的準(zhǔn)備工作
在將.NET Core WebApi 項目部署發(fā)布之前,嚴(yán)謹(jǐn)細致的準(zhǔn)備工作是確保項目順利上線的關(guān)鍵。就像運動員在比賽前要檢查裝備、調(diào)整狀態(tài)一樣,我們需要對項目進行全面的檢查和配置。
首先,仔細檢查項目的配置文件,這是項目運行的基礎(chǔ)設(shè)置。以appsettings.json文件為例,其中可能包含數(shù)據(jù)庫連接字符串、日志配置等重要信息。確保數(shù)據(jù)庫連接字符串準(zhǔn)確無誤,它就像是連接項目與數(shù)據(jù)庫的橋梁,一旦錯誤,項目將無法與數(shù)據(jù)庫進行正常通信。比如,如果使用的是 SQL Server 數(shù)據(jù)庫,連接字符串應(yīng)類似這樣:
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=YOUR_SERVER_NAME;Initial Catalog=YOUR_DATABASE_NAME;User ID=YOUR_USERNAME;Password=YOUR_PASSWORD"
}
}
如果是其他類型的數(shù)據(jù)庫,如 MySQL,連接字符串的格式會有所不同,但同樣需要確保各項參數(shù)準(zhǔn)確,包括服務(wù)器地址、數(shù)據(jù)庫名、用戶名和密碼等。
對于日志配置,要確認(rèn)日志級別、日志輸出路徑等設(shè)置是否符合項目需求。比如,如果希望在開發(fā)階段記錄詳細的日志信息以便調(diào)試,可將日志級別設(shè)置為 “Debug”;而在生產(chǎn)環(huán)境中,為了減少日志文件的大小和提高系統(tǒng)性能,可能將日志級別設(shè)置為 “Information” 或 “Warning”。日志輸出路徑也要合理設(shè)置,確保有足夠的磁盤空間來存儲日志文件,并且方便后續(xù)查看和分析。
同時,進行全面的代碼審查和測試也是必不可少的環(huán)節(jié)。代碼審查可以發(fā)現(xiàn)潛在的代碼質(zhì)量問題、安全漏洞以及不符合規(guī)范的地方??梢匝垐F隊中的其他成員一起進行代碼審查,不同的視角可能會發(fā)現(xiàn)不同的問題。例如,在審查用戶認(rèn)證相關(guān)的代碼時,要確保密碼加密方式安全可靠,防止密碼明文存儲帶來的安全風(fēng)險。
測試方面,要涵蓋單元測試、集成測試和功能測試。單元測試用于測試單個方法或類的功能,確保每個小的代碼單元都能正常工作。比如,對于一個計算訂單總價的方法,通過編寫單元測試用例,傳入不同的訂單商品和價格,驗證計算結(jié)果是否正確。集成測試則關(guān)注不同模塊之間的協(xié)作,測試 WebApi 與數(shù)據(jù)庫、緩存等組件之間的交互是否正常。功能測試從用戶的角度出發(fā),模擬用戶的操作,檢查系統(tǒng)是否滿足業(yè)務(wù)需求。比如,在一個電商系統(tǒng)中,進行功能測試時,模擬用戶注冊、登錄、添加商品到購物車、下單等一系列操作,檢查整個流程是否順暢,數(shù)據(jù)是否正確更新。
通過這些嚴(yán)格的檢查和測試,確保項目在發(fā)布前沒有錯誤和警告,為項目的成功部署發(fā)布奠定堅實的基礎(chǔ)。
(二)發(fā)布到 IIS 或其他服務(wù)器
接下來,我們以 IIS 為例,詳細介紹如何將.NET Core WebApi 項目部署到服務(wù)器上。IIS(Internet Information Services)是微軟提供的一種 Web 服務(wù)器,廣泛應(yīng)用于 Windows 系統(tǒng)中,它就像是一個專業(yè)的網(wǎng)站托管平臺,能夠穩(wěn)定地運行我們的 WebApi 項目。
安裝 IIS
:如果服務(wù)器上尚未安裝 IIS,首先需要進行安裝。以 Windows Server 系統(tǒng)為例,打開 “服務(wù)器管理器”,點擊 “添加角色和功能”。在彈出的向?qū)е?,選擇 “基于角色或基于功能的安裝”,然后點擊 “下一步”。在 “服務(wù)器角色” 中,勾選 “Web 服務(wù)器(IIS)”,按照提示一步步完成安裝。這個過程就像是在搭建一個舞臺,為 WebApi 項目的展示做好準(zhǔn)備。
安裝.NET Core Hosting Bundle
:IIS 默認(rèn)并不支持.NET Core 項目的運行,所以需要安裝.NET Core Hosting Bundle。這就像是給 IIS 安裝一個特殊的插件,讓它能夠識別和運行.NET Core 應(yīng)用。你可以從微軟官方網(wǎng)站(https://dotnet.microsoft.com/download/dotnet-core/thank-you/runtime-aspnetcore-8.0.7-windows-hosting-bundle-installer)下載對應(yīng)版本的安裝包,下載完成后,雙擊安裝包進行安裝,安裝過程中按照提示操作即可。
在 Visual Studio 中發(fā)布項目
:回到我們的開發(fā)環(huán)境,在 Visual Studio 中,右鍵點擊項目名稱,選擇 “發(fā)布”。在彈出的 “發(fā)布” 窗口中,發(fā)布目標(biāo)選擇 “文件系統(tǒng)”,然后點擊 “下一步”。在 “目標(biāo)位置” 處,選擇一個本地文件夾來保存發(fā)布文件,這個文件夾就像是一個臨時的倉庫,存放著我們即將部署到服務(wù)器上的項目文件。點擊 “完成” 后,再點擊 “發(fā)布” 按鈕,Visual Studio 會將項目編譯并生成發(fā)布文件,這些文件包含了項目運行所需的所有代碼、配置文件和依賴項。
配置 IIS 站點
:打開 IIS 管理器,在左側(cè)的 “連接” 面板中,右鍵點擊 “網(wǎng)站”,選擇 “添加網(wǎng)站”。在 “添加網(wǎng)站” 對話框中,輸入網(wǎng)站名稱,這個名稱可以根據(jù)項目的實際情況自定義,比如 “MyWebApiSite”。在 “物理路徑” 處,選擇剛才在 Visual Studio 中發(fā)布項目時指定的文件夾路徑,也就是我們存放發(fā)布文件的 “臨時倉庫” 位置。在 “綁定” 部分,設(shè)置網(wǎng)站的訪問地址和端口號。如果需要使用 HTTPS,還需要配置 SSL 證書。例如,設(shè)置訪問地址為 “http://localhost:8080”,端口號 8080 可以根據(jù)實際情況進行調(diào)整,只要不與服務(wù)器上其他已占用的端口沖突即可。
配置應(yīng)用程序池
:在 IIS 管理器中,找到剛才創(chuàng)建的網(wǎng)站對應(yīng)的應(yīng)用程序池。右鍵點擊應(yīng)用程序池,選擇 “基本設(shè)置”。在 “.NET CLR 版本” 下拉菜單中,選擇 “無托管代碼”,因為.NET Core 應(yīng)用不需要依賴傳統(tǒng)的.NET Framework 運行時,所以選擇 “無托管代碼” 模式。同時,將 “托管管道模式” 設(shè)置為 “集成”,這種模式能夠更好地支持.NET Core 應(yīng)用在 IIS 中的運行。
復(fù)制發(fā)布文件
:將在 Visual Studio 中生成的發(fā)布文件全部復(fù)制到 IIS 站點的物理路徑下。這一步就像是將貨物從 “臨時倉庫” 搬運到正式的 “銷售場所”,確保 IIS 能夠找到并運行這些文件。復(fù)制完成后,IIS 就可以根據(jù)配置的站點信息和應(yīng)用程序池設(shè)置,啟動并運行我們的.NET Core WebApi 項目了。
完成以上步驟后,在瀏覽器中輸入配置的網(wǎng)站訪問地址(如http://localhost:8080),如果一切配置正確,就可以看到我們的.NET Core WebApi 項目已經(jīng)成功部署并運行了。
七、總結(jié)與展望
通過以上內(nèi)容,我們深入了解了.NET Core WebApi 開發(fā)的各個關(guān)鍵環(huán)節(jié)。從開篇引入,認(rèn)識到前后端分離模式下后端開發(fā)的重要性,以及.NET Core WebApi 在其中的獨特優(yōu)勢。我們詳細學(xué)習(xí)了.NET Core 的特性和 WebApi 在開發(fā)中的關(guān)鍵角色,親手搭建了開發(fā)環(huán)境并創(chuàng)建了第一個項目。在核心開發(fā)技術(shù)方面,深入剖析了控制器與路由、請求與響應(yīng)處理以及數(shù)據(jù)訪問與持久化等關(guān)鍵技術(shù),掌握了它們的工作原理和實際應(yīng)用。同時,還分享了日志記錄、異常處理和緩存機制等實用開發(fā)技巧,這些技巧能夠大大提高項目的可維護性和性能。最后,我們完成了項目的部署發(fā)布,將開發(fā)成果呈現(xiàn)在服務(wù)器上,讓應(yīng)用能夠為用戶提供服務(wù)。
對于讀者而言,希望你們能夠積極嘗試動手實踐,將所學(xué)知識運用到實際項目中。只有通過不斷地實踐,才能真正掌握這些技術(shù),在遇到問題時不斷思考、探索,逐漸積累經(jīng)驗,成為一名優(yōu)秀的.NET Core WebApi 開發(fā)者。
展望未來,隨著技術(shù)的不斷發(fā)展,.NET Core 也將持續(xù)演進,其性能將不斷提升,功能將更加豐富。在未來的開發(fā)中,我們有望看到.NET Core WebApi 在更多領(lǐng)域得到廣泛應(yīng)用,如人工智能、物聯(lián)網(wǎng)等。它將與其他新興技術(shù)深度融合,為開發(fā)者帶來更多的創(chuàng)新空間和機遇。讓我們一起期待.NET Core WebApi 在未來的精彩表現(xiàn),不斷學(xué)習(xí)和探索,跟上技術(shù)發(fā)展的步伐,創(chuàng)造出更加優(yōu)秀的應(yīng)用程序。
閱讀原文:原文鏈接
該文章在 2025/2/5 18:29:33 編輯過