一、User
1、使用数据注解设置主键和外键
-
设置主键:在
User
类的U_uid
属性上使用[Key]
注解。 -
设置外键:在
Order
类中,创建一个表示外键的属性(例如UserU_uid
),并使用[ForeignKey]
注解指定它引用User
类的哪个属性。同时,在导航属性上使用[Required]
(如果外键不允许为空)和[InverseProperty]
(用于指定反向导航属性,可选)注解。
但是,通常我们会将外键属性的名称设置为与它所引用的主键属性名称相同(或遵循某种命名约定),这样EF可以自动推断出外键关系,而无需显式使用[ForeignKey]
注解。
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;namespace WebServerTest.Models
{public class User{[Key]public int U_uid { get; set; }public string U_name { get; set; }public string U_password { get; set; }public string U_email { get; set; }public string U_identity { get; set; }// 导航属性public ICollection<Order> Orders { get; set; }}public class Order{[Key]public int OrderId { get; set; }public string OrderDetails { get; set; }// 外键属性(通常与所引用的主键属性名称相同或遵循命名约定)public int U_uid { get; set; }// 导航属性[ForeignKey("U_uid")] // 实际上,如果属性名称与User类中的主键名称相同,这个注解可以省略public User User { get; set; }}
}
2、连接Mysql数据库
1>安装必要的 NuGet 包
Pomelo.EntityFrameworkCore.MySql
:这是一个流行的 Entity Framework Core 提供程序,用于与 MySQL 数据库交互。Microsoft.EntityFrameworkCore.Tools
(可选):这个包提供了一些有用的工具,比如迁移工具。
2>ServerVersion
参数
这个参数的缺失可能会导致问题,特别是当 MySql 提供程序需要知道服务器的确切版本来正确处理某些数据库特性或行为时。
通常,如果你不确定服务器的版本,或者想要避免在多个地方硬编码版本信息,使用 ServerVersion.AutoDetect(connectionString)
是一个好方法。它会尝试根据提供的连接字符串自动检测服务器的版本。
3>每一次添加新表、修改现有表的结构或进行其他数据库架构更改时,都要迁移使用:Add-Migration MyMigration -Context和 更新数据库使用:update-database
-
查看现有迁移:
首先,通过“程序包管理器控制台”(Package Manager Console)运行以下命令来查看当前项目中的所有迁移:Get-Migration
这个命令会列出所有已生成的迁移文件及其顺序。
-
删除迁移文件:
找到你想要删除的迁移文件(通常是上一次生成的迁移文件),并手动从项目的“Migrations”文件夹中删除它。 -
回退数据库:
由于迁移文件已经被删除,你需要将数据库架构回退到上一次迁移之前的状态。这可以通过在“程序包管理器控制台”中运行以下命令来实现:Update-Database -TargetMigration [PreviousMigrationName]
其中
[PreviousMigrationName]
是上一次迁移之前的迁移名称。如果这是你的第一个迁移并且你想要完全重置数据库,你可能需要使用-TargetMigration:0
(这取决于你的具体迁移配置,有时可能是其他值,比如一个特殊的起始迁移名称)。请注意,回退数据库可能会导致数据丢失,特别是如果删除的迁移包含了破坏性更改(如删除表或列)。因此,在执行此操作之前,请确保你已经备份了数据库。
-
清理迁移历史记录(可选):
如果你想要完全清理迁移历史记录(即删除__EFMigrationsHistory
表中的记录),你需要手动执行 SQL 脚本来删除这些记录。但是,这通常是不推荐的,因为它可能会导致数据库与迁移记录不一致。更好的做法是让迁移历史记录保持原样,以便将来可以轻松地跟踪和回退迁移。
4>全局取消跟踪机制
二、User的增删改查
1、[HttpGet("{id}")]
1>使用 .FindAsync
查找用户:使用主键索引,异步地从数据库中查找一个实体。
注意:它只查找主键列,而不是表中的所有列。
如果 FindAsync
方法返回 null
,这意味着在数据库中没有找到具有指定 id
的用户实体。在这种情况下,您的代码返回 NotFound()
,这是一个HTTP 404状态码,表示请求的资源不存在。
2>加上通过邮箱查询
-
ToList
:- 是一个同步方法,会立即执行并将结果加载到内存中。
- 如果处理的集合非常大,可能会阻塞当前线程并影响应用程序的响应性。
-
ToListAsync
:- 是一个异步方法,会返回一个
Task<List<T>>
对象,表示异步操作的任务。 - 使用
await
关键字可以等待异步操作完成并获取结果。 - 在等待期间,当前线程不会被阻塞,可以继续执行其他任务。
- 是一个异步方法,会返回一个
2、[HttpPut("{id}")]
1>_context.Entry(user).State = EntityState.Modified;
//设置实体状态为修改,意味着打算更新该实体的某些属性
Entry
提供了对实体跟踪信息的访问,包括实体的当前状态、哪些属性已被修改等。
2>.FirstOrDefault()
.First()
方法用于获取序列中的第一个元素。如果序列为空,则会抛出异常。.FirstOrDefault()
方法也用于获取第一个元素,但如果序列为空,则返回默认值(对于引用类型,默认值为null
;对于值类型,默认值为0
、false
等)。
3、[HttpPost]
1>DbUpdateException
数据库更新异常
通常发生在尝试执行数据库操作时,由于某些原因(如违反唯一性约束)操作失败。
2>Conflict()
,表示请求由于冲突而失败。
这通常用于HTTP请求中,表示客户端请求的资源状态与服务器当前状态冲突。
3>else { throw; }:
重新抛出捕获的异常
如果UserExists
方法返回false
(即不存在具有相同U_uid
的用户),则重新抛出捕获的异常。这意味着异常将被传递给调用者,可能需要进一步的处理或记录。
4、[HttpDelete("{id}")]
三、User相关的后端接口对应的前端界面
1、后端只有UsersController.cs、OnlineUsersController.cs、LoginController.cs
UsersController.cs:获取所有用户信息,对用户进行增删改查。更新到日志Logger中(数据库中的OperationLogs表格)。
LoginController.cs:对应登录界面,验证用户账号和密码是否相同。然后再生成相应的Token值。
OnlineUsersController:利用WebSocket获取在线的ID。
2、前端对应的
1>用户管理——在线
2>用户管理——管理
有四个地方调用了"/api/users",
3>用户管理——注册界面:这里注册成功会出现Token
前端调用的是UsersController.cs和LoginController.cs,没有写另外的控制器
4>登录Login界面
Token:前端用的是会话保存方式。这样只要用户不关闭这个界面,就能保存token信息。
如果前端使用cookie,那么点开这个界面,会弹出提示框:是否接受所有的cookie,得去点。
三、LoginUser:判断登录账号密码是否相同,创建token(即JWT)【理解见项目代码第1讲二、】
1、什么是token?——一种安全令牌,用于在客户端和服务器之间传递认证和授权信息。它可以包含用户的身份信息、权限等。
Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
2、实现Token:常见方式是JWT(JSON Web Token)
JWT是一种基于JSON的开放标准(RFC 7519),用于在各方之间安全地传输信息。JWT通常用于身份验证和信息交换,因为它包含三个部分:Header(头部)、Payload(负载)、Signature(签名),分别用于指定使用的算法、存储实际传输的数据以及确保数据完整性。
3、 学习JWT的token身份认证方案
从下图中我们可以看出它是基于Token的身份认证。
具体流程:客户端携带用户名和密码请求访问 - 服务器校验用户凭据 - 应用提供一个token给客户端 - 客户端存储token,并且在随后的每一次请求中都带着它 -服务器校验token并返回数据。