├── .gitignore ├── .vs └── DotNetCoreStudyDemo │ └── v16 │ └── .suo ├── AopConsoleDemo ├── AopConsoleDemo.csproj ├── MyIntercept.cs ├── MyProxy.cs └── Program.cs ├── AopModel ├── AopModel.csproj └── User.cs ├── AopService ├── AopService.csproj ├── IUserService.cs └── UserService.cs ├── DotNetCoreStudyDemo.sln ├── EFCoreTestDemo ├── Controllers │ ├── UserController.cs │ └── WeatherForecastController.cs ├── EFCoreTestDemo.csproj ├── Migrations │ ├── 20201107081134_InitialName.Designer.cs │ ├── 20201107081134_InitialName.cs │ ├── 20201107152638_InitialName1.Designer.cs │ ├── 20201107152638_InitialName1.cs │ ├── 20201108084351_UpdateNameAndType.Designer.cs │ ├── 20201108084351_UpdateNameAndType.cs │ └── MyTestDbContextModelSnapshot.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── WeatherForecast.cs ├── appsettings.Development.json └── appsettings.json ├── EFCoreTestModel ├── EFCoreTestModel.csproj └── User.cs ├── EFCoreTestRespository ├── EFCoreTestRespository.csproj ├── IUserRespository.cs ├── MyTestDbContext.cs └── UserRespository.cs ├── EFCoreTestService ├── EFCoreTestService.csproj ├── IUserService.cs └── UserService.cs ├── ExportExcelDemo ├── ExportExcelDemo.sln └── ExportExcelDemo │ ├── Controllers │ ├── ExportExcelController.cs │ └── WeatherForecastController.cs │ ├── ExportExcelDemo.csproj │ ├── ExportFile.xlsx │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Startup.cs │ ├── WeatherForecast.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── HttpClientConsoleDemo ├── HttpClientConsoleDemo.csproj └── Program.cs ├── HttpClientFactoryDemo ├── HttpClientFactoryDemo.sln └── HttpClientFactoryDemo │ ├── Controllers │ ├── TestHttpClientFactoryController.cs │ └── WeatherForecastController.cs │ ├── HttpClientFactoryDemo.csproj │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Startup.cs │ ├── WeatherForecast.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── MediatRAspNetCoreDemo ├── CommandMsg │ ├── UserAddMsg.cs │ └── UserAddMsgHandler.cs ├── Controllers │ ├── UserController.cs │ └── WeatherForecastController.cs ├── EventMsg │ ├── UserAddSuccessEMailHandler.cs │ ├── UserAddSuccessMessageHandler.cs │ ├── UserAddSuccessMsg.cs │ └── UserAddSuccessWeChatHandler.cs ├── MediatRAspNetCoreDemo.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── WeatherForecast.cs ├── appsettings.Development.json └── appsettings.json ├── MediatRConsoleDemo ├── MediatRConsoleDemo.csproj ├── NotificationMsg │ ├── MyNotificationHandler.cs │ ├── MyNotificationHandler1.cs │ └── MyNotificationMsg.cs ├── Program.cs └── RequestMsg │ ├── MyRequestHandler.cs │ ├── MyRequestHandler1.cs │ └── MyRequestMsg.cs ├── MediatorDemo ├── Colleague │ ├── HouseBuyer1.cs │ ├── HouseBuyer2.cs │ ├── HouseSeller1.cs │ ├── HouseSeller2.cs │ └── People.cs ├── Mediator │ ├── AnJuKe.cs │ └── HouseMediator.cs ├── MediatorDemo.csproj └── Program.cs ├── MemoryCacheConsoleDemo ├── IUserService.cs ├── MemoryCacheConsoleDemo.csproj ├── MyCacheAttribute.cs ├── MyInterceptor.cs ├── Program.cs └── UserService.cs ├── MemoryCacheWebApiDemo ├── Controllers │ └── WeatherForecastController.cs ├── MemoryCacheWebApiDemo.csproj ├── MyCacheAttribute.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── ResourceFilter.cs ├── Startup.cs ├── WeatherForecast.cs ├── appsettings.Development.json └── appsettings.json ├── MvcFilterDemo ├── Controllers │ └── WeatherForecastController.cs ├── Filters │ ├── MyActionFilter.cs │ ├── MyActionFilter1.cs │ ├── MyActionFilter2.cs │ ├── MyAuthorizeFilter.cs │ ├── MyExceptionFilter.cs │ ├── MyNoAttributeActionFilter.cs │ ├── MyResourceFilter.cs │ └── MyResultFilter.cs ├── MvcFilterDemo.csproj ├── MyFilterFactoryAttribute.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── WeatherForecast.cs ├── appsettings.Development.json └── appsettings.json ├── PDFDemo ├── Controllers │ ├── PDFTestController.cs │ └── WeatherForecastController.cs ├── Models │ └── Zoe.cs ├── PDFDemo.csproj ├── Program.cs ├── Properties │ ├── PublishProfiles │ │ └── FolderProfile.pubxml │ └── launchSettings.json ├── Rotativa │ ├── Linux │ │ ├── libwkhtmltox.so │ │ └── wkhtmltopdf │ ├── Mac │ │ └── wkhtmltopdf │ └── Windows │ │ └── wkhtmltopdf.exe ├── Startup.cs ├── Views │ ├── Zoe.cshtml │ └── ZoeData.cshtml ├── WeatherForecast.cs ├── appsettings.Development.json └── appsettings.json ├── README.md ├── SwaggerDemo ├── Controllers │ ├── ProductController.cs │ ├── UserController.cs │ └── WeatherForecastController.cs ├── Permission │ ├── PermissionHandler.cs │ └── PermissionRequirement.cs ├── Program.cs ├── Properties │ ├── PublishProfiles │ │ ├── FolderProfile.pubxml │ │ └── FolderProfile.pubxml.user │ └── launchSettings.json ├── Startup.cs ├── SwaggerDemo.csproj ├── SwaggerDemo.csproj.user ├── SwaggerDemo.xml ├── TestSwaggerModel.xml ├── WeatherForecast.cs ├── appsettings.Development.json └── appsettings.json ├── TestSwaggerModel ├── TestSwaggerModel.csproj ├── UserConditon.cs └── UserModel.cs └── test └── test.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from om https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # 7 | 8 | # User-specific files 9 | *.suo 10 | *.user 11 | *.userosscache 12 | *. 13 | *.sln.docstates 14 | 15 | # 16 | 17 | # User-specific files (MonoDevelop/Xamarin Studio) 18 | *.userprefs 19 | 20 | # Build results 21 | [Dd]ebug/ 22 | [Dd]ebugPublic/ 23 | [Rr]elease/ 24 | [Rr]eleases/ 25 | x64/ 26 | x86/ 27 | bld/ 28 | [Bb]in/ 29 | [Oo]bj/ 30 | [Ll]og/ 31 | 32 | # Visual Studio 2015/2017 cache/options directory 33 | .vs/ 34 | # Uncomment if you have tasks that create the project's static files in wwwroot 35 | #wwwroot/ 36 | 37 | # Visual Studio 2017 auto generated files 38 | Generated\ Files/ 39 | 40 | # MSTest test Results 41 | [Tt]est[Rr]esult*/ 42 | [Bb]uild[Ll]og.* 43 | 44 | # NUNIT 45 | *. 46 | *.VisualState.xml 47 | Tes 48 | ml 49 | TestResult.xml 50 | 51 | # 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | ts 60 | BenchmarkDotNet.Artifacts/ 61 | 62 | # 63 | 64 | # .NET Core 65 | re 66 | project.lock.json 67 | pro 68 | on 69 | project.fragment.lock.json 70 | art 71 | artifacts/ 72 | 73 | # StyleCop 74 | op 75 | StyleCopReport.xml 76 | 77 | # 78 | 79 | # Files built by Visual Studio 80 | *_i.c 81 | *_p.c 82 | *_i.h 83 | *.ilk 84 | *.meta 85 | *.obj 86 | *.iobj 87 | *.pch 88 | *.pdb 89 | *.ipdb 90 | *.pgc 91 | *.pgd 92 | *.rsp 93 | *.sbr 94 | *.tlb 95 | *.tli 96 | *.tlh 97 | *.tmp 98 | *.tmp_proj 99 | *.log 100 | *.vspscc 101 | *.vssscc 102 | .builds 103 | *.pidb 104 | *.svclog 105 | *.scc 106 | 107 | # Chutzpah Test files 108 | _Chutzpah* 109 | 110 | # Visual C++ cache files 111 | ipch/ 112 | *.aps 113 | *.ncb 114 | *.opendb 115 | *.opensdf 116 | *.sdf 117 | *.cachefile 118 | *. 119 | *.VC.db 120 | *.V 121 | *. 122 | *.VC.VC.opendb 123 | 124 | # 125 | 126 | # Visual Studio profiler 127 | *.psess 128 | *.vsp 129 | *.vspx 130 | *.sap 131 | 132 | # Visual Studio Trace Files 133 | *.e2e 134 | 135 | # TFS 2012 Local Workspace 136 | $tf/ 137 | 138 | # Guidance Automation Toolkit 139 | *.gpState 140 | 141 | # ReSharper is a .NET coding add-in 142 | _ReSharper*/ 143 | *.[Rr]e[Ss]harper 144 | *. 145 | *.DotSettings.user 146 | 147 | er 148 | 149 | # JustCode is a .NET coding add-in 150 | .JustCode 151 | 152 | # TeamCity is a build add-in 153 | _TeamCity* 154 | 155 | # DotCover is a Code Coverage Tool 156 | *.dotCover 157 | 158 | # AxoCover is a Code Coverage Tool 159 | .axoCover/* 160 | !.axoCover/er/settings.json 161 | 162 | # 163 | 164 | # Visual Studio code coverage results 165 | *.coverage 166 | *.coveragexml 167 | 168 | # NCrunch 169 | _NCrunch_* 170 | .*crunch*.h*.local.xml 171 | nCr 172 | nCrunchTemp_* 173 | 174 | # MightyMoose 175 | *.mm.* 176 | .* 177 | AutoTest.Net/ 178 | 179 | # 180 | 181 | # Web workbench (sass) 182 | .sass-cache/ 183 | 184 | # Installshield output folder 185 | [Ee]xpress/ 186 | 187 | # DocProject is a documentation genera 188 | /node_modules -------------------------------------------------------------------------------- /.vs/DotNetCoreStudyDemo/v16/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyq025/DotNetCoreStudyDemo/8ca9932e1cbb86ce33b982d10c914b8049436850/.vs/DotNetCoreStudyDemo/v16/.suo -------------------------------------------------------------------------------- /AopConsoleDemo/AopConsoleDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /AopConsoleDemo/MyIntercept.cs: -------------------------------------------------------------------------------- 1 | using Castle.DynamicProxy; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace AopConsoleDemo 7 | { 8 | public class MyIntercept : IInterceptor 9 | { 10 | public void Intercept(IInvocation invocation) 11 | { 12 | //执行原有方法之前 13 | Console.WriteLine("增加用户前执行业务"); 14 | 15 | //执行原有方法 16 | invocation.Proceed(); 17 | 18 | //执行原有方法之后 19 | Console.WriteLine("增加用户后执行业务"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /AopConsoleDemo/MyProxy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using System.Text; 5 | 6 | namespace AopConsoleDemo 7 | { 8 | public class MyProxy : DispatchProxy 9 | { 10 | //具体类型 11 | public object TargetClass { get; set; } 12 | 13 | protected override object Invoke(MethodInfo targetMethod, object[] args) 14 | { 15 | Console.WriteLine("增加用户前执行业务"); 16 | 17 | //调用原有方法 18 | targetMethod.Invoke(TargetClass, args); 19 | 20 | Console.WriteLine("增加用户后执行业务"); 21 | return true; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /AopConsoleDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using AopModel; 2 | using AopService; 3 | using Castle.DynamicProxy; 4 | using System; 5 | using System.Reflection; 6 | 7 | namespace AopConsoleDemo 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | Console.WriteLine("========原始需求========="); 14 | User user = new User { Name = "Zoe", Age = 18 }; 15 | IUserService userService = new UserService(); 16 | // 模拟增加一个用户 17 | userService.AddUser(user); 18 | 19 | Console.WriteLine("========动态代理 实现新需求========="); 20 | //1. 创建代理对象 21 | IUserService userService1 = DispatchProxy.Create(); 22 | //2. 因为调用的是实例方法,需要传提具体类型 23 | ((MyProxy)userService1).TargetClass = new UserService(); 24 | userService1.AddUser(user); 25 | 26 | Console.WriteLine("=============Castle.Core方式=============="); 27 | //先实例化一个代理类生成器 28 | ProxyGenerator generator = new ProxyGenerator(); 29 | //通过代理类生成器创建 30 | var u = generator.CreateInterfaceProxyWithTarget(new UserService(), new MyIntercept()); 31 | u.AddUser(user); 32 | Console.ReadLine(); 33 | 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /AopModel/AopModel.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AopModel/User.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace AopModel 6 | { 7 | public class User 8 | { 9 | public string Name { get; set; } 10 | public int Age { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /AopService/AopService.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /AopService/IUserService.cs: -------------------------------------------------------------------------------- 1 | using AopModel; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace AopService 7 | { 8 | public interface IUserService 9 | { 10 | bool AddUser(User user); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /AopService/UserService.cs: -------------------------------------------------------------------------------- 1 | using AopModel; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace AopService 7 | { 8 | public class UserService : IUserService 9 | { 10 | public bool AddUser(User user) 11 | { 12 | Console.WriteLine("用户添加成功"); 13 | return true; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DotNetCoreStudyDemo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30114.105 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SwaggerDemo", "SwaggerDemo\SwaggerDemo.csproj", "{D2F19E3A-FD2C-49EE-944F-160177C53E6A}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestSwaggerModel", "TestSwaggerModel\TestSwaggerModel.csproj", "{97B185A2-92CC-46A7-ACF1-DBE930CC899E}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MvcFilterDemo", "MvcFilterDemo\MvcFilterDemo.csproj", "{9D42BBD8-F21C-4287-BFFB-B665859583CE}" 11 | EndProject 12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MediatRDemo", "MediatRDemo", "{7BF8B6E0-2B94-4402-B205-06AEE5BBA53E}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediatRConsoleDemo", "MediatRConsoleDemo\MediatRConsoleDemo.csproj", "{202B46C4-4BBD-4AE9-B207-05CE6E238524}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediatorDemo", "MediatorDemo\MediatorDemo.csproj", "{CE33DB55-3394-4C37-B3AC-6C131C4B4EA7}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediatRAspNetCoreDemo", "MediatRAspNetCoreDemo\MediatRAspNetCoreDemo.csproj", "{5D9497C4-D236-41D3-A500-30FD1DEB4AFB}" 19 | EndProject 20 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EFCoreDemo", "EFCoreDemo", "{CE1CBAFE-9F39-44C4-84D0-78D17C9BA4D9}" 21 | EndProject 22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCoreTestDemo", "EFCoreTestDemo\EFCoreTestDemo.csproj", "{48209268-8D24-4217-814E-797AF98BE053}" 23 | EndProject 24 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCoreTestModel", "EFCoreTestModel\EFCoreTestModel.csproj", "{191EF22E-9CC8-44A4-84BE-E8D7607D448A}" 25 | EndProject 26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCoreTestService", "EFCoreTestService\EFCoreTestService.csproj", "{10C77DB3-8974-4AD3-B627-F1B869467202}" 27 | EndProject 28 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCoreTestRespository", "EFCoreTestRespository\EFCoreTestRespository.csproj", "{2F736444-E9DB-488C-AD34-5B3AE78DCE91}" 29 | EndProject 30 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "test", "test\test.csproj", "{FFAAC7D0-FA8E-41C3-9C59-31BFBCA739E2}" 31 | EndProject 32 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PDFDemo", "PDFDemo\PDFDemo.csproj", "{7C055ABF-24EC-4407-BC9D-BFA64CE7DD67}" 33 | EndProject 34 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MemoryCacheConsoleDemo", "MemoryCacheConsoleDemo\MemoryCacheConsoleDemo.csproj", "{68B48C09-DD20-4728-8FAC-91302CF30929}" 35 | EndProject 36 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MemoryCacheDemo", "MemoryCacheDemo", "{E25144DA-A80B-4542-82F0-32A835C76688}" 37 | EndProject 38 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MemoryCacheWebApiDemo", "MemoryCacheWebApiDemo\MemoryCacheWebApiDemo.csproj", "{1479D03A-E1FD-4AFC-8066-AE7FEB2FD93C}" 39 | EndProject 40 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AopDemo", "AopDemo", "{85DCDEC4-F74C-4865-8145-F666D73A68A8}" 41 | EndProject 42 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AopConsoleDemo", "AopConsoleDemo\AopConsoleDemo.csproj", "{F5FBF16E-F917-41B2-BD5C-E7716F72C298}" 43 | EndProject 44 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AopModel", "AopModel\AopModel.csproj", "{4572E923-C473-4DBB-ABFD-FEC8F105B2C3}" 45 | EndProject 46 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AopService", "AopService\AopService.csproj", "{DE066C01-1C3D-46F5-B9B2-9BE35B14EB5A}" 47 | EndProject 48 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HttpClientAndHttpClientFactoryDemo", "HttpClientAndHttpClientFactoryDemo", "{ED24AE38-001A-4E95-B024-9362CCFD8671}" 49 | EndProject 50 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HttpClientConsoleDemo", "HttpClientConsoleDemo\HttpClientConsoleDemo.csproj", "{DB1DF5AA-B892-48F0-8DED-7DBEEC327F9A}" 51 | EndProject 52 | Global 53 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 54 | Debug|Any CPU = Debug|Any CPU 55 | Release|Any CPU = Release|Any CPU 56 | EndGlobalSection 57 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 58 | {D2F19E3A-FD2C-49EE-944F-160177C53E6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {D2F19E3A-FD2C-49EE-944F-160177C53E6A}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {D2F19E3A-FD2C-49EE-944F-160177C53E6A}.Release|Any CPU.ActiveCfg = Release|Any CPU 61 | {D2F19E3A-FD2C-49EE-944F-160177C53E6A}.Release|Any CPU.Build.0 = Release|Any CPU 62 | {97B185A2-92CC-46A7-ACF1-DBE930CC899E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 63 | {97B185A2-92CC-46A7-ACF1-DBE930CC899E}.Debug|Any CPU.Build.0 = Debug|Any CPU 64 | {97B185A2-92CC-46A7-ACF1-DBE930CC899E}.Release|Any CPU.ActiveCfg = Release|Any CPU 65 | {97B185A2-92CC-46A7-ACF1-DBE930CC899E}.Release|Any CPU.Build.0 = Release|Any CPU 66 | {9D42BBD8-F21C-4287-BFFB-B665859583CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 67 | {9D42BBD8-F21C-4287-BFFB-B665859583CE}.Debug|Any CPU.Build.0 = Debug|Any CPU 68 | {9D42BBD8-F21C-4287-BFFB-B665859583CE}.Release|Any CPU.ActiveCfg = Release|Any CPU 69 | {9D42BBD8-F21C-4287-BFFB-B665859583CE}.Release|Any CPU.Build.0 = Release|Any CPU 70 | {202B46C4-4BBD-4AE9-B207-05CE6E238524}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 71 | {202B46C4-4BBD-4AE9-B207-05CE6E238524}.Debug|Any CPU.Build.0 = Debug|Any CPU 72 | {202B46C4-4BBD-4AE9-B207-05CE6E238524}.Release|Any CPU.ActiveCfg = Release|Any CPU 73 | {202B46C4-4BBD-4AE9-B207-05CE6E238524}.Release|Any CPU.Build.0 = Release|Any CPU 74 | {CE33DB55-3394-4C37-B3AC-6C131C4B4EA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 75 | {CE33DB55-3394-4C37-B3AC-6C131C4B4EA7}.Debug|Any CPU.Build.0 = Debug|Any CPU 76 | {CE33DB55-3394-4C37-B3AC-6C131C4B4EA7}.Release|Any CPU.ActiveCfg = Release|Any CPU 77 | {CE33DB55-3394-4C37-B3AC-6C131C4B4EA7}.Release|Any CPU.Build.0 = Release|Any CPU 78 | {5D9497C4-D236-41D3-A500-30FD1DEB4AFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 79 | {5D9497C4-D236-41D3-A500-30FD1DEB4AFB}.Debug|Any CPU.Build.0 = Debug|Any CPU 80 | {5D9497C4-D236-41D3-A500-30FD1DEB4AFB}.Release|Any CPU.ActiveCfg = Release|Any CPU 81 | {5D9497C4-D236-41D3-A500-30FD1DEB4AFB}.Release|Any CPU.Build.0 = Release|Any CPU 82 | {48209268-8D24-4217-814E-797AF98BE053}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 83 | {48209268-8D24-4217-814E-797AF98BE053}.Debug|Any CPU.Build.0 = Debug|Any CPU 84 | {48209268-8D24-4217-814E-797AF98BE053}.Release|Any CPU.ActiveCfg = Release|Any CPU 85 | {48209268-8D24-4217-814E-797AF98BE053}.Release|Any CPU.Build.0 = Release|Any CPU 86 | {191EF22E-9CC8-44A4-84BE-E8D7607D448A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 87 | {191EF22E-9CC8-44A4-84BE-E8D7607D448A}.Debug|Any CPU.Build.0 = Debug|Any CPU 88 | {191EF22E-9CC8-44A4-84BE-E8D7607D448A}.Release|Any CPU.ActiveCfg = Release|Any CPU 89 | {191EF22E-9CC8-44A4-84BE-E8D7607D448A}.Release|Any CPU.Build.0 = Release|Any CPU 90 | {10C77DB3-8974-4AD3-B627-F1B869467202}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 91 | {10C77DB3-8974-4AD3-B627-F1B869467202}.Debug|Any CPU.Build.0 = Debug|Any CPU 92 | {10C77DB3-8974-4AD3-B627-F1B869467202}.Release|Any CPU.ActiveCfg = Release|Any CPU 93 | {10C77DB3-8974-4AD3-B627-F1B869467202}.Release|Any CPU.Build.0 = Release|Any CPU 94 | {2F736444-E9DB-488C-AD34-5B3AE78DCE91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 95 | {2F736444-E9DB-488C-AD34-5B3AE78DCE91}.Debug|Any CPU.Build.0 = Debug|Any CPU 96 | {2F736444-E9DB-488C-AD34-5B3AE78DCE91}.Release|Any CPU.ActiveCfg = Release|Any CPU 97 | {2F736444-E9DB-488C-AD34-5B3AE78DCE91}.Release|Any CPU.Build.0 = Release|Any CPU 98 | {FFAAC7D0-FA8E-41C3-9C59-31BFBCA739E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 99 | {FFAAC7D0-FA8E-41C3-9C59-31BFBCA739E2}.Debug|Any CPU.Build.0 = Debug|Any CPU 100 | {FFAAC7D0-FA8E-41C3-9C59-31BFBCA739E2}.Release|Any CPU.ActiveCfg = Release|Any CPU 101 | {FFAAC7D0-FA8E-41C3-9C59-31BFBCA739E2}.Release|Any CPU.Build.0 = Release|Any CPU 102 | {7C055ABF-24EC-4407-BC9D-BFA64CE7DD67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 103 | {7C055ABF-24EC-4407-BC9D-BFA64CE7DD67}.Debug|Any CPU.Build.0 = Debug|Any CPU 104 | {7C055ABF-24EC-4407-BC9D-BFA64CE7DD67}.Release|Any CPU.ActiveCfg = Release|Any CPU 105 | {7C055ABF-24EC-4407-BC9D-BFA64CE7DD67}.Release|Any CPU.Build.0 = Release|Any CPU 106 | {68B48C09-DD20-4728-8FAC-91302CF30929}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 107 | {68B48C09-DD20-4728-8FAC-91302CF30929}.Debug|Any CPU.Build.0 = Debug|Any CPU 108 | {68B48C09-DD20-4728-8FAC-91302CF30929}.Release|Any CPU.ActiveCfg = Release|Any CPU 109 | {68B48C09-DD20-4728-8FAC-91302CF30929}.Release|Any CPU.Build.0 = Release|Any CPU 110 | {1479D03A-E1FD-4AFC-8066-AE7FEB2FD93C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 111 | {1479D03A-E1FD-4AFC-8066-AE7FEB2FD93C}.Debug|Any CPU.Build.0 = Debug|Any CPU 112 | {1479D03A-E1FD-4AFC-8066-AE7FEB2FD93C}.Release|Any CPU.ActiveCfg = Release|Any CPU 113 | {1479D03A-E1FD-4AFC-8066-AE7FEB2FD93C}.Release|Any CPU.Build.0 = Release|Any CPU 114 | {F5FBF16E-F917-41B2-BD5C-E7716F72C298}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 115 | {F5FBF16E-F917-41B2-BD5C-E7716F72C298}.Debug|Any CPU.Build.0 = Debug|Any CPU 116 | {F5FBF16E-F917-41B2-BD5C-E7716F72C298}.Release|Any CPU.ActiveCfg = Release|Any CPU 117 | {F5FBF16E-F917-41B2-BD5C-E7716F72C298}.Release|Any CPU.Build.0 = Release|Any CPU 118 | {4572E923-C473-4DBB-ABFD-FEC8F105B2C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 119 | {4572E923-C473-4DBB-ABFD-FEC8F105B2C3}.Debug|Any CPU.Build.0 = Debug|Any CPU 120 | {4572E923-C473-4DBB-ABFD-FEC8F105B2C3}.Release|Any CPU.ActiveCfg = Release|Any CPU 121 | {4572E923-C473-4DBB-ABFD-FEC8F105B2C3}.Release|Any CPU.Build.0 = Release|Any CPU 122 | {DE066C01-1C3D-46F5-B9B2-9BE35B14EB5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 123 | {DE066C01-1C3D-46F5-B9B2-9BE35B14EB5A}.Debug|Any CPU.Build.0 = Debug|Any CPU 124 | {DE066C01-1C3D-46F5-B9B2-9BE35B14EB5A}.Release|Any CPU.ActiveCfg = Release|Any CPU 125 | {DE066C01-1C3D-46F5-B9B2-9BE35B14EB5A}.Release|Any CPU.Build.0 = Release|Any CPU 126 | {DB1DF5AA-B892-48F0-8DED-7DBEEC327F9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 127 | {DB1DF5AA-B892-48F0-8DED-7DBEEC327F9A}.Debug|Any CPU.Build.0 = Debug|Any CPU 128 | {DB1DF5AA-B892-48F0-8DED-7DBEEC327F9A}.Release|Any CPU.ActiveCfg = Release|Any CPU 129 | {DB1DF5AA-B892-48F0-8DED-7DBEEC327F9A}.Release|Any CPU.Build.0 = Release|Any CPU 130 | EndGlobalSection 131 | GlobalSection(SolutionProperties) = preSolution 132 | HideSolutionNode = FALSE 133 | EndGlobalSection 134 | GlobalSection(NestedProjects) = preSolution 135 | {202B46C4-4BBD-4AE9-B207-05CE6E238524} = {7BF8B6E0-2B94-4402-B205-06AEE5BBA53E} 136 | {CE33DB55-3394-4C37-B3AC-6C131C4B4EA7} = {7BF8B6E0-2B94-4402-B205-06AEE5BBA53E} 137 | {5D9497C4-D236-41D3-A500-30FD1DEB4AFB} = {7BF8B6E0-2B94-4402-B205-06AEE5BBA53E} 138 | {48209268-8D24-4217-814E-797AF98BE053} = {CE1CBAFE-9F39-44C4-84D0-78D17C9BA4D9} 139 | {191EF22E-9CC8-44A4-84BE-E8D7607D448A} = {CE1CBAFE-9F39-44C4-84D0-78D17C9BA4D9} 140 | {10C77DB3-8974-4AD3-B627-F1B869467202} = {CE1CBAFE-9F39-44C4-84D0-78D17C9BA4D9} 141 | {2F736444-E9DB-488C-AD34-5B3AE78DCE91} = {CE1CBAFE-9F39-44C4-84D0-78D17C9BA4D9} 142 | {FFAAC7D0-FA8E-41C3-9C59-31BFBCA739E2} = {CE1CBAFE-9F39-44C4-84D0-78D17C9BA4D9} 143 | {68B48C09-DD20-4728-8FAC-91302CF30929} = {E25144DA-A80B-4542-82F0-32A835C76688} 144 | {1479D03A-E1FD-4AFC-8066-AE7FEB2FD93C} = {E25144DA-A80B-4542-82F0-32A835C76688} 145 | {F5FBF16E-F917-41B2-BD5C-E7716F72C298} = {85DCDEC4-F74C-4865-8145-F666D73A68A8} 146 | {4572E923-C473-4DBB-ABFD-FEC8F105B2C3} = {85DCDEC4-F74C-4865-8145-F666D73A68A8} 147 | {DE066C01-1C3D-46F5-B9B2-9BE35B14EB5A} = {85DCDEC4-F74C-4865-8145-F666D73A68A8} 148 | {DB1DF5AA-B892-48F0-8DED-7DBEEC327F9A} = {ED24AE38-001A-4E95-B024-9362CCFD8671} 149 | EndGlobalSection 150 | GlobalSection(ExtensibilityGlobals) = postSolution 151 | SolutionGuid = {97EB551C-541C-4437-BDDD-CF6961504A33} 152 | EndGlobalSection 153 | EndGlobal 154 | -------------------------------------------------------------------------------- /EFCoreTestDemo/Controllers/UserController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using EFCoreTestModel; 6 | using EFCoreTestRespository; 7 | using EFCoreTestService; 8 | using Microsoft.AspNetCore.Http; 9 | using Microsoft.AspNetCore.Mvc; 10 | 11 | namespace EFCoreTestDemo.Controllers 12 | { 13 | [Route("api/[controller]")] 14 | [ApiController] 15 | public class UserController : ControllerBase 16 | { 17 | private readonly IUserService _userService; 18 | 19 | public UserController(IUserService userService) 20 | { 21 | _userService = userService; 22 | } 23 | 24 | [HttpPost("AddUser")] 25 | public IActionResult AddUser() 26 | { 27 | User u = new User 28 | { 29 | UserName = "Zoe", 30 | UserPwd = "123456", 31 | Id = "10000", 32 | UserAddr = "China", 33 | UserBirth = DateTime.Now.AddYears(-20) 34 | }; 35 | int nRes = _userService.AddUser(u); 36 | return Ok(nRes); 37 | } 38 | 39 | [HttpPost("DeleteUser")] 40 | public IActionResult DeleteUser() 41 | { 42 | int nRes = _userService.DeleteUser("10000"); 43 | return Ok(nRes); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /EFCoreTestDemo/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace EFCoreTestDemo.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /EFCoreTestDemo/EFCoreTestDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | all 15 | runtime; build; native; contentfiles; analyzers; buildtransitive 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /EFCoreTestDemo/Migrations/20201107081134_InitialName.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using EFCoreTestRespository; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Metadata; 7 | using Microsoft.EntityFrameworkCore.Migrations; 8 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 9 | 10 | namespace EFCoreTestDemo.Migrations 11 | { 12 | [DbContext(typeof(MyTestDbContext))] 13 | [Migration("20201107081134_InitialName")] 14 | partial class InitialName 15 | { 16 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 17 | { 18 | #pragma warning disable 612, 618 19 | modelBuilder 20 | .HasAnnotation("ProductVersion", "3.1.9") 21 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 23 | 24 | modelBuilder.Entity("EFCoreTestModel.User", b => 25 | { 26 | b.Property("Id") 27 | .HasColumnType("nvarchar(450)"); 28 | 29 | b.Property("UserAddr") 30 | .HasColumnType("nvarchar(max)"); 31 | 32 | b.Property("UserBirth") 33 | .HasColumnType("datetime2"); 34 | 35 | b.Property("UserName") 36 | .HasColumnType("nvarchar(max)"); 37 | 38 | b.Property("UserPwd") 39 | .HasColumnType("nvarchar(max)"); 40 | 41 | b.HasKey("Id"); 42 | 43 | b.ToTable("Users"); 44 | }); 45 | #pragma warning restore 612, 618 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /EFCoreTestDemo/Migrations/20201107081134_InitialName.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | 4 | namespace EFCoreTestDemo.Migrations 5 | { 6 | public partial class InitialName : Migration 7 | { 8 | protected override void Up(MigrationBuilder migrationBuilder) 9 | { 10 | migrationBuilder.CreateTable( 11 | name: "Users", 12 | columns: table => new 13 | { 14 | Id = table.Column(nullable: false), 15 | UserName = table.Column(nullable: true), 16 | UserPwd = table.Column(nullable: true), 17 | UserAddr = table.Column(nullable: true), 18 | UserBirth = table.Column(nullable: false) 19 | }, 20 | constraints: table => 21 | { 22 | table.PrimaryKey("PK_Users", x => x.Id); 23 | }); 24 | } 25 | 26 | protected override void Down(MigrationBuilder migrationBuilder) 27 | { 28 | migrationBuilder.DropTable( 29 | name: "Users"); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /EFCoreTestDemo/Migrations/20201107152638_InitialName1.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using EFCoreTestRespository; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Metadata; 7 | using Microsoft.EntityFrameworkCore.Migrations; 8 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 9 | 10 | namespace EFCoreTestDemo.Migrations 11 | { 12 | [DbContext(typeof(MyTestDbContext))] 13 | [Migration("20201107152638_InitialName1")] 14 | partial class InitialName1 15 | { 16 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 17 | { 18 | #pragma warning disable 612, 618 19 | modelBuilder 20 | .HasAnnotation("ProductVersion", "3.1.9") 21 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 23 | 24 | modelBuilder.Entity("EFCoreTestModel.User", b => 25 | { 26 | b.Property("Id") 27 | .HasColumnType("nvarchar(450)"); 28 | 29 | b.Property("UserAddr") 30 | .HasColumnType("nvarchar(max)"); 31 | 32 | b.Property("UserBirth") 33 | .HasColumnType("datetime2"); 34 | 35 | b.Property("UserName") 36 | .HasColumnType("nvarchar(max)"); 37 | 38 | b.Property("UserPwd") 39 | .HasColumnType("nvarchar(max)"); 40 | 41 | b.HasKey("Id"); 42 | 43 | b.ToTable("Users"); 44 | }); 45 | #pragma warning restore 612, 618 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /EFCoreTestDemo/Migrations/20201107152638_InitialName1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace EFCoreTestDemo.Migrations 4 | { 5 | public partial class InitialName1 : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | 10 | } 11 | 12 | protected override void Down(MigrationBuilder migrationBuilder) 13 | { 14 | 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /EFCoreTestDemo/Migrations/20201108084351_UpdateNameAndType.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using EFCoreTestRespository; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Metadata; 7 | using Microsoft.EntityFrameworkCore.Migrations; 8 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 9 | 10 | namespace EFCoreTestDemo.Migrations 11 | { 12 | [DbContext(typeof(MyTestDbContext))] 13 | [Migration("20201108084351_UpdateNameAndType")] 14 | partial class UpdateNameAndType 15 | { 16 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 17 | { 18 | #pragma warning disable 612, 618 19 | modelBuilder 20 | .HasAnnotation("ProductVersion", "3.1.9") 21 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 23 | 24 | modelBuilder.Entity("EFCoreTestModel.User", b => 25 | { 26 | b.Property("Id") 27 | .HasColumnName("ID") 28 | .HasColumnType("varchar(128)"); 29 | 30 | b.Property("Age") 31 | .HasColumnType("nvarchar(max)"); 32 | 33 | b.Property("UserAddr") 34 | .HasColumnType("nvarchar(max)"); 35 | 36 | b.Property("UserBirth") 37 | .HasColumnType("datetime2"); 38 | 39 | b.Property("UserName") 40 | .HasColumnName("USER_NAME") 41 | .HasColumnType("varchar(128)"); 42 | 43 | b.Property("UserPwd") 44 | .IsRequired() 45 | .HasColumnName("USER_PWD") 46 | .HasColumnType("varchar(128)"); 47 | 48 | b.HasKey("Id"); 49 | 50 | b.ToTable("SYS_USER"); 51 | 52 | b.HasComment("用户表"); 53 | }); 54 | #pragma warning restore 612, 618 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /EFCoreTestDemo/Migrations/20201108084351_UpdateNameAndType.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace EFCoreTestDemo.Migrations 4 | { 5 | public partial class UpdateNameAndType : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.DropPrimaryKey( 10 | name: "PK_Users", 11 | table: "Users"); 12 | 13 | migrationBuilder.RenameTable( 14 | name: "Users", 15 | newName: "SYS_USER"); 16 | 17 | migrationBuilder.RenameColumn( 18 | name: "Id", 19 | table: "SYS_USER", 20 | newName: "ID"); 21 | 22 | migrationBuilder.RenameColumn( 23 | name: "UserPwd", 24 | table: "SYS_USER", 25 | newName: "USER_PWD"); 26 | 27 | migrationBuilder.RenameColumn( 28 | name: "UserName", 29 | table: "SYS_USER", 30 | newName: "USER_NAME"); 31 | 32 | migrationBuilder.AlterTable( 33 | name: "SYS_USER", 34 | comment: "用户表"); 35 | 36 | migrationBuilder.AlterColumn( 37 | name: "ID", 38 | table: "SYS_USER", 39 | type: "varchar(128)", 40 | nullable: false, 41 | oldClrType: typeof(string), 42 | oldType: "nvarchar(450)"); 43 | 44 | migrationBuilder.AlterColumn( 45 | name: "USER_PWD", 46 | table: "SYS_USER", 47 | type: "varchar(128)", 48 | nullable: false, 49 | oldClrType: typeof(string), 50 | oldType: "nvarchar(max)", 51 | oldNullable: true); 52 | 53 | migrationBuilder.AlterColumn( 54 | name: "USER_NAME", 55 | table: "SYS_USER", 56 | type: "varchar(128)", 57 | nullable: true, 58 | oldClrType: typeof(string), 59 | oldType: "nvarchar(max)", 60 | oldNullable: true); 61 | 62 | migrationBuilder.AddColumn( 63 | name: "Age", 64 | table: "SYS_USER", 65 | nullable: true); 66 | 67 | migrationBuilder.AddPrimaryKey( 68 | name: "PK_SYS_USER", 69 | table: "SYS_USER", 70 | column: "ID"); 71 | } 72 | 73 | protected override void Down(MigrationBuilder migrationBuilder) 74 | { 75 | migrationBuilder.DropPrimaryKey( 76 | name: "PK_SYS_USER", 77 | table: "SYS_USER"); 78 | 79 | migrationBuilder.DropColumn( 80 | name: "Age", 81 | table: "SYS_USER"); 82 | 83 | migrationBuilder.RenameTable( 84 | name: "SYS_USER", 85 | newName: "Users"); 86 | 87 | migrationBuilder.RenameColumn( 88 | name: "ID", 89 | table: "Users", 90 | newName: "Id"); 91 | 92 | migrationBuilder.RenameColumn( 93 | name: "USER_PWD", 94 | table: "Users", 95 | newName: "UserPwd"); 96 | 97 | migrationBuilder.RenameColumn( 98 | name: "USER_NAME", 99 | table: "Users", 100 | newName: "UserName"); 101 | 102 | migrationBuilder.AlterTable( 103 | name: "Users", 104 | oldComment: "用户表"); 105 | 106 | migrationBuilder.AlterColumn( 107 | name: "Id", 108 | table: "Users", 109 | type: "nvarchar(450)", 110 | nullable: false, 111 | oldClrType: typeof(string), 112 | oldType: "varchar(128)"); 113 | 114 | migrationBuilder.AlterColumn( 115 | name: "UserPwd", 116 | table: "Users", 117 | type: "nvarchar(max)", 118 | nullable: true, 119 | oldClrType: typeof(string), 120 | oldType: "varchar(128)"); 121 | 122 | migrationBuilder.AlterColumn( 123 | name: "UserName", 124 | table: "Users", 125 | type: "nvarchar(max)", 126 | nullable: true, 127 | oldClrType: typeof(string), 128 | oldType: "varchar(128)", 129 | oldNullable: true); 130 | 131 | migrationBuilder.AddPrimaryKey( 132 | name: "PK_Users", 133 | table: "Users", 134 | column: "Id"); 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /EFCoreTestDemo/Migrations/MyTestDbContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using EFCoreTestRespository; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Metadata; 7 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 8 | 9 | namespace EFCoreTestDemo.Migrations 10 | { 11 | [DbContext(typeof(MyTestDbContext))] 12 | partial class MyTestDbContextModelSnapshot : ModelSnapshot 13 | { 14 | protected override void BuildModel(ModelBuilder modelBuilder) 15 | { 16 | #pragma warning disable 612, 618 17 | modelBuilder 18 | .HasAnnotation("ProductVersion", "3.1.9") 19 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 20 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 21 | 22 | modelBuilder.Entity("EFCoreTestModel.User", b => 23 | { 24 | b.Property("Id") 25 | .HasColumnName("ID") 26 | .HasColumnType("varchar(128)"); 27 | 28 | b.Property("Age") 29 | .HasColumnType("nvarchar(max)"); 30 | 31 | b.Property("UserAddr") 32 | .HasColumnType("nvarchar(max)"); 33 | 34 | b.Property("UserBirth") 35 | .HasColumnType("datetime2"); 36 | 37 | b.Property("UserName") 38 | .HasColumnName("USER_NAME") 39 | .HasColumnType("varchar(128)"); 40 | 41 | b.Property("UserPwd") 42 | .IsRequired() 43 | .HasColumnName("USER_PWD") 44 | .HasColumnType("varchar(128)"); 45 | 46 | b.HasKey("Id"); 47 | 48 | b.ToTable("SYS_USER"); 49 | 50 | b.HasComment("用户表"); 51 | }); 52 | #pragma warning restore 612, 618 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /EFCoreTestDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace EFCoreTestDemo 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup() 24 | .ConfigureLogging((h,builder)=> { 25 | builder.SetMinimumLevel(LogLevel.Trace); 26 | builder.AddConsole(); 27 | builder.AddDebug(); 28 | }); 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /EFCoreTestDemo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:55395", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "EFCoreTestDemo": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "weatherforecast", 24 | "applicationUrl": "http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /EFCoreTestDemo/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using EFCoreTestRespository; 6 | using EFCoreTestService; 7 | using Microsoft.AspNetCore.Builder; 8 | using Microsoft.AspNetCore.Hosting; 9 | using Microsoft.AspNetCore.Mvc; 10 | using Microsoft.EntityFrameworkCore; 11 | using Microsoft.Extensions.Configuration; 12 | using Microsoft.Extensions.DependencyInjection; 13 | using Microsoft.Extensions.Hosting; 14 | using Microsoft.Extensions.Logging; 15 | 16 | namespace EFCoreTestDemo 17 | { 18 | public class Startup 19 | { 20 | public Startup(IConfiguration configuration) 21 | { 22 | Configuration = configuration; 23 | } 24 | 25 | public IConfiguration Configuration { get; } 26 | 27 | // This method gets called by the runtime. Use this method to add services to the container. 28 | public void ConfigureServices(IServiceCollection services) 29 | { 30 | //Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=master;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False 31 | services.AddControllers(); 32 | services.AddDbContext(db => db.UseSqlServer( 33 | @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=EFCoreTest1;Integrated Security=True; 34 | Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False", 35 | b=>b.MigrationsAssembly("EFCoreTestDemo"))); 36 | 37 | services.AddTransient(); 38 | services.AddTransient(); 39 | } 40 | 41 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 42 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 43 | { 44 | if (env.IsDevelopment()) 45 | { 46 | app.UseDeveloperExceptionPage(); 47 | } 48 | 49 | app.UseRouting(); 50 | 51 | app.UseAuthorization(); 52 | 53 | app.UseEndpoints(endpoints => 54 | { 55 | endpoints.MapControllers(); 56 | }); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /EFCoreTestDemo/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EFCoreTestDemo 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /EFCoreTestDemo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /EFCoreTestDemo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /EFCoreTestModel/EFCoreTestModel.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /EFCoreTestModel/User.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EFCoreTestModel 4 | { 5 | public class User 6 | { 7 | /// 8 | /// 用户ID 9 | /// 10 | public string Id { get; set; } 11 | /// 12 | /// 用户名 13 | /// 14 | public string UserName { get; set; } 15 | 16 | /// 17 | /// 密码 18 | /// 19 | public string UserPwd { get; set; } 20 | 21 | /// 22 | /// 用户地址 23 | /// 24 | public string UserAddr { get; set; } 25 | 26 | /// 27 | /// 用户生日 28 | /// 29 | public DateTime UserBirth { get; set; } 30 | 31 | /// 32 | /// 年龄 33 | /// 34 | public string Age { get; set; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /EFCoreTestRespository/EFCoreTestRespository.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /EFCoreTestRespository/IUserRespository.cs: -------------------------------------------------------------------------------- 1 | using EFCoreTestModel; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace EFCoreTestRespository 7 | { 8 | public interface IUserRespository 9 | { 10 | int AddUser(User user); 11 | int DeleteUser(string userId); 12 | int UpdateUser(User user); 13 | User GetUser(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /EFCoreTestRespository/MyTestDbContext.cs: -------------------------------------------------------------------------------- 1 | using EFCoreTestModel; 2 | using Microsoft.EntityFrameworkCore; 3 | using System; 4 | 5 | namespace EFCoreTestRespository 6 | { 7 | public class MyTestDbContext:DbContext 8 | { 9 | // 构造函数,传入一个option,用于传递数据库连接字符串 10 | public MyTestDbContext(DbContextOptions options) 11 | :base(options) 12 | { 13 | //ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; 14 | } 15 | public DbSet Users { get; set; } 16 | 17 | protected override void OnModelCreating(ModelBuilder modelBuilder) 18 | { 19 | modelBuilder.Entity(entity => 20 | { 21 | entity.ToTable("SYS_USER");// 设置表名 22 | entity.HasComment("用户表");// 设置表注释 23 | 24 | entity.Property(e => e.Id) 25 | .HasColumnName("ID")// 设置列名 26 | .HasColumnType("varchar(128)");//设置列类型和长度 27 | 28 | entity.Property(e => e.UserName) 29 | .HasColumnName("USER_NAME")// 设置列名 30 | .HasColumnType("varchar(128)");//设置列类型和长度 31 | 32 | entity.Property(e => e.UserPwd) 33 | .HasColumnName("USER_PWD")// 设置列名 34 | .HasColumnType("varchar(128)")//设置列类型和长度 35 | .IsRequired();// 设置为必填,即不为空 36 | 37 | }); 38 | base.OnModelCreating(modelBuilder); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /EFCoreTestRespository/UserRespository.cs: -------------------------------------------------------------------------------- 1 | using EFCoreTestModel; 2 | using Microsoft.EntityFrameworkCore; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using System.Linq.Expressions; 7 | using System.Linq; 8 | 9 | namespace EFCoreTestRespository 10 | { 11 | public class UserRespository : IUserRespository 12 | { 13 | private readonly DbContext _dbContext; 14 | 15 | public UserRespository(MyTestDbContext dbContext) 16 | { 17 | _dbContext = dbContext; 18 | } 19 | 20 | public int AddUser(User user) 21 | { 22 | //新增单个用户,这里主要是绑定关系及更改追踪状态,即更改为添加状态 23 | var tempUser = _dbContext.Set().Add(user); 24 | 25 | //新增多个用户,用AddRange,参数传list或可变参数都行 26 | //_dbContext.Set().AddRange(users); 27 | 28 | // 真正提交保存都是SaveChanges,上面只是改了状态而已 29 | return _dbContext.SaveChanges(); 30 | } 31 | 32 | public int DeleteUser(string userId) 33 | { 34 | // 删除一个用户,生成包装对象 35 | var tempUser = _dbContext.Set().Remove(new User() { Id = userId }); 36 | // 删除多个用户用RemoveRange 37 | //_dbContext.Set().RemoveRange(users); 38 | // 根据状态进行删除提交操作 39 | return _dbContext.SaveChanges(); 40 | } 41 | public int UpdateUser(User user) 42 | { 43 | // 更新一个用户,生成包装对象 44 | var tempUser =_dbContext.Set().Update(user); 45 | // 更新多个用户,用UpdateRange 46 | //_dbContext.Set().UpdateRange(users); 47 | // 根据状态进行更新提交操作 48 | return _dbContext.SaveChanges(); 49 | } 50 | 51 | public User GetUser() 52 | { 53 | // 方式1 54 | _dbContext.Set().Where(a => a.Id == "10000").FirstOrDefault(); 55 | 56 | // 使用AsNoTracking代表不追踪 57 | _dbContext.Set().AsNoTracking().Where(a => a.Id == "10000").FirstOrDefault(); 58 | 59 | // 方式2 Linq , from、where、select是一个linq最基本的关键字,必须要 60 | var res = from u in _dbContext.Set() 61 | where u.Id == "10000" 62 | select u; 63 | 64 | return res.FirstOrDefault(); 65 | } 66 | 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /EFCoreTestService/EFCoreTestService.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /EFCoreTestService/IUserService.cs: -------------------------------------------------------------------------------- 1 | using EFCoreTestModel; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace EFCoreTestService 7 | { 8 | public interface IUserService 9 | { 10 | int AddUser(User user); 11 | int DeleteUser(string userId); 12 | int UpdateUser(User user); 13 | User GetUser(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /EFCoreTestService/UserService.cs: -------------------------------------------------------------------------------- 1 | using EFCoreTestModel; 2 | using EFCoreTestRespository; 3 | using System; 4 | 5 | namespace EFCoreTestService 6 | { 7 | public class UserService: IUserService 8 | { 9 | private readonly IUserRespository _user; 10 | 11 | public UserService(IUserRespository user) 12 | { 13 | _user = user; 14 | } 15 | 16 | public int AddUser(User user) 17 | { 18 | return _user.AddUser(user); 19 | } 20 | 21 | public int DeleteUser(string userId) 22 | { 23 | return _user.DeleteUser(userId); 24 | } 25 | 26 | public User GetUser() 27 | { 28 | throw new NotImplementedException(); 29 | } 30 | 31 | public int UpdateUser(User user) 32 | { 33 | throw new NotImplementedException(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ExportExcelDemo/ExportExcelDemo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30204.135 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExportExcelDemo", "ExportExcelDemo\ExportExcelDemo.csproj", "{3901DECD-4D74-479F-9E48-B09B517ADBF8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3901DECD-4D74-479F-9E48-B09B517ADBF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {3901DECD-4D74-479F-9E48-B09B517ADBF8}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {3901DECD-4D74-479F-9E48-B09B517ADBF8}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {3901DECD-4D74-479F-9E48-B09B517ADBF8}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {CA718A14-E6BE-40DA-85CE-DA6EAB6460B8} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ExportExcelDemo/ExportExcelDemo/Controllers/ExportExcelController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.AspNetCore.Mvc; 9 | using OfficeOpenXml; 10 | using OfficeOpenXml.Style; 11 | 12 | namespace ExportExcelDemo.Controllers 13 | { 14 | [Route("api/[controller]")] 15 | [ApiController] 16 | public class ExportExcelController : ControllerBase 17 | { 18 | 19 | [HttpGet("FillDataExcel")] 20 | public IActionResult FillDataExcel() 21 | { 22 | using (var package = new ExcelPackage()) 23 | { 24 | // 需要添加一个Sheet,名称为"填充数据Demo" 25 | ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("填充数据Demo"); 26 | // 不需要创建行和列就可以定位单元格赋值 27 | worksheet.Cells[1, 1].Value = "Data1"; // 给第一行第一列单元格赋值为Data1 28 | worksheet.Cells[1, 2].Value = 666;// 给第一行第二列单元格赋值为666 29 | worksheet.Cells[1, 3].Value = "Data3";// 给第一行第三列单元格赋值为Data3 30 | worksheet.Cells[1, 4].Value = "Data4";// 给第一行第四列单元格赋值为Data4 31 | worksheet.Cells[1, 5].Value = 0.25;// 给第一行第五列单元格赋值为0.25 32 | 33 | worksheet.Cells["A2"].Value = "AData1"; // 给第二行第一列单元格赋值为AData1 34 | worksheet.Cells["B2"].Value = 888;// 给第二行第二列单元格赋值为888 35 | worksheet.Cells["C2"].Value = "AData3";// 给第二行第三列单元格赋值为AData3 36 | worksheet.Cells["D2"].Value = "AData4";// 给第二行第四列单元格赋值为AData4 37 | worksheet.Cells["E2"].Value = 0.25;// 给第二行第五列单元格赋值为0.25 38 | // 直接通过内存导出,不用先保存文件了 39 | var excelFileStream = new MemoryStream(package.GetAsByteArray()); 40 | 41 | return new FileStreamResult(excelFileStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 42 | } 43 | } 44 | 45 | 46 | [HttpGet("FormulaDataExcel")] 47 | public IActionResult FormulaDataExcel() 48 | { 49 | using (var package = new ExcelPackage()) 50 | { 51 | // 需要添加一个Sheet,名称为"填充数据Demo" 52 | ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("公式Demo"); 53 | // 不需要创建行和列就可以定位单元格赋值 54 | worksheet.Cells[1, 1].Value = 111; 55 | worksheet.Cells[1, 2].Value = 666; 56 | worksheet.Cells[1, 3].Value = 2.6; 57 | worksheet.Cells[1, 4].Value = 33; 58 | worksheet.Cells[1, 5].Value = 0.25; 59 | 60 | worksheet.Cells["A2"].Value = 35; 61 | worksheet.Cells["B2"].Value = 888; 62 | worksheet.Cells["C2"].Value = 6; 63 | worksheet.Cells["D2"].Value = 1; 64 | worksheet.Cells["E2"].Value = 0.25; 65 | 66 | //在第对应行中第六列单元格中 显示前五个单元格的和, 使用ExcelAddress定位计算的范围,第一行前五个单元求和 67 | worksheet.Cells[1, 6].Formula = string.Format("SUBTOTAL(9,{0})", new ExcelAddress(1, 1,1, 5).Address); 68 | // 第二行前五个单元求和 ,并赋值给指定单元格(第二行的第六个单元格) 69 | worksheet.Cells[2, 6].Formula = string.Format("SUBTOTAL(9,{0})", new ExcelAddress(2, 1, 2, 5).Address); 70 | 71 | // 定某个单元格范围的值使用公式, 这里指定第三行的值等于第一行乘以第二行 72 | worksheet.Cells["A3:E3"].Formula = "A1*A2"; 73 | 74 | // 直接通过内存导出,不用先保存文件了 75 | var excelFileStream = new MemoryStream(package.GetAsByteArray()); 76 | 77 | return new FileStreamResult(excelFileStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 78 | } 79 | } 80 | 81 | [HttpGet("StyleDataExcel")] 82 | public IActionResult StyleDataExcel() 83 | { 84 | using (var package = new ExcelPackage()) 85 | { 86 | // 需要添加一个Sheet,名称为"填充数据Demo" 87 | ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("样式Demo"); 88 | // 设置所有单元格的内容水平和垂直对齐 89 | worksheet.Cells.Style.VerticalAlignment = ExcelVerticalAlignment.Center; 90 | worksheet.Cells.Style.HorizontalAlignment = ExcelHorizontalAlignment.Left; 91 | // 设置所有单元格边框格式 92 | worksheet.Cells.Style.Border.Top.Style = ExcelBorderStyle.Thin; 93 | worksheet.Cells.Style.Border.Right.Style = ExcelBorderStyle.Thin; 94 | worksheet.Cells.Style.Border.Left.Style = ExcelBorderStyle.Thin; 95 | worksheet.Cells.Style.Border.Bottom.Style = ExcelBorderStyle.Thin; 96 | 97 | // 不需要创建行和列就可以定位单元格赋值 98 | worksheet.Cells[1, 1].Value = "表头1"; 99 | worksheet.Cells[1, 2].Value = "表头2"; 100 | worksheet.Cells[1, 3].Value = "表头3"; 101 | worksheet.Cells[1, 4].Value = "表头4"; 102 | worksheet.Cells[1, 5].Value = "表头5"; 103 | using (var range = worksheet.Cells[1, 1, 1, 5]) //获取一个区域,这里指的是第一行的1~5列区域 104 | { 105 | // 设置字体 106 | range.Style.Font.Bold = true; 107 | // 背景色填充 108 | range.Style.Fill.PatternType = ExcelFillStyle.Solid; 109 | range.Style.Fill.BackgroundColor.SetColor(1, 51, 204, 204); 110 | } 111 | 112 | //worksheet.Cells[1, 1].Style.Font.Bold = true; 113 | //worksheet.Cells[1, 2].Style.Font.Bold = true; 114 | //worksheet.Cells[1, 3].Style.Font.Bold = true; 115 | //worksheet.Cells[1, 4].Style.Font.Bold = true; 116 | //worksheet.Cells[1, 5].Style.Font.Bold = true; 117 | 118 | worksheet.Cells[2, 1].Value = 111; 119 | worksheet.Cells[2, 2].Value = 666; 120 | worksheet.Cells[2, 3].Value = 2.6; 121 | worksheet.Cells[2, 4].Value = 33; 122 | worksheet.Cells[2, 5].Value = 0.25; 123 | 124 | worksheet.Cells["A3"].Value = 35; 125 | worksheet.Cells["B3"].Value = 888; 126 | worksheet.Cells["C3"].Value = 6; 127 | worksheet.Cells["D3"].Value = 1; 128 | worksheet.Cells["E3"].Value = 0.25; 129 | 130 | 131 | // 直接通过内存导出,不用先保存文件了 132 | var excelFileStream = new MemoryStream(package.GetAsByteArray()); 133 | 134 | return new FileStreamResult(excelFileStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 135 | } 136 | } 137 | 138 | [HttpGet("MergeDataExcel")] 139 | public IActionResult MergeDataExcel() 140 | { 141 | using (var package = new ExcelPackage()) 142 | { 143 | // 需要添加一个Sheet,名称为"填充数据Demo" 144 | ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("合并Demo"); 145 | // 设置所有单元格的内容水平和垂直对齐 146 | worksheet.Cells.Style.VerticalAlignment = ExcelVerticalAlignment.Center; 147 | worksheet.Cells.Style.HorizontalAlignment = ExcelHorizontalAlignment.Left; 148 | // 设置所有单元格边框格式 149 | worksheet.Cells.Style.Border.Top.Style = ExcelBorderStyle.Thin; 150 | worksheet.Cells.Style.Border.Right.Style = ExcelBorderStyle.Thin; 151 | worksheet.Cells.Style.Border.Left.Style = ExcelBorderStyle.Thin; 152 | worksheet.Cells.Style.Border.Bottom.Style = ExcelBorderStyle.Thin; 153 | 154 | // 不需要创建行和列就可以定位单元格赋值 155 | worksheet.Cells[1, 1].Value = "表头1"; 156 | worksheet.Cells[1, 3].Value = "表头3"; 157 | worksheet.Cells[1, 4].Value = "表头4"; 158 | worksheet.Cells[1, 5].Value = "表头5"; 159 | MergeCell(worksheet, 1, 1, 1, 2);// 将第一行中的前两个单元进行合并 160 | using (var range = worksheet.Cells[1, 1, 1, 5]) //获取一个区域,这里指的是第一行的1~5列区域 161 | { 162 | // 设置字体 163 | range.Style.Font.Bold = true; 164 | // 背景色填充 165 | range.Style.Fill.PatternType = ExcelFillStyle.Solid; 166 | range.Style.Fill.BackgroundColor.SetColor(1, 51, 204, 204); 167 | } 168 | 169 | worksheet.Cells[2, 1].Value = 111; 170 | worksheet.Cells[2, 2].Value = 666; 171 | worksheet.Cells[2, 3].Value = 2.6; 172 | worksheet.Cells[2, 4].Value = 33; 173 | worksheet.Cells[2, 5].Value = 0.25; 174 | 175 | worksheet.Cells["A3"].Value = 111; 176 | worksheet.Cells["B3"].Value = 888; 177 | worksheet.Cells["C3"].Value = 6; 178 | worksheet.Cells["D3"].Value = 1; 179 | worksheet.Cells["E3"].Value = 0.25; 180 | 181 | worksheet.Cells["A4"].Value = 112; 182 | worksheet.Cells["B4"].Value = 8881; 183 | worksheet.Cells["C4"].Value = 612; 184 | worksheet.Cells["D4"].Value = 11; 185 | worksheet.Cells["E4"].Value = 0.251; 186 | 187 | MergeCell(worksheet, 1, 2);//合并第一列值相等的单元格,从第二行开始遍历 188 | // 直接通过内存导出,不用先保存文件了 189 | var excelFileStream = new MemoryStream(package.GetAsByteArray()); 190 | 191 | return new FileStreamResult(excelFileStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 192 | } 193 | } 194 | 195 | [HttpGet("FitDataExcel")] 196 | public IActionResult FitDataExcel() 197 | { 198 | using (var package = new ExcelPackage()) 199 | { 200 | // 需要添加一个Sheet,名称为"填充数据Demo" 201 | ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("合并Demo"); 202 | 203 | // 不需要创建行和列就可以定位单元格赋值 204 | worksheet.Cells[2, 3].Value = "表头3测试好长一段内容"; 205 | worksheet.Cells[3, 4].Value = "表头4测试好长一段内容"; 206 | worksheet.Cells[4, 5].Value = "表头5测试好长一段内容"; 207 | worksheet.Cells[5, 5].Value = "表头5测试好长一段内容"; 208 | 209 | // 单元格根据内容自动填充 210 | worksheet.Cells[3, 4].AutoFitColumns(); 211 | 212 | //缩小内容填充 213 | worksheet.Cells[4, 5].Style.ShrinkToFit = true; 214 | 215 | //换行显示 216 | worksheet.Cells[5, 5].Style.WrapText = true; 217 | 218 | // 直接通过内存导出,不用先保存文件了 219 | var excelFileStream = new MemoryStream(package.GetAsByteArray()); 220 | 221 | return new FileStreamResult(excelFileStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 222 | } 223 | } 224 | 225 | [HttpGet("SaveFileDataExcel")] 226 | public IActionResult SaveFileDataExcel() 227 | { 228 | using (var package = new ExcelPackage(new FileInfo("ExportFile.xlsx"))) 229 | { 230 | // 需要添加一个Sheet,名称为"填充数据Demo" 231 | ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("合并Demo"); 232 | 233 | // 不需要创建行和列就可以定位单元格赋值 234 | worksheet.Cells[1, 1].Value = "Data1"; // 给第一行第一列单元格赋值为Data1 235 | worksheet.Cells[1, 2].Value = 666;// 给第一行第二列单元格赋值为666 236 | worksheet.Cells[1, 3].Value = "Data3";// 给第一行第三列单元格赋值为Data3 237 | worksheet.Cells[1, 4].Value = "Data4";// 给第一行第四列单元格赋值为Data4 238 | worksheet.Cells[1, 5].Value = 0.25;// 给第一行第五列单元格赋值为0.25 239 | 240 | worksheet.Cells["A2"].Value = "AData1"; // 给第二行第一列单元格赋值为AData1 241 | worksheet.Cells["B2"].Value = 888;// 给第二行第二列单元格赋值为888 242 | worksheet.Cells["C2"].Value = "AData3";// 给第二行第三列单元格赋值为AData3 243 | worksheet.Cells["D2"].Value = "AData4";// 给第二行第四列单元格赋值为AData4 244 | worksheet.Cells["E2"].Value = 0.25;// 给第二行第五列单元格赋值为0.25 245 | 246 | // 保存文件 247 | package.Save(); 248 | } 249 | return Ok(); 250 | } 251 | 252 | 253 | /// 254 | /// 合并单元格,指定开始位置和结束位置即可 255 | /// 256 | private void MergeCell(ExcelWorksheet sheet, int fromRow, int toRow, int fromCol, int toCol) 257 | { 258 | // 合并很简单,将其Merge设置为true即可 259 | sheet.Cells[fromRow, fromCol, toRow, toCol].Merge = true; 260 | // 合并之后设置为水平居中和垂直居中 261 | sheet.Cells[fromRow, fromCol, toRow, toCol].Style.VerticalAlignment = ExcelVerticalAlignment.Center; 262 | sheet.Cells[fromRow, fromCol, toRow, toCol].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; 263 | } 264 | 265 | /// 266 | /// 合并指定列值相等的行 267 | /// 268 | private void MergeCell(ExcelWorksheet sheet, int col, int startRow) 269 | { 270 | int fromRow = startRow; 271 | int fromCol = col; 272 | int toRow = startRow; 273 | int toCol = col; 274 | // 获取指定单元格的值 275 | string value = sheet.Cells[startRow + 1, col].Value?.ToString(); 276 | // 循环遍历行 277 | for (int i = startRow + 1; i < sheet.Cells.Rows; i++) 278 | { 279 | // 获取相邻行对应单元格的值 280 | var valueNext = sheet.Cells[i + 1, col].Value?.ToString(); 281 | // 比较是否相等 282 | if (value != valueNext) 283 | { 284 | value = valueNext; // 将当前值更新为相邻值,方便后续继续遍历 285 | toRow = i; 286 | // 设置合并属性 287 | sheet.Cells[fromRow, fromCol, toRow, toCol].Merge = true; 288 | // 合并之后设置为垂直居中 289 | sheet.Cells[fromRow, fromCol, toRow, toCol].Style.VerticalAlignment = ExcelVerticalAlignment.Center; 290 | // 更新开始位置继续遍历 291 | fromRow = i + 1; 292 | } 293 | // 如果取得值为空就中断 294 | if (valueNext == null) 295 | { 296 | break; 297 | } 298 | } 299 | } 300 | } 301 | } 302 | -------------------------------------------------------------------------------- /ExportExcelDemo/ExportExcelDemo/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace ExportExcelDemo.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ExportExcelDemo/ExportExcelDemo/ExportExcelDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ExportExcelDemo/ExportExcelDemo/ExportFile.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyq025/DotNetCoreStudyDemo/8ca9932e1cbb86ce33b982d10c914b8049436850/ExportExcelDemo/ExportExcelDemo/ExportFile.xlsx -------------------------------------------------------------------------------- /ExportExcelDemo/ExportExcelDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace ExportExcelDemo 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ExportExcelDemo/ExportExcelDemo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "ExportExcelDemo": { 5 | "commandName": "Project", 6 | "launchBrowser": true, 7 | "launchUrl": "api/ExportExcel", 8 | "applicationUrl": "http://localhost:5000", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ExportExcelDemo/ExportExcelDemo/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.Mvc; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.DependencyInjection; 10 | using Microsoft.Extensions.Hosting; 11 | using Microsoft.Extensions.Logging; 12 | 13 | namespace ExportExcelDemo 14 | { 15 | public class Startup 16 | { 17 | public Startup(IConfiguration configuration) 18 | { 19 | Configuration = configuration; 20 | } 21 | 22 | public IConfiguration Configuration { get; } 23 | 24 | // This method gets called by the runtime. Use this method to add services to the container. 25 | public void ConfigureServices(IServiceCollection services) 26 | { 27 | services.AddControllers(); 28 | } 29 | 30 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 31 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 32 | { 33 | if (env.IsDevelopment()) 34 | { 35 | app.UseDeveloperExceptionPage(); 36 | } 37 | 38 | app.UseRouting(); 39 | 40 | app.UseAuthorization(); 41 | 42 | app.UseEndpoints(endpoints => 43 | { 44 | endpoints.MapControllers(); 45 | }); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ExportExcelDemo/ExportExcelDemo/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ExportExcelDemo 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ExportExcelDemo/ExportExcelDemo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ExportExcelDemo/ExportExcelDemo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /HttpClientConsoleDemo/HttpClientConsoleDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /HttpClientConsoleDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using System; 3 | using System.Net.Http; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace HttpClientConsoleDemo 8 | { 9 | class Program 10 | { 11 | public static async Task Main(string[] args) 12 | { 13 | // 使用.NetCore的依赖注入 14 | var serviceCollection = new ServiceCollection(); 15 | // 注入HttpClient相关服务 16 | serviceCollection.AddHttpClient(); 17 | // 构建一个容器 18 | var serviceProvider = serviceCollection.BuildServiceProvider(); 19 | IHttpClientFactory httpClientFactory = serviceProvider.GetService(); 20 | 21 | //下面是使用 22 | Console.WriteLine("开始访问自己的网站!"); 23 | for (int i = 0; i < 15; i++) 24 | { 25 | // 通过HttpClientFactory创建出一个HttpClient 26 | var client = httpClientFactory.CreateClient(); 27 | // 访问地址 28 | var response = await client.GetAsync("http://47.113.204.41/"); 29 | Console.WriteLine($"请求返回状态码:{response.StatusCode}"); 30 | } 31 | Console.WriteLine("访问完成!"); 32 | } 33 | 34 | private static HttpClient Client = new HttpClient(); 35 | private static async Task NewMethod1() 36 | { 37 | Console.WriteLine("开始访问自己的网站!"); 38 | // 循环访问多次 39 | for (int i = 0; i < 15; i++) 40 | { 41 | // 这里访问自己云服务器站点,没有做负载,所以方便看测试结果 42 | var result = await Client.GetAsync("http://47.113.204.41/"); 43 | Console.WriteLine($"请求返回状态码:{result.StatusCode}"); 44 | } 45 | Console.WriteLine("访问完成!"); 46 | } 47 | 48 | static async Task NewMethod() 49 | { 50 | Console.WriteLine("开始访问自己的网站!"); 51 | // 循环访问多次 52 | for (int i = 0; i < 15; i++) 53 | { 54 | // using包裹使用HttpClient 55 | using (HttpClient httpClient = new HttpClient()) 56 | { 57 | // 这里访问自己云服务器站点,没有做负载,所以方便看测试结果 58 | var result = await httpClient.GetAsync("http://47.113.204.41/"); 59 | Console.WriteLine($"请求返回状态码:{result.StatusCode}"); 60 | } 61 | } 62 | Console.WriteLine("访问完成!"); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /HttpClientFactoryDemo/HttpClientFactoryDemo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30114.105 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpClientFactoryDemo", "HttpClientFactoryDemo\HttpClientFactoryDemo.csproj", "{B19A5DCB-CD63-49BB-8D53-EE3919DE7A3E}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B19A5DCB-CD63-49BB-8D53-EE3919DE7A3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {B19A5DCB-CD63-49BB-8D53-EE3919DE7A3E}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {B19A5DCB-CD63-49BB-8D53-EE3919DE7A3E}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {B19A5DCB-CD63-49BB-8D53-EE3919DE7A3E}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {8C4E13AB-45F7-4A5F-B0E4-61049501F2B1} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /HttpClientFactoryDemo/HttpClientFactoryDemo/Controllers/TestHttpClientFactoryController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net.Http; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Http; 7 | using Microsoft.AspNetCore.Mvc; 8 | 9 | namespace HttpClientFactoryDemo.Controllers 10 | { 11 | [Route("api/[controller]")] 12 | [ApiController] 13 | public class TestHttpClientFactoryController : ControllerBase 14 | { 15 | // 定义变量 16 | private IHttpClientFactory _httpClientFactory; 17 | 18 | // 构造函数注入 19 | public TestHttpClientFactoryController(IHttpClientFactory httpClientFactory) 20 | { 21 | _httpClientFactory = httpClientFactory; 22 | } 23 | 24 | // 新增接口 25 | [HttpGet("TestHttpClientFactory")] 26 | public async Task TestHttpClientFactory() 27 | { 28 | // 通过工厂创建出HttpClient 29 | var client = _httpClientFactory.CreateClient(); 30 | // 访问远端服务, 这里根据需要可以访问接口服务 31 | var response = await client.GetAsync("http://47.113.204.41/"); 32 | // 解析内容,这里直接打印内容 33 | return Content($"状态码:{response.StatusCode.ToString()},内容:{response.Content.ReadAsStringAsync().Result}"); 34 | } 35 | 36 | [HttpGet("TestNamedHttpClient")] 37 | public async Task TestNamedHttpClient() 38 | { 39 | // 通过工厂创建出HttpClient 40 | var client = _httpClientFactory.CreateClient("NamedHttpClient"); 41 | // 访问远端服务, 这里根据需要可以访问接口服务 42 | var response = await client.GetAsync("http://47.113.204.41/"); 43 | // 解析内容,这里直接打印内容 44 | return Content($"状态码:{response.StatusCode.ToString()},内容:{response.Content.ReadAsStringAsync().Result}"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /HttpClientFactoryDemo/HttpClientFactoryDemo/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace HttpClientFactoryDemo.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /HttpClientFactoryDemo/HttpClientFactoryDemo/HttpClientFactoryDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /HttpClientFactoryDemo/HttpClientFactoryDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace HttpClientFactoryDemo 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /HttpClientFactoryDemo/HttpClientFactoryDemo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:51314", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "HttpClientFactoryDemo": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "weatherforecast", 24 | "applicationUrl": "http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /HttpClientFactoryDemo/HttpClientFactoryDemo/Startup.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyq025/DotNetCoreStudyDemo/8ca9932e1cbb86ce33b982d10c914b8049436850/HttpClientFactoryDemo/HttpClientFactoryDemo/Startup.cs -------------------------------------------------------------------------------- /HttpClientFactoryDemo/HttpClientFactoryDemo/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HttpClientFactoryDemo 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /HttpClientFactoryDemo/HttpClientFactoryDemo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /HttpClientFactoryDemo/HttpClientFactoryDemo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/CommandMsg/UserAddMsg.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MediatRAspNetCoreDemo.CommandMsg 8 | { 9 | public class UserAddMsg:IRequest 10 | { 11 | public string UserName { get; set; } 12 | public string UserAddr { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/CommandMsg/UserAddMsgHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace MediatRAspNetCoreDemo.CommandMsg 9 | { 10 | public class UserAddMsgHandler : IRequestHandler 11 | { 12 | public Task Handle(UserAddMsg request, CancellationToken cancellationToken) 13 | { 14 | //这里可以调用服务层直接添加用户,根据需求添加 15 | Console.WriteLine($"添加用户成功,用户名:{request.UserName}," + 16 | $"地址:{request.UserAddr}"); 17 | return Task.FromResult(1); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/Controllers/UserController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using MediatR; 6 | using MediatRAspNetCoreDemo.CommandMsg; 7 | using MediatRAspNetCoreDemo.EventMsg; 8 | using Microsoft.AspNetCore.Http; 9 | using Microsoft.AspNetCore.Mvc; 10 | 11 | namespace MediatRAspNetCoreDemo.Controllers 12 | { 13 | [Route("api/[controller]")] 14 | [ApiController] 15 | public class UserController : ControllerBase 16 | { 17 | private IMediator _mediator; 18 | 19 | public UserController(IMediator mediator) 20 | { 21 | _mediator = mediator; 22 | } 23 | 24 | [HttpGet("AddUser")] 25 | public async Task AddUser(string userName,string userAddr) 26 | { 27 | // 利用请求消息解耦 28 | UserAddMsg userAddMsg = new UserAddMsg { 29 | UserName=userName, 30 | UserAddr=userAddr 31 | }; 32 | int nResponse = await _mediator.Send(userAddMsg); 33 | //新增用户成功时发送消息提醒,比如有微信、短信、邮件 34 | if(nResponse==1) 35 | { 36 | // 利用通知消息解耦 37 | await _mediator.Publish(new UserAddSuccessMsg { 38 | UserName=userName, 39 | UserPwd="123456" 40 | }); 41 | } 42 | return Ok($"新增成功!{nResponse}"); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace MediatRAspNetCoreDemo.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/EventMsg/UserAddSuccessEMailHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace MediatRAspNetCoreDemo.EventMsg 9 | { 10 | public class UserAddSuccessEMailHandler : INotificationHandler 11 | { 12 | public Task Handle(UserAddSuccessMsg notification, CancellationToken cancellationToken) 13 | { 14 | Console.WriteLine($"发送邮件:用户添加成功,用户名是{notification.UserName}," + 15 | $"密码是{notification.UserPwd}"); 16 | return Task.CompletedTask; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/EventMsg/UserAddSuccessMessageHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace MediatRAspNetCoreDemo.EventMsg 9 | { 10 | public class UserAddSuccessMessageHandler : INotificationHandler 11 | { 12 | public Task Handle(UserAddSuccessMsg notification, CancellationToken cancellationToken) 13 | { 14 | Console.WriteLine($"发送短信:用户添加成功,用户名是{notification.UserName}," + 15 | $"密码是{notification.UserPwd}"); 16 | return Task.CompletedTask; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/EventMsg/UserAddSuccessMsg.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MediatRAspNetCoreDemo.EventMsg 8 | { 9 | public class UserAddSuccessMsg:INotification 10 | { 11 | public string UserName { get; set; } 12 | public string UserPwd { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/EventMsg/UserAddSuccessWeChatHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace MediatRAspNetCoreDemo.EventMsg 9 | { 10 | public class UserAddSuccessWeChatHandler : INotificationHandler 11 | { 12 | public Task Handle(UserAddSuccessMsg notification, CancellationToken cancellationToken) 13 | { 14 | Console.WriteLine($"推送微信:用户添加成功,用户名是{notification.UserName}," + 15 | $"密码是{notification.UserPwd}"); 16 | return Task.CompletedTask; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/MediatRAspNetCoreDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace MediatRAspNetCoreDemo 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:60242", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "MediatRAspNetCoreDemo": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "weatherforecast", 24 | "applicationUrl": "http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/Startup.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyq025/DotNetCoreStudyDemo/8ca9932e1cbb86ce33b982d10c914b8049436850/MediatRAspNetCoreDemo/Startup.cs -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MediatRAspNetCoreDemo 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /MediatRAspNetCoreDemo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /MediatRConsoleDemo/MediatRConsoleDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MediatRConsoleDemo/NotificationMsg/MyNotificationHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace MediatRConsoleDemo.NotificationMsg 9 | { 10 | /// 11 | /// 通知消息处理类,实现INotificationHandler接口,泛型参数只处理的消息类 12 | /// 13 | public class MyNotificationHandler : INotificationHandler 14 | { 15 | public Task Handle(MyNotificationMsg notification, CancellationToken cancellationToken) 16 | { 17 | Console.WriteLine($"MyNotificationHandler处理消息," + 18 | $"消息类型为:{notification.MsgType},消息内容为{notification.MsgContent}"); 19 | return Task.CompletedTask; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MediatRConsoleDemo/NotificationMsg/MyNotificationHandler1.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace MediatRConsoleDemo.NotificationMsg 9 | { 10 | /// 11 | /// 通知消息处理类,实现INotificationHandler接口,泛型参数只处理的消息类 12 | /// 13 | public class MyNotificationHandler1 : INotificationHandler 14 | { 15 | public Task Handle(MyNotificationMsg notification, CancellationToken cancellationToken) 16 | { 17 | Console.WriteLine($"MyNotificationHandler1处理消息," + 18 | $"消息类型为:{notification.MsgType},消息内容为{notification.MsgContent}"); 19 | return Task.CompletedTask; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MediatRConsoleDemo/NotificationMsg/MyNotificationMsg.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MediatRConsoleDemo.NotificationMsg 7 | { 8 | /// 9 | /// 抽象通知消息,实现INotification 10 | /// 11 | public class MyNotificationMsg: INotification 12 | { 13 | // 任意定义消息属性 14 | public string MsgType { get; set; } 15 | public string MsgContent { get; set; } 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MediatRConsoleDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using MediatRConsoleDemo.NotificationMsg; 3 | using MediatRConsoleDemo.RequestMsg; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using System; 6 | 7 | namespace MediatRConsoleDemo 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | // 使用自带的依赖注入 14 | var services = new ServiceCollection(); 15 | // 将MediatR相关组件进行注册,这里指明注册的程序集 16 | services.AddMediatR(typeof(Program).Assembly); 17 | 18 | // 取得容器 19 | var serviceProvider = services.BuildServiceProvider(); 20 | 21 | // 从容器中获取中介者 22 | var mediator = serviceProvider.GetService(); 23 | 24 | // 通过容器发送请求消息,然后IRequestHandler根据消息类型进行处理 25 | int nResponse = mediator.Send(new MyRequestMsg { RequestMsgType = "Request1" }).Result; 26 | 27 | Console.WriteLine($"Request消息处理完成!!!返回响应为{nResponse}"); 28 | 29 | Console.WriteLine($"====================以下是通知消息测试=========================="); 30 | 31 | mediator.Publish(new MyNotificationMsg { MsgType = "Notification", MsgContent = "TestNotify" }).ConfigureAwait(false); 32 | Console.WriteLine($"通知消息处理完成!!!"); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /MediatRConsoleDemo/RequestMsg/MyRequestHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace MediatRConsoleDemo.RequestMsg 9 | { 10 | /// 11 | /// 实现IRequestHandler代表是请求消息处理类,根据传入的消息类型智能处理对应的消息 12 | /// 13 | public class MyRequestHandler : IRequestHandler 14 | { 15 | public Task Handle(MyRequestMsg request, CancellationToken cancellationToken) 16 | { 17 | Console.WriteLine($"开始处理消息了,消息类型为:{request.RequestMsgType}"); 18 | return Task.FromResult(1); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MediatRConsoleDemo/RequestMsg/MyRequestHandler1.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace MediatRConsoleDemo.RequestMsg 9 | { 10 | /// 11 | /// 实现IRequestHandler代表是请求消息处理类,根据传入的消息类型智能处理对应的消息 12 | /// MyRequestMsg是请求消息类,int是指返回类型 13 | /// 14 | public class MyRequestHandler1 : IRequestHandler 15 | { 16 | public Task Handle(MyRequestMsg request, CancellationToken cancellationToken) 17 | { 18 | Console.WriteLine($"MyRequestHandler1开始处理消息了,消息类型为:{request.RequestMsgType}"); 19 | return Task.FromResult(1); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MediatRConsoleDemo/RequestMsg/MyRequestMsg.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MediatRConsoleDemo.RequestMsg 7 | { 8 | /// 9 | /// 实现 IRequest抽象请求消息 10 | /// 11 | public class MyRequestMsg : IRequest 12 | { 13 | /// 14 | /// 任意定义消息体,这里就定义了一个消息类型 15 | /// 16 | public string RequestMsgType { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MediatorDemo/Colleague/HouseBuyer1.cs: -------------------------------------------------------------------------------- 1 | using MediatorDemo.Mediator; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MediatorDemo.Colleague 7 | { 8 | /// 9 | /// 具体买房者1 10 | /// 11 | public class HouseBuyer1:People 12 | { 13 | public HouseBuyer1(HouseMediator mediator) 14 | :base(mediator) 15 | { } 16 | 17 | public void GetHouseMsg(string msg) 18 | { 19 | Console.WriteLine($"买房者1获得房源消息:{msg}"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MediatorDemo/Colleague/HouseBuyer2.cs: -------------------------------------------------------------------------------- 1 | using MediatorDemo.Mediator; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MediatorDemo.Colleague 7 | { 8 | /// 9 | /// 具体买房者2 10 | /// 11 | public class HouseBuyer2 : People 12 | { 13 | public HouseBuyer2(HouseMediator mediator) : base(mediator) 14 | { } 15 | 16 | public void GetHouseMsg(string msg) 17 | { 18 | Console.WriteLine($"买房者2获得房源消息:{msg}"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MediatorDemo/Colleague/HouseSeller1.cs: -------------------------------------------------------------------------------- 1 | using MediatorDemo.Mediator; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MediatorDemo.Colleague 7 | { 8 | /// 9 | /// 具体的卖房者1 10 | /// 11 | public class HouseSeller1 : People 12 | { 13 | public HouseSeller1(HouseMediator mediator) 14 | :base(mediator) 15 | { } 16 | 17 | public void GetBuyHouseMsg(string msg) 18 | { 19 | Console.WriteLine($"卖房者1获得需要买房的消息:{msg}"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MediatorDemo/Colleague/HouseSeller2.cs: -------------------------------------------------------------------------------- 1 | using MediatorDemo.Mediator; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MediatorDemo.Colleague 7 | { 8 | /// 9 | /// 具体的卖房者2 10 | /// 11 | public class HouseSeller2 : People 12 | { 13 | public HouseSeller2(HouseMediator mediator):base(mediator) 14 | { } 15 | 16 | public void GetBuyHouseMsg(string msg) 17 | { 18 | Console.WriteLine($"卖房者2获得需要买房的消息:{msg}"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MediatorDemo/Colleague/People.cs: -------------------------------------------------------------------------------- 1 | using MediatorDemo.Mediator; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MediatorDemo.Colleague 7 | { 8 | /// 9 | /// 抽象化人,买房和卖房者都是人 10 | /// 11 | public abstract class People 12 | { 13 | //和中介者关联 14 | protected HouseMediator _mediator; 15 | 16 | public People(HouseMediator mediator) 17 | { 18 | this._mediator = mediator; 19 | } 20 | 21 | // 都可以发送消息,卖房者发布房源,买房者发布购房意愿 22 | public void SendMsg(string msg) 23 | { 24 | _mediator.SendHouseMsg(msg, this); 25 | } 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /MediatorDemo/Mediator/AnJuKe.cs: -------------------------------------------------------------------------------- 1 | using MediatorDemo.Colleague; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MediatorDemo.Mediator 7 | { 8 | /// 9 | /// 房屋中介,这里拿安居客举例 10 | /// 11 | public class AnJuKe : HouseMediator 12 | { 13 | // 房屋中介需要知道所有人具体信息 14 | private HouseBuyer1 buyer1; 15 | private HouseBuyer2 buyer2; 16 | private HouseSeller1 seller1; 17 | private HouseSeller2 seller2; 18 | 19 | public HouseBuyer1 Buyer1 { set => buyer1 = value; } 20 | public HouseBuyer2 Buyer2 { set => buyer2 = value; } 21 | public HouseSeller1 Seller1 { set => seller1 = value; } 22 | public HouseSeller2 Seller2 { set => seller2 = value; } 23 | 24 | // 通过发送消息 25 | public override void SendHouseMsg(string msg, People people) 26 | { 27 | // 如果是卖房者发出房源,模拟买房者收到信息 28 | if(people==seller1||people==seller2) 29 | { 30 | buyer1.GetHouseMsg(msg); 31 | buyer2.GetHouseMsg(msg); 32 | } 33 | else// 买房者发布购房信息,卖房者收到信息 34 | { 35 | seller1.GetBuyHouseMsg(msg); 36 | seller2.GetBuyHouseMsg(msg); 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /MediatorDemo/Mediator/HouseMediator.cs: -------------------------------------------------------------------------------- 1 | using MediatorDemo.Colleague; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MediatorDemo.Mediator 7 | { 8 | /// 9 | /// 抽象化房屋中介,因为中介有很多家,如安居客、链家等 10 | /// 11 | public abstract class HouseMediator 12 | { 13 | public abstract void SendHouseMsg(string msg,People people); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MediatorDemo/MediatorDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MediatorDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using MediatorDemo.Colleague; 2 | using MediatorDemo.Mediator; 3 | using System; 4 | 5 | namespace MediatorDemo 6 | { 7 | class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | // 先有个房屋中介公司 12 | AnJuKe anjuke = new AnJuKe(); 13 | 14 | // 卖房者先找到房屋中介,从那发布房源信息,或获取买房者购房意愿 15 | HouseSeller1 seller1 = new HouseSeller1(anjuke); 16 | HouseSeller2 seller2 = new HouseSeller2(anjuke); 17 | 18 | // 买房者找到房屋中介,从那获取房源信息,或是发布购房信息 19 | HouseBuyer1 buyer1 = new HouseBuyer1(anjuke); 20 | HouseBuyer2 buyer2 = new HouseBuyer2(anjuke); 21 | 22 | // 房屋中介进行登记 23 | anjuke.Seller1 = seller1; 24 | anjuke.Seller2 = seller2; 25 | anjuke.Buyer1 = buyer1; 26 | anjuke.Buyer2 = buyer2; 27 | 28 | // 卖房者发布信息,其实是通过中介发布,发布之后所有买房者接受信息 29 | seller1.SendMsg("sell1精品好房源,速联,秒出"); 30 | 31 | // 买房者发布购房意愿信息,其实通过中介发布,发布之后相关人可以看到对应的信息 32 | buyer1.SendMsg("buyer1想入手两室一厅学区房,采光良好"); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /MemoryCacheConsoleDemo/IUserService.cs: -------------------------------------------------------------------------------- 1 | using Autofac.Extras.DynamicProxy; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MemoryCacheConsoleDemo 7 | { 8 | [Intercept(typeof(MyInterceptor))] 9 | public interface IUserService 10 | { 11 | string GetUser(string id); 12 | [MyCache] 13 | string GetUser1(string id); 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MemoryCacheConsoleDemo/MemoryCacheConsoleDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MemoryCacheConsoleDemo/MyCacheAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace MemoryCacheConsoleDemo 6 | { 7 | /// 8 | /// 自定义特性 9 | /// 10 | public class MyCacheAttribute:Attribute 11 | { 12 | // 里面可以带一些参数 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MemoryCacheConsoleDemo/MyInterceptor.cs: -------------------------------------------------------------------------------- 1 | using Castle.DynamicProxy; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Linq; 6 | using Microsoft.Extensions.Caching.Memory; 7 | 8 | namespace MemoryCacheConsoleDemo 9 | { 10 | public class MyInterceptor : IInterceptor 11 | { 12 | private IMemoryCache _memoryCache; 13 | 14 | /// 15 | /// 构造函数注入 16 | /// 17 | public MyInterceptor(IMemoryCache memoryCache) 18 | { 19 | _memoryCache = memoryCache; 20 | } 21 | 22 | public void Intercept(IInvocation invocation) 23 | { 24 | // 判断是否有自定义特性MyCacheAttribute 25 | var attr = invocation.Method.GetCustomAttributes(true) 26 | .FirstOrDefault(a => a.GetType() == typeof(MyCacheAttribute)); 27 | // 如果没有找到就不进行缓存 28 | if(attr==null) 29 | { 30 | invocation.Proceed(); 31 | } 32 | else// 找到就进行缓存 33 | { 34 | // 取的参数值作为缓存Key 35 | string strKey = invocation.Arguments[0].ToString(); 36 | //获取值 37 | var value = _memoryCache.Get(strKey); 38 | // 获取到就直接返回 39 | if (value != null) 40 | { 41 | invocation.ReturnValue="Intercept"+value; 42 | return; 43 | } 44 | // 没获取到就执行拦截到的方法 45 | invocation.Proceed(); 46 | // 将执行的结果进行缓存 47 | _memoryCache.Set(strKey, invocation.ReturnValue); 48 | 49 | } 50 | 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /MemoryCacheConsoleDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Autofac.Extras.DynamicProxy; 3 | using Microsoft.Extensions.Caching.Memory; 4 | using Microsoft.Extensions.Options; 5 | using System; 6 | 7 | namespace MemoryCacheConsoleDemo 8 | { 9 | public class Program 10 | { 11 | public static ContainerBuilder containerBuilder = new ContainerBuilder(); 12 | static void Main(string[] args) 13 | { 14 | // 注册用户服务 15 | containerBuilder.RegisterType().As() 16 | .AsImplementedInterfaces().PropertiesAutowired() 17 | .EnableInterfaceInterceptors();// 开启拦截器功能 18 | // 注册拦截器服务 19 | containerBuilder.RegisterType(typeof(MyInterceptor)); 20 | 21 | // 注册MemoryCache服务 22 | containerBuilder.Register(c=>new MemoryCache(new MemoryCacheOptions())).As() 23 | .AsImplementedInterfaces() 24 | .SingleInstance();// 单例模式注册 25 | 26 | var container = containerBuilder.Build(); 27 | 28 | 29 | // 从容器中获取实例 30 | IUserService userService = container.Resolve(); 31 | 32 | Console.WriteLine(userService.GetUser("coderZ")); 33 | 34 | Console.WriteLine(userService.GetUser("coderZ")); 35 | Console.WriteLine("========================="); 36 | Console.WriteLine(userService.GetUser1("coderZYQ")); 37 | Console.WriteLine(userService.GetUser1("coderZYQ")); 38 | 39 | 40 | 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /MemoryCacheConsoleDemo/UserService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Caching.Memory; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MemoryCacheConsoleDemo 7 | { 8 | public class UserService : IUserService 9 | { 10 | private IMemoryCache _memoryCache; 11 | 12 | public UserService(IMemoryCache memoryCache) 13 | { 14 | _memoryCache = memoryCache; 15 | } 16 | public string GetUser(string id) 17 | { 18 | var v = _memoryCache.Get(id); 19 | if(v==null) 20 | { 21 | // 直接调用方法设置即可,其他方法也一样 22 | _memoryCache.Set(id, id + ":Zoe"); 23 | return id + ":Zoe"; 24 | } 25 | else 26 | { 27 | return "Cache:" + v.ToString(); 28 | } 29 | } 30 | 31 | public string GetUser1(string id) 32 | { 33 | return id+":Zoe1"; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /MemoryCacheWebApiDemo/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace MemoryCacheWebApiDemo.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | [MyCache] 28 | public IEnumerable Get() 29 | { 30 | var rng = new Random(); 31 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 32 | { 33 | Date = DateTime.Now.AddDays(index), 34 | TemperatureC = rng.Next(-20, 55), 35 | Summary = Summaries[rng.Next(Summaries.Length)] 36 | }) 37 | .ToArray(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /MemoryCacheWebApiDemo/MemoryCacheWebApiDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MemoryCacheWebApiDemo/MyCacheAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace MemoryCacheWebApiDemo 6 | { 7 | public class MyCacheAttribute:Attribute 8 | { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MemoryCacheWebApiDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace MemoryCacheWebApiDemo 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MemoryCacheWebApiDemo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:56482", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "MemoryCacheWebApiDemo": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "weatherforecast", 24 | "applicationUrl": "http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /MemoryCacheWebApiDemo/ResourceFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.Controllers; 3 | using Microsoft.AspNetCore.Mvc.Filters; 4 | using Microsoft.Extensions.Caching.Memory; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Threading.Tasks; 10 | 11 | namespace MemoryCacheWebApiDemo 12 | { 13 | public class ResourceFilter : Attribute, IResourceFilter 14 | { 15 | private IMemoryCache _memoryCache; 16 | 17 | /// 18 | /// 构造函数注入 19 | /// 20 | public ResourceFilter(IMemoryCache memoryCache) 21 | { 22 | _memoryCache = memoryCache; 23 | } 24 | 25 | // 执行前 26 | public void OnResourceExecuting(ResourceExecutingContext context) 27 | { 28 | // 根据请求生成Key 29 | string key = GenerateKey(context); 30 | // 从缓存中获取数据 31 | var value = _memoryCache.Get(key); 32 | // 如果取到数据,直接返回,不走下面流程,提高效率 33 | if(value!=null) 34 | { 35 | context.Result = value as IActionResult; 36 | } 37 | } 38 | 39 | // 执行完毕 40 | public void OnResourceExecuted(ResourceExecutedContext context) 41 | { 42 | // 根据请求生成Key 43 | string key = GenerateKey(context); 44 | // 将执行结果进行缓存 45 | _memoryCache.Set(key, context.Result); 46 | } 47 | /// 48 | /// 根据请求生成Key 49 | /// 50 | private string GenerateKey(FilterContext context) 51 | { 52 | // 这里可以取得自定义的Attribute,可以进行判断是否进行缓存,这里就不写啦 53 | // 逻辑和MemoryCacheConsoleDemo逻辑一致 54 | var action = context.ActionDescriptor as ControllerActionDescriptor; 55 | var attr = action.MethodInfo.GetCustomAttribute(); 56 | 57 | // 根据请求生成Key 58 | string url = context.HttpContext.Request.Path; //这里可以把参数带上 59 | string param = context.HttpContext.Request.QueryString.Value; // Url参数 60 | return url + param; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /MemoryCacheWebApiDemo/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.Mvc; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.DependencyInjection; 10 | using Microsoft.Extensions.Hosting; 11 | using Microsoft.Extensions.Logging; 12 | 13 | namespace MemoryCacheWebApiDemo 14 | { 15 | public class Startup 16 | { 17 | public Startup(IConfiguration configuration) 18 | { 19 | Configuration = configuration; 20 | } 21 | 22 | public IConfiguration Configuration { get; } 23 | 24 | // This method gets called by the runtime. Use this method to add services to the container. 25 | public void ConfigureServices(IServiceCollection services) 26 | { 27 | services.AddControllers(options=>options.Filters.Add(typeof(ResourceFilter))); 28 | services.AddMemoryCache(); 29 | } 30 | 31 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 32 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 33 | { 34 | if (env.IsDevelopment()) 35 | { 36 | app.UseDeveloperExceptionPage(); 37 | } 38 | 39 | app.UseRouting(); 40 | 41 | app.UseAuthorization(); 42 | 43 | app.UseEndpoints(endpoints => 44 | { 45 | endpoints.MapControllers(); 46 | }); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MemoryCacheWebApiDemo/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MemoryCacheWebApiDemo 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MemoryCacheWebApiDemo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /MemoryCacheWebApiDemo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /MvcFilterDemo/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | using MvcFilterDemo.Filters; 8 | 9 | namespace MvcFilterDemo.Controllers 10 | { 11 | [ApiController] 12 | [Route("[controller]")] 13 | [MyAuthorizeFilter] 14 | [MyActionFilter1(Order =2)] 15 | public class WeatherForecastController : ControllerBase 16 | { 17 | private static readonly string[] Summaries = new[] 18 | { 19 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 20 | }; 21 | 22 | private readonly ILogger _logger; 23 | 24 | public WeatherForecastController(ILogger logger) 25 | { 26 | _logger = logger; 27 | } 28 | 29 | [HttpGet] 30 | //[MyActionFilter1] 31 | //[MyActionFilter] 32 | [MyActionFilter2(Order =1)] 33 | [MyFilterFactoryAttribute(typeof(MyNoAttributeActionFilter))] 34 | public IEnumerable Get() 35 | { 36 | 37 | Console.WriteLine("======Action方法执行======="); 38 | //throw new Exception("Action抛出异常了"); 39 | var rng = new Random(); 40 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 41 | { 42 | Date = DateTime.Now.AddDays(index), 43 | TemperatureC = rng.Next(-20, 55), 44 | Summary = Summaries[rng.Next(Summaries.Length)] 45 | }) 46 | .ToArray(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MvcFilterDemo/Filters/MyActionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MvcFilterDemo.Filters 8 | { 9 | /// 10 | /// 继承Attribute可以进行特性标注,实现IActionFilter 11 | /// 12 | public class MyActionFilter : Attribute, IActionFilter, IOrderedFilter 13 | { 14 | public int Order =>3; 15 | 16 | public void OnActionExecuted(ActionExecutedContext context) 17 | { 18 | // context.RouteData 获取路由相关信息 19 | Console.WriteLine("OnActionExecuted方法执行"); 20 | //throw new Exception("OnActionExecuted方法有异常"); 21 | } 22 | 23 | public void OnActionExecuting(ActionExecutingContext context) 24 | { 25 | // context.RouteData 获取路由相关信息 26 | // context.HttpContext 拿到HttpContext 无所不能 27 | if(!context.ModelState.IsValid) //如果是模型绑定,可以这样判断参数是否合法 28 | { 29 | Console.WriteLine("OnActionExecuting参数不合法"); 30 | } 31 | Console.WriteLine("OnActionExecuting方法执行"); 32 | //throw new Exception("OnActionExecuting异常了"); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /MvcFilterDemo/Filters/MyActionFilter1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MvcFilterDemo.Filters 8 | { 9 | /// 10 | /// 继承Attribute可以进行特性标注,实现IActionFilter 11 | /// 12 | public class MyActionFilter1 : Attribute, IActionFilter, IOrderedFilter 13 | { 14 | public int Order { get; set; } 15 | 16 | public void OnActionExecuted(ActionExecutedContext context) 17 | { 18 | // context.RouteData 获取路由相关信息 19 | Console.WriteLine("OnActionExecuted方法执行====controller"); 20 | //throw new Exception("OnActionExecuted方法有异常"); 21 | } 22 | 23 | public void OnActionExecuting(ActionExecutingContext context) 24 | { 25 | // context.RouteData 获取路由相关信息 26 | // context.HttpContext 拿到HttpContext 无所不能 27 | if(!context.ModelState.IsValid) //如果是模型绑定,可以这样判断参数是否合法 28 | { 29 | Console.WriteLine("OnActionExecuting参数不合法"); 30 | } 31 | Console.WriteLine("OnActionExecuting方法执行====controller"); 32 | //throw new Exception("OnActionExecuting异常了"); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /MvcFilterDemo/Filters/MyActionFilter2.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MvcFilterDemo.Filters 8 | { 9 | /// 10 | /// 继承Attribute可以进行特性标注,实现IActionFilter 11 | /// 12 | public class MyActionFilter2 : Attribute, IActionFilter, IOrderedFilter 13 | { 14 | public int Order { get; set; } 15 | 16 | public void OnActionExecuted(ActionExecutedContext context) 17 | { 18 | // context.RouteData 获取路由相关信息 19 | Console.WriteLine("OnActionExecuted方法执行====action"); 20 | //throw new Exception("OnActionExecuted方法有异常"); 21 | } 22 | public void OnActionExecuting(ActionExecutingContext context) 23 | { 24 | // context.RouteData 获取路由相关信息 25 | // context.HttpContext 拿到HttpContext 无所不能 26 | if(!context.ModelState.IsValid) //如果是模型绑定,可以这样判断参数是否合法 27 | { 28 | Console.WriteLine("OnActionExecuting参数不合法"); 29 | } 30 | Console.WriteLine("OnActionExecuting方法执行====action"); 31 | //throw new Exception("OnActionExecuting异常了"); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /MvcFilterDemo/Filters/MyAuthorizeFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.Authorization; 3 | using Microsoft.AspNetCore.Mvc.Filters; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MvcFilterDemo.Filters 10 | { 11 | /// 12 | /// 自定义授权过滤器,继承Atrribute表示可以进行特性标注,实现IAuthorizationFilter接口 13 | /// 14 | public class MyAuthorizeFilter : Attribute, IAuthorizationFilter 15 | { 16 | public void OnAuthorization(AuthorizationFilterContext context) 17 | { 18 | // 1. 可以验证是否登录, 比如使用Session,或是Jwt方式 19 | 20 | // 2. 获取请求的路径,与权限进行比对校验 21 | var strPath = context.HttpContext.Request.Path; 22 | 23 | // 改变控制台字体颜色 24 | Console.ForegroundColor = ConsoleColor.Green; 25 | Console.WriteLine($"MyAuthorizeFilter执行:{strPath}"); 26 | 27 | // 恢复原有字体颜色 28 | Console.ForegroundColor = ConsoleColor.Gray; 29 | 30 | // validate 结果是验证结果 31 | bool validate = false; 32 | 33 | // 结果如果验证失败,就返回没权限 34 | if(validate) 35 | { 36 | // 任意IActionResult,根据需求定义 37 | ContentResult contentResult = new ContentResult(); 38 | // 返回的状态码 39 | contentResult.StatusCode = 401; 40 | // 返回的内容 41 | contentResult.Content = "没权限"; 42 | 43 | // 直接指定结果返回 44 | context.Result = contentResult; 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /MvcFilterDemo/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.Filters; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MvcFilterDemo.Filters 9 | { 10 | public class MyExceptionFilter : Attribute, IExceptionFilter 11 | { 12 | public void OnException(ExceptionContext context) 13 | { 14 | Console.ForegroundColor = ConsoleColor.Red; 15 | Console.WriteLine($"捕获到异常:{context.Exception.Message+context.Exception.StackTrace},可以记录日志"); 16 | Console.ForegroundColor = ConsoleColor.Gray; 17 | // 代表异常已经处理 18 | context.ExceptionHandled = true; 19 | 20 | // 可以根据需求定义返回格式,ContentResult、JsonResult 等 21 | ContentResult contentResult = new ContentResult() { 22 | StatusCode=200, 23 | Content="联系管理员,异常编号10000" 24 | }; 25 | // 设置返回结果 26 | context.Result = contentResult; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MvcFilterDemo/Filters/MyNoAttributeActionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MvcFilterDemo.Filters 8 | { 9 | /// 10 | /// 继承Attribute可以进行特性标注,实现IActionFilter 11 | /// 12 | public class MyNoAttributeActionFilter :IActionFilter, IOrderedFilter 13 | { 14 | public int Order =>3; 15 | 16 | public void OnActionExecuted(ActionExecutedContext context) 17 | { 18 | // context.RouteData 获取路由相关信息 19 | Console.WriteLine("OnActionExecuted方法执行====MyNoAttributeActionFilter"); 20 | //throw new Exception("OnActionExecuted方法有异常"); 21 | } 22 | 23 | public void OnActionExecuting(ActionExecutingContext context) 24 | { 25 | // context.RouteData 获取路由相关信息 26 | // context.HttpContext 拿到HttpContext 无所不能 27 | if(!context.ModelState.IsValid) //如果是模型绑定,可以这样判断参数是否合法 28 | { 29 | Console.WriteLine("OnActionExecuting参数不合法"); 30 | } 31 | Console.WriteLine("OnActionExecuting方法执行====MyNoAttributeActionFilter"); 32 | //throw new Exception("OnActionExecuting异常了"); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /MvcFilterDemo/Filters/MyResourceFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MvcFilterDemo.Filters 8 | { 9 | /// 10 | /// 资源过滤器,继承Attribute,可以进行特性标注,实现IResourceFilter接口 11 | /// 12 | public class MyResourceFilter : Attribute, IResourceFilter 13 | { 14 | /// 15 | /// 资源过滤器前置方法,授权过滤器通过就执行 16 | /// 17 | public void OnResourceExecuting(ResourceExecutingContext context) 18 | { 19 | // 1. 可以在这做缓存,如果是页面可以做页面缓存 20 | // 如果是数据,可以做数据缓存,比如从Redis中取,得到之后就返回,后面逻辑不执行 21 | Console.WriteLine("==== OnResourceExecuting========"); 22 | //throw new Exception("OnResourceExecuting有异常"); 23 | } 24 | /// 25 | /// 资源过滤器后置方法,当所有处理返回时执行,然后返回的中间件管道 26 | /// 27 | public void OnResourceExecuted(ResourceExecutedContext context) 28 | { 29 | Console.WriteLine("==== OnResourceExecuted========"); 30 | //throw new Exception("OnResourceExecuted有异常"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /MvcFilterDemo/Filters/MyResultFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MvcFilterDemo.Filters 8 | { 9 | /// 10 | /// 继承Attribute可以进行特性标注,实现IResultFilter 11 | /// 12 | public class MyResultFilter : Attribute, IResultFilter 13 | { 14 | public void OnResultExecuted(ResultExecutedContext context) 15 | { 16 | 17 | // context.RouteData 获取路由相关信息 18 | // context.HttpContext 拿到HttpContext 无所不能 19 | Console.WriteLine("OnResultExecuted方法执行"); 20 | //throw new Exception("sd"); 21 | } 22 | 23 | public void OnResultExecuting(ResultExecutingContext context) 24 | { 25 | // context.RouteData 获取路由相关信息 26 | // context.HttpContext 拿到HttpContext 无所不能 27 | Console.WriteLine("OnResultExecuting方法执行"); 28 | //throw new Exception("sd1"); 29 | 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /MvcFilterDemo/MvcFilterDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MvcFilterDemo/MyFilterFactoryAttribute.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MvcFilterDemo 8 | { 9 | /// 10 | /// 继承Attribute就可以进行特性标注 11 | /// 12 | public class MyFilterFactoryAttribute : Attribute, IFilterFactory 13 | { 14 | public bool IsReusable =>true; 15 | 16 | /// 17 | /// 过滤器类型 18 | /// 19 | private Type filterType; 20 | 21 | /// 22 | /// 构造函数初始化过滤器类型 23 | /// 24 | public MyFilterFactoryAttribute(Type type) 25 | { 26 | filterType = type; 27 | } 28 | 29 | public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) 30 | { 31 | // 从容器中获取过滤器类型,所以前提过滤器服务需要提前注册 32 | return (IFilterMetadata)serviceProvider.GetService(filterType); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /MvcFilterDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace MvcFilterDemo 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MvcFilterDemo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:60381", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "MvcFilterDemo": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "weatherforecast", 24 | "applicationUrl": "http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /MvcFilterDemo/Startup.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyq025/DotNetCoreStudyDemo/8ca9932e1cbb86ce33b982d10c914b8049436850/MvcFilterDemo/Startup.cs -------------------------------------------------------------------------------- /MvcFilterDemo/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MvcFilterDemo 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MvcFilterDemo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /MvcFilterDemo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /PDFDemo/Controllers/PDFTestController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Http; 7 | using Microsoft.AspNetCore.Mvc; 8 | using PDFDemo.Models; 9 | using Wkhtmltopdf.NetCore; 10 | 11 | namespace PDFDemo.Controllers 12 | { 13 | [Route("api/[controller]")] 14 | [ApiController] 15 | public class PDFTestController : ControllerBase 16 | { 17 | // 生成pdf的实例对象 18 | private readonly IGeneratePdf _generatePdf; 19 | 20 | // 注入 21 | public PDFTestController(IGeneratePdf generatePdf) 22 | { 23 | _generatePdf = generatePdf; 24 | } 25 | 26 | /// 27 | /// 先看再下载 28 | /// 29 | [HttpGet("ExportPDFByHtml")] 30 | public IActionResult ExportPDFByHtml() 31 | { 32 | string strHtmlTemplate = @" 33 | 34 | 35 | 36 | 37 |
38 |

