如何使用.NET8 創(chuàng)建使用MySQL數(shù)據(jù)庫(kù)的webapi項(xiàng)目
使用 visual studio創(chuàng)建webapi項(xiàng)目
需要安裝的包
從上到下依次為:
- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.Tools
- Mysql.EntityFrameworkCore
- Pomelo.EntityFrameworkCore.MySql
- Swashbuckle.AspNetCore
新建控制器
控制器的命名必須以name+Controlles
的格式命名
using Microsoft.AspNetCore.Mvc; ? // 簡(jiǎn)單示例 namespace test_vs_api.Controllers { [Route("/[controller]/[action]")] // 路由為類名加方法名 [ApiController] // api控制器 public class TestController : Controller { [HttpGet("/[action]")] // 方法及路徑 使用方法名做路徑 如果以上使用了action 此處可以省略 public string GetMessage() { return "123"; } } }
添加數(shù)據(jù)庫(kù)連接字符串
在appsettings.json
文件里,添加數(shù)據(jù)庫(kù)連接字符串
"ConnectionStrings": { "MySQLConnection": "server=localhost;port=3306;uid=root;pwd=123456;database=yourdatabaase" },
server就是主機(jī)ip 本地就是localhost,uid是mysql數(shù)據(jù)庫(kù)的用戶名,pwd是mysql數(shù)據(jù)庫(kù)的密碼,database是數(shù)據(jù)庫(kù)名稱
注冊(cè)數(shù)據(jù)庫(kù)上下文
在Program.cs
中
// 注冊(cè)數(shù)據(jù)庫(kù)上下文 builder.Services.AddDbContext<DataContext>(options => { options.UseMySQL(builder.Configuration.GetConnectionString("DefaultConnection")!); });
創(chuàng)建數(shù)據(jù)庫(kù)上下文
首先在根目錄創(chuàng)建Data
文件夾,從中創(chuàng)建DataContext.cs
using Microsoft.EntityFrameworkCore; using test_vs_api.Entities; ? namespace test_vs_api.Data { public class DataContext : DbContext { public DataContext(DbContextOptions<DataContext> options) : base(options) { ? } ? public DbSet<數(shù)據(jù)庫(kù)表名> 表名{ get; set; } } }
關(guān)于遷移數(shù)據(jù)庫(kù)
打開(kāi)visual studio的程序包管理器控制臺(tái)
在 Visual Studio 中,當(dāng)您使用 Entity Framework (EF) 作為您的對(duì)象關(guān)系映射器 (ORM) 時(shí),Package Manager Console
通常用于運(yùn)行 EF 的命令。dir
命令在大多數(shù)命令行環(huán)境(包括 PowerShell 和命令提示符)中用于列出目錄中的文件和子目錄。但在 EF 的上下文中,您提到的 Add-Migration
和 Update-Database
是特定的 EF 命令。
以下是這些命令的簡(jiǎn)要說(shuō)明:
Add-Migration:
用途:此命令用于創(chuàng)建一個(gè)新的遷移。遷移是 EF 用來(lái)更改數(shù)據(jù)庫(kù)架構(gòu)的一種方式。每當(dāng)您更改了您的數(shù)據(jù)模型(例如,添加了一個(gè)新的類、更改了一個(gè)類的屬性等),您就需要?jiǎng)?chuàng)建一個(gè)遷移來(lái)反映這些更改到數(shù)據(jù)庫(kù)中。
語(yǔ)法:Add-Migration MigrationName
示例:Add-Migration Initial
會(huì)創(chuàng)建一個(gè)名為 "Initial" 的新遷移。
說(shuō)明:運(yùn)行此命令后,EF 會(huì)檢查您的數(shù)據(jù)模型與當(dāng)前數(shù)據(jù)庫(kù)架構(gòu)之間的差異,并為您生成一個(gè)遷移類。這個(gè)類包含了一個(gè) Up
方法和一個(gè) Down
方法。Up
方法用于應(yīng)用更改,而 Down
方法用于撤銷這些更改。
Update-Database:
用途:此命令用于應(yīng)用所有未應(yīng)用的遷移到您的數(shù)據(jù)庫(kù)。
語(yǔ)法:Update-Database
說(shuō)明:當(dāng)您運(yùn)行此命令時(shí),EF 會(huì)檢查已定義的遷移(通常在您的項(xiàng)目中的 Migrations
文件夾中)和數(shù)據(jù)庫(kù)中已應(yīng)用的遷移。然后,它會(huì)應(yīng)用所有尚未在數(shù)據(jù)庫(kù)中應(yīng)用的遷移。
簡(jiǎn)而言之,Add-Migration
用于創(chuàng)建新的遷移來(lái)反映數(shù)據(jù)模型的更改,而 Update-Database
則用于將這些更改應(yīng)用到數(shù)據(jù)庫(kù)中。這兩個(gè)命令在開(kāi)發(fā)過(guò)程中經(jīng)常使用,尤其是在數(shù)據(jù)庫(kù)架構(gòu)經(jīng)常更改的情況下。
在控制器中引入數(shù)據(jù)庫(kù)上下文
// 引用數(shù)據(jù)庫(kù)上下文 private readonly DataContext _context; public StaffController(DataContext context) { _context = context; }
關(guān)于 IActionResult
返回類型
public async Task<IActionResult> GetAllStaff() { var staffList = new List<Staff> { new Staff { id = 1, name = "張三", department = "研發(fā)部", sex = "男", CreateTime = "2024-2-4 16:45:50" } }; ? return Ok(staffList); }
IActionResult
是一個(gè)接口,它表示一個(gè)操作的結(jié)果。在 ASP.NET Core 中, IActionResult
接口是所有操作結(jié)果類型的基類。 IActionResult
接口定義了幾個(gè)方法,這些方法可以用來(lái)返回不同的操作結(jié)果。例如, Ok
方法返回一個(gè) 200 OK
狀態(tài)碼, BadRequest
方法返回一個(gè) 400 Bad Request
狀態(tài)碼, NotFound
方法返回一個(gè) 404 Not Found
狀態(tài)碼。
只有使用IActionResult
類型才會(huì)return
,Ok()
和 NotFound()
方法,來(lái)表示200或404
除此之外的ActionResult
類型
public async Task<ActionResult<List<Staff>>> GetAllStaff() { var staffList = new List<Staff> { new Staff { id = 1, name = "張三", department = "研發(fā)部", sex = "男", CreateTime = "2024-2-4 16:45:50" } }; ? return Ok(staffList); }
與上一個(gè)代碼段相比,這個(gè)代碼段的返回值類型從 IActionResult
改為了 ActionResult<List<Staff>>
。這意味著該方法將返回一個(gè)包含 List<Staff>
對(duì)象的 ActionResult
對(duì)象。
ActionResult
對(duì)象是一個(gè)泛型類型,它可以包含任何類型的對(duì)象。在該代碼段中, ActionResult
對(duì)象包含了一個(gè) List<Staff>
對(duì)象。
當(dāng)然我自己最直觀的感受就是他有了示例數(shù)據(jù)和下面的一個(gè)模式展示
GET請(qǐng)求獲取全部數(shù)據(jù)
[HttpGet] // 方法及路徑 public async Task<ActionResult<List<Staff>>> GetAllStaff() { var staffList = await _context.Staff.ToListAsync(); ? return Ok(staffList); }
GET請(qǐng)求根據(jù)id獲取單個(gè)數(shù)據(jù)
不需要分頁(yè)時(shí)
[HttpGet("{id}")] // 如果需要傳參則需要添加該參數(shù),表示參數(shù)為必需 public async Task<ActionResult<List<Staff>>> GetStaff(int id) { var staff = await _context.Staff.FindAsync(id); // 找到id相同的數(shù)據(jù) ? if(staff is null) return NotFound("找不到該員工。"); ? return Ok(staff); }
需要分頁(yè)時(shí)
// 分頁(yè)所需的數(shù)據(jù) 如果有多個(gè)接口需要使用,可以新建模型類以公用 public class PaginatedResult<T> { public required List<T> Data { get; set; } public int TotalCount { get; set; } public int TotalPages { get; set; } public int CurrentPage { get; set; } public int PageSize { get; set; } } ? [HttpGet] // 方法及路徑 public async Task<ActionResult<List<Staff>>> GetAllStaff(int page = 1, int size = 10) { ? // 驗(yàn)證頁(yè)碼和每頁(yè)大小是否合法 if (page < 1) page = 1; if (size < 1) size = 10; ? // 計(jì)算總記錄數(shù)和總頁(yè)數(shù) var totalCount = await _context.Staff.CountAsync(); var totalPages = (int)Math.Ceiling(totalCount / (double)size); ? // 使用Skip和Take方法進(jìn)行分頁(yè)查詢 var staffList = await _context.Staff .OrderBy(s => s.id) // 假設(shè)我們按ID排序,你可以根據(jù)需要修改排序條件 .Skip((page - 1) * size) .Take(size) .ToListAsync(); ? if (page > totalPages) return BadRequest("沒(méi)有更多數(shù)據(jù)!"); ? // 創(chuàng)建分頁(yè)結(jié)果對(duì)象 var paginatedResult = new PaginatedResult<Staff> { Data = staffList, TotalCount = totalCount, TotalPages = totalPages, CurrentPage = page, PageSize = size }; ? return Ok(paginatedResult); }
創(chuàng)建post添加請(qǐng)求時(shí)的參數(shù) (類 名)
當(dāng)我們需要進(jìn)行添加操作時(shí),我們需要傳遞添加所需的所有參數(shù)。這時(shí)我們可以使用創(chuàng)建控制器時(shí)提前創(chuàng)建的數(shù)據(jù)模型類。
通常在自行創(chuàng)建的Entities
或Models
文件夾中。
[HttpPost] // 如果需要傳參則需要添加該參數(shù),表示參數(shù)為必需 public async Task<IActionResult> AddStaff(Staff staff) { ? if (ModelState.IsValid) { staff.CreateTime = DateTime.Now.ToLocalTime(); // 將UTC時(shí)間格式轉(zhuǎn)換為本地時(shí)間格式 _context.Staff.Add(staff); // 通過(guò)數(shù)據(jù)庫(kù)上下文添加數(shù)據(jù)模型類的構(gòu)造函數(shù) await _context.SaveChangesAsync(); // 異步等待(async await)保存新數(shù)據(jù)值數(shù)據(jù)庫(kù) ? // 返回成功消息 return Content("添加成功!", "text/plain"); } else { // 如果模型狀態(tài)無(wú)效,返回錯(cuò)誤消息 return BadRequest("無(wú)效的請(qǐng)求數(shù)據(jù)。"); } }
Put請(qǐng)求更新數(shù)據(jù)
[HttpPut] public async Task<IActionResult> UpdateStaff(Staff UpdateStaff) { if (ModelState.IsValid) { var staff_form = await _context.Staff.FindAsync(UpdateStaff.id); // 找到id相同的數(shù)據(jù) ? if (staff_form is null) return NotFound("找不到該員工。"); ? // 依次更改數(shù)據(jù)字段 staff_form.name = UpdateStaff.name; staff_form.department = UpdateStaff.department; staff_form.sex = UpdateStaff.sex; ? await _context.SaveChangesAsync(); ? return Ok("修改成功!"); } else { // 如果模型狀態(tài)無(wú)效,返回錯(cuò)誤消息 return BadRequest("無(wú)效的請(qǐng)求數(shù)據(jù)。"); } }
Delete刪除數(shù)據(jù)
[HttpDelete] public async Task<IActionResult> DelStaff(int id) { var staff = await _context.Staff.FindAsync(id); // 找到id相同的數(shù)據(jù) ? if (staff is null) return NotFound("找不到該員工。"); ? _context.Staff.Remove(staff); ? await _context.SaveChangesAsync(); ? return Ok("刪除成功!"); }
關(guān)于創(chuàng)建時(shí)間
由于.NET8 webapi
中默認(rèn)使用UTC
的時(shí)間格式,而北京時(shí)間使用的是UTC+8
的時(shí)間格式。所以api
中返回的時(shí)間會(huì)比國(guó)內(nèi)本地時(shí)間晚八個(gè)小時(shí),我們需要對(duì)時(shí)間格式進(jìn)行轉(zhuǎn)換。
使用DateTime.Now.ToLocalTime();
將UTC
時(shí)間轉(zhuǎn)換為本地時(shí)間,不知道為什么在數(shù)據(jù)模型類中不管用。所以我在添加功能的api中手動(dòng)進(jìn)行轉(zhuǎn)換,雖然swagger
文檔顯示的仍是UTC
時(shí)間,但數(shù)據(jù)庫(kù)中已然轉(zhuǎn)換成功。
修改時(shí)間格式,將文件放到Entities
文件夾中
// 解決時(shí)間格式 ISO 8601 帶T的問(wèn)題 builder.Services.AddControllers().AddJsonOptions(configure => { configure.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter()); // 使用一個(gè)新類更改ISO 8601時(shí)間格式 });
關(guān)于跨域問(wèn)題
Cross-Origin Resource Sharing 跨源資源共享 (CORS):
- 是一種 W3C 標(biāo)準(zhǔn),允許服務(wù)器放寬同源策略。
- 不是安全功能,CORS 放松了安全限制。 允許 CORS 并不會(huì)使 API 更安全。 有關(guān)詳細(xì)信息,請(qǐng)參閱 CORS 的工作原理。
- 允許服務(wù)器顯式允許某些跨源請(qǐng)求,同時(shí)拒絕其他請(qǐng)求。
- 比早期技術(shù)(如 JSONP)更安全、更靈活。
—— 摘自微軟ASP.NET Core 8.0 文檔
文心一言給出的解決方案
您遇到的錯(cuò)誤是由于跨域資源共享(CORS)策略導(dǎo)致的。CORS是一種安全機(jī)制,它限制了從一個(gè)源(域、協(xié)議和端口)加載的網(wǎng)頁(yè)如何與另一個(gè)源的資源進(jìn)行交互。當(dāng)您嘗試使用Ajax從一個(gè)源(例如本地文件系統(tǒng)或localhost:某個(gè)端口
)向另一個(gè)源(在本例中是https://localhost:7033
)發(fā)送請(qǐng)求時(shí),瀏覽器會(huì)檢查響應(yīng)頭中是否包含Access-Control-Allow-Origin
字段,以確定是否允許這種跨域請(qǐng)求。
var builder = WebApplication.CreateBuilder(args); // 添加CORS服務(wù) builder.Services.AddCors(options => { options.AddPolicy("MyCorsPolicy", builder => { builder.WithOrigins("http://localhost:你的前端端口號(hào)", // ...其他源 ) .AllowAnyHeader() .AllowAnyMethod(); }); }); var app = builder.Build(); // 使用CORS中間件 app.UseCors("MyCorsPolicy"); // 其他中間件和終端配置... app.Run();
使用正則表達(dá)式校驗(yàn)
using System.ComponentModel.DataAnnotations; ? namespace test_vs_api.Entities { public class User { public int id { get; set; } public required string UserName { get; set; } public required string Password { get; set; } ? [RegularExpression(@"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", ErrorMessage = "請(qǐng)輸入有效的郵箱地址。")] // 像這樣 public required string Email { get; set; } public required string NickName { get; set; } public required DateTime CreateTime { get; set; } } }
部署在IIs
首先需要安裝.NET-hosting
文件,根據(jù)使用.NET版本進(jìn)行安裝。打開(kāi)IIS,安裝模塊。
添加網(wǎng)站,訪問(wèn)api路徑即可
部署在linux服務(wù)器
VS發(fā)布時(shí)部署模式選擇獨(dú)立,目標(biāo)運(yùn)行時(shí)選擇linux對(duì)應(yīng)的版本,數(shù)據(jù)庫(kù)與EF遷移記得勾選
如果部署模式
選擇框架依賴,那么服務(wù)器就要安裝dotnet
隨后將發(fā)布后的項(xiàng)目上傳至服務(wù)器任意目錄中,打開(kāi)終端輸入命令行./your_api
在linux運(yùn)行api
dotnet your_api.dll // 使用dotnet運(yùn)行 ./your_api // 獨(dú)立運(yùn)行 nohup dotnet yourapi.dll & // 在后臺(tái)持續(xù)運(yùn)行
接口拒絕訪問(wèn)時(shí)
在appsettings.json
文件中添加以下代碼
// 如果在訪問(wèn)接口時(shí),遇到了http請(qǐng)求被重定向到https的問(wèn)題,可以刪掉https的配置 "Kestrel": { "Endpoints": { "Http": { "Url": "http://*:5000" }, "Https": { "Url": "https://*:5001" } } }
到此這篇關(guān)于使用.NET8 創(chuàng)建使用MySQL數(shù)據(jù)庫(kù)的webapi項(xiàng)目的文章就介紹到這了,更多相關(guān).NET8 webapi項(xiàng)目?jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
asp.net 抓取網(wǎng)頁(yè)源碼三種實(shí)現(xiàn)方法
asp.net 抓取網(wǎng)頁(yè)源碼三種實(shí)現(xiàn)方法,需要的朋友可以參考一下2013-06-06Asp.net FileUpload上傳文件夾并檢測(cè)所有子文件的實(shí)現(xiàn)代碼
這篇文章主要介紹了Asp.net FileUpload上傳文件夾并檢測(cè)所有子文件的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-05-05ASP.NET記住登陸用戶名的具體實(shí)現(xiàn)
ASP.NET記住登陸用戶名的具體實(shí)現(xiàn),需要的朋友可以參考一下2013-06-06Ubuntu16.04系統(tǒng)搭建.Net Core開(kāi)發(fā)環(huán)境
本文詳細(xì)講解了Ubuntu系統(tǒng)搭建.Net Core開(kāi)發(fā)環(huán)境的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-02-02ASP.NET MVC自定義錯(cuò)誤頁(yè)面真的簡(jiǎn)單嗎?
ASP.NET MVC自定義錯(cuò)誤頁(yè)面真的簡(jiǎn)單嗎?這篇文章主要介紹了ASP.NET MVC自定義錯(cuò)誤頁(yè)面,感興趣的小伙伴們可以參考一下2016-10-10基于.net core微服務(wù)的另一種實(shí)現(xiàn)方法
這篇文章主要給大家介紹了基于.net core微服務(wù)的另一種實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07Repeater綁定dictionary數(shù)據(jù)源代碼及報(bào)錯(cuò)解決
為大家講解下Repeater綁定dictionary數(shù)據(jù)源以及報(bào)錯(cuò)處理的方法,感興趣的朋友可以參考下哈,希望對(duì)你有所幫助2013-04-04編寫的vs2005水晶報(bào)表程序在vs2008下正常使用的一些實(shí)現(xiàn)方法
以前用vs2005編寫的WEB程序,現(xiàn)在使用vs2008時(shí)總是出現(xiàn)水晶報(bào)表的錯(cuò)誤,不能使用。經(jīng)過(guò)本人實(shí)踐,總結(jié)一下錯(cuò)誤原因。2009-09-09.NET微服務(wù)架構(gòu)CI/CD鏡像自動(dòng)分發(fā)
這篇文章介紹了.NET微服務(wù)架構(gòu)CI/CD實(shí)現(xiàn)鏡像自動(dòng)分發(fā)的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-01-01ASP.NET與MySQL數(shù)據(jù)庫(kù)簡(jiǎn)明圖示入門教程
ASP.NET與MySQL數(shù)據(jù)庫(kù)簡(jiǎn)明圖示入門教程...2006-09-09