diff --git "a/\346\236\227\351\270\277\351\221\253/note2021-6-22-01.md" "b/\346\236\227\351\270\277\351\221\253/note2021-6-22-01.md" new file mode 100644 index 0000000000000000000000000000000000000000..8cc445775d1827818434a188a5ba8ace27d94abd --- /dev/null +++ "b/\346\236\227\351\270\277\351\221\253/note2021-6-22-01.md" @@ -0,0 +1,12 @@ +# Api(第一课)创建Api + +1.先建一个文件夹Minda.yglm.Api + +2.创建一个解决方案sln +执行 dotnet new sln + +3.创建一个项目 dotnet new webapi -n Minda.yglm.Api --no-https + +4.你还可以搭建一个测试项目 先d .. +然后 mkdir api.http + diff --git "a/\346\236\227\351\270\277\351\221\253/note2021-6-23-01.md" "b/\346\236\227\351\270\277\351\221\253/note2021-6-23-01.md" new file mode 100644 index 0000000000000000000000000000000000000000..7b95b61cef4fe9036ff83cf1160411bd811452ba --- /dev/null +++ "b/\346\236\227\351\270\277\351\221\253/note2021-6-23-01.md" @@ -0,0 +1,153 @@ +Api(第二课) dotnet初始化webapi项目并且进行restfull测试的demo + +1.先建sln ,项目 ,api.http + +2.在文件里面Controllers里面创建一个UsersContoller.cs + +创建一个Minda.yglm.Controllers控制器: + + + using System.Collections.Generic;//C#泛型集合 + using System.Linq;//添加引用Linq + using Microsoft.AspNetCore.Mvc; + using Minda.yglm.Api.Entity; + + namespace Minda.yglm.Controllers + { + [ApiController] + [Route("[controller]")] + public class UsersController : ControllerBase + { + [HttpGet] + public dynamic Get() + { + var users = GetUsers(); + return users; + } + + [HttpGet("{id}")] + public dynamic Get(int id) + { + var users = GetUsers(); + var user = users.Where(x => x.Id == id).FirstOrDefault(); + return user; + } + + [HttpPost] + public dynamic Post(dynamic model) + { + return new { Code = 1000, Data = model, Msg = "创建用户成功" }; + } + + [HttpPut("{id}")] + public dynamic Put(int id, dynamic model) + { + return new { + Code = 1000, + Data = model, + Msg = + string + .Format("你修改的用户的id为:{0},已经修改成功,请注意查收", + id) + }; + } + + [HttpDelete("{id}")] + public dynamic Delete(int id) + { + return new { + Code = 1000, + Msg = string.Format("删除指定id为{0}的用户成功", id) + }; + } + + private IEnumerable GetUsers() + { + var users = + new List { + new Users { Id = 1, Username = "10086", Password = "123" }, + new Users { Id = 2, Username = "10010", Password = "456" }, + new Users { Id = 3, Username = "10000", Password = "789" } + }; + + return users; + } + } + } + + + +3.然后在Entity创建一个对象Users: + + using System; + + namespace Minda.yglm.Api.Entity + { + public class Users + { + public Users() + { + CreatedTime = DateTime.Now; + UpdatedTime = DateTime.Now; + Remarks = ""; + } + + public int Id { get; set; } + + public string Username { get; set; } + + public string Password { get; set; } + + public DateTime CreatedTime { get; set; } + + public DateTime UpdatedTime { get; set; } + + public string Remarks { get; set; } + } + } + + +4.在api.http里面进行增删改查测试! + + + ### 获取用户列表 + GET http://localhost:5000/users HTTP/1.1 + + + ### 获取指定id的用户 + GET http://localhost:5000/users/2 HTTP/1.1 + + + ### 创建用户 + POST http://localhost:5000/users HTTP/1.1 + Content-Type: application/json + + { + "username":"lhx", + "password":"2000" + } + + + ### 修改指定用户 + PUT http://localhost:5000/users/2 HTTP/1.1 + Content-Type: application/json + + { + "username":"lhx", + "password":"2000" + } + + + ### 删除指定用户 + DELETE http://localhost:5000/users/1 HTTP/1.1 + + + + +5.需要添加的依赖包: + +1.Better Comments(不需要) +2.C# Extensions +3.C# XML Documentation Comments +4.Prettier - Code formatter +5.REST Client diff --git "a/\346\236\227\351\270\277\351\221\253/note2021-6-26-01.md" "b/\346\236\227\351\270\277\351\221\253/note2021-6-26-01.md" new file mode 100644 index 0000000000000000000000000000000000000000..3c4bc8d94222d4d3dd139d6850b8c75a5fac8bce --- /dev/null +++ "b/\346\236\227\351\270\277\351\221\253/note2021-6-26-01.md" @@ -0,0 +1,258 @@ +# Api(第三次课)连接数据库 + +安装 Entity Framework Core + +dotnet add package Microsoft.EntityFrameworkCore.Sqlserver + +创建模型 Admin3000Db.cs + +例: + using Microsoft.EntityFrameworkCore; + using Admin3000.Backend.Api.Entity; + + namespace Admin3000.Backend.Api.Db + { + public class Admin3000Db : DbContext + { + public DbSet Users { get; set; } + public DbSet Roles { get; set; } + public DbSet UserRoles { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder options) + => options.UseSqlServer(@"server=.;database=Admin3000;uid=sa;pwd=123456;"); + } + } + + + + + + +然后创建数据库 + + + +dotnet tool install --global dotnet-ef +dotnet add package Microsoft.EntityFrameworkCore.Design +dotnet ef migrations add 这是一个mysql + + + +创建数据表 +Roles表 + sing System; + + namespace Admin3000.Backend.Api.Entity + { + public class Roles + { + public int Id { get; set; } + public string RoleName { get; set; } + public bool IsActived { get; set; } + public bool IsDeleted { get; set; } + public DateTime CreatedTime { get; set; } + public DateTime UpdatedTime { get; set; } + } + } + + + +UserRoles表 + using System; + + namespace Admin3000.Backend.Api.Entity + { + public class UserRoles + { + public int Id { get; set; } + public int UserId { get; set; } + public int RoleId { get; set; } + public bool IsActived { get; set; } + public bool IsDelete { get; set; } + public DateTime CreatedTime { get; set; } + public DateTime UpdatedTime { get; set; } + + } + + } +User表: + using System; + + namespace Admin3000.Backend.Api.Entity + { + /// + /// 用户表 + /// + public class Users + { + public Users(){ + CreatedTime=DateTime.Now; + UpdatedTime=DateTime.Now; + Remarks=""; + } + /// + /// 表的主键 + /// + /// + public int Id { get; set; } + + public string Username { get; set; } + + public string Password { get; set; } + + public DateTime CreatedTime { get; set; } + + public DateTime UpdatedTime { get; set; } + + public string Remarks { get; set; } + } + } + + + +在controller/UsersController.cs里面写增删改查; + + using System.Collections.Generic; + using Admin3000.Backend.Api.Entity; + using Microsoft.AspNetCore.Mvc; + using System.Linq; + using Admin3000.Backend.Api.ParamModel; + using Newtonsoft.Json; + using System; + + namespace Admin3000.Backend.Controllers + { + [ApiController] + [Route("[controller]")] + public class UsersController : ControllerBase + { + private Admin3000.Backend.Api.Db.Admin3000Db db = new Api.Db.Admin3000Db(); + + [HttpGet] + public dynamic Get() + { + + var users = db.Users.ToList(); + return users; + } + + [HttpGet("{id}")] + public dynamic Get(int id) + { + var user = db.Users.Where(x => x.Id == id).FirstOrDefault(); + return user; + } + + [HttpPost] + public string Post(NewUser model) + { + JsonSerializerSettings settings = new JsonSerializerSettings(); + // settings.MissingMemberHandling = MissingMemberHandling.Ignore; + settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + var user = new Users + { + Username = model.Username, + Password = model.Password + }; + + db.Users.Add(user); + db.SaveChanges(); + + var res = new + { + Code = 1000, + Data = user, + Msg = "创建用户成功" + }; + return JsonConvert.SerializeObject(res, settings); + } + + [HttpPut("{id}")] + public dynamic Put(int id, NewUser model) + { + var user = db.Users.Where(x => x.Id == id).FirstOrDefault(); + + if (user != null) + { + user.Username = model.Username; + user.Password = model.Password; + user.UpdatedTime=DateTime.Now; + db.Update(user); + db.SaveChanges(); + return new + { + Code = 1000, + Data = user, + Msg = string.Format("你修改的用户的id为:{0},已经修改成功,请注意查收", id) + }; + } + else + { + return new + { + Code = 104, + Data = "", + Msg = "指定Id的用户不存在,请确认后重试" + }; + } + } + + [HttpDelete("{id}")] + public dynamic Delete(int id) + { + var user = db.Users.Where(x => x.Id == id).FirstOrDefault(); + if (user != null) + { + db.Users.Remove(user); + db.SaveChanges(); + return new + { + Code = 1000, + Msg = string.Format("删除指定id为{0}的用户成功", id) + }; + } + else + { + return new + { + Code = 104, + Data = "", + Msg = "指定Id的用户不存在,请确认后重试" + }; + } + + } + + private IEnumerable GetUsers() + { + var users = + new List { + new Users { + Id = 1, + Username = "admin", + Password = "芝麻开门" + }, + new Users { + Id = 2, + Username = "超级管理员", + Password = "芝麻开门" + }, + new Users { + Id = 3, + Username = "普通用户", + Password = "芝麻开门" + } + }; + + return users; + } + } + } + + + +dotnet ef database update + + +然后项目跑起来dotnet run +进行测试! \ No newline at end of file diff --git "a/\346\236\227\351\270\277\351\221\253/note2021-6-29-01.md" "b/\346\236\227\351\270\277\351\221\253/note2021-6-29-01.md" new file mode 100644 index 0000000000000000000000000000000000000000..710e5c8f0ed9992197fd76025c59635491bb9b0a --- /dev/null +++ "b/\346\236\227\351\270\277\351\221\253/note2021-6-29-01.md" @@ -0,0 +1,57 @@ +# Api 第四节课 +尝试抽象所有实体的共有属性 + +## 在Entity里面创建一个BaseEntity.cs表: + + using System; + + namespace Admin3000.Backend.Api.Entity + { + public abstract class BaseEntity + { + public int Id{get;set;} + public bool IsActived{get;set;} + public bool IsDeleted{get;set;} + public DateTime CreatedTime{get;set;} + public DateTime UpdatedTime{get;set;} + public int DisplayOrder{get;set;} + public string Remarks{get;set;} + } + } + +Roles表: + + public string RoleName { get; set; } + + public virtual IEnumerable UserRoles { get; set; } + + +Users表: + + public string Username { get; set; } + + public string Password { get; set; } + + public virtual IEnumerable UserRoles { get; set; } + +UserRoles表: + + public int UserId { get; set; } + public int RoleId { get; set; } + + public virtual Users User { get; set; } + public virtual Roles Role { get; set; } + + +下面这三个表都需要继承BaseEntity表 + + +## 尝试建立表之间的关系 + +在Roles表里面写一个语句: public virtual IEnumerable UserRoles { get; set; }(using System.Collections.Generic;需要调用这个) +在UserRoses表里面写: + public virtual Users User { get; set; } + public virtual Roles Role { get; set; } + +在Users表里面写: public virtual IEnumerable UserRoles { get; set; }(using System.Collections.Generic;需要调用这个) +然后在数据库查看表关系 \ No newline at end of file diff --git "a/\346\236\227\351\270\277\351\221\253/note2021-6-30-01.md" "b/\346\236\227\351\270\277\351\221\253/note2021-6-30-01.md" new file mode 100644 index 0000000000000000000000000000000000000000..a3e07004e196d23cb69c10a730214382b9e75f2b --- /dev/null +++ "b/\346\236\227\351\270\277\351\221\253/note2021-6-30-01.md" @@ -0,0 +1,197 @@ +# APi 第五次课 (继续完成未完成的封装,实现接口,经测试成功) + +在项目Admin3000里面创建一个文件Repository +然后创建一个EfRepository.cs + + using System; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.EntityFrameworkCore; + using Admin3000.Backend.Api.Entity; + using Admin3000.Backend.Api.Db; + + namespace Admin3000.Backend.Api.Repository + { + public class EfRepository : IRepository where T : BaseEntity + { + /// + /// 数据库上下文的变量,此处是使用常规手段,直接初始化一个数据库上下文的实例对象 + /// + /// + private Admin3000Db db = new Admin3000Db(); + + /// + /// 一个字段成员,用于内部Entity属性 + /// + private DbSet _entity; + + + /// + /// 一个访问受限的属性,只有访问器,总是返回一个代表T类型的表对象 + /// + /// + protected DbSet Entity + { + get + { + // 如果 _entity为空(没有指向一个对象),则从数据库上下文重新获得一个 + if (_entity == null) + { + _entity = db.Set(); + } + return _entity; + } + } + + /// + /// 代表一个可以用于查询T类型的表 + /// + /// + public IQueryable Table + { + get + { + return Entity.AsQueryable(); + } + } + + + /// + /// 删除(指定T类型,在数据库当中代表指定的表)指定Id的记录 + /// + /// + public void Delete(int id) + { + var t = Entity.Where(x => x.Id == id).FirstOrDefault(); + Entity.Remove(t); + db.SaveChanges(); + } + //获取T表对象内容 + public T GetById(int id) + { + var t = Entity.Where(x => x.Id == id).FirstOrDefault(); + return t; + } + 先插入数据 + public void Insert(T entity) + { + if (entity == null) + { + throw new System.NullReferenceException(); + } + + entity.IsActived=true; + entity.IsDeleted=false; + entity.CreatedTime=DateTime.Now; + entity.UpdatedTime=DateTime.Now; + entity.DisplayOrder=0; + + Entity.Add(entity); + db.SaveChanges(); + } + 然后实现异步插入数据库 + public async Task InsertAsync(T entity) + { + if (entity == null) + { + throw new System.NullReferenceException(); + } + + entity.IsActived=true; + entity.IsDeleted=false; + entity.CreatedTime=DateTime.Now; + entity.UpdatedTime=DateTime.Now; + entity.DisplayOrder=0; + + await Entity.AddAsync(entity); + await db.SaveChangesAsync(); + } + 先更新 + public void Update(T entity) + { + if (entity == null) + { + throw new System.NullReferenceException(); + } + + entity.UpdatedTime=DateTime.Now; + db.SaveChanges(); + } + 然后在异步更新到数据库 + public async Task UpdateAsync(T entity) + { + if (entity == null) + { + throw new System.NullReferenceException(); + } + + entity.UpdatedTime=DateTime.Now; + + await db.SaveChangesAsync(); + } + } + } + +IRepository.cs + + using System.Linq; + using System.Threading.Tasks; + + + namespace Admin3000.Backend.Api.Repository + { + public interface IRepository + { + IQueryable Table { get; } + + /// + /// 根据Id获取指定实体 + /// + /// + /// + T GetById(int id); + + /// + /// 使用实体对象,插入数据 + /// + /// 需要插入的对象 + void Insert(T entity); + + /// + /// 使用实体对象,插入数据(异步) + /// + /// 需要插入的对象 + /// + Task InsertAsync(T entity); + + /// + /// 根据对象更新数据 + /// + /// 要更新的对象 + void Update(T entity); + + + /// + /// 根据对象更新数据(异步) + /// + /// 要更新的对象 + /// + Task UpdateAsync(T entity); + + /// + /// 根据Id删除对应的记录 + /// + /// 主键id + void Delete(int id); + } + } + +在UsersController.cs 里面 + +将 private Admin3000.Backend.Api.Db.Admin3000Db db = new Api.Db.Admin3000Db(); + +替换成 + private Api.Db.Admin3000Db db=new Api.Db.Admin3000Db(); + private IRepository _usersRespository=new EfRepository(); + +然后跑起来进行测试! \ No newline at end of file diff --git "a/\346\236\227\351\270\277\351\221\253/note2021-7-02-01.md" "b/\346\236\227\351\270\277\351\221\253/note2021-7-02-01.md" new file mode 100644 index 0000000000000000000000000000000000000000..7d96919db539085bd0e12ca0c8bae46ac613a3f8 --- /dev/null +++ "b/\346\236\227\351\270\277\351\221\253/note2021-7-02-01.md" @@ -0,0 +1,494 @@ +# Api 第六次课 + +## 完成了IRespository接口的实现,并且做了一些简单的测试,目前没有发现问题 + +IRepository.cs: + + using System.Linq; + using System.Threading.Tasks; + using System.Collections.Generic; + + + namespace Admin3000.Backend.Api.Repository + { + public interface IRepository + { + IQueryable Table { get; } + + /// + /// 根据Id获取指定实体 + /// + /// + /// + T GetById(int id); + + /// + /// 使用实体对象,插入数据 + /// + /// 需要插入的对象 + void Insert(T entity); + + /// + /// 使用实体对象,插入数据(异步) + /// + /// 需要插入的对象 + /// + + + /// + /// 批量插入若干数据 + /// + /// 待插入的若干实体数据 + + + /// + /// 批量插入若干数据(异步) + /// + /// 待插入的若干实体数据 + /// + Task InsertBulkAsync(IEnumerable entities); + + Task InsertAsync(T entity); + + void InsertBulk (IEnumerable entities); + /// + /// 根据对象更新数据 + /// + /// 要更新的对象 + void Update(T entity); + + + /// + /// 根据对象更新数据(异步) + /// + /// 要更新的若干个实体 + /// + void UpdateBulk(IEnumerable entities); + + /// + /// 根据Id删除对应的记录 + /// + /// 主键id + void Delete(int id); + } + } + +EfRepository.cs: + + using System; + using System.Linq; + using System.Threading.Tasks; + using System.Collections.Generic; + using Microsoft.EntityFrameworkCore; + using Admin3000.Backend.Api.Entity; + using Admin3000.Backend.Api.Db; + + namespace Admin3000.Backend.Api.Repository + { + public class EfRepository : IRepository where T : BaseEntity + { + /// + /// 数据库上下文的变量,此处是使用常规手段,直接初始化一个数据库上下文的实例对象 + /// + /// + private Admin3000Db _db; + + public EfRepository(Admin3000Db db) + { + _db=db; + } + + /// + /// 一个字段成员,用于内部Entity属性 + /// + private DbSet _entity; + + + /// + /// 一个访问受限的属性,只有访问器,总是返回一个代表T类型的表对象 + /// + /// + protected DbSet Entity + { + get + { + // 如果 _entity为空(没有指向一个对象),则从数据库上下文重新获得一个 + if (_entity == null) + { + _entity = _db.Set(); + } + return _entity; + } + } + + /// + /// 代表一个可以用于查询T类型的表 + /// + /// + public IQueryable Table + { + get + { + return Entity.AsQueryable(); + } + } + + + /// + /// 删除(指定T类型,在数据库当中代表指定的表)指定Id的记录 + /// + /// + public void Delete(int id) + { + var t = Entity.Where(x => x.Id == id).FirstOrDefault(); + Entity.Remove(t); + _db.SaveChanges(); + } + + public T GetById(int id) + { + var t = Entity.Where(x => x.Id == id).FirstOrDefault(); + return t; + } + + public void Insert(T entity) + { + if (entity == null) + { + throw new System.NullReferenceException(); + } + + entity.IsActived = true; + entity.IsDeleted = false; + entity.CreatedTime = DateTime.Now; + entity.UpdatedTime = DateTime.Now; + entity.DisplayOrder = 0; + + Entity.Add(entity); + _db.SaveChanges(); + } + + public async Task InsertAsync(T entity) + { + if (entity == null) + { + throw new System.NullReferenceException(); + } + + entity.IsActived = true; + entity.IsDeleted = false; + entity.CreatedTime = DateTime.Now; + entity.UpdatedTime = DateTime.Now; + entity.DisplayOrder = 0; + + await Entity.AddAsync(entity); + await _db.SaveChangesAsync(); + } + + public void InsertBulk(IEnumerable entities) + { + foreach (var entity in entities) + { + entity.IsActived = true; + entity.IsDeleted = false; + entity.CreatedTime = DateTime.Now; + entity.UpdatedTime = DateTime.Now; + entity.DisplayOrder = 0; + } + Entity.AddRange(entities); + _db.SaveChanges(); + } + + public async Task InsertBulkAsync(IEnumerable entities) + { + foreach (var entity in entities) + { + entity.IsActived = true; + entity.IsDeleted = false; + entity.CreatedTime = DateTime.Now; + entity.UpdatedTime = DateTime.Now; + entity.DisplayOrder = 0; + } + await Entity.AddRangeAsync(entities); + await _db.SaveChangesAsync(); + } + + public void Update(T entity) + { + if (entity == null) + { + throw new System.NullReferenceException(); + } + + entity.UpdatedTime = DateTime.Now; + _db.SaveChanges(); + } + + public void UpdateBulk(IEnumerable entities) + { + foreach (var entity in entities) + { + entity.UpdatedTime = DateTime.Now; + } + + + _db.SaveChanges(); + } + } + } + +## 使用依赖注入的完成服务实例的获取,经过测试,可以正常获取到服务实例对象 + + 在UsersController.cs 里面 + + using System; + using System.Collections.Generic; + using Admin3000.Backend.Api.Entity; + using Microsoft.AspNetCore.Mvc; + using System.Linq; + using Admin3000.Backend.Api.ParamModel; + using Newtonsoft.Json; + using Admin3000.Backend.Api.Repository; + + + namespace Admin3000.Backend.Controllers + { + [ApiController] + [Route("[controller]")] + public class UsersController : ControllerBase + { + private IRepository _usersRespository; + + public UsersController(IRepository usersRespository) + { + _usersRespository=usersRespository; + } + + [HttpGet] + public dynamic Get() + { + // db.Users.up + + var users = _usersRespository.Table.ToList(); + return new + { + Code = 1000, + Data = users, + Msg = "获取用户列表成功^_^" + }; + } + + [HttpGet("{id}")] + public dynamic Get(int id) + { + var user = _usersRespository.GetById(id); + return user; + } + + [HttpPost] + public string Post(NewUser model) + { + JsonSerializerSettings settings = new JsonSerializerSettings(); + // settings.MissingMemberHandling = MissingMemberHandling.Ignore; + settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + var user = new Users + { + Username = model.Username, + Password = model.Password + }; + + _usersRespository.Insert(user); + + var res = new + { + Code = 1000, + Data = user, + Msg = "创建用户成功" + }; + return JsonConvert.SerializeObject(res, settings); + } + + [HttpPut("{id}")] + public dynamic Put(int id, NewUser model) + { + var user = _usersRespository.GetById(id); + + if (user != null) + { + user.Username = model.Username; + user.Password = model.Password; + user.UpdatedTime = DateTime.Now; + _usersRespository.Update(user); + return new + { + Code = 1000, + Data = user, + Msg = string.Format("你修改的用户的id为:{0},已经修改成功,请注意查收", id) + }; + } + else + { + return new + { + Code = 104, + Data = "", + Msg = "指定Id的用户不存在,请确认后重试" + }; + } + } + + [HttpDelete("{id}")] + public dynamic Delete(int id) + { + var user = _usersRespository.GetById(id); + if (user != null) + { + _usersRespository.Delete(id); + return new + { + Code = 1000, + Msg = string.Format("删除指定id为{0}的用户成功", id) + }; + } + else + { + return new + { + Code = 104, + Data = "", + Msg = "指定Id的用户不存在,请确认后重试" + }; + } + + } + + private IEnumerable GetUsers() + { + var users = + new List { + new Users { + Id = 1, + Username = "admin", + Password = "芝麻开门" + }, + new Users { + Id = 2, + Username = "超级管理员", + Password = "芝麻开门" + }, + new Users { + Id = 3, + Username = "普通用户", + Password = "芝麻开门" + } + }; + + return users; + } + } + } + +Admin3000.Backend.Api/Data/Admin3000Db.cs: + + using Microsoft.EntityFrameworkCore; + using Admin3000.Backend.Api.Entity; + + namespace Admin3000.Backend.Api.Db + { + public class Admin3000Db : DbContext + { + // 因为我们使用AddDbContext到容器,所以此处必须得有带参数的构造函数(而且必须传递DbContextOptions类型的参数,同时父类也得调用这个参数) + public Admin3000Db(DbContextOptions options):base(options) + { + + } + + public DbSet Users { get; set; } + public DbSet Roles { get; set; } + public DbSet UserRoles { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder builder) + => builder.UseSqlServer(@"server=.;database=Admin3000;uid=sa;pwd=123456;"); + } + } + + +Admin3000.Backend.Api/Startup.cs: + + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Builder; + using Microsoft.AspNetCore.Hosting; + using Microsoft.AspNetCore.Mvc; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + using Microsoft.Extensions.Logging; + using Microsoft.EntityFrameworkCore; + using Admin3000.Backend.Api.Repository; + + namespace Admin3000.Backend.Api + { + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + // 注册数据库上下文到容器 + services.AddDbContext(o =>o.UseSqlServer()); + // 注册对数据库的基本操作服务到容器 + services.AddScoped(typeof(IRepository<>),typeof(EfRepository<>)); + + services.AddControllers(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseRouting(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + } + } + + +## 使用到的技术包括,但不限于如下所列: + +1. 基于`asp.net core`和`netcoreapp3.1` +1. 基于`asp.net core`和`netcoreapp3.1`, +2. 基于`EntityFramework core`和数据迁移技术 +3. 基于控制反转(IoC)和依赖注入技术(DI) +4. 使用Restfull约定,来分别完成数据的CRUD,类似如下用法: + + | 路由形式 | 说明 | + | - | -| + | get /users | 获取用户列表 | + | get /users/:id | 获取指定id的用户 | + | post /users | 增加用户 | + | put /users/:id | 修改指定用户 | + | delete /users/:id | 删除指定用户 | + + +5. 自行封装的对数据库的CRUD操作 + 用到了泛型、异步方法、接口、接口实现、泛型接口、集合、完整的属性(使用了私有类型字段) +6. 基于webapi的路由模式 \ No newline at end of file diff --git "a/\346\236\227\351\270\277\351\221\253/note2021-7-03-01.md" "b/\346\236\227\351\270\277\351\221\253/note2021-7-03-01.md" new file mode 100644 index 0000000000000000000000000000000000000000..6c7f36457f6ca56dc41d86a5775fb94bee6f46d7 --- /dev/null +++ "b/\346\236\227\351\270\277\351\221\253/note2021-7-03-01.md" @@ -0,0 +1,71 @@ +# 复习C#的一些内容还有Api的简介详情书 + +## C#基础 + +### 接口 +1.什么是接口? + +实体把自己提供给外界的一种抽象化物(可以为另一实体),用以由内部操作分离出外部沟通方法,使其能被内部修改而不影响外界其他实体与其交互的方式。 + +2.接口的作用? + +接口是一个让很多C#初学者容易迷糊的东西,用起来好像很简单 +3.接口的用法? + +使用类型去继承(或者实现)接口 +### 泛型 +1.什么是泛型? +一种类型占位符 + +2.泛型的作用? +使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能 + +3.泛型的用法? +泛型的类型、集合、接口 + +### 属性 + +1.类型的成员 +字段:类型中的变量 +属性:具有get、set的类型成员 +方法:类型当中可被外部访问的函数 + +2.自动属性 + +没有字段配合,自己具有get或set的一种类型成员 + +## Api的简介详情书 + + +1. 基于`asp.net core`和`netcoreapp3.1` +1. 基于`asp.net core`和`netcoreapp3.1`, +2. 基于`EntityFramework core`和数据迁移技术 +3. 基于控制反转(IoC)和依赖注入技术(DI) +4. 使用Restfull约定,来分别完成数据的CRUD,类似如下用法: + + | 路由形式 | 说明 | + | - | -| + | get /users | 获取用户列表 | + | get /users/:id | 获取指定id的用户 | + | post /users | 增加用户 | + | put /users/:id | 修改指定用户 | + | delete /users/:id | 删除指定用户 | + + +5. 自行封装的对数据库的CRUD操作 + 用到了泛型、异步方法、接口、接口实现、泛型接口、集合、完整的属性(使用了私有类型字段) +6. 基于webapi的路由模式 +7.Sqlserver 2014 +8.Vscode 以及各种插件 +9.Api测试的各种玩法 +10.dotnet运行的命令: + + dotnet new sln -n Admin3000.backend + cd Admin3000.backend + dotnet add package Microsoft.EntityFramworkCore + dotnet add package Microsoft.EntityFramworkCore.Sqlserver + (定义实体类型、数据库上下文,定义数据连接字符串) + dotnet tool install --global dotnet-ef + dotnet add package Microsoft.EntityFramworkCore.Design\ + dotnet ef migrations add xxx + dotnet ef database update \ No newline at end of file diff --git "a/\346\236\227\351\270\277\351\221\253/note2021-7-06-01.md" "b/\346\236\227\351\270\277\351\221\253/note2021-7-06-01.md" new file mode 100644 index 0000000000000000000000000000000000000000..d0815c925732e9060f8e7362fcae887c5724c3a4 --- /dev/null +++ "b/\346\236\227\351\270\277\351\221\253/note2021-7-06-01.md" @@ -0,0 +1,349 @@ +# Api第八次课 (Jwt) + +步骤一:在配置文件中设置一些配置 +步骤二:在UsersController中,新增加一个用户登录方法,用于用户的登录,登录成功,返回token +步骤三:真正生成token的,单独写一个帮助类 + +生成JWT Token需要预设一些参数。我们在appsetting.json里先设置好: + + { + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*", + "TokenParameter": { + "secret": "123456123456123456", + "issuer": "WooZ", + "accessExpiration": 120, + "refreshExpiration": 1440 + } + } + + +然后在paramModel里面的TokenParameter.cs里面创建一个映射TokenParameter的类。这个类不是必须,只是为了写着方便。不想这样写,也可以直接读配置,再转成数据。 + + namespace Admin3000.Backend.Api.ParamModel + { + public class TokenParameter + { + //token的密钥,不能泄露,泄露意味着所有人都可以生成你的token并且访问你的服务或者接口 + public string Secret { get; set; } + + //发行人(可以是个人或组织) + public string Issuer { get; set; } + + //token的作用时间,单位为分钟,过期后需要重新获取 + public int AccessExpiration { get; set; } + + //类似一个token的东西的作用时间,单位为分钟,用于重新获取token + public int RefreshExpiration { get; set; } + } + } + +然后在UsersController控制器文件里面完成Token和refreshToken的生成和返回。 + + [HttpPost, Route("token")] + public dynamic GetToken(NewUser model) + { + var username = model.Username.Trim(); + var password = model.Password.Trim(); + + var user = _usersRespository.Table.Where(x => x.Username == username && x.Password == password).FirstOrDefault(); + + if (user == null) + { + return new + { + Code = 1001, + Data = user, + Msg = "用户名或密码不正确,请核对后重试" + }; + } + + var token = TokenHelper.GenerateToekn(_tokenParameter, user); + var refreshToken = "123456"; + + var res = new + { + Code = 1000, + Data = new { Token = token, RefreshToken = refreshToken }, + Msg = "用户登录成功,获取token成功" + }; + return res; + } + + +在utils里面创建一个TokenHelper.cs: + + + using System; + using System.IdentityModel.Tokens.Jwt; + using System.Security.Claims; + using System.Text; + using Admin3000.Backend.Api.Entity; + using Admin3000.Backend.Api.ParamModel; + using Microsoft.IdentityModel.Tokens; + + namespace Admin3000.Backend.Api.Utils + { + public class TokenHelper + { + public static string GenerateToekn(TokenParameter tokenParameter,Users user) + { + + var claims = new[] + { + new Claim(ClaimTypes.Name, user.Username), + new Claim(ClaimTypes.Role, "admin"), + }; + + var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenParameter.Secret)); + var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); + var jwtToken = new JwtSecurityToken(tokenParameter.Issuer, null, claims, expires: DateTime.UtcNow.AddMinutes(tokenParameter.AccessExpiration), signingCredentials: credentials); + + var token = new JwtSecurityTokenHandler().WriteToken(jwtToken); + + return token; + } + } + } + + +然后userscontroller添加一些小东西: + + using System; + using System.Collections.Generic; + using Admin3000.Backend.Api.Entity; + using Microsoft.AspNetCore.Mvc; + using System.Linq; + using Admin3000.Backend.Api.ParamModel; + using Newtonsoft.Json; + using Admin3000.Backend.Api.Repository; + using Admin3000.Backend.Api.Utils; + using Microsoft.Extensions.Configuration; + + namespace Admin3000.Backend.Controllers + { + [ApiController] + [Route("[controller]")] + public class UsersController : ControllerBase + { + private IRepository _usersRespository; + private TokenParameter _tokenParameter; + private readonly IConfiguration _configuration; + + public UsersController(IConfiguration configuration, IRepository usersRespository) + { + _configuration = configuration; + _usersRespository = usersRespository; + _tokenParameter = _configuration.GetSection("TokenParameter").Get(); + } + + [HttpGet] + public dynamic Get() + { + // db.Users.up + + var users = _usersRespository.Table.ToList(); + return new + { + Code = 1000, + Data = users, + Msg = "获取用户列表成功^_^" + }; + } + + [HttpGet("{id}")] + public dynamic Get(int id) + { + var user = _usersRespository.GetById(id); + + if (user == null) + { + return new + { + Code = 1000, + Data = "", + Msg = "指定用户不存在" + }; + + } + return new + { + Code = 1000, + Data = user, + Msg = "获取用户列表成功^_^" + }; + + } + + [HttpPost] + public string Post(NewUser model) + { + JsonSerializerSettings settings = new JsonSerializerSettings(); + // settings.MissingMemberHandling = MissingMemberHandling.Ignore; + settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + var user = new Users + { + Username = model.Username, + Password = model.Password + }; + + _usersRespository.Insert(user); + + var res = new + { + Code = 1000, + Data = user, + Msg = "创建用户成功" + }; + return JsonConvert.SerializeObject(res, settings); + } + + [HttpPut("{id}")] + public dynamic Put(int id, NewUser model) + { + var user = _usersRespository.GetById(id); + + if (user != null) + { + user.Username = model.Username; + user.Password = model.Password; + user.UpdatedTime = DateTime.Now; + _usersRespository.Update(user); + return new + { + Code = 1000, + Data = user, + Msg = string.Format("你修改的用户的id为:{0},已经修改成功,请注意查收", id) + }; + } + else + { + return new + { + Code = 104, + Data = "", + Msg = "指定Id的用户不存在,请确认后重试" + }; + } + } + + [HttpDelete("{id}")] + public dynamic Delete(int id) + { + var user = _usersRespository.GetById(id); + if (user != null) + { + _usersRespository.Delete(id); + return new + { + Code = 1000, + Msg = string.Format("删除指定id为{0}的用户成功", id) + }; + } + else + { + return new + { + Code = 104, + Data = "", + Msg = "指定Id的用户不存在,请确认后重试" + }; + } + + } + + private IEnumerable GetUsers() + { + var users = + new List { + new Users { + Id = 1, + Username = "admin", + Password = "芝麻开门" + }, + new Users { + Id = 2, + Username = "超级管理员", + Password = "芝麻开门" + }, + new Users { + Id = 3, + Username = "普通用户", + Password = "芝麻开门" + } + }; + + return users; + } + + [HttpPost, Route("token")] + public dynamic GetToken(NewUser model) + { + var username = model.Username.Trim(); + var password = model.Password.Trim(); + + var user = _usersRespository.Table.Where(x => x.Username == username && x.Password == password).FirstOrDefault(); + + if (user == null) + { + return new + { + Code = 1001, + Data = user, + Msg = "用户名或密码不正确,请核对后重试" + }; + } + + var token = TokenHelper.GenerateToekn(_tokenParameter, user); + var refreshToken = "123456"; + + var res = new + { + Code = 1000, + Data = new { Token = token, RefreshToken = refreshToken }, + Msg = "用户登录成功,获取token成功" + }; + return res; + } + } + } + +这样子然后测试跑一下,如果有token创建成功就行了! + +token验证: + +Admin3000.Backend.Api/Startup.cs: + + // 注册验证器(使用何种配置来验证token) + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(option => + { + // 是否要求使用https + option.RequireHttpsMetadata=false; + // 是否保存token + option.SaveToken=true; + // 使用配置中间件,获得token的配置 + var tokenParameter=Configuration.GetSection("TokenParameter").Get(); + // 验证器的核心属性 + option.TokenValidationParameters=new TokenValidationParameters + { + ValidateIssuerSigningKey=true,//要不要验证生成token的密钥 + IssuerSigningKey=new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenParameter.Secret)), + ValidateIssuer=true, // 要不要验证发行token的人(个人或者组织) + ValidIssuer=tokenParameter.Issuer, + ValidateAudience=false // 是否验证受众 + }; + }); + + + + // 将token的验证注册到中间件 + app.UseAuthentication(); + + diff --git "a/\346\236\227\351\270\277\351\221\253/note2021-7-08-01.md" "b/\346\236\227\351\270\277\351\221\253/note2021-7-08-01.md" new file mode 100644 index 0000000000000000000000000000000000000000..97a1d46dfcb4fbb88359918373b22f89527fb1c7 --- /dev/null +++ "b/\346\236\227\351\270\277\351\221\253/note2021-7-08-01.md" @@ -0,0 +1,197 @@ +# Api(第九次课)日志审计 + +1.先在Entity里面创建AuditInfo表:(定义审计日志信息) + + public class AuditInfo : BaseEntity + { + /// + /// 调用参数 + /// + public string Parameters { get; set; } + /// + /// 浏览器信息 + /// + public string BrowserInfo { get; set; } + /// + /// 客户端信息 + /// + public string ClientName { get; set; } + /// + /// 客户端IP地址 + /// + public string ClientIpAddress { get; set; } + /// + /// 执行耗时 + /// + public int ExecutionDuration { get; set; } + /// + /// 执行时间 + /// + public DateTime ExecutionTime { get; set; } + /// + /// 返回内容 + /// + public string ReturnValue { get; set; } + /// + /// 异常对象 + /// + public string Exception { get; set; } + /// + /// 方法名 + /// + public string MethodName { get; set; } + /// + /// 服务名 + /// + public string ServiceName { get; set; } + /// + /// 调用者信息 + /// + public string UserInfo { get; set; } + /// + /// 自定义数据 + /// + public string CustomData { get; set; } + } + +2.然后再data文件夹里面添加Admin3000Db.cs + +添加 public DbSet AuditInfo { get; set; } + +3.然后实现审计日志过滤器: +在Filters文件夹里面:创建一个AuditLogActionFilter.cs: + + using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Controllers; + using Microsoft.AspNetCore.Mvc.Filters; + using Microsoft.Extensions.Logging; + using Newtonsoft.Json; + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; + using System.Reflection; + using System.Threading.Tasks; + using Admin3000.Backend.Api.Entity; + using Admin3000.Backend.Api.Repository; + + namespace Admin3000.Backend.Api.Filters + { + public class AuditLogActionFilter : IAsyncActionFilter + { + private readonly IRepository _auditLogService; + public AuditLogActionFilter( + IRepository auditLogService + ) + { + _auditLogService = auditLogService; + } + + public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) + { + // 判断是否写日志 + if (!ShouldSaveAudit(context)) + { + await next(); + return; + } + //接口Type + var type = (context.ActionDescriptor as ControllerActionDescriptor).ControllerTypeInfo.AsType(); + //方法信息 + var method = (context.ActionDescriptor as ControllerActionDescriptor).MethodInfo; + //方法参数 + var arguments = context.ActionArguments; + //开始计时 + var stopwatch = Stopwatch.StartNew(); + var auditInfo = new AuditInfo + { + UserInfo = "林鸿鑫", + ServiceName = type != null ? type.FullName : "", + MethodName = method.Name, + ////请求参数转Json + Parameters = JsonConvert.SerializeObject(arguments), + ExecutionTime = DateTime.Now, + BrowserInfo = context.HttpContext.Request.Headers["User-Agent"], + ClientIpAddress = context.HttpContext.Connection.RemoteIpAddress.ToString(), + //ClientName = _clientInfoProvider.ComputerName.TruncateWithPostfix(EntityDefault.FieldsLength100), + // Id = Guid.NewGuid().ToString() + }; + + ActionExecutedContext result = null; + try + { + result = await next(); + if (result.Exception != null && !result.ExceptionHandled) + { + auditInfo.Exception = result.Exception.ToString(); + } + } + catch (Exception ex) + { + auditInfo.Exception = ex.ToString(); + throw; + } + finally + { + stopwatch.Stop(); + auditInfo.ExecutionDuration = Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds); + + if (result != null) + { + switch (result.Result) + { + case ObjectResult objectResult: + auditInfo.ReturnValue = JsonConvert.SerializeObject(objectResult.Value); + break; + + case JsonResult jsonResult: + auditInfo.ReturnValue = JsonConvert.SerializeObject(jsonResult.Value); + break; + + case ContentResult contentResult: + auditInfo.ReturnValue = contentResult.Content; + break; + } + } + Console.WriteLine(auditInfo.ToString()); + //保存审计日志 + await _auditLogService.InsertAsync(auditInfo); + } + } + + /// + /// 是否需要记录审计 + /// + /// + /// + private bool ShouldSaveAudit(ActionExecutingContext context) + { + if (!(context.ActionDescriptor is ControllerActionDescriptor)) + return false; + var methodInfo = (context.ActionDescriptor as ControllerActionDescriptor).MethodInfo; + + if (methodInfo == null) + { + return false; + } + + if (!methodInfo.IsPublic) + { + return false; + } + + return true; + } + } + } + +4.注册过滤器 +在Startup.cs 添加 + +//日志打印 + services.AddControllers(options=> + { + options.Filters.Add(typeof(AuditLogActionFilter)); + }); + } diff --git "a/\346\236\227\351\270\277\351\221\253/note2021-7-10-01.md" "b/\346\236\227\351\270\277\351\221\253/note2021-7-10-01.md" new file mode 100644 index 0000000000000000000000000000000000000000..d25db1597588083b98e08fd67f322ee263e2a4e9 --- /dev/null +++ "b/\346\236\227\351\270\277\351\221\253/note2021-7-10-01.md" @@ -0,0 +1,13 @@ +# 前后端分离第一节 + + +先下载淘宝镜像 + +然后创建一个admin3000.frontend项目 + +先进行路由封装 + + +在初始化模板 + +这可能要用到npm i element-ui 安装配置文件 \ No newline at end of file