Zoe

39 |
40 |
41 |

欢迎关注Code综艺圈

42 |
43 | "; 44 | // 生成pdf 45 | var pdf = _generatePdf.GetPDF(strHtmlTemplate); 46 | var pdfFileStream = new MemoryStream(); 47 | pdfFileStream.Write(pdf, 0,pdf.Length); 48 | pdfFileStream.Position = 0; 49 | // 以文件流形式返回,类型设置为application/pdf,在浏览器中可以查看 50 | return new FileStreamResult(pdfFileStream, "application/pdf"); 51 | } 52 | 53 | /// 54 | /// 直接保存 55 | /// 56 | [HttpGet("SavePDFByHtml")] 57 | public IActionResult SavePDFByHtml() 58 | { 59 | // 导出html模板 60 | string strHtmlTemplate = @" 61 | 62 | 63 | 64 | 65 |
66 |

Zoe

67 |
68 |
69 |

欢迎关注Code综艺圈

70 |
71 | "; 72 | var pdf = _generatePdf.GetPDF(strHtmlTemplate); 73 | // 将文件流直接保存,指定保存的文件名,可以根据需求生成 74 | System.IO.File.WriteAllBytes("testpdf.pdf", pdf); 75 | return Ok("成功"); 76 | } 77 | 78 | [HttpGet("TestMarginAndPageSize")] 79 | public IActionResult TestMarginAndPageSize() 80 | { 81 | string strHtmlTemplate = @" 82 | 83 | 84 | 85 | 86 |
87 |

