亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

如何使用.NET8 創(chuàng)建使用MySQL數(shù)據(jù)庫(kù)的webapi項(xiàng)目

 更新時(shí)間:2024年04月18日 10:29:07   作者:Chelase  
這篇文章主要介紹了如何使用.NET8 創(chuàng)建使用MySQL數(shù)據(jù)庫(kù)的webapi項(xiàng)目,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下

使用 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-MigrationUpdate-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)建的EntitiesModels文件夾中。

[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)文章

最新評(píng)論