From 367f8f88305f3b01eb7f04ddecac992d5a6c194c Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Sat, 20 Mar 2021 21:56:15 +0800 Subject: [PATCH 01/31] v1.0.1 --- CC.Yi.API/Controllers/StudentController.cs | 42 ++++++++++++++- .../Migrations/20210320082935_yi2.Designer.cs | 40 +++++++++++++++ CC.Yi.API/Migrations/20210320082935_yi2.cs | 31 +++++++++++ .../Migrations/DataContextModelSnapshot.cs | 4 +- CC.Yi.API/Program.cs | 19 ++++++- CC.Yi.API/appsettings.json | 2 +- CC.Yi.BLL/BaseBll.cs | 27 +++++++++- CC.Yi.DAL/BaseDal.cs | 29 +++++++++-- CC.Yi.DAL/DbContentFactory.cs | 51 ++++++++----------- CC.Yi.DAL/T4DAL.cs | 3 -- CC.Yi.DAL/T4DAL.tt | 3 -- CC.Yi.DALFactory/T4StaticDalFactory.cs | 2 +- CC.Yi.DALFactory/T4StaticDalFactory.tt | 2 +- CC.Yi.IBLL/IBaseBll.cs | 18 ++++++- CC.Yi.IDAL/IBaseDal.cs | 15 ++++++ CC.Yi.Model/student.cs | 2 +- 16 files changed, 240 insertions(+), 50 deletions(-) create mode 100644 CC.Yi.API/Migrations/20210320082935_yi2.Designer.cs create mode 100644 CC.Yi.API/Migrations/20210320082935_yi2.cs diff --git a/CC.Yi.API/Controllers/StudentController.cs b/CC.Yi.API/Controllers/StudentController.cs index 5411f596..41de2620 100644 --- a/CC.Yi.API/Controllers/StudentController.cs +++ b/CC.Yi.API/Controllers/StudentController.cs @@ -1,4 +1,5 @@ using CC.Yi.IBLL; +using CC.Yi.Model; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; @@ -20,11 +21,50 @@ namespace CC.Yi.API.Controllers _logger = logger; } + + #region + //下面,经典的 增删改查 即为简易--Yi意框架 + //注意:请确保你的数据库中存在合理的数据 + #endregion [HttpGet] - public IActionResult Test() + public IActionResult GetTest()//查 { var data = _studentBll.GetAllEntities().ToList(); return Content(Common.JsonFactory.JsonToString(data)); } + [HttpGet] + public IActionResult AddTest()//增 + { + List students = new List() {new student { name = "学生a" } ,new student { name="学生d"} }; + _studentBll.Add(students); + return Content("ok"); + + } + [HttpGet] + public IActionResult RemoveTest()//删 + { + + if (_studentBll.Delete(u=>u.name=="学生a")) + { + return Content("ok"); + } + else + { + return Content("no"); + } + } + [HttpGet] + public IActionResult UpdateTest()//改 + { + if (_studentBll.Update(new student { id=2, name = "学生a" }, "name")) + { + return Content("ok"); + } + else + { + return Content("no"); + } + + } } } diff --git a/CC.Yi.API/Migrations/20210320082935_yi2.Designer.cs b/CC.Yi.API/Migrations/20210320082935_yi2.Designer.cs new file mode 100644 index 00000000..c9bbf025 --- /dev/null +++ b/CC.Yi.API/Migrations/20210320082935_yi2.Designer.cs @@ -0,0 +1,40 @@ +// +using CC.Yi.Model; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace CC.Yi.API.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20210320082935_yi2")] + partial class yi2 + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.4") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("CC.Yi.Model.student", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("id"); + + b.ToTable("student"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/CC.Yi.API/Migrations/20210320082935_yi2.cs b/CC.Yi.API/Migrations/20210320082935_yi2.cs new file mode 100644 index 00000000..6875efa1 --- /dev/null +++ b/CC.Yi.API/Migrations/20210320082935_yi2.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace CC.Yi.API.Migrations +{ + public partial class yi2 : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "name", + table: "student", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(int), + oldType: "int"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "name", + table: "student", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + } + } +} diff --git a/CC.Yi.API/Migrations/DataContextModelSnapshot.cs b/CC.Yi.API/Migrations/DataContextModelSnapshot.cs index d2ae13a7..1952adda 100644 --- a/CC.Yi.API/Migrations/DataContextModelSnapshot.cs +++ b/CC.Yi.API/Migrations/DataContextModelSnapshot.cs @@ -25,8 +25,8 @@ namespace CC.Yi.API.Migrations .HasColumnType("int") .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - b.Property("name") - .HasColumnType("int"); + b.Property("name") + .HasColumnType("nvarchar(max)"); b.HasKey("id"); diff --git a/CC.Yi.API/Program.cs b/CC.Yi.API/Program.cs index 5457af7a..970c28f8 100644 --- a/CC.Yi.API/Program.cs +++ b/CC.Yi.API/Program.cs @@ -1,5 +1,7 @@ +using CC.Yi.DAL; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; @@ -13,7 +15,22 @@ namespace CC.Yi.API { public static void Main(string[] args) { - CreateHostBuilder(args).Build().Run(); + var host = CreateHostBuilder(args).Build(); + var scope = host.Services.CreateScope(); + { + var services = scope.ServiceProvider; + try + { + var context = services.GetRequiredService(); + DbContentFactory.Initialize(context); + } + catch (Exception ex) + { + var logger = services.GetRequiredService>(); + logger.LogError(ex, "An error occurred while seeding the database."); + } + } + host.Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => diff --git a/CC.Yi.API/appsettings.json b/CC.Yi.API/appsettings.json index 8fcd04df..0112e26e 100644 --- a/CC.Yi.API/appsettings.json +++ b/CC.Yi.API/appsettings.json @@ -8,5 +8,5 @@ }, "AllowedHosts": "*", "ConnectionStringBySQL": "server=.;Database=cctest;UId=sa;PWD=Qz52013142020.", - "ConnectionStringByMySQL": "Data Source=49.235.212.122;Database=GraduationProject;User ID=root;Password=Qz52013142020.;pooling=true;port=3306;sslmode=none;CharSet=utf8;" + "ConnectionStringByMySQL": "Data Source=.;Database=cctest;User ID=root;Password=Qz52013142020.;pooling=true;port=3306;sslmode=none;CharSet=utf8;" } diff --git a/CC.Yi.BLL/BaseBll.cs b/CC.Yi.BLL/BaseBll.cs index 5e7a1a4f..908a6b28 100644 --- a/CC.Yi.BLL/BaseBll.cs +++ b/CC.Yi.BLL/BaseBll.cs @@ -15,6 +15,7 @@ namespace CC.Yi.BLL { CurrentDal = cd; } + public IQueryable GetAllEntities() { return CurrentDal.GetAllEntities(); @@ -49,12 +50,24 @@ namespace CC.Yi.BLL return entity; } + public bool Add(IEnumerable entities) + { + CurrentDal.AddRange(entities); + return DbSession.SaveChanges() > 0; + } + public bool Update(T entity) { CurrentDal.Update(entity); return DbSession.SaveChanges() > 0; } + public bool Update(T entity, params string[] propertyNames) + { + CurrentDal.Update(entity,propertyNames); + return DbSession.SaveChanges() > 0; + } + public bool Delete(T entity) { CurrentDal.Delete(entity); @@ -73,14 +86,24 @@ namespace CC.Yi.BLL return DbSession.SaveChanges() > 0; } - public int DeleteList(List ids) + public bool Delete(IEnumerable ids) { foreach (var id in ids) { CurrentDal.Detete(id); } - return DbSession.SaveChanges();//这里把SaveChanges方法提到了循环体外,自然就与数据库交互一次 + return DbSession.SaveChanges()>0; } + public bool Delete(Expression> where) + { + IQueryable entities = CurrentDal.GetEntities(where); + if (entities != null) + { + CurrentDal.DeteteRange(entities); + return DbSession.SaveChanges()>0; + } + return false; + } } } diff --git a/CC.Yi.DAL/BaseDal.cs b/CC.Yi.DAL/BaseDal.cs index 70e00edd..4839e885 100644 --- a/CC.Yi.DAL/BaseDal.cs +++ b/CC.Yi.DAL/BaseDal.cs @@ -1,7 +1,9 @@ using CC.Yi.IDAL; using CC.Yi.Model; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.ChangeTracking; using System; +using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -9,10 +11,9 @@ namespace CC.Yi.DAL { public class BaseDal : IBaseDal where T : class, new() { - public DataContext Db; - public BaseDal(DataContext _Db) + public DbContext Db { - Db = _Db; + get { return DbContentFactory.GetCurrentDbContent(); } } public IQueryable GetEntities(Expression> whereLambda) { @@ -65,6 +66,11 @@ namespace CC.Yi.DAL //Db.SaveChanges(); return entity; } + public bool AddRange(IEnumerable entities) + { + Db.Set().AddRange(entities); + return true; + } public bool Update(T entity) { @@ -73,7 +79,16 @@ namespace CC.Yi.DAL //return Db.SaveChanges() > 0; return true; } - + public bool Update(T entity, params string[] propertyNames) + { + EntityEntry entry = Db.Entry(entity); + entry.State = EntityState.Unchanged; + foreach (var item in propertyNames) + { + entry.Property(item).IsModified = true; + } + return true; + } public bool Delete(T entity) { @@ -87,6 +102,12 @@ namespace CC.Yi.DAL Db.Set().Remove(entity);//由于这里先Find找到了实体,所以这里可以用Remove标记该实体要移除(删除)。如果不是先Find到实体就需要用System.Data.Entity.EntityState.Deleted return true; } + public bool DeteteRange(IEnumerable entity) + { + Db.Set().RemoveRange(entity); + return true; + } + } } diff --git a/CC.Yi.DAL/DbContentFactory.cs b/CC.Yi.DAL/DbContentFactory.cs index a89b3cb8..9ca47789 100644 --- a/CC.Yi.DAL/DbContentFactory.cs +++ b/CC.Yi.DAL/DbContentFactory.cs @@ -8,43 +8,36 @@ namespace CC.Yi.DAL { public class DbContentFactory { - private static DataContext Webcontext; - - public DbContentFactory(DataContext webContext) + private static DataContext Webcontext; + public static void Initialize(DataContext webContext) { Webcontext = webContext; } - - //public static void Initialize(DataContext webContext) - //{ - // Webcontext = webContext; - //} public static DataContext GetCurrentDbContent() { - ////return new DataModelContainer(); - ////一次请求共用一个上下文实例 - ////每一次http请求都会开启一个新的线程,保证在一个线程中,DbContext是唯一的 - ////CallContext:是线程内部唯一的数据槽(一块内存空间/容器),相当于一个键值对数据容器,通过key获取value了,需要引入System.Runtime.Remoting.Messaging;命名空间 - //DbContext db = CallContext.GetData("DbContext") as DbContext; - ////从 CallContext 中检索具有指定key“DbContext”的对象,并强转为DbContext - //if (db == null)//线程在数据槽里面没有此上下文 - //{ - // db = Webcontext; - // CallContext.SetData("DbContext", db);//放到数据槽中去,DbContext是key,db是value - //} - //return db; - return Webcontext; + //return new DataModelContainer(); + //一次请求共用一个上下文实例 + //每一次http请求都会开启一个新的线程,保证在一个线程中,DbContext是唯一的 + //CallContext:是线程内部唯一的数据槽(一块内存空间/容器),相当于一个键值对数据容器,通过key获取value了,需要引入System.Runtime.Remoting.Messaging;命名空间 + DataContext db = CallContext.GetData("DbContext") as DataContext; + //从 CallContext 中检索具有指定key“DbContext”的对象,并强转为DbContext + if (db == null)//线程在数据槽里面没有此上下文 + { + db = Webcontext; + CallContext.SetData("DbContext", db);//放到数据槽中去,DbContext是key,db是value + } + return db; } - //private static class CallContext - //{ - // static ConcurrentDictionary> state = new ConcurrentDictionary>(); + private static class CallContext + { + static ConcurrentDictionary> state = new ConcurrentDictionary>(); - // public static void SetData(string name, object data) => - // state.GetOrAdd(name, _ => new AsyncLocal()).Value = data; + public static void SetData(string name, object data) => + state.GetOrAdd(name, _ => new AsyncLocal()).Value = data; - // public static object GetData(string name) => - // state.TryGetValue(name, out AsyncLocal data) ? data.Value : null; - //} + public static object GetData(string name) => + state.TryGetValue(name, out AsyncLocal data) ? data.Value : null; + } } } diff --git a/CC.Yi.DAL/T4DAL.cs b/CC.Yi.DAL/T4DAL.cs index e4656a91..ad7c9133 100644 --- a/CC.Yi.DAL/T4DAL.cs +++ b/CC.Yi.DAL/T4DAL.cs @@ -8,8 +8,5 @@ namespace CC.Yi.DAL { public partial class studentDal : BaseDal, IstudentDal { - public studentDal(DataContext _Db) : base(_Db) - { - } } } \ No newline at end of file diff --git a/CC.Yi.DAL/T4DAL.tt b/CC.Yi.DAL/T4DAL.tt index bd65067b..618fe8e4 100644 --- a/CC.Yi.DAL/T4DAL.tt +++ b/CC.Yi.DAL/T4DAL.tt @@ -25,9 +25,6 @@ namespace CC.Yi.DAL #> public partial class <#=k #>Dal : BaseDal<<#=k #>>, I<#=k #>Dal { - public <#=k #>Dal(DataContext _Db) : base(_Db) - { - } } <# } #> } \ No newline at end of file diff --git a/CC.Yi.DALFactory/T4StaticDalFactory.cs b/CC.Yi.DALFactory/T4StaticDalFactory.cs index 2733dbb1..9b6f14b9 100644 --- a/CC.Yi.DALFactory/T4StaticDalFactory.cs +++ b/CC.Yi.DALFactory/T4StaticDalFactory.cs @@ -15,7 +15,7 @@ namespace CC.Yi.DALFactory IstudentDal Data = CallContext.GetData("studentDal") as IstudentDal; if (Data == null) { - Data = new studentDal(DbSessionFactory.GetCurrentDbSession().GetDbContent()); + Data = new studentDal(); CallContext.SetData("studentDal", Data); } return Data; diff --git a/CC.Yi.DALFactory/T4StaticDalFactory.tt b/CC.Yi.DALFactory/T4StaticDalFactory.tt index 40388a29..f6194b8f 100644 --- a/CC.Yi.DALFactory/T4StaticDalFactory.tt +++ b/CC.Yi.DALFactory/T4StaticDalFactory.tt @@ -32,7 +32,7 @@ namespace CC.Yi.DALFactory I<#=k #>Dal Data = CallContext.GetData("<#=k #>Dal") as I<#=k #>Dal; if (Data == null) { - Data = new <#=k #>Dal(DbSessionFactory.GetCurrentDbSession().GetDbContent()); + Data = new <#=k #>Dal(); CallContext.SetData("<#=k #>Dal", Data); } return Data; diff --git a/CC.Yi.IBLL/IBaseBll.cs b/CC.Yi.IBLL/IBaseBll.cs index dae45507..456c9be7 100644 --- a/CC.Yi.IBLL/IBaseBll.cs +++ b/CC.Yi.IBLL/IBaseBll.cs @@ -11,6 +11,7 @@ namespace CC.Yi.IBLL //得到全部实体 #endregion IQueryable GetAllEntities(); + #region //通过表达式得到实体 #endregion @@ -36,11 +37,21 @@ namespace CC.Yi.IBLL #endregion T Add(T entity); + #region + //添加多个实体 + #endregion + bool Add(IEnumerable entities); + #region //更新实体 #endregion bool Update(T entity); + #region + //更新实体部分属性 + #endregion + bool Update(T entity, params string[] propertyNames); + #region //删除实体 #endregion @@ -54,6 +65,11 @@ namespace CC.Yi.IBLL #region //通过id列表删除多个实体 #endregion - int DeleteList(List ids); + bool Delete(IEnumerable ids); + + #region + //通过表达式删除实体 + #endregion + bool Delete(Expression> where); } } diff --git a/CC.Yi.IDAL/IBaseDal.cs b/CC.Yi.IDAL/IBaseDal.cs index a7b2d0cd..f4daf158 100644 --- a/CC.Yi.IDAL/IBaseDal.cs +++ b/CC.Yi.IDAL/IBaseDal.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -36,11 +37,20 @@ namespace CC.Yi.IDAL #endregion T Add(T entity); + #region + //添加多个实体 + #endregion + bool AddRange(IEnumerable entities); #region //更新单个实体 #endregion bool Update(T entity); + #region + //更新单个实体部分属性 + #endregion + bool Update(T entity, params string[] propertyNames); + #region //删除单个实体 #endregion @@ -50,5 +60,10 @@ namespace CC.Yi.IDAL //通过id删除实体 #endregion bool Detete(int id); + + #region + //删除多个实体 + #endregion + bool DeteteRange(IEnumerable entity); } } diff --git a/CC.Yi.Model/student.cs b/CC.Yi.Model/student.cs index 8a11819c..90ee09b7 100644 --- a/CC.Yi.Model/student.cs +++ b/CC.Yi.Model/student.cs @@ -11,6 +11,6 @@ namespace CC.Yi.Model [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int id { get; set; } - public int name { get; set; } + public string name { get; set; } } } From 5e7cc088174142cece1adb8f7dbdbb0f9eb33813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sat, 20 Mar 2021 22:20:34 +0800 Subject: [PATCH 02/31] add README.md. --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..3fd34654 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# CC.Yi + +#### 介绍 +基于.NET的MVC三成架构的框架--Yi意框架(意义是为了开发更简易) + +#### 软件架构 +软件架构说明 +开发完成时间:2021/3/19 +请记住,这是一个值得纪念的日子 + +我们将在之后更新教程手册! +#### 安装教程 + +1. xxxx +2. xxxx +3. xxxx + +#### 使用说明 + +1. xxxx +2. xxxx +3. xxxx + + From d4c5d89763792ae86721791e098694e9059c0ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sat, 20 Mar 2021 22:23:31 +0800 Subject: [PATCH 03/31] add LICENSE. --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..29f81d81 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 1ecb92df332745894383d0f233c00a41864f67ae Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Sun, 21 Mar 2021 02:13:08 +0800 Subject: [PATCH 04/31] v1.0.2 --- CC.Yi.API/CC.Yi.API.csproj | 2 ++ CC.Yi.API/Program.cs | 3 ++- CC.Yi.API/Startup.cs | 17 +++++++++++++++-- CC.Yi.Common/CC.Yi.Common.csproj | 2 ++ CC.Yi.Common/Castle/CustomAutofacAop.cs | 23 +++++++++++++++++++++++ CC.Yi.IBLL/CC.Yi.IBLL.csproj | 1 + CC.Yi.IBLL/IBaseBll.cs | 5 ++++- 7 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 CC.Yi.Common/Castle/CustomAutofacAop.cs diff --git a/CC.Yi.API/CC.Yi.API.csproj b/CC.Yi.API/CC.Yi.API.csproj index 4e2559a2..697c4d89 100644 --- a/CC.Yi.API/CC.Yi.API.csproj +++ b/CC.Yi.API/CC.Yi.API.csproj @@ -5,6 +5,8 @@ + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CC.Yi.API/Program.cs b/CC.Yi.API/Program.cs index 970c28f8..f10b5838 100644 --- a/CC.Yi.API/Program.cs +++ b/CC.Yi.API/Program.cs @@ -1,3 +1,4 @@ +using Autofac.Extensions.DependencyInjection; using CC.Yi.DAL; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; @@ -38,6 +39,6 @@ namespace CC.Yi.API .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); - }); + }).UseServiceProviderFactory(new AutofacServiceProviderFactory()); } } diff --git a/CC.Yi.API/Startup.cs b/CC.Yi.API/Startup.cs index fe9446c4..ec647137 100644 --- a/CC.Yi.API/Startup.cs +++ b/CC.Yi.API/Startup.cs @@ -1,5 +1,8 @@ +using Autofac; +using Autofac.Extras.DynamicProxy; using CC.Yi.BLL; +using CC.Yi.Common.Castle; using CC.Yi.DAL; using CC.Yi.IBLL; using CC.Yi.IDAL; @@ -45,8 +48,18 @@ namespace CC.Yi.API { options.UseSqlServer(connection, b => b.MigrationsAssembly("CC.Yi.API"));//ݿ }); - services.AddScoped(typeof(IBaseDal<>), typeof(BaseDal<>)); - services.AddScoped(typeof(IstudentBll), typeof(studentBll)); + //עתAutofac + //services.AddScoped(typeof(IBaseDal<>), typeof(BaseDal<>)); + //services.AddScoped(typeof(IstudentBll), typeof(studentBll)); + } + + //̬ AOP˼ע Autofac + public void ConfigureContainer(ContainerBuilder builder) + { + builder.RegisterType(typeof(CustomAutofacAop)); + builder.RegisterGeneric(typeof(BaseDal<>)).As(typeof(IBaseDal<>)) ; + builder.RegisterType().As().EnableInterfaceInterceptors();//ʾעǰҪִCastle + } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/CC.Yi.Common/CC.Yi.Common.csproj b/CC.Yi.Common/CC.Yi.Common.csproj index a20524d3..efd8020e 100644 --- a/CC.Yi.Common/CC.Yi.Common.csproj +++ b/CC.Yi.Common/CC.Yi.Common.csproj @@ -5,6 +5,8 @@ + + diff --git a/CC.Yi.Common/Castle/CustomAutofacAop.cs b/CC.Yi.Common/Castle/CustomAutofacAop.cs new file mode 100644 index 00000000..526d39ef --- /dev/null +++ b/CC.Yi.Common/Castle/CustomAutofacAop.cs @@ -0,0 +1,23 @@ +using Castle.DynamicProxy; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CC.Yi.Common.Castle +{ + public class CustomAutofacAop : IInterceptor + { + public void Intercept(IInvocation invocation) + { + { + + //这里写执行方法前 + } + invocation.Proceed();//执行具体的实例 + { + + //这里写执行方法后 + } + } + } +} diff --git a/CC.Yi.IBLL/CC.Yi.IBLL.csproj b/CC.Yi.IBLL/CC.Yi.IBLL.csproj index 54b41008..778e1962 100644 --- a/CC.Yi.IBLL/CC.Yi.IBLL.csproj +++ b/CC.Yi.IBLL/CC.Yi.IBLL.csproj @@ -6,6 +6,7 @@ + diff --git a/CC.Yi.IBLL/IBaseBll.cs b/CC.Yi.IBLL/IBaseBll.cs index 456c9be7..ff781ea7 100644 --- a/CC.Yi.IBLL/IBaseBll.cs +++ b/CC.Yi.IBLL/IBaseBll.cs @@ -1,10 +1,13 @@ -using System; +using Autofac.Extras.DynamicProxy; +using CC.Yi.Common.Castle; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace CC.Yi.IBLL { + [Intercept(typeof(CustomAutofacAop))] public interface IBaseBll where T : class, new() { #region From 27d352f62e39c4f498e75cf49ed996ce13d40ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sun, 21 Mar 2021 02:34:22 +0800 Subject: [PATCH 05/31] update README.md. --- README.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3fd34654..5289a3ab 100644 --- a/README.md +++ b/README.md @@ -2,23 +2,38 @@ #### 介绍 基于.NET的MVC三成架构的框架--Yi意框架(意义是为了开发更简易) +第一版开发完成时间:2021/3/19 (请记住,这是一个值得纪念的日子) + #### 软件架构 -软件架构说明 -开发完成时间:2021/3/19 -请记住,这是一个值得纪念的日子 +架构:.NET5 +mysql+sql server(后期我们将集成数据+前端Vue,让开发更加简易!) +操作系统:Windows,Linux +扩展:EFcore,Autofac,Castle,HttpRuntimeCache,Memcache,Redis,Swagger,T4 (后期我们会添加更多) +封装:Json处理模块,滑动验证码模块,base64图片处理模块(后期我们会添加更多) +思想:简单工厂模式,抽象工厂模式,观察者模式,面向AOP思想,面向对象开发 + + +#### 目录结构 +Model:模型层(first code代码优先添加模型,数据自动生成) +DAL:数据处理层(处理数据但并未加载进内存) +BLL:业务逻辑层(数据的逻辑将在这层处理) +Common:工具层(工具人层,方法已封装,一键调用) +API:接口层(接入Swagger,可视化测试接口) + -我们将在之后更新教程手册! #### 安装教程 - +我们将在之后更新教程手册! 1. xxxx 2. xxxx 3. xxxx #### 使用说明 - +我们将在之后更新教程手册! 1. xxxx 2. xxxx 3. xxxx +#### 联系我们: +QQ:454313500 + From d4708ed7ed8338ba9d3965bf7e800996d16d1b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sun, 21 Mar 2021 02:34:55 +0800 Subject: [PATCH 06/31] update README.md. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5289a3ab..3dcb8800 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ #### 介绍 基于.NET的MVC三成架构的框架--Yi意框架(意义是为了开发更简易) + 第一版开发完成时间:2021/3/19 (请记住,这是一个值得纪念的日子) From 2faf72c46e8f23a860285bf6459fa29522e9dc8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sun, 21 Mar 2021 02:35:20 +0800 Subject: [PATCH 07/31] update README.md. --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 3dcb8800..6d3958b1 100644 --- a/README.md +++ b/README.md @@ -8,28 +8,38 @@ #### 软件架构 架构:.NET5 +mysql+sql server(后期我们将集成数据+前端Vue,让开发更加简易!) + 操作系统:Windows,Linux + 扩展:EFcore,Autofac,Castle,HttpRuntimeCache,Memcache,Redis,Swagger,T4 (后期我们会添加更多) + 封装:Json处理模块,滑动验证码模块,base64图片处理模块(后期我们会添加更多) + 思想:简单工厂模式,抽象工厂模式,观察者模式,面向AOP思想,面向对象开发 #### 目录结构 Model:模型层(first code代码优先添加模型,数据自动生成) + DAL:数据处理层(处理数据但并未加载进内存) + BLL:业务逻辑层(数据的逻辑将在这层处理) + Common:工具层(工具人层,方法已封装,一键调用) + API:接口层(接入Swagger,可视化测试接口) #### 安装教程 我们将在之后更新教程手册! + 1. xxxx 2. xxxx 3. xxxx #### 使用说明 我们将在之后更新教程手册! + 1. xxxx 2. xxxx 3. xxxx From 26f45303c35a0fa070fa4a734f21500b0fe58f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sun, 21 Mar 2021 02:37:31 +0800 Subject: [PATCH 08/31] update README.md. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6d3958b1..6f87b456 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ #### 目录结构 +![输入图片说明](https://images.gitee.com/uploads/images/2021/0321/023715_59bef411_3049273.png "屏幕截图.png") Model:模型层(first code代码优先添加模型,数据自动生成) DAL:数据处理层(处理数据但并未加载进内存) From 055d34737a03c6ac7befb4ff9cbace80020a6766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sun, 21 Mar 2021 02:37:46 +0800 Subject: [PATCH 09/31] update README.md. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6f87b456..47683dab 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ #### 目录结构 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0321/023715_59bef411_3049273.png "屏幕截图.png") + Model:模型层(first code代码优先添加模型,数据自动生成) DAL:数据处理层(处理数据但并未加载进内存) From 0d6e84a00aa09c1d445ac894f1d8d23f1f9b0ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sun, 21 Mar 2021 15:17:11 +0800 Subject: [PATCH 10/31] update README.md. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 47683dab..e3ad670b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ 操作系统:Windows,Linux -扩展:EFcore,Autofac,Castle,HttpRuntimeCache,Memcache,Redis,Swagger,T4 (后期我们会添加更多) +扩展:EFcore,Autofac,Castle,Memcache,Redis,Swagger,T4 (后期我们会添加更多) 封装:Json处理模块,滑动验证码模块,base64图片处理模块(后期我们会添加更多) From bfcc162e2fd3793deb231ad0635b42010e449e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sun, 21 Mar 2021 15:26:35 +0800 Subject: [PATCH 11/31] update README.md. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e3ad670b..03783808 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ 操作系统:Windows,Linux -扩展:EFcore,Autofac,Castle,Memcache,Redis,Swagger,T4 (后期我们会添加更多) +扩展:EFcore,Autofac,Castle,Redis,Swagger,T4 (后期我们会添加更多) 封装:Json处理模块,滑动验证码模块,base64图片处理模块(后期我们会添加更多) From dc4429d66c68b0bf2c190e8b6a5f2d4e6e707575 Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Sun, 21 Mar 2021 15:51:49 +0800 Subject: [PATCH 12/31] v1.0.3 --- CC.Yi.API/Controllers/StudentController.cs | 2 +- CC.Yi.API/Startup.cs | 7 +- CC.Yi.API/appsettings.json | 4 + CC.Yi.Common/CC.Yi.Common.csproj | 3 +- CC.Yi.Common/Cache/CacheHelper.cs | 53 ++++++++++ CC.Yi.Common/Cache/ICacheWriter.cs | 31 ++++++ CC.Yi.Common/Cache/RedisCacheService.cs | 96 +++++++++++++++++++ .../{JsonFactory.cs => JsonHelper.cs} | 2 +- 8 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 CC.Yi.Common/Cache/CacheHelper.cs create mode 100644 CC.Yi.Common/Cache/ICacheWriter.cs create mode 100644 CC.Yi.Common/Cache/RedisCacheService.cs rename CC.Yi.Common/{JsonFactory.cs => JsonHelper.cs} (84%) diff --git a/CC.Yi.API/Controllers/StudentController.cs b/CC.Yi.API/Controllers/StudentController.cs index 41de2620..66fc4c0b 100644 --- a/CC.Yi.API/Controllers/StudentController.cs +++ b/CC.Yi.API/Controllers/StudentController.cs @@ -30,7 +30,7 @@ namespace CC.Yi.API.Controllers public IActionResult GetTest()//查 { var data = _studentBll.GetAllEntities().ToList(); - return Content(Common.JsonFactory.JsonToString(data)); + return Content(Common.JsonHelper.JsonToString(data)); } [HttpGet] public IActionResult AddTest()//增 diff --git a/CC.Yi.API/Startup.cs b/CC.Yi.API/Startup.cs index ec647137..3206fc1c 100644 --- a/CC.Yi.API/Startup.cs +++ b/CC.Yi.API/Startup.cs @@ -2,6 +2,7 @@ using Autofac; using Autofac.Extras.DynamicProxy; using CC.Yi.BLL; +using CC.Yi.Common.Cache; using CC.Yi.Common.Castle; using CC.Yi.DAL; using CC.Yi.IBLL; @@ -51,6 +52,11 @@ namespace CC.Yi.API //עתAutofac //services.AddScoped(typeof(IBaseDal<>), typeof(BaseDal<>)); //services.AddScoped(typeof(IstudentBll), typeof(studentBll)); + services.AddSingleton(typeof(ICacheWriter), new RedisCacheService(new Microsoft.Extensions.Caching.Redis.RedisCacheOptions() + { + Configuration = Configuration.GetSection("Cache.ConnectionString").Value, + InstanceName = Configuration.GetSection("Cache.InstanceName").Value + })); } //̬ AOP˼ע Autofac @@ -59,7 +65,6 @@ namespace CC.Yi.API builder.RegisterType(typeof(CustomAutofacAop)); builder.RegisterGeneric(typeof(BaseDal<>)).As(typeof(IBaseDal<>)) ; builder.RegisterType().As().EnableInterfaceInterceptors();//ʾעǰҪִCastle - } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/CC.Yi.API/appsettings.json b/CC.Yi.API/appsettings.json index 0112e26e..b5156473 100644 --- a/CC.Yi.API/appsettings.json +++ b/CC.Yi.API/appsettings.json @@ -7,6 +7,10 @@ } }, "AllowedHosts": "*", + "Cache": { + "InstanceName": "Redis", + "ConnectionString": "127.0.0.1:12345,password=123456" + }, "ConnectionStringBySQL": "server=.;Database=cctest;UId=sa;PWD=Qz52013142020.", "ConnectionStringByMySQL": "Data Source=.;Database=cctest;User ID=root;Password=Qz52013142020.;pooling=true;port=3306;sslmode=none;CharSet=utf8;" } diff --git a/CC.Yi.Common/CC.Yi.Common.csproj b/CC.Yi.Common/CC.Yi.Common.csproj index efd8020e..4230a367 100644 --- a/CC.Yi.Common/CC.Yi.Common.csproj +++ b/CC.Yi.Common/CC.Yi.Common.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 @@ -7,6 +7,7 @@ + diff --git a/CC.Yi.Common/Cache/CacheHelper.cs b/CC.Yi.Common/Cache/CacheHelper.cs new file mode 100644 index 00000000..0bc435b0 --- /dev/null +++ b/CC.Yi.Common/Cache/CacheHelper.cs @@ -0,0 +1,53 @@ +using Autofac; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CC.Yi.Common.Cache +{ + public class CacheHelper + { + public static ICacheWriter CacheWriter { get; set; } + static CacheHelper() + { + + //这里存在一些问题 + ContainerBuilder containerBuilder = new ContainerBuilder(); + IContainer container = containerBuilder.Build(); + CacheHelper.CacheWriter = container.Resolve(); + } + + public static void AddCache(string key, string value, int expDate) + { + CacheWriter.Add(key, value, expDate); + } + + //没有过期参数,表示用不过期 + public static void AddCache(string key, string value) + { + CacheWriter.Add(key, value); + } + + public static object GetCache(string key) + { + return CacheWriter.Get(key); + } + public static void SetCache(string key, string value, int expDate) + { + + CacheWriter.Replace(key, value, expDate); + } + + //没有过期参数,表示用不过期 + public static void SetCache(string key, string value) + { + CacheWriter.Replace(key, value); + } + + public static void Remove(string key) + { + CacheWriter.Remove(key); + } + + } +} diff --git a/CC.Yi.Common/Cache/ICacheWriter.cs b/CC.Yi.Common/Cache/ICacheWriter.cs new file mode 100644 index 00000000..21a6c943 --- /dev/null +++ b/CC.Yi.Common/Cache/ICacheWriter.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CC.Yi.Common.Cache +{ + public interface ICacheWriter + { + //void AddCache(string key, object value, DateTime expDate); + //void AddCache(string key, object value); + //object GetCache(string key); + //T GetCache(string key); + //void SetCache(string key, object value, DateTime expDate); + //void SetCache(string key, object value); + //bool Delete(string key); + + string Get(string key); + + string GetString(string key); + + void AddString(string key, string value); + + void Add(string key, string value, int ExpirationTime = 20); + + void Remove(string key); + + void Replace(string key, string value, int ExpirationTime = 20); + } +} diff --git a/CC.Yi.Common/Cache/RedisCacheService.cs b/CC.Yi.Common/Cache/RedisCacheService.cs new file mode 100644 index 00000000..c4dd22e9 --- /dev/null +++ b/CC.Yi.Common/Cache/RedisCacheService.cs @@ -0,0 +1,96 @@ +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Caching.Redis; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CC.Yi.Common.Cache +{ + public class RedisCacheService :ICacheWriter + { + private RedisCache _redisCache = null; + public RedisCacheService(RedisCacheOptions options) + { + _redisCache = new RedisCache(options); + } + /// + /// 获取缓存 + /// + /// 缓存key + /// + public string Get(string key) + { + try + { + if (!string.IsNullOrEmpty(key)) + { + return Encoding.UTF8.GetString(_redisCache.Get(key)); + } + else + { + return string.Empty; + } + } + catch + { + return null; + } + } + /// + /// 添加缓存 + /// + /// 缓存key + /// 缓存值 + /// 绝对过期时间(分钟) + public void Add(string key, string value, int ExpirationTime = 20) + { + if (!string.IsNullOrEmpty(key)) + { + _redisCache.Set(key, Encoding.UTF8.GetBytes(value), new DistributedCacheEntryOptions() + { + AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(ExpirationTime) + }); + } + } + + public void AddString(string key, string value) + { + _redisCache.SetString(key, value); + } + + public string GetString(string key) + + { + return _redisCache.GetString(key); + } + + /// + /// 移除缓存 + /// + /// 缓存key + public void Remove(string key) + { + if (!string.IsNullOrEmpty(key)) + { + _redisCache.Remove(key); + } + } + /// + /// 更新缓存 + /// + /// 缓存key + /// 缓存值 + /// + public void Replace(string key, string value, int ExpirationTime = 20) + { + if (!string.IsNullOrEmpty(key)) + { + _redisCache.Remove(key); + _redisCache.Set(key, Encoding.UTF8.GetBytes(value), new DistributedCacheEntryOptions() + { + AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(ExpirationTime) + }); + } + } + } +} diff --git a/CC.Yi.Common/JsonFactory.cs b/CC.Yi.Common/JsonHelper.cs similarity index 84% rename from CC.Yi.Common/JsonFactory.cs rename to CC.Yi.Common/JsonHelper.cs index f51b56c4..b427195b 100644 --- a/CC.Yi.Common/JsonFactory.cs +++ b/CC.Yi.Common/JsonHelper.cs @@ -2,7 +2,7 @@ namespace CC.Yi.Common { - public static class JsonFactory + public static class JsonHelper { public static string JsonToString(object q) { From da68f9255dd677b6e816f661f71ce03957001436 Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Mon, 22 Mar 2021 10:28:36 +0800 Subject: [PATCH 13/31] v1.0.4 --- CC.Yi.Common/CC.Yi.Common.csproj | 1 + CC.Yi.Common/HttpHelper.cs | 76 ++++++++++++++ CC.Yi.Common/imageHelper.cs | 167 +++++++++++++++++++++++++++++++ 3 files changed, 244 insertions(+) create mode 100644 CC.Yi.Common/HttpHelper.cs create mode 100644 CC.Yi.Common/imageHelper.cs diff --git a/CC.Yi.Common/CC.Yi.Common.csproj b/CC.Yi.Common/CC.Yi.Common.csproj index 4230a367..3e6d258d 100644 --- a/CC.Yi.Common/CC.Yi.Common.csproj +++ b/CC.Yi.Common/CC.Yi.Common.csproj @@ -9,6 +9,7 @@ + diff --git a/CC.Yi.Common/HttpHelper.cs b/CC.Yi.Common/HttpHelper.cs new file mode 100644 index 00000000..6bfdfb18 --- /dev/null +++ b/CC.Yi.Common/HttpHelper.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace CC.Yi.Common +{ + public static class HttpHelper + { + public static string HttpGet(string Url, string postDataStr="") + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr); + request.Method = "GET"; + request.ContentType = "text/html;charset=UTF-8"; + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + Stream myResponseStream = response.GetResponseStream(); + StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); + string retString = myStreamReader.ReadToEnd(); + myStreamReader.Close(); + myResponseStream.Close(); + + return retString; + } + + public static bool HttpIOGet(string Url, string file, string postDataStr="") + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr); + request.Method = "GET"; + request.ContentType = "text/html;charset=UTF-8"; + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + Stream myResponseStream = response.GetResponseStream(); + FileStream writer = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write); + byte[] buffer = new byte[1024]; + int c; + while ((c = myResponseStream.Read(buffer, 0, buffer.Length)) > 0) + { + writer.Write(buffer, 0, c); + } + writer.Close(); + myResponseStream.Close(); + + return true; + } + + public static string HttpPost(string Url, string postDataStr="") + { + CookieContainer cookie = new CookieContainer(); + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); + request.Method = "POST"; + request.ContentType = "application/x-www-form-urlencoded"; + request.ContentLength = Encoding.UTF8.GetByteCount(postDataStr); + request.CookieContainer = cookie; + Stream myRequestStream = request.GetRequestStream(); + StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312")); + myStreamWriter.Write(postDataStr); + myStreamWriter.Close(); + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + + response.Cookies = cookie.GetCookies(response.ResponseUri); + Stream myResponseStream = response.GetResponseStream(); + StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); + string retString = myStreamReader.ReadToEnd(); + myStreamReader.Close(); + myResponseStream.Close(); + + return retString; + } + } +} diff --git a/CC.Yi.Common/imageHelper.cs b/CC.Yi.Common/imageHelper.cs new file mode 100644 index 00000000..170aba9c --- /dev/null +++ b/CC.Yi.Common/imageHelper.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.IO; +using System.IO.Compression; +using System.Drawing; + +namespace CC.Yi.Common +{ + public class SimilarPhoto + { + Image SourceImg; + public SimilarPhoto(string filePath) + { + SourceImg = Image.FromFile(filePath); + } + public SimilarPhoto(Stream stream) + { + SourceImg = Image.FromStream(stream); + } + public String GetHash() + { + Image image = ReduceSize(); + Byte[] grayValues = ReduceColor(image); + Byte average = CalcAverage(grayValues); + String reslut = ComputeBits(grayValues, average); + return reslut; + } + // Step 1 : Reduce size to 8*8 + private Image ReduceSize(int width = 8, int height = 8) + { + Image image = SourceImg.GetThumbnailImage(width, height, () => { return false; }, IntPtr.Zero); + return image; + } + // Step 2 : Reduce Color + private Byte[] ReduceColor(Image image) + { + Bitmap bitMap = new Bitmap(image); + Byte[] grayValues = new Byte[image.Width * image.Height]; + for (int x = 0; x < image.Width; x++) + for (int y = 0; y < image.Height; y++) + { + Color color = bitMap.GetPixel(x, y); + byte grayValue = (byte)((color.R * 30 + color.G * 59 + color.B * 11) / 100); + grayValues[x * image.Width + y] = grayValue; + } + return grayValues; + } + // Step 3 : Average the colors + private Byte CalcAverage(byte[] values) + { + int sum = 0; + for (int i = 0; i < values.Length; i++) + sum += (int)values[i]; + return Convert.ToByte(sum / values.Length); + } + // Step 4 : Compute the bits + private String ComputeBits(byte[] values, byte averageValue) + { + char[] result = new char[values.Length]; + for (int i = 0; i < values.Length; i++) + { + if (values[i] < averageValue) + result[i] = '0'; + else + result[i] = '1'; + } + SourceImg.Dispose(); + return new String(result); + } + // Compare hash + public static Int32 CalcSimilarDegree(string a, string b) + { + if (a.Length != b.Length) + throw new ArgumentException(); + int count = 0; + for (int i = 0; i < a.Length; i++) + { + if (a[i] != b[i]) + count++; + } + return count; + } + } + public static class imageHelper + { + public static int Compare(string filePath1, string filePath2) + { + SimilarPhoto photo1 = new SimilarPhoto(filePath1); + SimilarPhoto photo2 = new SimilarPhoto(filePath2); + return SimilarPhoto.CalcSimilarDegree(photo1.GetHash(), photo2.GetHash()); + } + public static bool ByStringToSave(string name, string iss) + { + iss = iss.Replace("data:image/png;base64,", "").Replace("data:image/jgp;base64,", "") + .Replace("data:image/jpg;base64,", "").Replace("data:image/jpeg;base64,", ""); + byte[] arr = Convert.FromBase64String(iss); + MemoryStream ms = new MemoryStream(arr); + Bitmap bmp = new Bitmap(ms); + string StudentWorkImages = "StudentWorkImages"; + + if (Directory.Exists(@"./wwwroot/" + StudentWorkImages) == false)//如果不存在就创建file文件夹 + { + Directory.CreateDirectory(@"./wwwroot/" + StudentWorkImages); + } + + + + bmp.Save(@"./wwwroot/" + StudentWorkImages + "/" + name + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg); + ms.Close(); + return true; + } + public static bool CreateZip() + { + string file_path = @"./wwwroot/StudentWorkImages.zip"; + string file_path2 = @"./wwwroot/StudentWorkImages/"; + if (File.Exists(file_path)) + { + File.Delete(file_path); + } + + ZipFile.CreateFromDirectory(file_path2, file_path); + return true; + } + public static bool DeleteAll() + { + string file_path = @"./wwwroot/StudentWorkImages/"; + if (Directory.Exists(file_path)) + { + DelectDir(file_path); + return true; + } + else + return false; + } + public static bool DeleteByString(string name) + { + File.Delete(@"./wwwroot/StudentWorkImages/" + name + ".jpg"); + return true; + } + public static void DelectDir(string srcPath) + { + try + { + DirectoryInfo dir = new DirectoryInfo(srcPath); + FileSystemInfo[] fileinfo = dir.GetFileSystemInfos(); //返回目录中所有文件和子目录 + foreach (FileSystemInfo i in fileinfo) + { + if (i is DirectoryInfo) //判断是否文件夹 + { + DirectoryInfo subdir = new DirectoryInfo(i.FullName); + subdir.Delete(true); //删除子目录和文件 + } + else + { + File.Delete(i.FullName); //删除指定文件 + } + } + } + catch (Exception e) + { + Console.Write(e.ToString()); + } + } + } +} From 82ffcb6f553fd81b7027c1fa92976c347ae4cd65 Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Tue, 23 Mar 2021 13:58:44 +0800 Subject: [PATCH 14/31] v1.0.5 --- CC.Yi.API/CC.Yi.API.csproj | 8 +++- CC.Yi.API/Controllers/StudentController.cs | 8 +++- CC.Yi.API/Program.cs | 46 +++++++++++++++------- CC.Yi.API/nlog.config | 35 ++++++++++++++++ CC.Yi.Common/CC.Yi.Common.csproj | 1 + 5 files changed, 81 insertions(+), 17 deletions(-) create mode 100644 CC.Yi.API/nlog.config diff --git a/CC.Yi.API/CC.Yi.API.csproj b/CC.Yi.API/CC.Yi.API.csproj index 697c4d89..25450b8f 100644 --- a/CC.Yi.API/CC.Yi.API.csproj +++ b/CC.Yi.API/CC.Yi.API.csproj @@ -1,4 +1,4 @@ - + net5.0 @@ -21,4 +21,10 @@ + + + Always + + + diff --git a/CC.Yi.API/Controllers/StudentController.cs b/CC.Yi.API/Controllers/StudentController.cs index 66fc4c0b..eaf61812 100644 --- a/CC.Yi.API/Controllers/StudentController.cs +++ b/CC.Yi.API/Controllers/StudentController.cs @@ -19,6 +19,7 @@ namespace CC.Yi.API.Controllers { _studentBll = studentBll; _logger = logger; + _logger.LogInformation("现在你进入了StudentController控制器"); } @@ -29,13 +30,15 @@ namespace CC.Yi.API.Controllers [HttpGet] public IActionResult GetTest()//查 { + _logger.LogInformation("调用查方法"); var data = _studentBll.GetAllEntities().ToList(); return Content(Common.JsonHelper.JsonToString(data)); } [HttpGet] public IActionResult AddTest()//增 { - List students = new List() {new student { name = "学生a" } ,new student { name="学生d"} }; + _logger.LogInformation("调用增方法"); + List students = new List() {new student { name = "学生a" } ,new student { name="学生d"} }; _studentBll.Add(students); return Content("ok"); @@ -43,7 +46,7 @@ namespace CC.Yi.API.Controllers [HttpGet] public IActionResult RemoveTest()//删 { - + _logger.LogInformation("调用删方法"); if (_studentBll.Delete(u=>u.name=="学生a")) { return Content("ok"); @@ -56,6 +59,7 @@ namespace CC.Yi.API.Controllers [HttpGet] public IActionResult UpdateTest()//改 { + _logger.LogInformation("调用改方法"); if (_studentBll.Update(new student { id=2, name = "学生a" }, "name")) { return Content("ok"); diff --git a/CC.Yi.API/Program.cs b/CC.Yi.API/Program.cs index f10b5838..83fc65fc 100644 --- a/CC.Yi.API/Program.cs +++ b/CC.Yi.API/Program.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using NLog.Web; using System; using System.Collections.Generic; using System.Linq; @@ -16,22 +17,33 @@ namespace CC.Yi.API { public static void Main(string[] args) { - var host = CreateHostBuilder(args).Build(); - var scope = host.Services.CreateScope(); + var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger(); + try { + logger.Debug("Yiܡ"); + var host = CreateHostBuilder(args).Build(); + var scope = host.Services.CreateScope(); var services = scope.ServiceProvider; - try - { - var context = services.GetRequiredService(); - DbContentFactory.Initialize(context); - } - catch (Exception ex) - { - var logger = services.GetRequiredService>(); - logger.LogError(ex, "An error occurred while seeding the database."); - } + var context = services.GetRequiredService();//ȡ + DbContentFactory.Initialize(context);//þ̬෽ע + host.Run(); + logger.Info("Yiɹ"); } - host.Run(); + catch (Exception exception) + { + //NLog: catch setup errors + logger.Error(exception, "Stopped program because of exception"); + throw; + } + finally + { + // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux) + NLog.LogManager.Shutdown(); + } + + + + } public static IHostBuilder CreateHostBuilder(string[] args) => @@ -39,6 +51,12 @@ namespace CC.Yi.API .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); - }).UseServiceProviderFactory(new AutofacServiceProviderFactory()); + }).UseServiceProviderFactory(new AutofacServiceProviderFactory()) + .ConfigureLogging(logging => + { + // logging.ClearProviders(); // п̨ + logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); + }).UseNLog(); + } } diff --git a/CC.Yi.API/nlog.config b/CC.Yi.API/nlog.config new file mode 100644 index 00000000..ff359770 --- /dev/null +++ b/CC.Yi.API/nlog.config @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CC.Yi.Common/CC.Yi.Common.csproj b/CC.Yi.Common/CC.Yi.Common.csproj index 3e6d258d..c1361bd4 100644 --- a/CC.Yi.Common/CC.Yi.Common.csproj +++ b/CC.Yi.Common/CC.Yi.Common.csproj @@ -9,6 +9,7 @@ + From b5ed74fabdd113aadfe85fa76f012e2138945cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Tue, 23 Mar 2021 14:07:37 +0800 Subject: [PATCH 15/31] update README.md. --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 03783808..ed114207 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ 操作系统:Windows,Linux -扩展:EFcore,Autofac,Castle,Redis,Swagger,T4 (后期我们会添加更多) +扩展:EFcore,Autofac,Castle,Redis,Swagger,T4 ,Nlog(后期我们会添加更多) 封装:Json处理模块,滑动验证码模块,base64图片处理模块(后期我们会添加更多) @@ -35,16 +35,17 @@ API:接口层(接入Swagger,可视化测试接口) #### 安装教程 我们将在之后更新教程手册! -1. xxxx -2. xxxx -3. xxxx +1. 下载全部源码 +2. 使用Visual Studio 2019在windows环境中打开CC.Yi.sln文件即可 + #### 使用说明 我们将在之后更新教程手册! -1. xxxx -2. xxxx -3. xxxx +1. 添加一个数据库,并修改连接数据库的配置文件 +2. 添加模型类,使用Add-Migration xxx迁移,再使用Update-Database更新数据库 +3. 向T4Model添加模型名,一键转换生成T4 +4. 控制器构造函数进行依赖注入直接使用 #### 联系我们: QQ:454313500 From ea8dd04c8ca3fae7e28278a5500413d47b2f6bc3 Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Tue, 23 Mar 2021 14:27:59 +0800 Subject: [PATCH 16/31] v1.0.6 --- CC.Yi.API/CC.Yi.API.csproj | 19 ++++++++++++++++++ CC.Yi.API/Program.cs | 2 +- CC.Yi.API/Startup.cs | 8 +------- CC.Yi.API/T4Startup.cs | 23 ++++++++++++++++++++++ CC.Yi.API/T4Startup.tt | 40 ++++++++++++++++++++++++++++++++++++++ T4Model/说明.txt | 5 +++++ test.cs | 16 +++++++++++++++ 7 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 CC.Yi.API/T4Startup.cs create mode 100644 CC.Yi.API/T4Startup.tt create mode 100644 T4Model/说明.txt create mode 100644 test.cs diff --git a/CC.Yi.API/CC.Yi.API.csproj b/CC.Yi.API/CC.Yi.API.csproj index 25450b8f..d2836df9 100644 --- a/CC.Yi.API/CC.Yi.API.csproj +++ b/CC.Yi.API/CC.Yi.API.csproj @@ -27,4 +27,23 @@ + + + + + + + True + True + T4Startup.tt + + + + + + TextTemplatingFileGenerator + T4Startup.cs + + + diff --git a/CC.Yi.API/Program.cs b/CC.Yi.API/Program.cs index 83fc65fc..06ecf46f 100644 --- a/CC.Yi.API/Program.cs +++ b/CC.Yi.API/Program.cs @@ -56,7 +56,7 @@ namespace CC.Yi.API { // logging.ClearProviders(); // п̨ logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); - }).UseNLog(); + }).UseNLog();//nlog־ } } diff --git a/CC.Yi.API/Startup.cs b/CC.Yi.API/Startup.cs index 3206fc1c..5eee61b8 100644 --- a/CC.Yi.API/Startup.cs +++ b/CC.Yi.API/Startup.cs @@ -59,13 +59,7 @@ namespace CC.Yi.API })); } - //̬ AOP˼ע Autofac - public void ConfigureContainer(ContainerBuilder builder) - { - builder.RegisterType(typeof(CustomAutofacAop)); - builder.RegisterGeneric(typeof(BaseDal<>)).As(typeof(IBaseDal<>)) ; - builder.RegisterType().As().EnableInterfaceInterceptors();//ʾעǰҪִCastle - } + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) diff --git a/CC.Yi.API/T4Startup.cs b/CC.Yi.API/T4Startup.cs new file mode 100644 index 00000000..75e8a6fd --- /dev/null +++ b/CC.Yi.API/T4Startup.cs @@ -0,0 +1,23 @@ +using Autofac; +using Autofac.Extras.DynamicProxy; +using CC.Yi.BLL; +using CC.Yi.Common.Castle; +using CC.Yi.DAL; +using CC.Yi.IBLL; +using CC.Yi.IDAL; +using System; + + +namespace CC.Yi.API +{ + public partial class Startup + { + //动态 面向AOP思想的依赖注入 Autofac + public void ConfigureContainer(ContainerBuilder builder) + { + builder.RegisterType(typeof(CustomAutofacAop)); + builder.RegisterGeneric(typeof(BaseDal<>)).As(typeof(IBaseDal<>)); + builder.RegisterType().As().EnableInterfaceInterceptors();//表示注入前后要执行Castle,AOP + } + } +} \ No newline at end of file diff --git a/CC.Yi.API/T4Startup.tt b/CC.Yi.API/T4Startup.tt new file mode 100644 index 00000000..166ebfc5 --- /dev/null +++ b/CC.Yi.API/T4Startup.tt @@ -0,0 +1,40 @@ +<#@ template debug="false" hostspecific="true" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.IO" #> +<#@ output extension=".cs" #> +<# + string solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)");//获取解决方案路径 + string txt; + StreamReader sr = new StreamReader(solutionsPath+@"\T4Model\T4Model.txt"); + txt=sr.ReadToEnd(); + sr.Close(); + string[] ModelData= txt.Split(','); + #> +using Autofac; +using Autofac.Extras.DynamicProxy; +using CC.Yi.BLL; +using CC.Yi.Common.Castle; +using CC.Yi.DAL; +using CC.Yi.IBLL; +using CC.Yi.IDAL; +using System; + + +namespace CC.Yi.API +{ + public partial class Startup + { + //动态 面向AOP思想的依赖注入 Autofac + public void ConfigureContainer(ContainerBuilder builder) + { + builder.RegisterType(typeof(CustomAutofacAop)); + builder.RegisterGeneric(typeof(BaseDal<>)).As(typeof(IBaseDal<>)); +<# foreach(string k in ModelData){#> + builder.RegisterType<<#=k #>Bll>().AsBll>().EnableInterfaceInterceptors();//表示注入前后要执行Castle,AOP +<# } #> + } + } +} \ No newline at end of file diff --git a/T4Model/说明.txt b/T4Model/说明.txt new file mode 100644 index 00000000..7abbdd18 --- /dev/null +++ b/T4Model/说明.txt @@ -0,0 +1,5 @@ +这里存放T4要生成的模型 +使用英文的 , 分隔 +例如: +student,teacher +点击 生成->转换所有t4模板 即可完成生成 \ No newline at end of file diff --git a/test.cs b/test.cs new file mode 100644 index 00000000..72b12401 --- /dev/null +++ b/test.cs @@ -0,0 +1,16 @@ +using System; + + +namespace CC.Yi.API +{ + public class Startup + { + //动态 面向AOP思想的依赖注入 Autofac + public void ConfigureContainer(ContainerBuilder builder) + { + builder.RegisterType(typeof(CustomAutofacAop)); + builder.RegisterGeneric(typeof(BaseDal<>)).As(typeof(IBaseDal<>)); + builder.RegisterType().As().EnableInterfaceInterceptors();//表示注入前后要执行Castle,AOP + } + } +} \ No newline at end of file From 06c32afa03149ad93226d2559f31eb0867fb11b3 Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Tue, 23 Mar 2021 14:29:21 +0800 Subject: [PATCH 17/31] v1.0.6 --- test.cs | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 test.cs diff --git a/test.cs b/test.cs deleted file mode 100644 index 72b12401..00000000 --- a/test.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - - -namespace CC.Yi.API -{ - public class Startup - { - //动态 面向AOP思想的依赖注入 Autofac - public void ConfigureContainer(ContainerBuilder builder) - { - builder.RegisterType(typeof(CustomAutofacAop)); - builder.RegisterGeneric(typeof(BaseDal<>)).As(typeof(IBaseDal<>)); - builder.RegisterType().As().EnableInterfaceInterceptors();//表示注入前后要执行Castle,AOP - } - } -} \ No newline at end of file From c62389a7c0d879f8523dd5587f6684cf97e3cc35 Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Thu, 25 Mar 2021 20:44:12 +0800 Subject: [PATCH 18/31] v1.0.7 --- CC.Yi.API/Controllers/StudentController.cs | 32 +- .../Migrations/20210325123550_yi3.Designer.cs | 93 ++++++ CC.Yi.API/Migrations/20210325123550_yi3.cs | 42 +++ .../Migrations/20210325124241_yi4.Designer.cs | 301 +++++++++++++++++ CC.Yi.API/Migrations/20210325124241_yi4.cs | 315 ++++++++++++++++++ .../Migrations/DataContextModelSnapshot.cs | 261 +++++++++++++++ CC.Yi.API/Startup.cs | 20 +- CC.Yi.Common/Cache/CacheHelper.cs | 2 +- CC.Yi.Model/CC.Yi.Model.csproj | 1 + CC.Yi.Model/DataContext.cs | 6 +- CC.Yi.Model/T4DataContext.cs | 3 +- CC.Yi.Model/T4DataContext.tt | 3 +- CC.Yi.Model/result_user.cs | 13 + CC.Yi.ViewModel/Program.cs | 12 - 14 files changed, 1083 insertions(+), 21 deletions(-) create mode 100644 CC.Yi.API/Migrations/20210325123550_yi3.Designer.cs create mode 100644 CC.Yi.API/Migrations/20210325123550_yi3.cs create mode 100644 CC.Yi.API/Migrations/20210325124241_yi4.Designer.cs create mode 100644 CC.Yi.API/Migrations/20210325124241_yi4.cs create mode 100644 CC.Yi.Model/result_user.cs delete mode 100644 CC.Yi.ViewModel/Program.cs diff --git a/CC.Yi.API/Controllers/StudentController.cs b/CC.Yi.API/Controllers/StudentController.cs index eaf61812..311e2508 100644 --- a/CC.Yi.API/Controllers/StudentController.cs +++ b/CC.Yi.API/Controllers/StudentController.cs @@ -1,5 +1,6 @@ using CC.Yi.IBLL; using CC.Yi.Model; +using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; @@ -13,14 +14,39 @@ namespace CC.Yi.API.Controllers [Route("[controller]/[action]")] public class StudentController : ControllerBase { - private readonly ILogger _logger; + private readonly ILogger _logger;//处理日志相关文件 + + private UserManager _userManager;//处理用户相关逻辑:添加密码,修改密码,添加删除角色等等 + private SignInManager _signInManager;//处理注册登录的相关逻辑 + private IstudentBll _studentBll; - public StudentController(ILogger logger, IstudentBll studentBll) + public StudentController(ILogger logger, IstudentBll studentBll, UserManager userManager, SignInManager signInManager) { - _studentBll = studentBll; + _logger = logger; _logger.LogInformation("现在你进入了StudentController控制器"); + _studentBll = studentBll; + _userManager = userManager; + _signInManager = signInManager; } + #region + //关于身份认证配置使用: + //在需要身份认证的控制器上打上 [Authorize] 特性标签 + #endregion + //[HttpGet] + //public async Task IdentityTest() + //{ + // //用户登入 + // var data = await _signInManager.PasswordSignInAsync("账号", "密码", false, false); //"是否记住密码","是否登入失败锁定用户" + // //用户登出 + // await _signInManager.SignOutAsync(); + // //创建用户 + // var data2 = await _userManager.CreateAsync(new result_user { UserName="账户",Email="邮箱"},"密码"); + // //获取用户 + // var data3 = _userManager.Users;//这里可以使用Linq表达式Select + // return Ok(); + //} + #region diff --git a/CC.Yi.API/Migrations/20210325123550_yi3.Designer.cs b/CC.Yi.API/Migrations/20210325123550_yi3.Designer.cs new file mode 100644 index 00000000..2803473c --- /dev/null +++ b/CC.Yi.API/Migrations/20210325123550_yi3.Designer.cs @@ -0,0 +1,93 @@ +// +using System; +using CC.Yi.Model; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace CC.Yi.API.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20210325123550_yi3")] + partial class yi3 + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.4") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("CC.Yi.Model.result_user", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedUserName") + .HasColumnType("nvarchar(max)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("result_user"); + }); + + modelBuilder.Entity("CC.Yi.Model.student", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("id"); + + b.ToTable("student"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/CC.Yi.API/Migrations/20210325123550_yi3.cs b/CC.Yi.API/Migrations/20210325123550_yi3.cs new file mode 100644 index 00000000..ba0128cc --- /dev/null +++ b/CC.Yi.API/Migrations/20210325123550_yi3.cs @@ -0,0 +1,42 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace CC.Yi.API.Migrations +{ + public partial class yi3 : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "result_user", + columns: table => new + { + Id = table.Column(type: "nvarchar(450)", nullable: false), + UserName = table.Column(type: "nvarchar(max)", nullable: true), + NormalizedUserName = table.Column(type: "nvarchar(max)", nullable: true), + Email = table.Column(type: "nvarchar(max)", nullable: true), + NormalizedEmail = table.Column(type: "nvarchar(max)", nullable: true), + EmailConfirmed = table.Column(type: "bit", nullable: false), + PasswordHash = table.Column(type: "nvarchar(max)", nullable: true), + SecurityStamp = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true), + PhoneNumber = table.Column(type: "nvarchar(max)", nullable: true), + PhoneNumberConfirmed = table.Column(type: "bit", nullable: false), + TwoFactorEnabled = table.Column(type: "bit", nullable: false), + LockoutEnd = table.Column(type: "datetimeoffset", nullable: true), + LockoutEnabled = table.Column(type: "bit", nullable: false), + AccessFailedCount = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_result_user", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "result_user"); + } + } +} diff --git a/CC.Yi.API/Migrations/20210325124241_yi4.Designer.cs b/CC.Yi.API/Migrations/20210325124241_yi4.Designer.cs new file mode 100644 index 00000000..dff90a75 --- /dev/null +++ b/CC.Yi.API/Migrations/20210325124241_yi4.Designer.cs @@ -0,0 +1,301 @@ +// +using System; +using CC.Yi.Model; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace CC.Yi.API.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20210325124241_yi4")] + partial class yi4 + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.4") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("CC.Yi.Model.student", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("id"); + + b.ToTable("student"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers"); + + b.HasDiscriminator("Discriminator").HasValue("IdentityUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("CC.Yi.Model.result_user", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.HasDiscriminator().HasValue("result_user"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/CC.Yi.API/Migrations/20210325124241_yi4.cs b/CC.Yi.API/Migrations/20210325124241_yi4.cs new file mode 100644 index 00000000..4b105b4d --- /dev/null +++ b/CC.Yi.API/Migrations/20210325124241_yi4.cs @@ -0,0 +1,315 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace CC.Yi.API.Migrations +{ + public partial class yi4 : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropPrimaryKey( + name: "PK_result_user", + table: "result_user"); + + migrationBuilder.RenameTable( + name: "result_user", + newName: "AspNetUsers"); + + migrationBuilder.AlterColumn( + name: "UserName", + table: "AspNetUsers", + type: "nvarchar(256)", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "NormalizedUserName", + table: "AspNetUsers", + type: "nvarchar(256)", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "NormalizedEmail", + table: "AspNetUsers", + type: "nvarchar(256)", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Email", + table: "AspNetUsers", + type: "nvarchar(256)", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AddColumn( + name: "Discriminator", + table: "AspNetUsers", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddPrimaryKey( + name: "PK_AspNetUsers", + table: "AspNetUsers", + column: "Id"); + + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(type: "nvarchar(450)", nullable: false), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + UserId = table.Column(type: "nvarchar(450)", nullable: false), + ClaimType = table.Column(type: "nvarchar(max)", nullable: true), + ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + ProviderKey = table.Column(type: "nvarchar(450)", nullable: false), + ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true), + UserId = table.Column(type: "nvarchar(450)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(type: "nvarchar(450)", nullable: false), + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + Name = table.Column(type: "nvarchar(450)", nullable: false), + Value = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + RoleId = table.Column(type: "nvarchar(450)", nullable: false), + ClaimType = table.Column(type: "nvarchar(max)", nullable: true), + ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(type: "nvarchar(450)", nullable: false), + RoleId = table.Column(type: "nvarchar(450)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true, + filter: "[NormalizedUserName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true, + filter: "[NormalizedName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropPrimaryKey( + name: "PK_AspNetUsers", + table: "AspNetUsers"); + + migrationBuilder.DropIndex( + name: "EmailIndex", + table: "AspNetUsers"); + + migrationBuilder.DropIndex( + name: "UserNameIndex", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "Discriminator", + table: "AspNetUsers"); + + migrationBuilder.RenameTable( + name: "AspNetUsers", + newName: "result_user"); + + migrationBuilder.AlterColumn( + name: "UserName", + table: "result_user", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(256)", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "NormalizedUserName", + table: "result_user", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(256)", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "NormalizedEmail", + table: "result_user", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(256)", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Email", + table: "result_user", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(256)", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AddPrimaryKey( + name: "PK_result_user", + table: "result_user", + column: "Id"); + } + } +} diff --git a/CC.Yi.API/Migrations/DataContextModelSnapshot.cs b/CC.Yi.API/Migrations/DataContextModelSnapshot.cs index 1952adda..9ea1d271 100644 --- a/CC.Yi.API/Migrations/DataContextModelSnapshot.cs +++ b/CC.Yi.API/Migrations/DataContextModelSnapshot.cs @@ -1,4 +1,5 @@ // +using System; using CC.Yi.Model; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -32,6 +33,266 @@ namespace CC.Yi.API.Migrations b.ToTable("student"); }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers"); + + b.HasDiscriminator("Discriminator").HasValue("IdentityUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("CC.Yi.Model.result_user", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.HasDiscriminator().HasValue("result_user"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); #pragma warning restore 612, 618 } } diff --git a/CC.Yi.API/Startup.cs b/CC.Yi.API/Startup.cs index 5eee61b8..0a0989e0 100644 --- a/CC.Yi.API/Startup.cs +++ b/CC.Yi.API/Startup.cs @@ -11,6 +11,7 @@ using CC.Yi.Model; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; +using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -37,7 +38,7 @@ namespace CC.Yi.API // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - + services.AddControllers(); services.AddSwaggerGen(c => { @@ -49,6 +50,8 @@ namespace CC.Yi.API { options.UseSqlServer(connection, b => b.MigrationsAssembly("CC.Yi.API"));//ݿ }); + + //עתAutofac //services.AddScoped(typeof(IBaseDal<>), typeof(BaseDal<>)); //services.AddScoped(typeof(IstudentBll), typeof(studentBll)); @@ -57,6 +60,19 @@ namespace CC.Yi.API Configuration = Configuration.GetSection("Cache.ConnectionString").Value, InstanceName = Configuration.GetSection("Cache.InstanceName").Value })); + + + //Identity֤ + services.AddIdentity(options => + { + options.Password.RequiredLength = 6;//̳ + options.Password.RequireDigit = false;// + options.Password.RequireLowercase = false;//Сдĸ + options.Password.RequireNonAlphanumeric = false;//ַ + options.Password.RequireUppercase = false;//дĸ + //options.User.RequireUniqueEmail = false;//עǷԲظ + //options.User.AllowedUserNameCharacters="abcd"//ַֻ + }).AddEntityFrameworkStores().AddDefaultTokenProviders(); } @@ -71,6 +87,8 @@ namespace CC.Yi.API app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "CC.Yi.API v1")); } + app.UseAuthentication(); + app.UseHttpsRedirection(); app.UseRouting(); diff --git a/CC.Yi.Common/Cache/CacheHelper.cs b/CC.Yi.Common/Cache/CacheHelper.cs index 0bc435b0..8b55955c 100644 --- a/CC.Yi.Common/Cache/CacheHelper.cs +++ b/CC.Yi.Common/Cache/CacheHelper.cs @@ -1,4 +1,5 @@ using Autofac; +using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.Text; @@ -10,7 +11,6 @@ namespace CC.Yi.Common.Cache public static ICacheWriter CacheWriter { get; set; } static CacheHelper() { - //这里存在一些问题 ContainerBuilder containerBuilder = new ContainerBuilder(); IContainer container = containerBuilder.Build(); diff --git a/CC.Yi.Model/CC.Yi.Model.csproj b/CC.Yi.Model/CC.Yi.Model.csproj index dffcf8d1..f620b157 100644 --- a/CC.Yi.Model/CC.Yi.Model.csproj +++ b/CC.Yi.Model/CC.Yi.Model.csproj @@ -13,6 +13,7 @@ + all diff --git a/CC.Yi.Model/DataContext.cs b/CC.Yi.Model/DataContext.cs index df55c3b5..71992485 100644 --- a/CC.Yi.Model/DataContext.cs +++ b/CC.Yi.Model/DataContext.cs @@ -1,13 +1,15 @@ -using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using System; namespace CC.Yi.Model { - public partial class DataContext : DbContext + public partial class DataContext : IdentityDbContext { public DataContext(DbContextOptions options) : base(options) { } + public DbSet result_user { get; set; } } } diff --git a/CC.Yi.Model/T4DataContext.cs b/CC.Yi.Model/T4DataContext.cs index ab0edf2f..df21a4f0 100644 --- a/CC.Yi.Model/T4DataContext.cs +++ b/CC.Yi.Model/T4DataContext.cs @@ -2,10 +2,11 @@ using System; using System.Collections.Generic; using System.Text; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; namespace CC.Yi.Model { - public partial class DataContext :DbContext + public partial class DataContext :IdentityDbContext { public DbSet student { get; set; } } diff --git a/CC.Yi.Model/T4DataContext.tt b/CC.Yi.Model/T4DataContext.tt index dcfd940e..61baf89b 100644 --- a/CC.Yi.Model/T4DataContext.tt +++ b/CC.Yi.Model/T4DataContext.tt @@ -17,10 +17,11 @@ using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Text; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; namespace CC.Yi.Model { - public partial class DataContext :DbContext + public partial class DataContext :IdentityDbContext { <# foreach(string k in ModelData){ #> diff --git a/CC.Yi.Model/result_user.cs b/CC.Yi.Model/result_user.cs new file mode 100644 index 00000000..9c60b1a8 --- /dev/null +++ b/CC.Yi.Model/result_user.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Identity; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CC.Yi.Model +{ + public class result_user : IdentityUser + { + //你可以在这里添加你额外需要的字段例如 + //public int level { get; set; } + } +} diff --git a/CC.Yi.ViewModel/Program.cs b/CC.Yi.ViewModel/Program.cs deleted file mode 100644 index 69cc429d..00000000 --- a/CC.Yi.ViewModel/Program.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace CC.Yi.ViewModel -{ - class Program - { - static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - } - } -} From 75ee279d5a92c14f4083874a2fa11aaf4c6d103d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Thu, 25 Mar 2021 20:46:00 +0800 Subject: [PATCH 19/31] update README.md. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ed114207..996399ae 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ 操作系统:Windows,Linux -扩展:EFcore,Autofac,Castle,Redis,Swagger,T4 ,Nlog(后期我们会添加更多) +扩展:EFcore,Autofac,Identity,Castle,Redis,Swagger,T4 ,Nlog(后期我们会添加更多) 封装:Json处理模块,滑动验证码模块,base64图片处理模块(后期我们会添加更多) From 2bbdf7d83317e188ad8cda48b548b728ab8693b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sat, 27 Mar 2021 18:29:47 +0800 Subject: [PATCH 20/31] update README.md. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 996399ae..e21f2cda 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ 第一版开发完成时间:2021/3/19 (请记住,这是一个值得纪念的日子) +为了更简易的开发,我们在2021/3/27 加入了vue分支(我们将持续更新) + #### 软件架构 架构:.NET5 +mysql+sql server(后期我们将集成数据+前端Vue,让开发更加简易!) From a400b05bdcfbf0f63278976243aaf8438ea3f1fc Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Sun, 28 Mar 2021 01:11:53 +0800 Subject: [PATCH 21/31] v1.0.8 --- CC.Yi.IDAL/CC.Yi.IDAL.csproj | 9 +++++++++ CC.Yi.IDAL/T4IDbSession.cs | 15 +++++++++++++++ CC.Yi.IDAL/T4IDbSession.tt | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 CC.Yi.IDAL/T4IDbSession.cs create mode 100644 CC.Yi.IDAL/T4IDbSession.tt diff --git a/CC.Yi.IDAL/CC.Yi.IDAL.csproj b/CC.Yi.IDAL/CC.Yi.IDAL.csproj index bfba3015..91214ffd 100644 --- a/CC.Yi.IDAL/CC.Yi.IDAL.csproj +++ b/CC.Yi.IDAL/CC.Yi.IDAL.csproj @@ -14,6 +14,10 @@ TextTemplatingFileGenerator T4IDAL.cs + + TextTemplatingFileGenerator + T4IDbSession.cs + @@ -26,6 +30,11 @@ True T4IDAL.tt + + True + True + T4IDbSession.tt + diff --git a/CC.Yi.IDAL/T4IDbSession.cs b/CC.Yi.IDAL/T4IDbSession.cs new file mode 100644 index 00000000..aab497df --- /dev/null +++ b/CC.Yi.IDAL/T4IDbSession.cs @@ -0,0 +1,15 @@ +using CC.Yi.Model; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CC.Yi.IDAL +{ + public partial interface IDbSession + { + IstudentDal studentDal{get;} + + } +} \ No newline at end of file diff --git a/CC.Yi.IDAL/T4IDbSession.tt b/CC.Yi.IDAL/T4IDbSession.tt new file mode 100644 index 00000000..b0d2226a --- /dev/null +++ b/CC.Yi.IDAL/T4IDbSession.tt @@ -0,0 +1,33 @@ +<#@ template debug="false" hostspecific="true" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.IO" #> +<#@ output extension=".cs" #> +<# + string solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)");//获取解决方案路径 + string txt; + StreamReader sr = new StreamReader(solutionsPath+@"\T4Model\T4Model.txt"); + txt=sr.ReadToEnd(); + sr.Close(); + string[] ModelData= txt.Split(','); + #> +using CC.Yi.Model; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CC.Yi.IDAL +{ + public partial interface IDbSession + { +<# foreach(string k in ModelData){ + #> + I<#=k #>Dal <#=k #>Dal{get;} + +<# } #> + } +} \ No newline at end of file From b1549f00b60cf0e9730c066eb037915e1ba05037 Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Sun, 28 Mar 2021 20:56:27 +0800 Subject: [PATCH 22/31] v1.0.9 --- CC.Yi.API/Program.cs | 8 ++++---- CC.Yi.API/Startup.cs | 11 +++++++++++ CC.Yi.DAL/DbContentFactory.cs | 2 ++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/CC.Yi.API/Program.cs b/CC.Yi.API/Program.cs index 06ecf46f..9fe2b1eb 100644 --- a/CC.Yi.API/Program.cs +++ b/CC.Yi.API/Program.cs @@ -22,10 +22,10 @@ namespace CC.Yi.API { logger.Debug("Yiܡ"); var host = CreateHostBuilder(args).Build(); - var scope = host.Services.CreateScope(); - var services = scope.ServiceProvider; - var context = services.GetRequiredService();//ȡ - DbContentFactory.Initialize(context);//þ̬෽ע + //var scope = host.Services.CreateScope(); + //var services = scope.ServiceProvider; + //var context = services.GetRequiredService();//ȡ + //DbContentFactory.Initialize(context);//þ̬෽ע host.Run(); logger.Info("Yiɹ"); } diff --git a/CC.Yi.API/Startup.cs b/CC.Yi.API/Startup.cs index 0a0989e0..9ffc7e32 100644 --- a/CC.Yi.API/Startup.cs +++ b/CC.Yi.API/Startup.cs @@ -75,11 +75,21 @@ namespace CC.Yi.API }).AddEntityFrameworkStores().AddDefaultTokenProviders(); } + private void InitData(IServiceProvider serviceProvider) + { + var serviceScope = serviceProvider.GetRequiredService().CreateScope(); + + var context = serviceScope.ServiceProvider.GetService(); + DbContentFactory.Initialize(context);//þ̬෽ע + + } + // 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(); @@ -99,6 +109,7 @@ namespace CC.Yi.API { endpoints.MapControllers(); }); + InitData(app.ApplicationServices); } } } diff --git a/CC.Yi.DAL/DbContentFactory.cs b/CC.Yi.DAL/DbContentFactory.cs index 9ca47789..2ef1c920 100644 --- a/CC.Yi.DAL/DbContentFactory.cs +++ b/CC.Yi.DAL/DbContentFactory.cs @@ -9,6 +9,8 @@ namespace CC.Yi.DAL public class DbContentFactory { private static DataContext Webcontext; + + public static void Initialize(DataContext webContext) { Webcontext = webContext; From 4cc8b0b84469d07fc9ad626fb4d3c2303a7e830f Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Sat, 3 Apr 2021 13:18:01 +0800 Subject: [PATCH 23/31] v1.1.0 --- CC.Yi.DALFactory/DbSession.cs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/CC.Yi.DALFactory/DbSession.cs b/CC.Yi.DALFactory/DbSession.cs index 71b38475..b6de042d 100644 --- a/CC.Yi.DALFactory/DbSession.cs +++ b/CC.Yi.DALFactory/DbSession.cs @@ -10,7 +10,31 @@ namespace CC.Yi.DALFactory { public int SaveChanges() { - return DbContentFactory.GetCurrentDbContent().SaveChanges(); + var context = DbContentFactory.GetCurrentDbContent(); + + var saved = false; + while (!saved) + { + try + { + // Attempt to save changes to the database + context.SaveChanges(); + saved = true; + } + catch (DbUpdateConcurrencyException ex) + { + foreach (var entry in ex.Entries) + { + var databaseValues = entry.GetDatabaseValues(); + + // Refresh original values to bypass next concurrency check + entry.OriginalValues.SetValues(databaseValues); + + } + } + } + + return 1; } public DataContext GetDbContent() { From d26140ac18529d3f3c528e4558564556822b58a2 Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Wed, 7 Apr 2021 12:21:08 +0800 Subject: [PATCH 24/31] v1.1.1 --- CC.Yi.BLL/BaseBll.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CC.Yi.BLL/BaseBll.cs b/CC.Yi.BLL/BaseBll.cs index 908a6b28..90cd98a0 100644 --- a/CC.Yi.BLL/BaseBll.cs +++ b/CC.Yi.BLL/BaseBll.cs @@ -45,9 +45,9 @@ namespace CC.Yi.BLL public T Add(T entity) { - CurrentDal.Add(entity); + var myEntity=CurrentDal.Add(entity); DbSession.SaveChanges(); - return entity; + return myEntity; } public bool Add(IEnumerable entities) From 8673e8fd857f1be4cc4b7f84a3b1b5f3159d65c8 Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Sat, 10 Apr 2021 18:28:45 +0800 Subject: [PATCH 25/31] v1.1.2 --- CC.Yi.API/Controllers/StudentController.cs | 43 +-- .../Migrations/20210410090937_yi5.Designer.cs | 40 +++ CC.Yi.API/Migrations/20210410090937_yi5.cs | 220 +++++++++++++++ .../Migrations/DataContextModelSnapshot.cs | 261 ------------------ CC.Yi.API/Startup.cs | 62 +++-- CC.Yi.API/appsettings.json | 5 +- CC.Yi.Common/JsonHelper.cs | 16 +- CC.Yi.Common/Result.cs | 40 +++ CC.Yi.DALFactory/DbSession.cs | 2 +- CC.Yi.Model/DataContext.cs | 7 +- CC.Yi.Model/T4DataContext.cs | 4 +- CC.Yi.Model/T4DataContext.tt | 4 +- 12 files changed, 386 insertions(+), 318 deletions(-) create mode 100644 CC.Yi.API/Migrations/20210410090937_yi5.Designer.cs create mode 100644 CC.Yi.API/Migrations/20210410090937_yi5.cs create mode 100644 CC.Yi.Common/Result.cs diff --git a/CC.Yi.API/Controllers/StudentController.cs b/CC.Yi.API/Controllers/StudentController.cs index 311e2508..c194db1f 100644 --- a/CC.Yi.API/Controllers/StudentController.cs +++ b/CC.Yi.API/Controllers/StudentController.cs @@ -1,7 +1,9 @@ using CC.Yi.IBLL; using CC.Yi.Model; +using Common; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -16,18 +18,18 @@ namespace CC.Yi.API.Controllers { private readonly ILogger _logger;//处理日志相关文件 - private UserManager _userManager;//处理用户相关逻辑:添加密码,修改密码,添加删除角色等等 - private SignInManager _signInManager;//处理注册登录的相关逻辑 + //private UserManager _userManager;//处理用户相关逻辑:添加密码,修改密码,添加删除角色等等 + //private SignInManager _signInManager;//处理注册登录的相关逻辑 private IstudentBll _studentBll; - public StudentController(ILogger logger, IstudentBll studentBll, UserManager userManager, SignInManager signInManager) + public StudentController(ILogger logger, IstudentBll studentBll) { _logger = logger; _logger.LogInformation("现在你进入了StudentController控制器"); _studentBll = studentBll; - _userManager = userManager; - _signInManager = signInManager; + //_userManager = userManager; + //_signInManager = signInManager; } #region //关于身份认证配置使用: @@ -54,45 +56,52 @@ namespace CC.Yi.API.Controllers //注意:请确保你的数据库中存在合理的数据 #endregion [HttpGet] - public IActionResult GetTest()//查 + public async Task GetTest()//查 { _logger.LogInformation("调用查方法"); - var data = _studentBll.GetAllEntities().ToList(); - return Content(Common.JsonHelper.JsonToString(data)); + var data =await _studentBll.GetAllEntities().ToListAsync(); + return Result.Success("查询成功").SetData(data); } [HttpGet] - public IActionResult AddTest()//增 + public Result AddTest()//增 { _logger.LogInformation("调用增方法"); List students = new List() {new student { name = "学生a" } ,new student { name="学生d"} }; - _studentBll.Add(students); - return Content("ok"); + if (_studentBll.Add(students)) + { + return Result.Success("增加成功"); + } + else + { + return Result.Error("增加失败"); + } + } [HttpGet] - public IActionResult RemoveTest()//删 + public Result RemoveTest()//删 { _logger.LogInformation("调用删方法"); if (_studentBll.Delete(u=>u.name=="学生a")) { - return Content("ok"); + return Result.Success("删除成功"); } else { - return Content("no"); + return Result.Error("删除失败"); } } [HttpGet] - public IActionResult UpdateTest()//改 + public Result UpdateTest()//改 { _logger.LogInformation("调用改方法"); if (_studentBll.Update(new student { id=2, name = "学生a" }, "name")) { - return Content("ok"); + return Result.Success("修改成功"); } else { - return Content("no"); + return Result.Error("修改失败"); } } diff --git a/CC.Yi.API/Migrations/20210410090937_yi5.Designer.cs b/CC.Yi.API/Migrations/20210410090937_yi5.Designer.cs new file mode 100644 index 00000000..6038f52c --- /dev/null +++ b/CC.Yi.API/Migrations/20210410090937_yi5.Designer.cs @@ -0,0 +1,40 @@ +// +using CC.Yi.Model; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace CC.Yi.API.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20210410090937_yi5")] + partial class yi5 + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.4") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("CC.Yi.Model.student", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("id"); + + b.ToTable("student"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/CC.Yi.API/Migrations/20210410090937_yi5.cs b/CC.Yi.API/Migrations/20210410090937_yi5.cs new file mode 100644 index 00000000..73cf0845 --- /dev/null +++ b/CC.Yi.API/Migrations/20210410090937_yi5.cs @@ -0,0 +1,220 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace CC.Yi.API.Migrations +{ + public partial class yi5 : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(type: "nvarchar(450)", nullable: false), + ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(type: "nvarchar(450)", nullable: false), + AccessFailedCount = table.Column(type: "int", nullable: false), + ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true), + Discriminator = table.Column(type: "nvarchar(max)", nullable: false), + Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + EmailConfirmed = table.Column(type: "bit", nullable: false), + LockoutEnabled = table.Column(type: "bit", nullable: false), + LockoutEnd = table.Column(type: "datetimeoffset", nullable: true), + NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + PasswordHash = table.Column(type: "nvarchar(max)", nullable: true), + PhoneNumber = table.Column(type: "nvarchar(max)", nullable: true), + PhoneNumberConfirmed = table.Column(type: "bit", nullable: false), + SecurityStamp = table.Column(type: "nvarchar(max)", nullable: true), + TwoFactorEnabled = table.Column(type: "bit", nullable: false), + UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ClaimType = table.Column(type: "nvarchar(max)", nullable: true), + ClaimValue = table.Column(type: "nvarchar(max)", nullable: true), + RoleId = table.Column(type: "nvarchar(450)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ClaimType = table.Column(type: "nvarchar(max)", nullable: true), + ClaimValue = table.Column(type: "nvarchar(max)", nullable: true), + UserId = table.Column(type: "nvarchar(450)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + ProviderKey = table.Column(type: "nvarchar(450)", nullable: false), + ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true), + UserId = table.Column(type: "nvarchar(450)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(type: "nvarchar(450)", nullable: false), + RoleId = table.Column(type: "nvarchar(450)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(type: "nvarchar(450)", nullable: false), + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + Name = table.Column(type: "nvarchar(450)", nullable: false), + Value = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true, + filter: "[NormalizedName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true, + filter: "[NormalizedUserName] IS NOT NULL"); + } + } +} diff --git a/CC.Yi.API/Migrations/DataContextModelSnapshot.cs b/CC.Yi.API/Migrations/DataContextModelSnapshot.cs index 9ea1d271..1952adda 100644 --- a/CC.Yi.API/Migrations/DataContextModelSnapshot.cs +++ b/CC.Yi.API/Migrations/DataContextModelSnapshot.cs @@ -1,5 +1,4 @@ // -using System; using CC.Yi.Model; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -33,266 +32,6 @@ namespace CC.Yi.API.Migrations b.ToTable("student"); }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => - { - b.Property("Id") - .HasColumnType("nvarchar(450)"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex") - .HasFilter("[NormalizedName] IS NOT NULL"); - - b.ToTable("AspNetRoles"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => - { - b.Property("Id") - .HasColumnType("nvarchar(450)"); - - b.Property("AccessFailedCount") - .HasColumnType("int"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("Discriminator") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("bit"); - - b.Property("LockoutEnabled") - .HasColumnType("bit"); - - b.Property("LockoutEnd") - .HasColumnType("datetimeoffset"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("PasswordHash") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumber") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("bit"); - - b.Property("SecurityStamp") - .HasColumnType("nvarchar(max)"); - - b.Property("TwoFactorEnabled") - .HasColumnType("bit"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex") - .HasFilter("[NormalizedUserName] IS NOT NULL"); - - b.ToTable("AspNetUsers"); - - b.HasDiscriminator("Discriminator").HasValue("IdentityUser"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderKey") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderDisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); - - b.Property("RoleId") - .HasColumnType("nvarchar(450)"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); - - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("Name") - .HasColumnType("nvarchar(450)"); - - b.Property("Value") - .HasColumnType("nvarchar(max)"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens"); - }); - - modelBuilder.Entity("CC.Yi.Model.result_user", b => - { - b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); - - b.HasDiscriminator().HasValue("result_user"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); #pragma warning restore 612, 618 } } diff --git a/CC.Yi.API/Startup.cs b/CC.Yi.API/Startup.cs index 9ffc7e32..abe98ff5 100644 --- a/CC.Yi.API/Startup.cs +++ b/CC.Yi.API/Startup.cs @@ -38,50 +38,62 @@ namespace CC.Yi.API // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - + services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "CC.Yi.API", Version = "v1" }); }); - string connection = Configuration["ConnectionStringBySQL"]; + services.AddSession(); + services.AddMvc(); + string connection1 = Configuration["ConnectionStringBySQL"]; string connection2 = Configuration["ConnectionStringByMySQL"]; + string connection3 = Configuration["ConnectionStringBySQLite"]; services.AddDbContext(options => { - options.UseSqlServer(connection, b => b.MigrationsAssembly("CC.Yi.API"));//ݿ + options.UseSqlServer(connection1, b => b.MigrationsAssembly("CC.Yi.API"));//ݿ }); //עתAutofac //services.AddScoped(typeof(IBaseDal<>), typeof(BaseDal<>)); //services.AddScoped(typeof(IstudentBll), typeof(studentBll)); - services.AddSingleton(typeof(ICacheWriter), new RedisCacheService(new Microsoft.Extensions.Caching.Redis.RedisCacheOptions() - { - Configuration = Configuration.GetSection("Cache.ConnectionString").Value, - InstanceName = Configuration.GetSection("Cache.InstanceName").Value - })); + + //reidsע + //services.AddSingleton(typeof(ICacheWriter), new RedisCacheService(new Microsoft.Extensions.Caching.Redis.RedisCacheOptions() + //{ + // Configuration = Configuration.GetSection("Cache.ConnectionString").Value, + // InstanceName = Configuration.GetSection("Cache.InstanceName").Value + //})); //Identity֤ - services.AddIdentity(options => + //services.AddIdentity(options => + // { + // options.Password.RequiredLength = 6;//̳ + // options.Password.RequireDigit = false;// + // options.Password.RequireLowercase = false;//Сдĸ + // options.Password.RequireNonAlphanumeric = false;//ַ + // options.Password.RequireUppercase = false;//дĸ + // //options.User.RequireUniqueEmail = false;//עǷԲظ + // //options.User.AllowedUserNameCharacters="abcd"//ַֻ + //}).AddEntityFrameworkStores().AddDefaultTokenProviders(); + services.AddCors(options => options.AddPolicy("CorsPolicy",// + builder => { - options.Password.RequiredLength = 6;//̳ - options.Password.RequireDigit = false;// - options.Password.RequireLowercase = false;//Сдĸ - options.Password.RequireNonAlphanumeric = false;//ַ - options.Password.RequireUppercase = false;//дĸ - //options.User.RequireUniqueEmail = false;//עǷԲظ - //options.User.AllowedUserNameCharacters="abcd"//ַֻ - }).AddEntityFrameworkStores().AddDefaultTokenProviders(); + builder.AllowAnyMethod() + .SetIsOriginAllowed(_ => true) + .AllowAnyHeader() + .AllowCredentials(); + })); } private void InitData(IServiceProvider serviceProvider) { var serviceScope = serviceProvider.GetRequiredService().CreateScope(); - - var context = serviceScope.ServiceProvider.GetService(); - DbContentFactory.Initialize(context);//þ̬෽ע - + + var context = serviceScope.ServiceProvider.GetService(); + DbContentFactory.Initialize(context);//þ̬෽ע } @@ -89,7 +101,7 @@ namespace CC.Yi.API // 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(); @@ -97,10 +109,10 @@ namespace CC.Yi.API app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "CC.Yi.API v1")); } - app.UseAuthentication(); - + //app.UseAuthentication(); + app.UseCors("CorsPolicy"); app.UseHttpsRedirection(); - + app.UseSession(); app.UseRouting(); app.UseAuthorization(); diff --git a/CC.Yi.API/appsettings.json b/CC.Yi.API/appsettings.json index b5156473..429d06ac 100644 --- a/CC.Yi.API/appsettings.json +++ b/CC.Yi.API/appsettings.json @@ -11,6 +11,7 @@ "InstanceName": "Redis", "ConnectionString": "127.0.0.1:12345,password=123456" }, - "ConnectionStringBySQL": "server=.;Database=cctest;UId=sa;PWD=Qz52013142020.", - "ConnectionStringByMySQL": "Data Source=.;Database=cctest;User ID=root;Password=Qz52013142020.;pooling=true;port=3306;sslmode=none;CharSet=utf8;" + "ConnectionStringBySQL": "server=.;Database=YIDB;UId=sa;PWD=Qz52013142020.", + "ConnectionStringByMySQL": "Data Source=.;Database=YIDB;User ID=root;Password=Qz52013142020.;pooling=true;port=3306;sslmode=none;CharSet=utf8;", + "ConnectionStringBySQLite": "Filename=YIDB.db" } diff --git a/CC.Yi.Common/JsonHelper.cs b/CC.Yi.Common/JsonHelper.cs index b427195b..bf4c8dfa 100644 --- a/CC.Yi.Common/JsonHelper.cs +++ b/CC.Yi.Common/JsonHelper.cs @@ -4,9 +4,21 @@ namespace CC.Yi.Common { public static class JsonHelper { - public static string JsonToString(object q) + public static string JsonToString(object data=null, int code = 200, bool flag = true, string message = "成功") { - return Newtonsoft.Json.JsonConvert.SerializeObject(q); + return Newtonsoft.Json.JsonConvert.SerializeObject(new { code = code, flag = flag, message = message, data = data }); + } + public static string JsonToString2(object data = null, int code = 200, bool flag = true, string message = "成功",int count=0) + { + return Newtonsoft.Json.JsonConvert.SerializeObject(new { code = code, flag = flag, message = message, count=count,data = data }); + } + public static string ToString(object data) + { + return Newtonsoft.Json.JsonConvert.SerializeObject(data); + } + public static T ToJson(string data) + { + return Newtonsoft.Json.JsonConvert.DeserializeObject(data); } } } diff --git a/CC.Yi.Common/Result.cs b/CC.Yi.Common/Result.cs new file mode 100644 index 00000000..0b4940ce --- /dev/null +++ b/CC.Yi.Common/Result.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace Common +{ + /// + /// 结果数据 + /// + public class Result + { + public bool Status { get; set; } + public int Code { get; set; } + public string Msg { get; set; } + public object Data { get; set; } + public static Result Instance(bool status, string msg) + { + return new Result() { Status = status,Code=500, Msg = msg }; + } + public static Result Error(string msg) + { + return new Result() { Status = false, Code = 500, Msg = msg }; + } + public static Result Success(string msg= "succeed") + { + return new Result() { Status = true, Code = 200, Msg = msg }; + } + public Result SetData(object obj) + { + this.Data = obj; + return this; + } + public Result SetCode(int Code) + { + this.Code = Code; + return this; + } + } +} \ No newline at end of file diff --git a/CC.Yi.DALFactory/DbSession.cs b/CC.Yi.DALFactory/DbSession.cs index b6de042d..7fa154f4 100644 --- a/CC.Yi.DALFactory/DbSession.cs +++ b/CC.Yi.DALFactory/DbSession.cs @@ -18,7 +18,7 @@ namespace CC.Yi.DALFactory try { // Attempt to save changes to the database - context.SaveChanges(); + context.SaveChangesAsync(); saved = true; } catch (DbUpdateConcurrencyException ex) diff --git a/CC.Yi.Model/DataContext.cs b/CC.Yi.Model/DataContext.cs index 71992485..98a047bd 100644 --- a/CC.Yi.Model/DataContext.cs +++ b/CC.Yi.Model/DataContext.cs @@ -1,15 +1,14 @@ -using Microsoft.AspNetCore.Identity.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using System; namespace CC.Yi.Model { - public partial class DataContext : IdentityDbContext + public partial class DataContext : DbContext { public DataContext(DbContextOptions options) : base(options) { } - public DbSet result_user { get; set; } + //public DbSet result_user { get; set; } } } diff --git a/CC.Yi.Model/T4DataContext.cs b/CC.Yi.Model/T4DataContext.cs index df21a4f0..584f6d63 100644 --- a/CC.Yi.Model/T4DataContext.cs +++ b/CC.Yi.Model/T4DataContext.cs @@ -2,11 +2,9 @@ using System; using System.Collections.Generic; using System.Text; -using Microsoft.AspNetCore.Identity.EntityFrameworkCore; - namespace CC.Yi.Model { - public partial class DataContext :IdentityDbContext + public partial class DataContext :DbContext { public DbSet student { get; set; } } diff --git a/CC.Yi.Model/T4DataContext.tt b/CC.Yi.Model/T4DataContext.tt index 61baf89b..2fa74f5b 100644 --- a/CC.Yi.Model/T4DataContext.tt +++ b/CC.Yi.Model/T4DataContext.tt @@ -17,11 +17,9 @@ using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Text; -using Microsoft.AspNetCore.Identity.EntityFrameworkCore; - namespace CC.Yi.Model { - public partial class DataContext :IdentityDbContext + public partial class DataContext :DbContext { <# foreach(string k in ModelData){ #> From f799707b7ade49176926f59920b1b64b2e63c82c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sat, 10 Apr 2021 18:32:13 +0800 Subject: [PATCH 26/31] update README.md. --- README.md | 112 +++++++++++++++++++++++++++--------------------------- 1 file changed, 57 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index e21f2cda..6755925a 100644 --- a/README.md +++ b/README.md @@ -1,55 +1,57 @@ -# CC.Yi - -#### 介绍 -基于.NET的MVC三成架构的框架--Yi意框架(意义是为了开发更简易) - -第一版开发完成时间:2021/3/19 (请记住,这是一个值得纪念的日子) - -为了更简易的开发,我们在2021/3/27 加入了vue分支(我们将持续更新) - - -#### 软件架构 -架构:.NET5 +mysql+sql server(后期我们将集成数据+前端Vue,让开发更加简易!) - -操作系统:Windows,Linux - -扩展:EFcore,Autofac,Identity,Castle,Redis,Swagger,T4 ,Nlog(后期我们会添加更多) - -封装:Json处理模块,滑动验证码模块,base64图片处理模块(后期我们会添加更多) - -思想:简单工厂模式,抽象工厂模式,观察者模式,面向AOP思想,面向对象开发 - - -#### 目录结构 -![输入图片说明](https://images.gitee.com/uploads/images/2021/0321/023715_59bef411_3049273.png "屏幕截图.png") - -Model:模型层(first code代码优先添加模型,数据自动生成) - -DAL:数据处理层(处理数据但并未加载进内存) - -BLL:业务逻辑层(数据的逻辑将在这层处理) - -Common:工具层(工具人层,方法已封装,一键调用) - -API:接口层(接入Swagger,可视化测试接口) - - -#### 安装教程 -我们将在之后更新教程手册! - -1. 下载全部源码 -2. 使用Visual Studio 2019在windows环境中打开CC.Yi.sln文件即可 - - -#### 使用说明 -我们将在之后更新教程手册! - -1. 添加一个数据库,并修改连接数据库的配置文件 -2. 添加模型类,使用Add-Migration xxx迁移,再使用Update-Database更新数据库 -3. 向T4Model添加模型名,一键转换生成T4 -4. 控制器构造函数进行依赖注入直接使用 - -#### 联系我们: -QQ:454313500 - - +# CC.Yi + +#### 介绍 +基于.NET5的MVC三层架构的高并发高解耦简易型框架--Yi意框架(意义是为了开发更简易) + +第一版开发完成时间:2021/3/19 (请记住,这是一个值得纪念的日子) + +为了更简易的开发,我们在2021/3/27 加入了vue分支(我们将持续更新) + + +#### 软件架构 +架构:.NET5(后期我们将集成数据+前端Vue,让开发更加简易!) + +支持的数据库: SQL Server,MySQL,SQLite,reidis + +操作系统:Windows,Linux + +扩展:EFcore,Autofac,Identity,Castle,Redis,Swagger,T4 ,Nlog(后期我们会添加更多) + +封装:Json处理模块,滑动验证码模块,base64图片处理模块(后期我们会添加更多) + +思想:简单工厂模式,抽象工厂模式,观察者模式,面向AOP思想,面向对象开发 + + +#### 目录结构 +![输入图片说明](https://images.gitee.com/uploads/images/2021/0321/023715_59bef411_3049273.png "屏幕截图.png") + +Model:模型层(first code代码优先添加模型,数据自动生成) + +DAL:数据处理层(处理数据但并未加载进内存) + +BLL:业务逻辑层(数据的逻辑将在这层处理) + +Common:工具层(工具人层,方法已封装,一键调用) + +API:接口层(接入Swagger,可视化测试接口) + + +#### 安装教程 +我们将在之后更新教程手册! + +1. 下载全部源码 +2. 使用Visual Studio 2019在windows环境中打开CC.Yi.sln文件即可 + + +#### 使用说明 +我们将在之后更新教程手册! + +1. 添加一个数据库,并修改连接数据库的配置文件 +2. 添加模型类,使用Add-Migration xxx迁移,再使用Update-Database更新数据库 +3. 向T4Model添加模型名,一键转换生成T4 +4. 控制器构造函数进行依赖注入直接使用 + +#### 联系我们: +QQ:454313500 + + From d9e826af687c698a09b6627ec46ed7e8f87b4b63 Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Tue, 13 Apr 2021 12:42:37 +0800 Subject: [PATCH 27/31] v1.1.3 --- CC.Yi.API/Controllers/StudentController.cs | 4 ++-- CC.Yi.Common/Result.cs | 26 +++++++++++----------- CC.Yi.DAL/DbContentFactory.cs | 24 +++++++++++++------- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/CC.Yi.API/Controllers/StudentController.cs b/CC.Yi.API/Controllers/StudentController.cs index c194db1f..45e52835 100644 --- a/CC.Yi.API/Controllers/StudentController.cs +++ b/CC.Yi.API/Controllers/StudentController.cs @@ -1,6 +1,6 @@ -using CC.Yi.IBLL; +using CC.Yi.Common; +using CC.Yi.IBLL; using CC.Yi.Model; -using Common; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; diff --git a/CC.Yi.Common/Result.cs b/CC.Yi.Common/Result.cs index 0b4940ce..6f210764 100644 --- a/CC.Yi.Common/Result.cs +++ b/CC.Yi.Common/Result.cs @@ -3,37 +3,37 @@ using System.Collections.Generic; using System.Linq; using System.Web; -namespace Common +namespace CC.Yi.Common { /// /// 结果数据 /// public class Result { - public bool Status { get; set; } - public int Code { get; set; } - public string Msg { get; set; } - public object Data { get; set; } + public bool status { get; set; } + public int code { get; set; } + public string msg { get; set; } + public object data { get; set; } public static Result Instance(bool status, string msg) { - return new Result() { Status = status,Code=500, Msg = msg }; + return new Result() { status = status, code = 500, msg = msg }; } - public static Result Error(string msg) + public static Result Error(string msg = "fail") { - return new Result() { Status = false, Code = 500, Msg = msg }; + return new Result() { status = false, code = 500, msg = msg }; } - public static Result Success(string msg= "succeed") + public static Result Success(string msg = "succeed") { - return new Result() { Status = true, Code = 200, Msg = msg }; + return new Result() { status = true, code = 200, msg = msg }; } - public Result SetData(object obj) + public Result SetData(object obj) { - this.Data = obj; + this.data = obj; return this; } public Result SetCode(int Code) { - this.Code = Code; + this.code = Code; return this; } } diff --git a/CC.Yi.DAL/DbContentFactory.cs b/CC.Yi.DAL/DbContentFactory.cs index 2ef1c920..7e110070 100644 --- a/CC.Yi.DAL/DbContentFactory.cs +++ b/CC.Yi.DAL/DbContentFactory.cs @@ -17,18 +17,26 @@ namespace CC.Yi.DAL } public static DataContext GetCurrentDbContent() { - //return new DataModelContainer(); - //一次请求共用一个上下文实例 - //每一次http请求都会开启一个新的线程,保证在一个线程中,DbContext是唯一的 - //CallContext:是线程内部唯一的数据槽(一块内存空间/容器),相当于一个键值对数据容器,通过key获取value了,需要引入System.Runtime.Remoting.Messaging;命名空间 - DataContext db = CallContext.GetData("DbContext") as DataContext; + object myLock = new object(); + lock (myLock) + { + //return new DataModelContainer(); + //一次请求共用一个上下文实例 + //每一次http请求都会开启一个新的线程,保证在一个线程中,DbContext是唯一的 + //CallContext:是线程内部唯一的数据槽(一块内存空间/容器),相当于一个键值对数据容器,通过key获取value了,需要引入System.Runtime.Remoting.Messaging;命名空间 + DataContext db = CallContext.GetData("DbContext") as DataContext; //从 CallContext 中检索具有指定key“DbContext”的对象,并强转为DbContext + if (db == null)//线程在数据槽里面没有此上下文 { - db = Webcontext; - CallContext.SetData("DbContext", db);//放到数据槽中去,DbContext是key,db是value - } + + + db = Webcontext; + CallContext.SetData("DbContext", db);//放到数据槽中去,DbContext是key,db是value + } + return db; + } } private static class CallContext From 577c131163a55803cbfaf79b6e0634168e46aade Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Thu, 15 Apr 2021 16:49:35 +0800 Subject: [PATCH 28/31] v1.1.4 --- CC.Yi.API/Controllers/StudentController.cs | 10 +++ CC.Yi.Common/CC.Yi.Common.csproj | 1 + CC.Yi.Common/Cache/CacheHelper.cs | 40 +++++---- CC.Yi.Common/Cache/ICacheWriter.cs | 25 ++---- CC.Yi.Common/Cache/RedisCache.cs | 46 +++++++++++ CC.Yi.Common/Cache/RedisCacheService.cs | 96 ---------------------- 6 files changed, 82 insertions(+), 136 deletions(-) create mode 100644 CC.Yi.Common/Cache/RedisCache.cs delete mode 100644 CC.Yi.Common/Cache/RedisCacheService.cs diff --git a/CC.Yi.API/Controllers/StudentController.cs b/CC.Yi.API/Controllers/StudentController.cs index 45e52835..f0101f08 100644 --- a/CC.Yi.API/Controllers/StudentController.cs +++ b/CC.Yi.API/Controllers/StudentController.cs @@ -1,4 +1,5 @@ using CC.Yi.Common; +using CC.Yi.Common.Cache; using CC.Yi.IBLL; using CC.Yi.Model; using Microsoft.AspNetCore.Identity; @@ -49,6 +50,15 @@ namespace CC.Yi.API.Controllers // return Ok(); //} + #region + //下面,这里是操作reids + #endregion + [HttpGet] + public Result GetReids() + { + var data = CacheHelper.CacheWriter.GetCache("key01"); + return Result.Success(data); + } #region diff --git a/CC.Yi.Common/CC.Yi.Common.csproj b/CC.Yi.Common/CC.Yi.Common.csproj index c1361bd4..2d1ddc8f 100644 --- a/CC.Yi.Common/CC.Yi.Common.csproj +++ b/CC.Yi.Common/CC.Yi.Common.csproj @@ -10,6 +10,7 @@ + diff --git a/CC.Yi.Common/Cache/CacheHelper.cs b/CC.Yi.Common/Cache/CacheHelper.cs index 8b55955c..e77f8fbc 100644 --- a/CC.Yi.Common/Cache/CacheHelper.cs +++ b/CC.Yi.Common/Cache/CacheHelper.cs @@ -11,42 +11,40 @@ namespace CC.Yi.Common.Cache public static ICacheWriter CacheWriter { get; set; } static CacheHelper() { - //这里存在一些问题 - ContainerBuilder containerBuilder = new ContainerBuilder(); - IContainer container = containerBuilder.Build(); - CacheHelper.CacheWriter = container.Resolve(); + CacheHelper.CacheWriter = new RedisCache(); } - public static void AddCache(string key, string value, int expDate) + + + + public bool AddCache(string key, T value, DateTime expDate) { - CacheWriter.Add(key, value, expDate); + return CacheWriter.AddCache(key,value,expDate); } - //没有过期参数,表示用不过期 - public static void AddCache(string key, string value) + public bool AddCache(string key, T value) { - CacheWriter.Add(key, value); + return CacheWriter.AddCache(key, value); } - public static object GetCache(string key) + public bool RemoveCache(string key) { - return CacheWriter.Get(key); - } - public static void SetCache(string key, string value, int expDate) - { - - CacheWriter.Replace(key, value, expDate); + return CacheWriter.RemoveCache(key); } - //没有过期参数,表示用不过期 - public static void SetCache(string key, string value) + public T GetCache(string key) { - CacheWriter.Replace(key, value); + return CacheWriter.GetCache(key); } - public static void Remove(string key) + public bool SetCache(string key, T value, DateTime expDate) { - CacheWriter.Remove(key); + return CacheWriter.SetCache(key,value,expDate); + } + + public bool SetCache(string key, T value) + { + return CacheWriter.SetCache(key, value); } } diff --git a/CC.Yi.Common/Cache/ICacheWriter.cs b/CC.Yi.Common/Cache/ICacheWriter.cs index 21a6c943..712f6857 100644 --- a/CC.Yi.Common/Cache/ICacheWriter.cs +++ b/CC.Yi.Common/Cache/ICacheWriter.cs @@ -8,24 +8,11 @@ namespace CC.Yi.Common.Cache { public interface ICacheWriter { - //void AddCache(string key, object value, DateTime expDate); - //void AddCache(string key, object value); - //object GetCache(string key); - //T GetCache(string key); - //void SetCache(string key, object value, DateTime expDate); - //void SetCache(string key, object value); - //bool Delete(string key); - - string Get(string key); - - string GetString(string key); - - void AddString(string key, string value); - - void Add(string key, string value, int ExpirationTime = 20); - - void Remove(string key); - - void Replace(string key, string value, int ExpirationTime = 20); + bool AddCache(string key, T value, DateTime expDate); + bool AddCache(string key, T value); + bool RemoveCache(string key); + T GetCache(string key); + bool SetCache(string key, T value, DateTime expDate); + bool SetCache(string key, T value); } } diff --git a/CC.Yi.Common/Cache/RedisCache.cs b/CC.Yi.Common/Cache/RedisCache.cs new file mode 100644 index 00000000..a1273002 --- /dev/null +++ b/CC.Yi.Common/Cache/RedisCache.cs @@ -0,0 +1,46 @@ +using ServiceStack.Redis; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CC.Yi.Common.Cache +{ + public class RedisCache : ICacheWriter + { + private RedisClient client; + public RedisCache() + { + client = new RedisClient("127.0.0.1", 6379, "52013142020."); + } + + public bool AddCache(string key, T value, DateTime expDate) + { + return client.Add(key, value, expDate); + } + + public bool AddCache(string key, T value) + { + return client.Add(key, value); + } + + public bool RemoveCache(string key) + { + return client.Remove(key); + } + + public T GetCache(string key) + { + return client.Get(key); + } + + public bool SetCache(string key,T value, DateTime expDate) + { + return client.Set(key, value, expDate); + } + + public bool SetCache(string key, T value) + { + return client.Set(key, value); + } + } +} diff --git a/CC.Yi.Common/Cache/RedisCacheService.cs b/CC.Yi.Common/Cache/RedisCacheService.cs deleted file mode 100644 index c4dd22e9..00000000 --- a/CC.Yi.Common/Cache/RedisCacheService.cs +++ /dev/null @@ -1,96 +0,0 @@ -using Microsoft.Extensions.Caching.Distributed; -using Microsoft.Extensions.Caching.Redis; -using System; -using System.Collections.Generic; -using System.Text; - -namespace CC.Yi.Common.Cache -{ - public class RedisCacheService :ICacheWriter - { - private RedisCache _redisCache = null; - public RedisCacheService(RedisCacheOptions options) - { - _redisCache = new RedisCache(options); - } - /// - /// 获取缓存 - /// - /// 缓存key - /// - public string Get(string key) - { - try - { - if (!string.IsNullOrEmpty(key)) - { - return Encoding.UTF8.GetString(_redisCache.Get(key)); - } - else - { - return string.Empty; - } - } - catch - { - return null; - } - } - /// - /// 添加缓存 - /// - /// 缓存key - /// 缓存值 - /// 绝对过期时间(分钟) - public void Add(string key, string value, int ExpirationTime = 20) - { - if (!string.IsNullOrEmpty(key)) - { - _redisCache.Set(key, Encoding.UTF8.GetBytes(value), new DistributedCacheEntryOptions() - { - AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(ExpirationTime) - }); - } - } - - public void AddString(string key, string value) - { - _redisCache.SetString(key, value); - } - - public string GetString(string key) - - { - return _redisCache.GetString(key); - } - - /// - /// 移除缓存 - /// - /// 缓存key - public void Remove(string key) - { - if (!string.IsNullOrEmpty(key)) - { - _redisCache.Remove(key); - } - } - /// - /// 更新缓存 - /// - /// 缓存key - /// 缓存值 - /// - public void Replace(string key, string value, int ExpirationTime = 20) - { - if (!string.IsNullOrEmpty(key)) - { - _redisCache.Remove(key); - _redisCache.Set(key, Encoding.UTF8.GetBytes(value), new DistributedCacheEntryOptions() - { - AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(ExpirationTime) - }); - } - } - } -} From 7e73d35bd2730089a0b9c25e9e3006515bac3d83 Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Fri, 16 Apr 2021 19:21:56 +0800 Subject: [PATCH 29/31] v1.1.5 --- CC.Yi.API/Controllers/StudentController.cs | 5 +-- CC.Yi.API/Filter/DbContextFilter.cs | 22 ++++++++++++ CC.Yi.API/Startup.cs | 26 ++++++++++---- CC.Yi.DAL/DbContentFactory.cs | 41 ++++++++++++---------- CC.Yi.DALFactory/DbSession.cs | 2 +- 5 files changed, 68 insertions(+), 28 deletions(-) create mode 100644 CC.Yi.API/Filter/DbContextFilter.cs diff --git a/CC.Yi.API/Controllers/StudentController.cs b/CC.Yi.API/Controllers/StudentController.cs index f0101f08..b3301a7e 100644 --- a/CC.Yi.API/Controllers/StudentController.cs +++ b/CC.Yi.API/Controllers/StudentController.cs @@ -1,4 +1,5 @@ -using CC.Yi.Common; +using CC.Yi.API.Filter; +using CC.Yi.Common; using CC.Yi.Common.Cache; using CC.Yi.IBLL; using CC.Yi.Model; @@ -15,7 +16,7 @@ namespace CC.Yi.API.Controllers { [ApiController] [Route("[controller]/[action]")] - public class StudentController : ControllerBase + public class StudentController : Controller { private readonly ILogger _logger;//处理日志相关文件 diff --git a/CC.Yi.API/Filter/DbContextFilter.cs b/CC.Yi.API/Filter/DbContextFilter.cs new file mode 100644 index 00000000..82fd8aac --- /dev/null +++ b/CC.Yi.API/Filter/DbContextFilter.cs @@ -0,0 +1,22 @@ +using CC.Yi.DAL; +using CC.Yi.Model; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CC.Yi.API.Filter +{ + public class DbContextFilter : ActionFilterAttribute + { + public override void OnActionExecuting(ActionExecutingContext filterContext) + { + var cache = filterContext.HttpContext.RequestServices.GetService(typeof(DataContext)) as DataContext; + DbContentFactory.Initialize(cache); + base.OnActionExecuting(filterContext); + + } + } +} diff --git a/CC.Yi.API/Startup.cs b/CC.Yi.API/Startup.cs index abe98ff5..1e429dd7 100644 --- a/CC.Yi.API/Startup.cs +++ b/CC.Yi.API/Startup.cs @@ -1,6 +1,7 @@ using Autofac; using Autofac.Extras.DynamicProxy; +using CC.Yi.API.Filter; using CC.Yi.BLL; using CC.Yi.Common.Cache; using CC.Yi.Common.Castle; @@ -35,7 +36,7 @@ namespace CC.Yi.API 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) { @@ -45,7 +46,16 @@ namespace CC.Yi.API c.SwaggerDoc("v1", new OpenApiInfo { Title = "CC.Yi.API", Version = "v1" }); }); services.AddSession(); - services.AddMvc(); + + + + //ù + Action filters = new Action(r => { + r.Filters.Add(typeof(DbContextFilter)); + }); + services.AddMvc(filters); + + //ݿ string connection1 = Configuration["ConnectionStringBySQL"]; string connection2 = Configuration["ConnectionStringByMySQL"]; string connection3 = Configuration["ConnectionStringBySQLite"]; @@ -78,7 +88,9 @@ namespace CC.Yi.API // //options.User.RequireUniqueEmail = false;//עǷԲظ // //options.User.AllowedUserNameCharacters="abcd"//ַֻ //}).AddEntityFrameworkStores().AddDefaultTokenProviders(); - services.AddCors(options => options.AddPolicy("CorsPolicy",// + + // + services.AddCors(options => options.AddPolicy("CorsPolicy", builder => { builder.AllowAnyMethod() @@ -88,17 +100,17 @@ namespace CC.Yi.API })); } + //ʼʹú private void InitData(IServiceProvider serviceProvider) { - var serviceScope = serviceProvider.GetRequiredService().CreateScope(); + //var serviceScope = serviceProvider.GetRequiredService().CreateScope(); - var context = serviceScope.ServiceProvider.GetService(); - DbContentFactory.Initialize(context);//þ̬෽ע + //var context = serviceScope.ServiceProvider.GetService(); + //DbContentFactory.Initialize(context);//þ̬෽ע } - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { diff --git a/CC.Yi.DAL/DbContentFactory.cs b/CC.Yi.DAL/DbContentFactory.cs index 7e110070..73113740 100644 --- a/CC.Yi.DAL/DbContentFactory.cs +++ b/CC.Yi.DAL/DbContentFactory.cs @@ -9,34 +9,39 @@ namespace CC.Yi.DAL public class DbContentFactory { private static DataContext Webcontext; - + private static object myLock = new object(); public static void Initialize(DataContext webContext) { - Webcontext = webContext; + + Monitor.Enter(myLock); + { + Webcontext = webContext; + } } public static DataContext GetCurrentDbContent() { - object myLock = new object(); - lock (myLock) - { - //return new DataModelContainer(); - //一次请求共用一个上下文实例 - //每一次http请求都会开启一个新的线程,保证在一个线程中,DbContext是唯一的 - //CallContext:是线程内部唯一的数据槽(一块内存空间/容器),相当于一个键值对数据容器,通过key获取value了,需要引入System.Runtime.Remoting.Messaging;命名空间 - DataContext db = CallContext.GetData("DbContext") as DataContext; - //从 CallContext 中检索具有指定key“DbContext”的对象,并强转为DbContext + + DataContext db = CallContext.GetData("DbContext") as DataContext; if (db == null)//线程在数据槽里面没有此上下文 { - - - db = Webcontext; - CallContext.SetData("DbContext", db);//放到数据槽中去,DbContext是key,db是value - } - - return db; + db = Webcontext; + CallContext.SetData("DbContext", db);//放到数据槽中去,DbContext是key,db是value } + + try + { + Monitor.Exit(myLock); + } + catch + { + } + + + return db; + + } private static class CallContext diff --git a/CC.Yi.DALFactory/DbSession.cs b/CC.Yi.DALFactory/DbSession.cs index 7fa154f4..b6de042d 100644 --- a/CC.Yi.DALFactory/DbSession.cs +++ b/CC.Yi.DALFactory/DbSession.cs @@ -18,7 +18,7 @@ namespace CC.Yi.DALFactory try { // Attempt to save changes to the database - context.SaveChangesAsync(); + context.SaveChanges(); saved = true; } catch (DbUpdateConcurrencyException ex) From 87dc5b1363339cfbc5e48df9b9a0353d374a8c9d Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Sun, 18 Apr 2021 15:16:14 +0800 Subject: [PATCH 30/31] v1.2.0 --- CC.Yi.API/CC.Yi.API.csproj | 1 + CC.Yi.API/Controllers/StudentController.cs | 55 ++++++++++++++++ CC.Yi.API/Extension/SwaggerExtension.cs | 76 ++++++++++++++++++++++ CC.Yi.API/Startup.cs | 41 +++++++++--- CC.Yi.Common/Cache/RedisCache.cs | 2 + CC.Yi.Common/Jwt/JwtConst.cs | 12 ++++ 6 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 CC.Yi.API/Extension/SwaggerExtension.cs create mode 100644 CC.Yi.Common/Jwt/JwtConst.cs diff --git a/CC.Yi.API/CC.Yi.API.csproj b/CC.Yi.API/CC.Yi.API.csproj index d2836df9..6b3e84cf 100644 --- a/CC.Yi.API/CC.Yi.API.csproj +++ b/CC.Yi.API/CC.Yi.API.csproj @@ -7,6 +7,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CC.Yi.API/Controllers/StudentController.cs b/CC.Yi.API/Controllers/StudentController.cs index b3301a7e..ecbe8d2f 100644 --- a/CC.Yi.API/Controllers/StudentController.cs +++ b/CC.Yi.API/Controllers/StudentController.cs @@ -1,15 +1,21 @@ using CC.Yi.API.Filter; using CC.Yi.Common; using CC.Yi.Common.Cache; +using CC.Yi.Common.Jwt; using CC.Yi.IBLL; using CC.Yi.Model; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; using System; using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; using System.Linq; +using System.Security.Claims; +using System.Text; using System.Threading.Tasks; namespace CC.Yi.API.Controllers @@ -61,12 +67,58 @@ namespace CC.Yi.API.Controllers return Result.Success(data); } + #region + //下面,权限验证 + #endregion + + //发送令牌 + [HttpGet] + public Result Login(string role) + { + string userName = "admin"; + var claims = new[] + { + new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") , + new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}"), + new Claim(ClaimTypes.Name, userName), + new Claim(ClaimTypes.Role,role) + + }; + var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey)); + var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); + + var token = new JwtSecurityToken( + issuer: JwtConst.Domain, + audience: JwtConst.Domain, + claims: claims, + expires: DateTime.Now.AddMinutes(30), + signingCredentials: creds); + + var tokenData= new JwtSecurityTokenHandler().WriteToken(token); + return Result.Success("欢迎你!管理员!").SetData(new { token= tokenData }); + } + + [HttpGet] + [Authorize(Policy = "myadmin")]//基于策略的验证 + public Result MyAdmin() + { + return Result.Success("欢迎你!管理员!"); + } + + [HttpGet] + [Authorize(Roles ="user")]//基于角色的验证 + public Result MyUser() + { + return Result.Success("欢迎你!游客!"); + } + #region //下面,经典的 增删改查 即为简易--Yi意框架 //注意:请确保你的数据库中存在合理的数据 #endregion [HttpGet] + [DbContextFilter] public async Task GetTest()//查 { _logger.LogInformation("调用查方法"); @@ -74,6 +126,7 @@ namespace CC.Yi.API.Controllers return Result.Success("查询成功").SetData(data); } [HttpGet] + [DbContextFilter] public Result AddTest()//增 { _logger.LogInformation("调用增方法"); @@ -90,6 +143,7 @@ namespace CC.Yi.API.Controllers } [HttpGet] + [DbContextFilter] public Result RemoveTest()//删 { _logger.LogInformation("调用删方法"); @@ -103,6 +157,7 @@ namespace CC.Yi.API.Controllers } } [HttpGet] + [DbContextFilter] public Result UpdateTest()//改 { _logger.LogInformation("调用改方法"); diff --git a/CC.Yi.API/Extension/SwaggerExtension.cs b/CC.Yi.API/Extension/SwaggerExtension.cs new file mode 100644 index 00000000..6db50f61 --- /dev/null +++ b/CC.Yi.API/Extension/SwaggerExtension.cs @@ -0,0 +1,76 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; +using System; +using System.IO; + +namespace CC.Yi.API.Extension +{ + /// + /// Swagger文档扩展方法 + /// + public static class SwaggerExtension + { + public static IServiceCollection AddSwaggerService(this IServiceCollection services) + { + var apiInfo = new OpenApiInfo + { + Title = "Yi意框架-API接口", + Version = "v1", + Contact = new OpenApiContact { Name = "橙子", Email = "454313500@qq.com", Url = new System.Uri("https://jiftcc.com") } + }; + #region 注册Swagger服务 + services.AddSwaggerGen(c => + { + c.SwaggerDoc("v1", apiInfo); + + //添加注释服务 + //为 Swagger JSON and UI设置xml文档注释路径 + //获取应用程序所在目录(绝对路径,不受工作目录影响,建议采用此方法获取路径使用windwos&Linux) + var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location); + var apiXmlPath = Path.Combine(basePath, @"ApiDoc.xml");//控制器层注释 + var entityXmlPath = Path.Combine(basePath, @"Model\ModelDoc.xml");//实体注释 + //c.IncludeXmlComments(apiXmlPath, true);//true表示显示控制器注释 + //c.IncludeXmlComments(entityXmlPath); + + //添加控制器注释 + //c.DocumentFilter(); + + //添加header验证信息 + //c.OperationFilter(); + //var security = new Dictionary> { { "Bearer", new string[] { } }, }; + + c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme() + { + Description = "文本框里输入从服务器获取的Token。格式为:Bearer + 空格+token",//JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\" + Name = "Authorization",////jwt默认的参数名称 + In = ParameterLocation.Header,////jwt默认存放Authorization信息的位置(请求头中) + Type = SecuritySchemeType.ApiKey, + }); + c.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { new OpenApiSecurityScheme + { + Reference = new OpenApiReference() + { + Id = "Bearer", + Type = ReferenceType.SecurityScheme + } + }, Array.Empty() } + }); + }); + #endregion + + return services; + } + + public static void UseSwaggerService(this IApplicationBuilder app) + { + //在 Startup.Configure 方法中,启用中间件为生成的 JSON 文档和 Swagger UI 提供服务: + // Enable middleware to serve generated Swagger as a JSON endpoint. + app.UseSwagger(); + app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "JwtTest v1")); + } + + } +} diff --git a/CC.Yi.API/Startup.cs b/CC.Yi.API/Startup.cs index 1e429dd7..55003dc4 100644 --- a/CC.Yi.API/Startup.cs +++ b/CC.Yi.API/Startup.cs @@ -1,14 +1,17 @@ using Autofac; using Autofac.Extras.DynamicProxy; +using CC.Yi.API.Extension; using CC.Yi.API.Filter; using CC.Yi.BLL; using CC.Yi.Common.Cache; using CC.Yi.Common.Castle; +using CC.Yi.Common.Jwt; using CC.Yi.DAL; using CC.Yi.IBLL; using CC.Yi.IDAL; using CC.Yi.Model; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; @@ -19,10 +22,12 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Threading.Tasks; namespace CC.Yi.API @@ -39,19 +44,40 @@ namespace CC.Yi.API public void ConfigureServices(IServiceCollection services) { + // Jwt + services.AddAuthorization(options => + { + //ûڲԵ֤ + options.AddPolicy("myadmin", policy => + policy.RequireRole("admin")); + }); + + + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => { + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = true,//Ƿ֤Issuer + ValidateAudience = true,//Ƿ֤Audience + ValidateLifetime = true,//Ƿ֤ʧЧʱ + ClockSkew = TimeSpan.FromSeconds(30), + ValidateIssuerSigningKey = true,//Ƿ֤SecurityKey + ValidAudience = JwtConst.Domain,//Audience + ValidIssuer = JwtConst.Domain,//Issuerǰǩjwtһ + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey))//õSecurityKey + }; + }); + services.AddControllers(); - services.AddSwaggerGen(c => - { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "CC.Yi.API", Version = "v1" }); - }); + services.AddSwaggerService(); services.AddSession(); //ù Action filters = new Action(r => { - r.Filters.Add(typeof(DbContextFilter)); + //r.Filters.Add(typeof(DbContextFilter)); }); services.AddMvc(filters); @@ -117,8 +143,7 @@ namespace CC.Yi.API if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); - app.UseSwagger(); - app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "CC.Yi.API v1")); + app.UseSwaggerService(); } //app.UseAuthentication(); @@ -126,7 +151,7 @@ namespace CC.Yi.API app.UseHttpsRedirection(); app.UseSession(); app.UseRouting(); - + app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => diff --git a/CC.Yi.Common/Cache/RedisCache.cs b/CC.Yi.Common/Cache/RedisCache.cs index a1273002..3e695f02 100644 --- a/CC.Yi.Common/Cache/RedisCache.cs +++ b/CC.Yi.Common/Cache/RedisCache.cs @@ -8,6 +8,8 @@ namespace CC.Yi.Common.Cache public class RedisCache : ICacheWriter { private RedisClient client; + public string redisIp { get; set; } + public RedisCache() { client = new RedisClient("127.0.0.1", 6379, "52013142020."); diff --git a/CC.Yi.Common/Jwt/JwtConst.cs b/CC.Yi.Common/Jwt/JwtConst.cs new file mode 100644 index 00000000..1e7713ff --- /dev/null +++ b/CC.Yi.Common/Jwt/JwtConst.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CC.Yi.Common.Jwt +{ + public class JwtConst + { + public const string SecurityKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB"; + public const string Domain = "http://localhost:5000"; + } +} From 10903bb218e2f52d3676565c0d2c51bfffd4ab10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sun, 18 Apr 2021 15:49:17 +0800 Subject: [PATCH 31/31] update README.md. --- README.md | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6755925a..953473d6 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,61 @@ # CC.Yi #### 介绍 -基于.NET5的MVC三层架构的高并发高解耦简易型框架--Yi意框架(意义是为了开发更简易) +基于.NET5的前后端分离三层架构的高并发高解耦简易型框架--Yi意框架(意义是为了开发更简易) -第一版开发完成时间:2021/3/19 (请记住,这是一个值得纪念的日子) - -为了更简易的开发,我们在2021/3/27 加入了vue分支(我们将持续更新) +第一版开发公布时间:2021/3/19 (请记住,这是一个值得纪念的日子) +为了适配更简易的开发,我们在2021/3/27 加入了Yi-Easy分支(我们将持续更新) #### 软件架构 -架构:.NET5(后期我们将集成数据+前端Vue,让开发更加简易!) + +Yi意框架 + + Yi意框架源码 + + CC.Yi(.Net5核心版本) + + CC.Yi.Easy(.Net5精简版本) + + Yi意框架应用(图片管理系统) + + CC.Yi.PictureManagement(Betav0.0.1Yi框架后端) + + CC.Yi.PictureManagement(Vue-ElementUI前端) + + Yi意框架应用(作业管理系统) + + CC.Yi.WorkManagement(v1.0.0Yi意框架后端) + + CC.Yi.WorkManagement(Vue-ElementUI前端) + + Yi意框架应用(权限管理系统) + + CC.Yi.RolePermission(v1.1.0Yi意框架后端) + + CC.Yi.RolePermission(Vue-Vuetify前端) + + Yi意框架应用(题库管理系统) + + CC.Yi.QuestionBank(v1.2.0Yi意框架后端) + + CC.Yi.QuestionBank(Vue-Vuetify前端) + + +架构:后端.NET5 ,前端Vue 支持的数据库: SQL Server,MySQL,SQLite,reidis 操作系统:Windows,Linux -扩展:EFcore,Autofac,Identity,Castle,Redis,Swagger,T4 ,Nlog(后期我们会添加更多) +扩展:EFcore,Autofac,Identity,Castle,Redis,Swagger,T4 ,Nlog ,Jwt -封装:Json处理模块,滑动验证码模块,base64图片处理模块(后期我们会添加更多) +封装:Json处理模块,滑动验证码模块,base64图片处理模块,HTTP请求 思想:简单工厂模式,抽象工厂模式,观察者模式,面向AOP思想,面向对象开发 +其他: nginx前后端集群配置,前后端跨域设置,权限认证配置,swaggerToken配置 + #### 目录结构 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0321/023715_59bef411_3049273.png "屏幕截图.png")