Zoe

88 |
89 |
90 |

欢迎关注Code综艺圈

91 |
92 | "; 93 | var options = new ConvertOptions 94 | { 95 | PageMargins = new Wkhtmltopdf.NetCore.Options.Margins 96 | { 97 | Bottom = 10,//下边距 98 | Left = 0,//左边距 99 | Right = 0,//右边距 100 | Top = 15//上边距 101 | }, 102 | PageSize = Wkhtmltopdf.NetCore.Options.Size.A5 103 | }; 104 | _generatePdf.SetConvertOptions(options); 105 | var pdf = _generatePdf.GetPDF(strHtmlTemplate); 106 | var pdfFileStream = new MemoryStream(); 107 | pdfFileStream.Write(pdf, 0, pdf.Length); 108 | pdfFileStream.Position = 0; 109 | return new FileStreamResult(pdfFileStream, "application/pdf"); 110 | } 111 | 112 | [HttpGet("ExportByRazorView")] 113 | public async Task ExportByRazorView() 114 | { 115 | var pdf = await _generatePdf.GetByteArray("Views/Zoe.cshtml"); 116 | var pdfFileStream = new MemoryStream(); 117 | pdfFileStream.Write(pdf, 0, pdf.Length); 118 | pdfFileStream.Position = 0; 119 | return new FileStreamResult(pdfFileStream, "application/pdf"); 120 | } 121 | 122 | [HttpGet("ExportByRazorViewData")] 123 | public async Task ExportByRazorViewData() 124 | { 125 | Zoe zoe = new Zoe { 126 | Name="Zoe,好酷", 127 | WeiXin="Code综艺圈" 128 | }; 129 | var pdf = await _generatePdf.GetByteArray("Views/ZoeData.cshtml",zoe); 130 | var pdfFileStream = new MemoryStream(); 131 | pdfFileStream.Write(pdf, 0, pdf.Length); 132 | pdfFileStream.Position = 0; 133 | return new FileStreamResult(pdfFileStream, "application/pdf"); 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /PDFDemo/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace PDFDemo.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /PDFDemo/Models/Zoe.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace PDFDemo.Models 7 | { 8 | public class Zoe 9 | { 10 | public string Name { get; set; } 11 | public string WeiXin { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /PDFDemo/PDFDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Always 15 | 16 | 17 | Always 18 | 19 | 20 | Always 21 | 22 | 23 | Always 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /PDFDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace PDFDemo 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /PDFDemo/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | False 8 | False 9 | True 10 | Release 11 | Any CPU 12 | FileSystem 13 | bin\Release\netcoreapp3.1\publish\ 14 | FileSystem 15 | 16 | -------------------------------------------------------------------------------- /PDFDemo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:51402", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "PDFDemo": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "weatherforecast", 24 | "applicationUrl": "http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /PDFDemo/Rotativa/Linux/libwkhtmltox.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyq025/DotNetCoreStudyDemo/8ca9932e1cbb86ce33b982d10c914b8049436850/PDFDemo/Rotativa/Linux/libwkhtmltox.so -------------------------------------------------------------------------------- /PDFDemo/Rotativa/Linux/wkhtmltopdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyq025/DotNetCoreStudyDemo/8ca9932e1cbb86ce33b982d10c914b8049436850/PDFDemo/Rotativa/Linux/wkhtmltopdf -------------------------------------------------------------------------------- /PDFDemo/Rotativa/Mac/wkhtmltopdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyq025/DotNetCoreStudyDemo/8ca9932e1cbb86ce33b982d10c914b8049436850/PDFDemo/Rotativa/Mac/wkhtmltopdf -------------------------------------------------------------------------------- /PDFDemo/Rotativa/Windows/wkhtmltopdf.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyq025/DotNetCoreStudyDemo/8ca9932e1cbb86ce33b982d10c914b8049436850/PDFDemo/Rotativa/Windows/wkhtmltopdf.exe -------------------------------------------------------------------------------- /PDFDemo/Startup.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyq025/DotNetCoreStudyDemo/8ca9932e1cbb86ce33b982d10c914b8049436850/PDFDemo/Startup.cs -------------------------------------------------------------------------------- /PDFDemo/Views/Zoe.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Zoe 8 | 9 | 10 |
Zoe 好酷!!!!
11 |
关注 Code综艺圈 一块学呀,来来来
12 | 13 | 14 | -------------------------------------------------------------------------------- /PDFDemo/Views/ZoeData.cshtml: -------------------------------------------------------------------------------- 1 | @model PDFDemo.Models.Zoe 2 | 3 | 4 | 5 | 6 | 7 | Zoe 8 | 9 | 10 |
@Model.Name
11 |
关注 @Model.WeiXin 一块学呀,来来来
12 | 13 | 14 | -------------------------------------------------------------------------------- /PDFDemo/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PDFDemo 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /PDFDemo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /PDFDemo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DotNetCoreStudyDemo 2 | Code综艺圈涉及相关学习Demo 3 | 4 | SwaggerDemo项目包含Jwt相关代码 5 | -------------------------------------------------------------------------------- /SwaggerDemo/Controllers/ProductController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Authorization; 6 | using Microsoft.AspNetCore.Http; 7 | using Microsoft.AspNetCore.Mvc; 8 | 9 | namespace SwaggerDemo.Controllers 10 | { 11 | [Route("api/[controller]")] 12 | [ApiController] 13 | [Authorize] 14 | [AllowAnonymous] 15 | public class ProductController : ControllerBase 16 | { 17 | 18 | /// 19 | /// 管理员配置产品相关信息 20 | /// 21 | [HttpPost("AdminConfigProductData")] 22 | //[Authorize(Roles ="Admin")] 23 | //[Authorize(Policy = "AdminPolicy")] 24 | [Authorize(Policy = "Permission")] 25 | public ActionResult AdminConfigProductData() 26 | { 27 | return Ok("管理员配置产品信息"); 28 | } 29 | 30 | /// 31 | /// 维护员提交产品维护记录信息 32 | /// 33 | [HttpPost("MaintainProductInfo")] 34 | //[Authorize(Roles = "Maintain")] 35 | //[Authorize(Policy = "AdminAndMaintainPolicy")] 36 | [Authorize(Policy = "Permission")] 37 | public ActionResult MaintainProductInfo() 38 | { 39 | return Ok("维护员提交产品维护记录信息"); 40 | } 41 | 42 | /// 43 | /// 用户访问产品信息 44 | /// 45 | [HttpPost("UserProductInfo")] 46 | //[Authorize(Roles = "User")] 47 | //[Authorize(Policy = "AdminAndMaintainPolicy")] 48 | [Authorize(Policy = "Permission")] 49 | public ActionResult UserProductInfo() 50 | { 51 | return Ok("用户访问产品信息"); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /SwaggerDemo/Controllers/UserController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IdentityModel.Tokens.Jwt; 4 | using System.Linq; 5 | using System.Security.Claims; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using Microsoft.AspNetCore.Authorization; 9 | using Microsoft.AspNetCore.Http; 10 | using Microsoft.AspNetCore.Mvc; 11 | using Microsoft.IdentityModel.Tokens; 12 | using SwaggerDemo.Permission; 13 | using TestSwaggerModel; 14 | 15 | namespace SwaggerDemo.Controllers 16 | { 17 | /// 18 | /// 用户API 19 | /// 20 | [Route("api/[controller]")] 21 | [ApiController] 22 | public class UserController : ControllerBase 23 | { 24 | 25 | //通过构造函数注入 PermissionRequirement,注册的时候用的是单例模式 26 | private PermissionRequirement _permissionRequirement; 27 | public UserController(PermissionRequirement permissionRequirement) 28 | { 29 | _permissionRequirement = permissionRequirement; 30 | } 31 | 32 | /// 33 | /// 登录Api,传入用户名和密码 34 | /// 35 | [HttpPost("Login")] 36 | public ActionResult Login(UserConditon userConditon) 37 | { 38 | // 返回用户信息,模拟从数据库中查询用户得到用户信息 39 | if(userConditon==null||userConditon.UserName!="Code综艺圈"||userConditon.Pwd!="Zoe") 40 | { 41 | return Ok("登录失败~~~"); 42 | } 43 | // 这里可以根据需要将其权限放在Redis中,每次登陆时都重新存,即登陆获取最新权限 44 | // 这里模拟通过userId从数据库中获取分配的接口权限信息,这里存在内存中 45 | _permissionRequirement.Permissions = new List { 46 | new PermissionData{ UserId="Zoe1111",Url="/api/Product/AdminConfigProductData" }, 47 | //new PermissionData{ UserId="Zoe1111",Url="/api/Product/MaintainProductInfo" }, 48 | new PermissionData{ UserId="Zoe1111",Url="/api/Product/UserProductInfo" } 49 | }; 50 | // 生成Token并返回 51 | string token = GenerateToke("Zoe1111", "Code综艺圈"); 52 | return Ok(token); 53 | } 54 | private string GenerateToke(string userId, string userName) 55 | { 56 | // 秘钥,这是生成Token需要秘钥,就是理论提及到签名那块的秘钥 57 | string secret = "TestSecretTestSecretTestSecretTestSecret"; 58 | // 签发者,是由谁颁发的 59 | string issuer = "TestIssuer"; 60 | // 接受者,是给谁用的 61 | string audience = "TestAudience"; 62 | // 指定秘钥 63 | var securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret)); 64 | // 签名凭据,指定对应的签名算法,结合理论那块看哦~~~ 65 | var sigingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); 66 | // 自定义payload信息,每一个claim代表一个属性键值对,就类似身份证上的姓名,出生年月一样 67 | var claims = new Claim[] { new Claim("userId", userId), 68 | new Claim("userName", userName), 69 | // claims中添加角色属性,这里的键一定要用微软封装好的ClaimTypes.Role 70 | new Claim(ClaimTypes.Role,"Admin"), 71 | new Claim(ClaimTypes.Role,"Maintain") 72 | }; 73 | 74 | // 组装生成Token的数据 75 | SecurityToken securityToken = new JwtSecurityToken( 76 | issuer: issuer,// 颁发者 77 | audience: audience,// 接受者 78 | claims: claims,//自定义的payload信息 79 | signingCredentials: sigingCredentials,// 凭据 80 | expires: DateTime.Now.AddMinutes(30) // 设置超时时间,30分钟之后过期 81 | ); 82 | // 生成Token 83 | return new JwtSecurityTokenHandler().WriteToken(securityToken); 84 | } 85 | 86 | /// 87 | /// 获取用户信息 88 | /// 89 | [HttpPost("GetUserInfo")] 90 | [Authorize] 91 | public ActionResult GetUserInfo() 92 | { 93 | return Ok("获取用户信息成功"); 94 | } 95 | /// 96 | /// 测试接口 97 | /// 98 | [HttpPost("TestNoAuth")] 99 | public ActionResult TestNoAuth() 100 | { 101 | return Content("不需要认证就能访问"); 102 | } 103 | 104 | 105 | 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /SwaggerDemo/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace SwaggerDemo.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SwaggerDemo/Permission/PermissionHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authentication; 2 | using Microsoft.AspNetCore.Authorization; 3 | using Microsoft.AspNetCore.Http; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace SwaggerDemo.Permission 10 | { 11 | /// 12 | /// 权限处理的关键类 13 | /// 14 | public class PermissionHandler : AuthorizationHandler 15 | { 16 | /// 17 | /// 通过IHttpContextAccessor可以获取HttpContext相关信息,但一定要注册服务 18 | /// 19 | private readonly IHttpContextAccessor _accessor; 20 | /// 21 | /// 用于判断请求是否带有凭据和是否登录 22 | /// 23 | public IAuthenticationSchemeProvider Scheme { get; set; } 24 | /// 25 | /// 构造函数注入 26 | /// 27 | public PermissionHandler(IHttpContextAccessor accessor,IAuthenticationSchemeProvider scheme) 28 | { 29 | this._accessor = accessor; 30 | Scheme = scheme; 31 | } 32 | protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) 33 | { 34 | try 35 | { 36 | //拿到HttpContext就无所不能啦 37 | var httpContext = _accessor.HttpContext; 38 | //判断资源数据中权限列表中是否有权限 39 | if (!requirement.Permissions.Any()) 40 | { 41 | //没有直接返回无权限,也可以重新获取权限,实现不退出重新登录就可获取最新权限 42 | context.Fail(); 43 | } 44 | //判读请求是否拥有凭据,即是否登录 45 | var defaultAuthenticate = await Scheme.GetDefaultAuthenticateSchemeAsync(); 46 | if (defaultAuthenticate == null) 47 | { 48 | context.Fail(); 49 | } 50 | var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name); 51 | //不为空代表登录成功,为空登录失败 52 | if (result?.Principal != null) 53 | { 54 | // 获取生成Token时放在payload里的userId 55 | string userId = _accessor.HttpContext.User.FindFirst("userId").Value; 56 | // 获取当前请求的地址 57 | string requestUrl = httpContext.Request.Path.Value.ToLower(); 58 | // 从权限表中查找当前用户是否有当前请求地址的权限 59 | var permission = requirement.Permissions.FirstOrDefault(a => a.Url.ToLower() == requestUrl && a.UserId == userId); 60 | // 如果没找到,代表没有权限 61 | if (permission == null) 62 | { 63 | context.Fail(); 64 | } 65 | // 如果找到,就继续往下执行 66 | context.Succeed(requirement); 67 | } 68 | else 69 | { 70 | // 获取不到对应值就返回无权限 71 | context.Fail(); 72 | } 73 | } 74 | catch (Exception ex) 75 | { 76 | context.Fail(); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /SwaggerDemo/Permission/PermissionRequirement.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace SwaggerDemo.Permission 8 | { 9 | /// 10 | /// 资源数据的载体,可以根据需求自定义任何数据 11 | /// 需要实现IAuthorizationRequirement接口进行标识 12 | /// 13 | public class PermissionRequirement:IAuthorizationRequirement 14 | { 15 | /// 16 | /// 存放系统中所有权限 17 | /// 18 | public List Permissions { get; set; } 19 | 20 | } 21 | 22 | /// 23 | /// 定义了一个权限数据存储类,包含用户ID和对应的权限访问的Url地址 24 | /// 25 | public class PermissionData 26 | { 27 | /// 28 | /// 用户ID 29 | /// 30 | public string UserId { get; set; } 31 | /// 32 | /// 用户对应的 Url地址 33 | /// 34 | public string Url { get; set; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /SwaggerDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace SwaggerDemo 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SwaggerDemo/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | False 8 | False 9 | True 10 | Release 11 | Any CPU 12 | FileSystem 13 | bin\Release\netcoreapp3.1\publish\ 14 | FileSystem 15 | 16 | -------------------------------------------------------------------------------- /SwaggerDemo/Properties/PublishProfiles/FolderProfile.pubxml.user: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | <_PublishTargetUrl>H:\DotNetProject\SwaggerDemo\bin\Release\netcoreapp3.1\publish\ 8 | 9 | -------------------------------------------------------------------------------- /SwaggerDemo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:62485", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "SwaggerDemo": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "weatherforecast", 24 | "applicationUrl": "http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SwaggerDemo/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Microsoft.AspNetCore.Authorization; 8 | using Microsoft.AspNetCore.Builder; 9 | using Microsoft.AspNetCore.Hosting; 10 | using Microsoft.AspNetCore.Http; 11 | using Microsoft.AspNetCore.Mvc; 12 | using Microsoft.Extensions.Configuration; 13 | using Microsoft.Extensions.DependencyInjection; 14 | using Microsoft.Extensions.Hosting; 15 | using Microsoft.Extensions.Logging; 16 | using Microsoft.IdentityModel.Tokens; 17 | using Microsoft.OpenApi.Models; 18 | using SwaggerDemo.Permission; 19 | using Swashbuckle.AspNetCore.Filters; 20 | 21 | namespace SwaggerDemo 22 | { 23 | public class Startup 24 | { 25 | public Startup(IConfiguration configuration) 26 | { 27 | Configuration = configuration; 28 | } 29 | 30 | public IConfiguration Configuration { get; } 31 | 32 | // This method gets called by the runtime. Use this method to add services to the container. 33 | public void ConfigureServices(IServiceCollection services) 34 | { 35 | services.AddControllers(); 36 | // 注册Swagger相关组件 37 | services.AddSwaggerGen(option => 38 | { 39 | // 配置Swagger 文档信息,第一个参数很重要"TestSwagger",得和后续注册中间件一直 40 | option.SwaggerDoc("TestSwagger", new OpenApiInfo 41 | { 42 | // 文档版本 43 | Version = "TestSwagger-V1", 44 | // 标题 45 | Title = "TestSwagger 接口文档", 46 | // 描述 47 | Description = "这是TestSwagger文档,版本为V1", 48 | // 联系方式,地址和邮箱配置 49 | Contact = new OpenApiContact { Name = "TestSwagger-C", Email = "Test@xxx.com", Url = new Uri("https://www.cnblogs.com/zoe-zyq/") }, 50 | License = new OpenApiLicense { Name = "TestSwagger-L", Url = new Uri("https://www.cnblogs.com/zoe-zyq/") } 51 | }); 52 | // 指定Action排序方式,这里是按Action相对路径进行排序 53 | option.OrderActionsBy(o => o.RelativePath); 54 | 55 | //设置注释提示,主要是指定xml文件路径,从xml中读取相关的信息 56 | var basePath = AppContext.BaseDirectory; 57 | // 配置API读取注释 58 | var apiXml = Path.Combine(basePath, "SwaggerDemo.xml"); 59 | option.IncludeXmlComments(apiXml, true); 60 | 61 | // 配置Model读取注释 62 | var modelXml = Path.Combine(basePath, "TestSwaggerModel.xml"); 63 | option.IncludeXmlComments(modelXml); 64 | 65 | #region Swagger扩展-增加输入Token即添加小锁功能,清楚看见接口是否安全 66 | // 方式1 67 | option.OperationFilter(); 68 | option.OperationFilter(); 69 | // 将Token放在请求头中传递到后台 70 | option.OperationFilter(); 71 | 72 | // 指定名称必须为oauth2,因为SecurityRequirementsOperationFilter默认securitySchemaName指定为oauth2 73 | option.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme 74 | { 75 | Description = "Jwt认证授权,在输入框中输入'Bearer token'(Bearer和token之间有一个空格)", 76 | Name = "Authorization",//设置参数名 77 | In = ParameterLocation.Header,//在请求头中添加名称Authorization 78 | Type = SecuritySchemeType.ApiKey, 79 | }); 80 | 81 | //方式2 82 | //option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme 83 | //{ 84 | // Description = "Jwt认证授权", 85 | // Name = "Authorization", 86 | // In = ParameterLocation.Header, 87 | // Type = SecuritySchemeType.ApiKey, 88 | // BearerFormat = "JWT", 89 | // Scheme = "bearer" 90 | //}); 91 | //option.AddSecurityRequirement(new OpenApiSecurityRequirement { 92 | // { 93 | // new OpenApiSecurityScheme{ 94 | // Reference = new OpenApiReference 95 | // { 96 | // Type = ReferenceType.SecurityScheme, 97 | // Id="Bearer" 98 | // } 99 | // }, 100 | // new List() 101 | // } 102 | //}); 103 | #endregion 104 | }); 105 | 106 | #region 集成JWT 107 | // 将公共的信息提取出来,这里可以放到配置文件中,统一读取;以下直接在程序中写死了 108 | // 秘钥,这是生成Token需要秘钥,就是理论提及到签名那块的秘钥 109 | string secret = "TestSecretTestSecretTestSecretTestSecret"; 110 | // 签发者,是由谁颁发的 111 | string issuer = "TestIssuer"; 112 | // 接受者,是给谁用的 113 | string audience = "TestAudience"; 114 | // 注册服务,显示指定为Bearer 115 | services.AddAuthentication("Bearer") 116 | .AddJwtBearer(options => 117 | { 118 | // 配置Jwt信息 119 | options.TokenValidationParameters = new TokenValidationParameters 120 | { 121 | // 是否验证秘钥 122 | ValidateIssuerSigningKey = true, 123 | // 指定秘钥 124 | IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)), 125 | 126 | // 是否验证颁发者 127 | ValidateIssuer = true, 128 | // 指定颁发者 129 | ValidIssuer = issuer, 130 | 131 | // 是否验证接受者 132 | ValidateAudience = true, 133 | // 指定接受者 134 | ValidAudience = audience, 135 | 136 | // 设置必须要有超时时间 137 | RequireExpirationTime = true, 138 | // 设置必须验证超时 139 | ValidateLifetime = true, 140 | 141 | // 将其赋值为0时,即设置有效时间到期,就马上失效 142 | ClockSkew = TimeSpan.Zero 143 | }; 144 | }); 145 | #endregion 146 | 147 | 148 | var permissionRequirement = new PermissionRequirement 149 | { 150 | Permissions = new List() 151 | }; 152 | 153 | 154 | //针对授权定义策略 155 | services.AddAuthorization(option => 156 | { 157 | ////AminPolicy策略就是要求Admin角色才能访问接口 158 | //option.AddPolicy("AdminPolicy", p => p.RequireRole("Admin").Build()); 159 | ////AdminOrMaintainPolicy策略只要有Admin或Maintain其中一个角色即可访问接口 160 | //option.AddPolicy("AdminOrMaintainPolicy", p => p.RequireRole("Admin", "Maintain").Build()); 161 | ////AdminOrUserPolicy策略只要有Admin或User其中一个角色即可访问接口 162 | //option.AddPolicy("AdminOrUserPolicy", p => p.RequireRole("Admin", "User").Build()); 163 | 164 | ////AdminAndMaintainPolicy策略必须要同时有Admin和Maintain两个个角色才能访问接口 165 | //option.AddPolicy("AdminAndMaintainPolicy", p => p.RequireRole("Admin").RequireRole("User").Build()); 166 | 167 | // 同样是策略模式,只是基于Requirement进行权限验证,验证逻辑自己写 168 | option.AddPolicy("Permission", p => p.Requirements.Add(permissionRequirement)); 169 | }); 170 | // 将权限验证的关键类注册,Jwt的策略模式指定为Requirements时就会自动执行该类方法 171 | services.AddScoped(); 172 | // 将permissionRequirement实例注册为单例模式,保证系统中就一个实例,方便权限数据共享 173 | services.AddSingleton(permissionRequirement); 174 | // 注册IHttpContextAccessor,后续可以通过它可以获取HttpContext,操作方便 175 | services.AddSingleton(); 176 | } 177 | 178 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 179 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 180 | { 181 | if (env.IsDevelopment()) 182 | { 183 | app.UseDeveloperExceptionPage(); 184 | } 185 | // 注册Swagger中间件 186 | app.UseSwagger(); 187 | // 注册Swagger界面中间件 188 | app.UseSwaggerUI(option => 189 | { 190 | // 配置文档数据来源及名称设置,其中第一个参数中TestSwagger和注册组件时的名称一致 191 | option.SwaggerEndpoint($"/swagger/TestSwagger/swagger.json", "TestSwaggerCode"); 192 | // 设置为空,代表根路径就可访问到Swagger的主页 193 | option.RoutePrefix = ""; 194 | }); 195 | 196 | app.UseRouting(); 197 | 198 | app.UseAuthentication(); 199 | 200 | app.UseAuthorization(); 201 | 202 | app.UseEndpoints(endpoints => 203 | { 204 | endpoints.MapControllers(); 205 | }); 206 | } 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /SwaggerDemo/SwaggerDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | SwaggerDemo.xml 9 | 1701;1702;1591 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Always 25 | 26 | 27 | Always 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /SwaggerDemo/SwaggerDemo.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ProjectDebugger 5 | 6 | 7 | SwaggerDemo 8 | ApiControllerEmptyScaffolder 9 | root/Controller 10 | FolderProfile 11 | 12 | -------------------------------------------------------------------------------- /SwaggerDemo/SwaggerDemo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SwaggerDemo 5 | 6 | 7 | 8 | 9 | 管理员配置产品相关信息 10 | 11 | 12 | 13 | 14 | 维护员提交产品维护记录信息 15 | 16 | 17 | 18 | 19 | 用户访问产品信息 20 | 21 | 22 | 23 | 24 | 用户API 25 | 26 | 27 | 28 | 29 | 登录Api,传入用户名和密码 30 | 31 | 32 | 33 | 34 | 获取用户信息 35 | 36 | 37 | 38 | 39 | 测试接口 40 | 41 | 42 | 43 | 44 | 权限处理的关键类 45 | 46 | 47 | 48 | 49 | 通过IHttpContextAccessor可以获取HttpContext相关信息,但一定要注册服务 50 | 51 | 52 | 53 | 54 | 用于判断请求是否带有凭据和是否登录 55 | 56 | 57 | 58 | 59 | 构造函数注入 60 | 61 | 62 | 63 | 64 | 资源数据的载体,可以根据需求自定义任何数据 65 | 需要实现IAuthorizationRequirement接口进行标识 66 | 67 | 68 | 69 | 70 | 存放系统中所有权限 71 | 72 | 73 | 74 | 75 | 定义了一个权限数据存储类,包含用户ID和对应的权限访问的Url地址 76 | 77 | 78 | 79 | 80 | 用户ID 81 | 82 | 83 | 84 | 85 | 用户对应的 Url地址 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /SwaggerDemo/TestSwaggerModel.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TestSwaggerModel 5 | 6 | 7 | 8 | 9 | 用户登录条件 10 | 11 | 12 | 13 | 14 | 用户名 15 | 16 | 17 | 18 | 19 | 密码 20 | 21 | 22 | 23 | 24 | 返回的用户信息 25 | 26 | 27 | 28 | 29 | 用户名 30 | 31 | 32 | 33 | 34 | 密码 35 | 36 | 37 | 38 | 39 | 年龄 40 | 41 | 42 | 43 | 44 | 地址 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /SwaggerDemo/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SwaggerDemo 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SwaggerDemo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SwaggerDemo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /TestSwaggerModel/TestSwaggerModel.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | ..\SwaggerDemo\TestSwaggerModel.xml 9 | 1701;1702;1591 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TestSwaggerModel/UserConditon.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace TestSwaggerModel 6 | { 7 | /// 8 | /// 用户登录条件 9 | /// 10 | public class UserConditon 11 | { 12 | /// 13 | /// 用户名 14 | /// 15 | public string UserName { get; set; } 16 | /// 17 | /// 密码 18 | /// 19 | public string Pwd { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TestSwaggerModel/UserModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TestSwaggerModel 4 | {/// 5 | /// 返回的用户信息 6 | /// 7 | public class UserModel 8 | { 9 | /// 10 | /// 用户名 11 | /// 12 | public string UserName { get; set; } 13 | /// 14 | /// 密码 15 | /// 16 | public string Pwd { get; set; } 17 | /// 18 | /// 年龄 19 | /// 20 | public int Age { get; set; } 21 | /// 22 | /// 地址 23 | /// 24 | public string Addr { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | runtime; build; native; contentfiles; analyzers; buildtransitive 11 | all 12 | 13 | 14 | 15 | 16 | 17 | --------------------------------------------------------------------------------