├── .gitattributes ├── .gitignore ├── Blog.Core_IOC&DI ├── .gitignore ├── AppCore │ ├── AppCore.csproj │ ├── Controllers │ │ └── SysSampleController.cs │ ├── CoreAPIXml │ │ ├── AppCore.xml │ │ └── model.xml │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Common │ ├── Common.csproj │ └── Helper │ │ ├── Appsettings.cs │ │ ├── HtmlHelper.cs │ │ ├── RecursionHelper.cs │ │ └── SerializeHelper.cs ├── CoreAPIXml │ └── AppCore.xml ├── IRepository │ ├── BASE │ │ └── IBaseRepository.cs │ ├── IRepository.csproj │ └── ISysSampleRepository.cs ├── IServices │ ├── BASE │ │ └── IBaseServices.cs │ ├── IServices.csproj │ └── ISysSampleServices.cs ├── Model │ ├── Common │ │ └── MessageModel.cs │ ├── Model.csproj │ ├── SysSample.cs │ └── UtilConvert.cs ├── ProjectCore.sln ├── README.md ├── Repository │ ├── BASE │ │ └── BaseRepository.cs │ ├── Repository.csproj │ ├── SysSampleRepository.cs │ └── sugar │ │ ├── BaseDBConfig.cs │ │ └── DbContext.cs └── Services │ ├── BASE │ └── BaseServices.cs │ ├── Services.csproj │ └── SysSampleServices.cs ├── Blog.Core_JWT ├── .gitignore ├── Autho.JWT.Policy │ ├── Autho.JWT.Policy.csproj │ ├── Autho.JWT.Policy.xml │ ├── Controllers │ │ └── ValuesController.cs │ ├── Policys │ │ ├── JwtToken.cs │ │ ├── PermissionHandler.cs │ │ ├── PermissionItem.cs │ │ └── PermissionRequirement.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── UtilConvert.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Autho.JWT │ ├── Autho.JWT.csproj │ ├── Autho.JWT.xml │ ├── Controllers │ │ └── ValuesController.cs │ ├── Helper │ │ ├── Appsettings.cs │ │ ├── JwtHelper.cs │ │ └── JwtTokenAuth.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Autho.sln └── README.md ├── Blog.Core_Repository ├── .gitignore ├── AppCore │ ├── AppCore.csproj │ ├── Controllers │ │ └── SysSampleController.cs │ ├── CoreAPIXml │ │ ├── AppCore.xml │ │ └── model.xml │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Common │ ├── Common.csproj │ └── Helper │ │ ├── Appsettings.cs │ │ ├── HtmlHelper.cs │ │ ├── RecursionHelper.cs │ │ └── SerializeHelper.cs ├── CoreAPIXml │ └── AppCore.xml ├── IRepository │ ├── BASE │ │ └── IBaseRepository.cs │ ├── IRepository.csproj │ └── ISysSampleRepository.cs ├── IServices │ ├── BASE │ │ └── IBaseServices.cs │ ├── IServices.csproj │ └── ISysSampleServices.cs ├── Model │ ├── Common │ │ └── MessageModel.cs │ ├── Model.csproj │ ├── SysSample.cs │ └── UtilConvert.cs ├── ProjectCore.sln ├── README.md ├── Repository │ ├── BASE │ │ └── BaseRepository.cs │ ├── Repository.csproj │ ├── SysSampleRepository.cs │ └── sugar │ │ ├── BaseDBConfig.cs │ │ └── DbContext.cs └── Services │ ├── BASE │ └── BaseServices.cs │ ├── Services.csproj │ └── SysSampleServices.cs └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015/2017 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # Visual Studio 2017 auto generated files 34 | Generated\ Files/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # Benchmark Results 50 | BenchmarkDotNet.Artifacts/ 51 | 52 | # .NET Core 53 | project.lock.json 54 | project.fragment.lock.json 55 | artifacts/ 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_h.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *_wpftmp.csproj 81 | *.log 82 | *.vspscc 83 | *.vssscc 84 | .builds 85 | *.pidb 86 | *.svclog 87 | *.scc 88 | 89 | # Chutzpah Test files 90 | _Chutzpah* 91 | 92 | # Visual C++ cache files 93 | ipch/ 94 | *.aps 95 | *.ncb 96 | *.opendb 97 | *.opensdf 98 | *.sdf 99 | *.cachefile 100 | *.VC.db 101 | *.VC.VC.opendb 102 | 103 | # Visual Studio profiler 104 | *.psess 105 | *.vsp 106 | *.vspx 107 | *.sap 108 | 109 | # Visual Studio Trace Files 110 | *.e2e 111 | 112 | # TFS 2012 Local Workspace 113 | $tf/ 114 | 115 | # Guidance Automation Toolkit 116 | *.gpState 117 | 118 | # ReSharper is a .NET coding add-in 119 | _ReSharper*/ 120 | *.[Rr]e[Ss]harper 121 | *.DotSettings.user 122 | 123 | # JustCode is a .NET coding add-in 124 | .JustCode 125 | 126 | # TeamCity is a build add-in 127 | _TeamCity* 128 | 129 | # DotCover is a Code Coverage Tool 130 | *.dotCover 131 | 132 | # AxoCover is a Code Coverage Tool 133 | .axoCover/* 134 | !.axoCover/settings.json 135 | 136 | # Visual Studio code coverage results 137 | *.coverage 138 | *.coveragexml 139 | 140 | # NCrunch 141 | _NCrunch_* 142 | .*crunch*.local.xml 143 | nCrunchTemp_* 144 | 145 | # MightyMoose 146 | *.mm.* 147 | AutoTest.Net/ 148 | 149 | # Web workbench (sass) 150 | .sass-cache/ 151 | 152 | # Installshield output folder 153 | [Ee]xpress/ 154 | 155 | # DocProject is a documentation generator add-in 156 | DocProject/buildhelp/ 157 | DocProject/Help/*.HxT 158 | DocProject/Help/*.HxC 159 | DocProject/Help/*.hhc 160 | DocProject/Help/*.hhk 161 | DocProject/Help/*.hhp 162 | DocProject/Help/Html2 163 | DocProject/Help/html 164 | 165 | # Click-Once directory 166 | publish/ 167 | 168 | # Publish Web Output 169 | *.[Pp]ublish.xml 170 | *.azurePubxml 171 | # Note: Comment the next line if you want to checkin your web deploy settings, 172 | # but database connection strings (with potential passwords) will be unencrypted 173 | *.pubxml 174 | *.publishproj 175 | 176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 177 | # checkin your Azure Web App publish settings, but sensitive information contained 178 | # in these scripts will be unencrypted 179 | PublishScripts/ 180 | 181 | # NuGet Packages 182 | *.nupkg 183 | # The packages folder can be ignored because of Package Restore 184 | **/[Pp]ackages/* 185 | # except build/, which is used as an MSBuild target. 186 | !**/[Pp]ackages/build/ 187 | # Uncomment if necessary however generally it will be regenerated when needed 188 | #!**/[Pp]ackages/repositories.config 189 | # NuGet v3's project.json files produces more ignorable files 190 | *.nuget.props 191 | *.nuget.targets 192 | 193 | # Microsoft Azure Build Output 194 | csx/ 195 | *.build.csdef 196 | 197 | # Microsoft Azure Emulator 198 | ecf/ 199 | rcf/ 200 | 201 | # Windows Store app package directories and files 202 | AppPackages/ 203 | BundleArtifacts/ 204 | Package.StoreAssociation.xml 205 | _pkginfo.txt 206 | *.appx 207 | 208 | # Visual Studio cache files 209 | # files ending in .cache can be ignored 210 | *.[Cc]ache 211 | # but keep track of directories ending in .cache 212 | !*.[Cc]ache/ 213 | 214 | # Others 215 | ClientBin/ 216 | ~$* 217 | *~ 218 | *.dbmdl 219 | *.dbproj.schemaview 220 | *.jfm 221 | *.pfx 222 | *.publishsettings 223 | orleans.codegen.cs 224 | 225 | # Including strong name files can present a security risk 226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 227 | #*.snk 228 | 229 | # Since there are multiple workflows, uncomment next line to ignore bower_components 230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 231 | #bower_components/ 232 | 233 | # RIA/Silverlight projects 234 | Generated_Code/ 235 | 236 | # Backup & report files from converting an old project file 237 | # to a newer Visual Studio version. Backup files are not needed, 238 | # because we have git ;-) 239 | _UpgradeReport_Files/ 240 | Backup*/ 241 | UpgradeLog*.XML 242 | UpgradeLog*.htm 243 | ServiceFabricBackup/ 244 | *.rptproj.bak 245 | 246 | # SQL Server files 247 | *.mdf 248 | *.ldf 249 | *.ndf 250 | 251 | # Business Intelligence projects 252 | *.rdl.data 253 | *.bim.layout 254 | *.bim_*.settings 255 | *.rptproj.rsuser 256 | 257 | # Microsoft Fakes 258 | FakesAssemblies/ 259 | 260 | # GhostDoc plugin setting file 261 | *.GhostDoc.xml 262 | 263 | # Node.js Tools for Visual Studio 264 | .ntvs_analysis.dat 265 | node_modules/ 266 | 267 | # Visual Studio 6 build log 268 | *.plg 269 | 270 | # Visual Studio 6 workspace options file 271 | *.opt 272 | 273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 274 | *.vbw 275 | 276 | # Visual Studio LightSwitch build output 277 | **/*.HTMLClient/GeneratedArtifacts 278 | **/*.DesktopClient/GeneratedArtifacts 279 | **/*.DesktopClient/ModelManifest.xml 280 | **/*.Server/GeneratedArtifacts 281 | **/*.Server/ModelManifest.xml 282 | _Pvt_Extensions 283 | 284 | # Paket dependency manager 285 | .paket/paket.exe 286 | paket-files/ 287 | 288 | # FAKE - F# Make 289 | .fake/ 290 | 291 | # JetBrains Rider 292 | .idea/ 293 | *.sln.iml 294 | 295 | # CodeRush personal settings 296 | .cr/personal 297 | 298 | # Python Tools for Visual Studio (PTVS) 299 | __pycache__/ 300 | *.pyc 301 | 302 | # Cake - Uncomment if you are using it 303 | # tools/** 304 | # !tools/packages.config 305 | 306 | # Tabs Studio 307 | *.tss 308 | 309 | # Telerik's JustMock configuration file 310 | *.jmconfig 311 | 312 | # BizTalk build output 313 | *.btp.cs 314 | *.btm.cs 315 | *.odx.cs 316 | *.xsd.cs 317 | 318 | # OpenCover UI analysis results 319 | OpenCover/ 320 | 321 | # Azure Stream Analytics local run output 322 | ASALocalRun/ 323 | 324 | # MSBuild Binary and Structured Log 325 | *.binlog 326 | 327 | # NVidia Nsight GPU debugger configuration file 328 | *.nvuser 329 | 330 | # MFractors (Xamarin productivity tool) working folder 331 | .mfractor/ 332 | 333 | # Local History for Visual Studio 334 | .localhistory/ 335 | 336 | # wwwroot/images 337 | *images/ -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015/2017 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # Visual Studio 2017 auto generated files 34 | Generated\ Files/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # Benchmark Results 50 | BenchmarkDotNet.Artifacts/ 51 | 52 | # .NET Core 53 | project.lock.json 54 | project.fragment.lock.json 55 | artifacts/ 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_h.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *_wpftmp.csproj 81 | *.log 82 | *.vspscc 83 | *.vssscc 84 | .builds 85 | *.pidb 86 | *.svclog 87 | *.scc 88 | 89 | # Chutzpah Test files 90 | _Chutzpah* 91 | 92 | # Visual C++ cache files 93 | ipch/ 94 | *.aps 95 | *.ncb 96 | *.opendb 97 | *.opensdf 98 | *.sdf 99 | *.cachefile 100 | *.VC.db 101 | *.VC.VC.opendb 102 | 103 | # Visual Studio profiler 104 | *.psess 105 | *.vsp 106 | *.vspx 107 | *.sap 108 | 109 | # Visual Studio Trace Files 110 | *.e2e 111 | 112 | # TFS 2012 Local Workspace 113 | $tf/ 114 | 115 | # Guidance Automation Toolkit 116 | *.gpState 117 | 118 | # ReSharper is a .NET coding add-in 119 | _ReSharper*/ 120 | *.[Rr]e[Ss]harper 121 | *.DotSettings.user 122 | 123 | # JustCode is a .NET coding add-in 124 | .JustCode 125 | 126 | # TeamCity is a build add-in 127 | _TeamCity* 128 | 129 | # DotCover is a Code Coverage Tool 130 | *.dotCover 131 | 132 | # AxoCover is a Code Coverage Tool 133 | .axoCover/* 134 | !.axoCover/settings.json 135 | 136 | # Visual Studio code coverage results 137 | *.coverage 138 | *.coveragexml 139 | 140 | # NCrunch 141 | _NCrunch_* 142 | .*crunch*.local.xml 143 | nCrunchTemp_* 144 | 145 | # MightyMoose 146 | *.mm.* 147 | AutoTest.Net/ 148 | 149 | # Web workbench (sass) 150 | .sass-cache/ 151 | 152 | # Installshield output folder 153 | [Ee]xpress/ 154 | 155 | # DocProject is a documentation generator add-in 156 | DocProject/buildhelp/ 157 | DocProject/Help/*.HxT 158 | DocProject/Help/*.HxC 159 | DocProject/Help/*.hhc 160 | DocProject/Help/*.hhk 161 | DocProject/Help/*.hhp 162 | DocProject/Help/Html2 163 | DocProject/Help/html 164 | 165 | # Click-Once directory 166 | publish/ 167 | 168 | # Publish Web Output 169 | *.[Pp]ublish.xml 170 | *.azurePubxml 171 | # Note: Comment the next line if you want to checkin your web deploy settings, 172 | # but database connection strings (with potential passwords) will be unencrypted 173 | *.pubxml 174 | *.publishproj 175 | 176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 177 | # checkin your Azure Web App publish settings, but sensitive information contained 178 | # in these scripts will be unencrypted 179 | PublishScripts/ 180 | 181 | # NuGet Packages 182 | *.nupkg 183 | # The packages folder can be ignored because of Package Restore 184 | **/[Pp]ackages/* 185 | # except build/, which is used as an MSBuild target. 186 | !**/[Pp]ackages/build/ 187 | # Uncomment if necessary however generally it will be regenerated when needed 188 | #!**/[Pp]ackages/repositories.config 189 | # NuGet v3's project.json files produces more ignorable files 190 | *.nuget.props 191 | *.nuget.targets 192 | 193 | # Microsoft Azure Build Output 194 | csx/ 195 | *.build.csdef 196 | 197 | # Microsoft Azure Emulator 198 | ecf/ 199 | rcf/ 200 | 201 | # Windows Store app package directories and files 202 | AppPackages/ 203 | BundleArtifacts/ 204 | Package.StoreAssociation.xml 205 | _pkginfo.txt 206 | *.appx 207 | 208 | # Visual Studio cache files 209 | # files ending in .cache can be ignored 210 | *.[Cc]ache 211 | # but keep track of directories ending in .cache 212 | !*.[Cc]ache/ 213 | 214 | # Others 215 | ClientBin/ 216 | ~$* 217 | *~ 218 | *.dbmdl 219 | *.dbproj.schemaview 220 | *.jfm 221 | *.pfx 222 | *.publishsettings 223 | orleans.codegen.cs 224 | 225 | # Including strong name files can present a security risk 226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 227 | #*.snk 228 | 229 | # Since there are multiple workflows, uncomment next line to ignore bower_components 230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 231 | #bower_components/ 232 | 233 | # RIA/Silverlight projects 234 | Generated_Code/ 235 | 236 | # Backup & report files from converting an old project file 237 | # to a newer Visual Studio version. Backup files are not needed, 238 | # because we have git ;-) 239 | _UpgradeReport_Files/ 240 | Backup*/ 241 | UpgradeLog*.XML 242 | UpgradeLog*.htm 243 | ServiceFabricBackup/ 244 | *.rptproj.bak 245 | 246 | # SQL Server files 247 | *.mdf 248 | *.ldf 249 | *.ndf 250 | 251 | # Business Intelligence projects 252 | *.rdl.data 253 | *.bim.layout 254 | *.bim_*.settings 255 | *.rptproj.rsuser 256 | 257 | # Microsoft Fakes 258 | FakesAssemblies/ 259 | 260 | # GhostDoc plugin setting file 261 | *.GhostDoc.xml 262 | 263 | # Node.js Tools for Visual Studio 264 | .ntvs_analysis.dat 265 | node_modules/ 266 | 267 | # Visual Studio 6 build log 268 | *.plg 269 | 270 | # Visual Studio 6 workspace options file 271 | *.opt 272 | 273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 274 | *.vbw 275 | 276 | # Visual Studio LightSwitch build output 277 | **/*.HTMLClient/GeneratedArtifacts 278 | **/*.DesktopClient/GeneratedArtifacts 279 | **/*.DesktopClient/ModelManifest.xml 280 | **/*.Server/GeneratedArtifacts 281 | **/*.Server/ModelManifest.xml 282 | _Pvt_Extensions 283 | 284 | # Paket dependency manager 285 | .paket/paket.exe 286 | paket-files/ 287 | 288 | # FAKE - F# Make 289 | .fake/ 290 | 291 | # JetBrains Rider 292 | .idea/ 293 | *.sln.iml 294 | 295 | # CodeRush personal settings 296 | .cr/personal 297 | 298 | # Python Tools for Visual Studio (PTVS) 299 | __pycache__/ 300 | *.pyc 301 | 302 | # Cake - Uncomment if you are using it 303 | # tools/** 304 | # !tools/packages.config 305 | 306 | # Tabs Studio 307 | *.tss 308 | 309 | # Telerik's JustMock configuration file 310 | *.jmconfig 311 | 312 | # BizTalk build output 313 | *.btp.cs 314 | *.btm.cs 315 | *.odx.cs 316 | *.xsd.cs 317 | 318 | # OpenCover UI analysis results 319 | OpenCover/ 320 | 321 | # Azure Stream Analytics local run output 322 | ASALocalRun/ 323 | 324 | # MSBuild Binary and Structured Log 325 | *.binlog 326 | 327 | # NVidia Nsight GPU debugger configuration file 328 | *.nvuser 329 | 330 | # MFractors (Xamarin productivity tool) working folder 331 | .mfractor/ 332 | 333 | # Local History for Visual Studio 334 | .localhistory/ 335 | 336 | # wwwroot/images 337 | *images/ -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/AppCore/AppCore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.2 5 | InProcess 6 | 7 | 8 | 9 | 10 | ..\AppCore\CoreAPIXml\AppCore.xml 11 | 1701;1702;1591 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | Always 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/AppCore/Controllers/SysSampleController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Microsoft.AspNetCore.Mvc; 4 | using IServices; 5 | using Model; 6 | 7 | namespace AppCore.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | [ApiController] 11 | public class SysSampleController : ControllerBase 12 | { 13 | private readonly ISysSampleServices _sysSampleServices ; 14 | 15 | /// 16 | /// 构造函数 17 | /// 18 | /// 实例化 19 | public SysSampleController(ISysSampleServices sysSampleServices) 20 | { 21 | this._sysSampleServices = sysSampleServices; 22 | } 23 | 24 | /// 25 | /// 获取列表 26 | /// 27 | /// 根据id获取 28 | /// 29 | [HttpGet("{id}")] 30 | public async Task> Get(string id) 31 | { 32 | return await this._sysSampleServices.Query(d => d.id == id); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/AppCore/CoreAPIXml/AppCore.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AppCore 5 | 6 | 7 | 8 | 9 | 构造函数 10 | 11 | 实例化 12 | 13 | 14 | 15 | 获取列表 16 | 17 | 根据id获取 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/AppCore/CoreAPIXml/model.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Model 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 | 操作是否成功 0成功 1失败 30 | 31 | 32 | 33 | 34 | 返回信息 35 | 36 | 37 | 38 | 39 | 返回数据集数量 40 | 41 | 42 | 43 | 44 | 返回数据集合 45 | 46 | 47 | 48 | 49 | 测试 50 | 51 | 52 | 53 | 54 | 标识 55 | 56 | 57 | 58 | 59 | 名称 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/AppCore/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace AppCore 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateWebHostBuilder(args).Build().Run(); 11 | } 12 | 13 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 14 | WebHost.CreateDefaultBuilder(args) 15 | .UseStartup(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/AppCore/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "AppCore": { 5 | "commandName": "Project", 6 | "launchBrowser": true, 7 | "launchUrl": "swagger", 8 | "applicationUrl": "http://localhost:5100", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/AppCore/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using Autofac; 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 Swashbuckle.AspNetCore.Swagger; 11 | using Autofac.Extensions.DependencyInjection; 12 | using System.Reflection; 13 | 14 | namespace AppCore 15 | { 16 | public class Startup 17 | { 18 | public Startup(IConfiguration configuration) 19 | { 20 | Configuration = configuration; 21 | } 22 | 23 | public IConfiguration Configuration { get; } 24 | 25 | 26 | 27 | // This method gets called by the runtime. Use this method to add services to the container. 28 | public IServiceProvider ConfigureServices(IServiceCollection services) 29 | { 30 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); 31 | 32 | var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath; 33 | 34 | #region Swagger 35 | 36 | services.AddSwaggerGen(c => 37 | { 38 | c.SwaggerDoc("v1", new Info 39 | { 40 | Version = "v0.1.0", 41 | Title = "AppCore API", 42 | Description = "框架说明文档", 43 | TermsOfService = "None", 44 | Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "AppCore", Email = "18732976928@163.com", Url = "https://www.jianshu.com/u/94102b59cc2a" } 45 | }); 46 | 47 | 48 | var xmlPath = Path.Combine(basePath, "AppCore.xml");//这个就是刚刚配置的xml文件名 49 | c.IncludeXmlComments(xmlPath, true);//默认的第二个参数是false,这个是controller的注释,记得修改 50 | 51 | var xmlModelPath = Path.Combine(basePath, "model.xml"); 52 | c.IncludeXmlComments(xmlModelPath); 53 | 54 | 55 | #region Token绑定到ConfigureServices 56 | //添加header验证信息 57 | //c.OperationFilter(); 58 | var security = new Dictionary> { { "AppCore", new string[] { } }, }; 59 | c.AddSecurityRequirement(security); 60 | //方案名称“Blog.Core”可自定义,上下一致即可 61 | c.AddSecurityDefinition("AppCore", new ApiKeyScheme 62 | { 63 | Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"", 64 | Name = "Authorization",//jwt默认的参数名称 65 | In = "header",//jwt默认存放Authorization信息的位置(请求头中) 66 | Type = "apiKey" 67 | }); 68 | #endregion 69 | 70 | 71 | }); 72 | 73 | #endregion 74 | 75 | 76 | 77 | #region AutoFac 78 | 79 | //实例化 AutoFac 容器 80 | var builder = new ContainerBuilder(); 81 | 82 | //注册要通过反射创建的组件(注释:需要手动引用实体层) 83 | //builder.RegisterType().As(); 84 | //builder.RegisterType().As(); 85 | 86 | //通过反射将Services和Repository两个程序集的全部方法注入,要记得!!!这个注入的是实现类层,不是接口层 IServices 87 | try 88 | { 89 | var servicesDllFile = Path.Combine(basePath, "Services.dll"); 90 | var assemblysServices = Assembly.LoadFrom(servicesDllFile); 91 | builder.RegisterAssemblyTypes(assemblysServices).AsImplementedInterfaces(); 92 | 93 | var repositoryDllFile = Path.Combine(basePath, "Repository.dll"); 94 | var assemblysRepository = Assembly.LoadFrom(repositoryDllFile); 95 | builder.RegisterAssemblyTypes(assemblysRepository).AsImplementedInterfaces(); 96 | 97 | } 98 | catch (Exception) 99 | { 100 | throw new Exception("※※★※※ 如果你是第一次下载项目,请先F6编译,然后再F5执行,因为解耦了,如果你是发布的模式,请检查bin文件夹是否存在Repository.dll和service.dll ※※★※※"); 101 | } 102 | 103 | //将services填充到Autofac容器生成器中 104 | builder.Populate(services); 105 | 106 | //使用已进行的组件登记创建新容器 107 | var ApplicationContainer = builder.Build(); 108 | 109 | #endregion 110 | 111 | return new AutofacServiceProvider(ApplicationContainer);//第三方IOC接管 core内置DI容器 112 | 113 | } 114 | 115 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 116 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 117 | { 118 | if (env.IsDevelopment()) 119 | { 120 | app.UseDeveloperExceptionPage(); 121 | } 122 | 123 | app.UseSwagger(); 124 | app.UseSwaggerUI(c => 125 | { 126 | c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1"); 127 | }); 128 | 129 | 130 | app.UseMvc(); 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/AppCore/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/AppCore/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*", 8 | "AppSettings": { 9 | "RedisCaching": { 10 | "Enabled": true, 11 | "ConnectionString": "127.0.0.1:6379" 12 | }, 13 | "SqlServer": { 14 | "SqlServerConnection": "Server=.;Database=AppsDB_new;User ID=sa;Password=sa;", 15 | "ProviderName": "System.Data.SqlClient" 16 | }, 17 | "Date": "2018-08-28", 18 | "Author": "AppCore" 19 | }, 20 | "Audience": { 21 | "Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs", 22 | "Issuer": "AppCore", 23 | "Audience": "wr" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Common/Common.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Common/Helper/Appsettings.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using Microsoft.Extensions.Configuration.Json; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Common 8 | { 9 | /// 10 | /// appsettings.json操作类 11 | /// 12 | public class Appsettings 13 | { 14 | static IConfiguration Configuration { get; set; } 15 | static Appsettings() 16 | { 17 | //ReloadOnChange = true; 当appsettings.json被修改时重新加载 18 | Configuration = new ConfigurationBuilder() 19 | .Add(new JsonConfigurationSource { Path = "appsettings.json", ReloadOnChange = true }) 20 | .Build(); 21 | } 22 | /// 23 | /// 封装要操作的字符 24 | /// 25 | /// 26 | /// 27 | public static string app(params string[] sections) 28 | { 29 | try 30 | { 31 | var val = string.Empty; 32 | for (int i = 0; i < sections.Length; i++) 33 | { 34 | val += sections[i] + ":"; 35 | } 36 | 37 | return Configuration[val.TrimEnd(':')]; 38 | } 39 | catch (Exception) 40 | { 41 | return ""; 42 | } 43 | 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Common/Helper/HtmlHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Blog.Core.Common.Helper 6 | { 7 | public static class HtmlHelper 8 | { 9 | #region 去除富文本中的HTML标签 10 | /// 11 | /// 去除富文本中的HTML标签 12 | /// 13 | /// 14 | /// 15 | /// 16 | public static string ReplaceHtmlTag(string html, int length = 0) 17 | { 18 | string strText = System.Text.RegularExpressions.Regex.Replace(html, "<[^>]+>", ""); 19 | strText = System.Text.RegularExpressions.Regex.Replace(strText, "&[^;]+;", ""); 20 | 21 | if (length > 0 && strText.Length > length) 22 | return strText.Substring(0, length); 23 | 24 | return strText; 25 | } 26 | #endregion 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Common/Helper/RecursionHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Blog.Core.Common.Helper 7 | { 8 | /// 9 | /// 泛型递归求树形结构 10 | /// 11 | public static class RecursionHelper 12 | { 13 | public static void LoopToAppendChildren(List all, PermissionTree curItem, int pid, bool needbtn) 14 | { 15 | 16 | var subItems = all.Where(ee => ee.Pid == curItem.value).ToList(); 17 | 18 | var btnItems = subItems.Where(ss => ss.isbtn == true).ToList(); 19 | if (subItems.Count > 0) 20 | { 21 | curItem.btns = new List(); 22 | curItem.btns.AddRange(btnItems); 23 | } 24 | else 25 | { 26 | curItem.btns = null; 27 | } 28 | 29 | if (!needbtn) 30 | { 31 | subItems = subItems.Where(ss => ss.isbtn == false).ToList(); 32 | } 33 | if (subItems.Count > 0) 34 | { 35 | curItem.children = new List(); 36 | curItem.children.AddRange(subItems); 37 | } 38 | else 39 | { 40 | curItem.children = null; 41 | } 42 | 43 | if (curItem.isbtn) 44 | { 45 | //curItem.label += "按钮"; 46 | } 47 | 48 | foreach (var subItem in subItems) 49 | { 50 | if (subItem.value == pid && pid > 0) 51 | { 52 | //subItem.disabled = true;//禁用当前节点 53 | } 54 | LoopToAppendChildren(all, subItem, pid, needbtn); 55 | } 56 | } 57 | 58 | 59 | 60 | public static void LoopNaviBarAppendChildren(List all, NavigationBar curItem) 61 | { 62 | 63 | var subItems = all.Where(ee => ee.pid == curItem.id).ToList(); 64 | 65 | if (subItems.Count > 0) 66 | { 67 | curItem.children = new List(); 68 | curItem.children.AddRange(subItems); 69 | } 70 | else 71 | { 72 | curItem.children = null; 73 | } 74 | 75 | 76 | foreach (var subItem in subItems) 77 | { 78 | LoopNaviBarAppendChildren(all, subItem); 79 | } 80 | } 81 | 82 | 83 | 84 | public static void LoopToAppendChildrenT(List all, T curItem, string parentIdName = "Pid", string idName = "value", string childrenName = "children") 85 | { 86 | var subItems = all.Where(ee => ee.GetType().GetProperty(parentIdName).GetValue(ee, null).ToString() == curItem.GetType().GetProperty(idName).GetValue(curItem, null).ToString()).ToList(); 87 | 88 | if (subItems.Count > 0) curItem.GetType().GetField(childrenName).SetValue(curItem, subItems); 89 | foreach (var subItem in subItems) 90 | { 91 | LoopToAppendChildrenT(all, subItem); 92 | } 93 | } 94 | } 95 | 96 | public class PermissionTree 97 | { 98 | public int value { get; set; } 99 | public int Pid { get; set; } 100 | public string label { get; set; } 101 | public int order { get; set; } 102 | public bool isbtn { get; set; } 103 | public bool disabled { get; set; } 104 | public List children { get; set; } 105 | public List btns { get; set; } 106 | } 107 | public class NavigationBar 108 | { 109 | public int id { get; set; } 110 | public int pid { get; set; } 111 | public int order { get; set; } 112 | public string name { get; set; } 113 | public string path { get; set; } 114 | public string iconCls { get; set; } 115 | public NavigationBarMeta meta { get; set; } 116 | public List children { get; set; } 117 | } 118 | 119 | public class NavigationBarMeta 120 | { 121 | public string title { get; set; } 122 | public bool requireAuth { get; set; } = true; 123 | 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Common/Helper/SerializeHelper.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Blog.Core.Common 9 | { 10 | public class SerializeHelper 11 | { 12 | /// 13 | /// 序列化 14 | /// 15 | /// 16 | /// 17 | public static byte[] Serialize(object item) 18 | { 19 | var jsonString = JsonConvert.SerializeObject(item); 20 | 21 | return Encoding.UTF8.GetBytes(jsonString); 22 | } 23 | /// 24 | /// 反序列化 25 | /// 26 | /// 27 | /// 28 | /// 29 | public static TEntity Deserialize(byte[] value) 30 | { 31 | if (value == null) 32 | { 33 | return default(TEntity); 34 | } 35 | var jsonString = Encoding.UTF8.GetString(value); 36 | return JsonConvert.DeserializeObject(jsonString); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/CoreAPIXml/AppCore.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AppCore 5 | 6 | 7 | 8 | 9 | 获取值 10 | 11 | 12 | 13 | 14 | 15 | 根据id获取 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 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/IRepository/BASE/IBaseRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace IRepository.BASE 8 | { 9 | public interface IBaseRepository where TEntity : class 10 | { 11 | Task QueryByID(object objId); 12 | Task QueryByID(object objId, bool blnUseCache = false); 13 | Task> QueryByIDs(object[] lstIds); 14 | 15 | Task Add(TEntity model); 16 | 17 | Task DeleteById(object id); 18 | 19 | Task Delete(TEntity model); 20 | 21 | Task DeleteByIds(object[] ids); 22 | 23 | Task Update(TEntity model); 24 | Task Update(TEntity entity, string strWhere); 25 | Task Update(TEntity entity, List lstColumns = null, List lstIgnoreColumns = null, string strWhere = ""); 26 | 27 | Task> Query(); 28 | Task> Query(string strWhere); 29 | Task> Query(Expression> whereExpression); 30 | Task> Query(Expression> whereExpression, string strOrderByFileds); 31 | Task> Query(Expression> whereExpression, Expression> orderByExpression, bool isAsc = true); 32 | Task> Query(string strWhere, string strOrderByFileds); 33 | Task> Query(Expression> whereExpression, int intTop, string strOrderByFileds); 34 | Task> Query(string strWhere, int intTop, string strOrderByFileds); 35 | Task> Query( 36 | Expression> whereExpression, int intPageIndex, int intPageSize, string strOrderByFileds); 37 | Task> Query(string strWhere, int intPageIndex, int intPageSize, string strOrderByFileds); 38 | Task> QueryPage(Expression> whereExpression, int intPageIndex = 0, int intPageSize = 20, string strOrderByFileds = null); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/IRepository/IRepository.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/IRepository/ISysSampleRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Text; 5 | using IRepository.BASE; 6 | using Model; 7 | 8 | 9 | namespace IRepository 10 | { 11 | public interface ISysSampleRepository: IBaseRepository 12 | { 13 | int Sum(int i,int j); 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/IServices/BASE/IBaseServices.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace IServices.BASE 8 | { 9 | public interface IBaseServices where TEntity : class 10 | { 11 | Task QueryByID(object objId); 12 | Task QueryByID(object objId, bool blnUseCache = false); 13 | Task> QueryByIDs(object[] lstIds); 14 | 15 | Task Add(TEntity model); 16 | 17 | Task DeleteById(object id); 18 | 19 | Task Delete(TEntity model); 20 | 21 | Task DeleteByIds(object[] ids); 22 | 23 | Task Update(TEntity model); 24 | Task Update(TEntity entity, string strWhere); 25 | 26 | Task Update(TEntity entity, List lstColumns = null, List lstIgnoreColumns = null, string strWhere = ""); 27 | 28 | Task> Query(); 29 | Task> Query(string strWhere); 30 | Task> Query(Expression> whereExpression); 31 | Task> Query(Expression> whereExpression, string strOrderByFileds); 32 | Task> Query(Expression> whereExpression, Expression> orderByExpression, bool isAsc = true); 33 | Task> Query(string strWhere, string strOrderByFileds); 34 | 35 | Task> Query(Expression> whereExpression, int intTop, string strOrderByFileds); 36 | Task> Query(string strWhere, int intTop, string strOrderByFileds); 37 | 38 | Task> Query( 39 | Expression> whereExpression, int intPageIndex, int intPageSize, string strOrderByFileds); 40 | Task> Query(string strWhere, int intPageIndex, int intPageSize, string strOrderByFileds); 41 | 42 | 43 | Task> QueryPage(Expression> whereExpression, int intPageIndex = 0, int intPageSize = 20, string strOrderByFileds = null); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/IServices/IServices.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/IServices/ISysSampleServices.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Text; 5 | using Model; 6 | using IServices.BASE; 7 | 8 | namespace IServices 9 | { 10 | public interface ISysSampleServices:IBaseServices 11 | { 12 | int Sum(int i, int j); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Model/Common/MessageModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Model.Common 6 | { 7 | 8 | /// 9 | /// 消息实体类 10 | /// 11 | public class MessageModel 12 | { 13 | /// 14 | /// 操作是否成功 15 | /// 16 | public bool Success { get; set; } 17 | /// 18 | /// 返回信息 19 | /// 20 | public string Msg { get; set; } 21 | /// 22 | /// 返回数据集合 23 | /// 24 | public List Data { get; set; } 25 | 26 | } 27 | 28 | public class LayUITableModel 29 | { 30 | /// 31 | /// 操作是否成功 0成功 1失败 32 | /// 33 | public int code { get; set; } 34 | /// 35 | /// 返回信息 36 | /// 37 | public string msg { get; set; } 38 | /// 39 | /// 返回数据集数量 40 | /// 41 | public int count { get; set; } 42 | /// 43 | /// 返回数据集合 44 | /// 45 | public List data { get; set; } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Model/Model.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 1701;1702;1591 9 | ..\AppCore\CoreAPIXml\model.xml 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Model/SysSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Model 4 | { 5 | /// 6 | /// 测试 7 | /// 8 | public class SysSample 9 | { 10 | /// 11 | /// 标识 12 | /// 13 | public string id { get; set; } 14 | 15 | /// 16 | /// 名称 17 | /// 18 | public string name { get; set; } 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Model/UtilConvert.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | namespace Model 6 | { 7 | /// 8 | /// 9 | /// 10 | public static class UtilConvert 11 | { 12 | /// 13 | /// 14 | /// 15 | /// 16 | /// 17 | public static int ObjToInt(this object thisValue) 18 | { 19 | int reval = 0; 20 | if (thisValue == null) return 0; 21 | if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval)) 22 | { 23 | return reval; 24 | } 25 | return reval; 26 | } 27 | /// 28 | /// 29 | /// 30 | /// 31 | /// 32 | /// 33 | public static int ObjToInt(this object thisValue, int errorValue) 34 | { 35 | int reval = 0; 36 | if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval)) 37 | { 38 | return reval; 39 | } 40 | return errorValue; 41 | } 42 | /// 43 | /// 44 | /// 45 | /// 46 | /// 47 | public static double ObjToMoney(this object thisValue) 48 | { 49 | double reval = 0; 50 | if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval)) 51 | { 52 | return reval; 53 | } 54 | return 0; 55 | } 56 | /// 57 | /// 58 | /// 59 | /// 60 | /// 61 | /// 62 | public static double ObjToMoney(this object thisValue, double errorValue) 63 | { 64 | double reval = 0; 65 | if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval)) 66 | { 67 | return reval; 68 | } 69 | return errorValue; 70 | } 71 | /// 72 | /// 73 | /// 74 | /// 75 | /// 76 | public static string ObjToString(this object thisValue) 77 | { 78 | if (thisValue != null) return thisValue.ToString().Trim(); 79 | return ""; 80 | } 81 | /// 82 | /// 83 | /// 84 | /// 85 | /// 86 | /// 87 | public static string ObjToString(this object thisValue, string errorValue) 88 | { 89 | if (thisValue != null) return thisValue.ToString().Trim(); 90 | return errorValue; 91 | } 92 | /// 93 | /// 94 | /// 95 | /// 96 | /// 97 | public static Decimal ObjToDecimal(this object thisValue) 98 | { 99 | Decimal reval = 0; 100 | if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval)) 101 | { 102 | return reval; 103 | } 104 | return 0; 105 | } 106 | /// 107 | /// 108 | /// 109 | /// 110 | /// 111 | /// 112 | public static Decimal ObjToDecimal(this object thisValue, decimal errorValue) 113 | { 114 | Decimal reval = 0; 115 | if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval)) 116 | { 117 | return reval; 118 | } 119 | return errorValue; 120 | } 121 | /// 122 | /// 123 | /// 124 | /// 125 | /// 126 | public static DateTime ObjToDate(this object thisValue) 127 | { 128 | DateTime reval = DateTime.MinValue; 129 | if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) 130 | { 131 | reval = Convert.ToDateTime(thisValue); 132 | } 133 | return reval; 134 | } 135 | /// 136 | /// 137 | /// 138 | /// 139 | /// 140 | /// 141 | public static DateTime ObjToDate(this object thisValue, DateTime errorValue) 142 | { 143 | DateTime reval = DateTime.MinValue; 144 | if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) 145 | { 146 | return reval; 147 | } 148 | return errorValue; 149 | } 150 | /// 151 | /// 152 | /// 153 | /// 154 | /// 155 | public static bool ObjToBool(this object thisValue) 156 | { 157 | bool reval = false; 158 | if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval)) 159 | { 160 | return reval; 161 | } 162 | return reval; 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/ProjectCore.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.421 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppCore", "AppCore\AppCore.csproj", "{76AADD4B-FAAD-4C11-938F-E99C534A64E8}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model", "Model\Model.csproj", "{35584B6F-2C03-4E6B-B582-3A955166CACD}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common", "Common\Common.csproj", "{F2776822-08CF-4369-897B-FF34403087AE}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRepository", "IRepository\IRepository.csproj", "{97B9568F-C07A-44A4-9F6F-82B0FCFCF72F}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Repository", "Repository\Repository.csproj", "{E61E1EED-EB17-47F8-B162-C937B6424F3B}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IServices", "IServices\IServices.csproj", "{CAD4A598-9BD8-4A5A-971A-D8A4531E9993}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Services", "Services\Services.csproj", "{0079EBEA-223D-43AA-A8A0-E62635962620}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {76AADD4B-FAAD-4C11-938F-E99C534A64E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {76AADD4B-FAAD-4C11-938F-E99C534A64E8}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {76AADD4B-FAAD-4C11-938F-E99C534A64E8}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {76AADD4B-FAAD-4C11-938F-E99C534A64E8}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {35584B6F-2C03-4E6B-B582-3A955166CACD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {35584B6F-2C03-4E6B-B582-3A955166CACD}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {35584B6F-2C03-4E6B-B582-3A955166CACD}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {35584B6F-2C03-4E6B-B582-3A955166CACD}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {F2776822-08CF-4369-897B-FF34403087AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {F2776822-08CF-4369-897B-FF34403087AE}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {F2776822-08CF-4369-897B-FF34403087AE}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {F2776822-08CF-4369-897B-FF34403087AE}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {97B9568F-C07A-44A4-9F6F-82B0FCFCF72F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {97B9568F-C07A-44A4-9F6F-82B0FCFCF72F}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {97B9568F-C07A-44A4-9F6F-82B0FCFCF72F}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {97B9568F-C07A-44A4-9F6F-82B0FCFCF72F}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {E61E1EED-EB17-47F8-B162-C937B6424F3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {E61E1EED-EB17-47F8-B162-C937B6424F3B}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {E61E1EED-EB17-47F8-B162-C937B6424F3B}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {E61E1EED-EB17-47F8-B162-C937B6424F3B}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {CAD4A598-9BD8-4A5A-971A-D8A4531E9993}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {CAD4A598-9BD8-4A5A-971A-D8A4531E9993}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {CAD4A598-9BD8-4A5A-971A-D8A4531E9993}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {CAD4A598-9BD8-4A5A-971A-D8A4531E9993}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {0079EBEA-223D-43AA-A8A0-E62635962620}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {0079EBEA-223D-43AA-A8A0-E62635962620}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {0079EBEA-223D-43AA-A8A0-E62635962620}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {0079EBEA-223D-43AA-A8A0-E62635962620}.Release|Any CPU.Build.0 = Release|Any CPU 54 | EndGlobalSection 55 | GlobalSection(SolutionProperties) = preSolution 56 | HideSolutionNode = FALSE 57 | EndGlobalSection 58 | GlobalSection(ExtensibilityGlobals) = postSolution 59 | SolutionGuid = {0B09EA65-CB9C-48AD-9BC8-8A39F471995A} 60 | EndGlobalSection 61 | EndGlobal 62 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/README.md: -------------------------------------------------------------------------------- 1 | # BlogArti/Blog.Core_IOC&DI 2 | 3 | 这里是将博客园《从壹开始前后端分离》的NetCore 后端项目Blog.Core 进行拆分,这是其中之一: 4 | ``` 5 | 6 | 7 | 2、Blog.Core_IOC&DI -> 依赖注入IoC学习【文章对应:09】 8 | 9 | 10 | ``` 11 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Repository/Repository.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | ..\AppCore\bin\Debug\ 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Repository/SysSampleRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Text; 5 | using SqlSugar; 6 | using IRepository; 7 | //using IRepository.BASE; 8 | using Model; 9 | using Repository.sugar; 10 | using Repository.BASE; 11 | 12 | 13 | namespace Repository 14 | { 15 | public class SysSampleRepository : BaseRepository, ISysSampleRepository 16 | { 17 | 18 | //private DbContext context; 19 | //private SqlSugarClient db; 20 | //private SimpleClient entityDB; 21 | 22 | //internal SqlSugarClient Db 23 | //{ 24 | // get { return db; } 25 | // private set { db = value; } 26 | //} 27 | //public DbContext Context 28 | //{ 29 | // get { return context; } 30 | // set { context = value; } 31 | //} 32 | //public SysSampleRepository() 33 | //{ 34 | // DbContext.Init(BaseDBConfig.ConnectionString); 35 | // context = DbContext.GetDbContext(); 36 | // db = context.Db; 37 | // entityDB = context.GetEntityDB(db); 38 | //} 39 | //public int Add(SysSample model) 40 | //{ 41 | // //返回的i是long类型,这里你可以根据你的业务需要进行处理 42 | // var i = db.Insertable(model).ExecuteReturnBigIdentity(); 43 | // //return i.ObjToInt(); 44 | // return Convert.ToInt32(i); 45 | //} 46 | 47 | //public bool Delete(SysSample model) 48 | //{ 49 | // var i = db.Deleteable(model).ExecuteCommand(); 50 | // return i > 0; 51 | //} 52 | 53 | //public List Query(Expression> whereExpression) 54 | //{ 55 | // return entityDB.GetList(whereExpression); 56 | 57 | //} 58 | 59 | public int Sum(int i, int j) 60 | { 61 | return i + j; 62 | } 63 | 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Repository/sugar/BaseDBConfig.cs: -------------------------------------------------------------------------------- 1 | using Common; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Text; 6 | 7 | namespace Repository.sugar 8 | { 9 | public class BaseDBConfig 10 | { 11 | //public static string ConnectionString = File.ReadAllText(@"D:\my-file\dbCountPsw1.txt").Trim(); 12 | 13 | //正常格式 - 因ioc注入所以不能使用 14 | //public static string ConnectionString = "server=.;uid=sa;pwd=sa;database=AppsDB_new"; 15 | 16 | //ioc注入使用 17 | public static string ConnectionString = Appsettings.app(new string[] { "AppSettings", "SqlServer", "SqlServerConnection" });//获取连接字符串 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Services/BASE/BaseServices.cs: -------------------------------------------------------------------------------- 1 | using IRepository.BASE; 2 | using IServices.BASE; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq.Expressions; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Services.BASE 10 | { 11 | public class BaseServices: IBaseServices where TEntity : class, new() 12 | { 13 | //public IBaseRepository baseDal = new BaseRepository(); 14 | 15 | public IBaseRepository baseDal; 16 | 17 | public async Task QueryByID(object objId) 18 | { 19 | return await baseDal.QueryByID(objId); 20 | } 21 | /// 22 | /// 功能描述:根据ID查询一条数据 23 | /// 作  者:AZLinli.Blog.Core 24 | /// 25 | /// id(必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]),如果是联合主键,请使用Where条件 26 | /// 是否使用缓存 27 | /// 数据实体 28 | public async Task QueryByID(object objId, bool blnUseCache = false) 29 | { 30 | return await baseDal.QueryByID(objId, blnUseCache); 31 | } 32 | 33 | /// 34 | /// 功能描述:根据ID查询数据 35 | /// 作  者:AZLinli.Blog.Core 36 | /// 37 | /// id列表(必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]),如果是联合主键,请使用Where条件 38 | /// 数据实体列表 39 | public async Task> QueryByIDs(object[] lstIds) 40 | { 41 | return await baseDal.QueryByIDs(lstIds); 42 | } 43 | 44 | /// 45 | /// 写入实体数据 46 | /// 47 | /// 博文实体类 48 | /// 49 | public async Task Add(TEntity entity) 50 | { 51 | return await baseDal.Add(entity); 52 | } 53 | 54 | /// 55 | /// 更新实体数据 56 | /// 57 | /// 博文实体类 58 | /// 59 | public async Task Update(TEntity entity) 60 | { 61 | return await baseDal.Update(entity); 62 | } 63 | public async Task Update(TEntity entity, string strWhere) 64 | { 65 | return await baseDal.Update(entity, strWhere); 66 | } 67 | 68 | public async Task Update( 69 | TEntity entity, 70 | List lstColumns = null, 71 | List lstIgnoreColumns = null, 72 | string strWhere = "" 73 | ) 74 | { 75 | return await baseDal.Update(entity, lstColumns, lstIgnoreColumns, strWhere); 76 | } 77 | 78 | 79 | /// 80 | /// 根据实体删除一条数据 81 | /// 82 | /// 博文实体类 83 | /// 84 | public async Task Delete(TEntity entity) 85 | { 86 | return await baseDal.Delete(entity); 87 | } 88 | 89 | /// 90 | /// 删除指定ID的数据 91 | /// 92 | /// 主键ID 93 | /// 94 | public async Task DeleteById(object id) 95 | { 96 | return await baseDal.DeleteById(id); 97 | } 98 | 99 | /// 100 | /// 删除指定ID集合的数据(批量删除) 101 | /// 102 | /// 主键ID集合 103 | /// 104 | public async Task DeleteByIds(object[] ids) 105 | { 106 | return await baseDal.DeleteByIds(ids); 107 | } 108 | 109 | 110 | 111 | /// 112 | /// 功能描述:查询所有数据 113 | /// 作  者:AZLinli.Blog.Core 114 | /// 115 | /// 数据列表 116 | public async Task> Query() 117 | { 118 | return await baseDal.Query(); 119 | } 120 | 121 | /// 122 | /// 功能描述:查询数据列表 123 | /// 作  者:AZLinli.Blog.Core 124 | /// 125 | /// 条件 126 | /// 数据列表 127 | public async Task> Query(string strWhere) 128 | { 129 | return await baseDal.Query(strWhere); 130 | } 131 | 132 | /// 133 | /// 功能描述:查询数据列表 134 | /// 作  者:AZLinli.Blog.Core 135 | /// 136 | /// whereExpression 137 | /// 数据列表 138 | public async Task> Query(Expression> whereExpression) 139 | { 140 | return await baseDal.Query(whereExpression); 141 | } 142 | /// 143 | /// 功能描述:查询一个列表 144 | /// 作  者:AZLinli.Blog.Core 145 | /// 146 | /// 条件表达式 147 | /// 排序字段,如name asc,age desc 148 | /// 数据列表 149 | public async Task> Query(Expression> whereExpression, Expression> orderByExpression, bool isAsc = true) 150 | { 151 | return await baseDal.Query(whereExpression, orderByExpression, isAsc); 152 | } 153 | 154 | public async Task> Query(Expression> whereExpression, string strOrderByFileds) 155 | { 156 | return await baseDal.Query(whereExpression, strOrderByFileds); 157 | } 158 | 159 | /// 160 | /// 功能描述:查询一个列表 161 | /// 作  者:AZLinli.Blog.Core 162 | /// 163 | /// 条件 164 | /// 排序字段,如name asc,age desc 165 | /// 数据列表 166 | public async Task> Query(string strWhere, string strOrderByFileds) 167 | { 168 | return await baseDal.Query(strWhere, strOrderByFileds); 169 | } 170 | 171 | /// 172 | /// 功能描述:查询前N条数据 173 | /// 作  者:AZLinli.Blog.Core 174 | /// 175 | /// 条件表达式 176 | /// 前N条 177 | /// 排序字段,如name asc,age desc 178 | /// 数据列表 179 | public async Task> Query(Expression> whereExpression, int intTop, string strOrderByFileds) 180 | { 181 | return await baseDal.Query(whereExpression, intTop, strOrderByFileds); 182 | } 183 | 184 | /// 185 | /// 功能描述:查询前N条数据 186 | /// 作  者:AZLinli.Blog.Core 187 | /// 188 | /// 条件 189 | /// 前N条 190 | /// 排序字段,如name asc,age desc 191 | /// 数据列表 192 | public async Task> Query( 193 | string strWhere, 194 | int intTop, 195 | string strOrderByFileds) 196 | { 197 | return await baseDal.Query(strWhere, intTop, strOrderByFileds); 198 | } 199 | 200 | /// 201 | /// 功能描述:分页查询 202 | /// 作  者:AZLinli.Blog.Core 203 | /// 204 | /// 条件表达式 205 | /// 页码(下标0) 206 | /// 页大小 207 | /// 数据总量 208 | /// 排序字段,如name asc,age desc 209 | /// 数据列表 210 | public async Task> Query( 211 | Expression> whereExpression, 212 | int intPageIndex, 213 | int intPageSize, 214 | string strOrderByFileds) 215 | { 216 | return await baseDal.Query( 217 | whereExpression, 218 | intPageIndex, 219 | intPageSize, 220 | strOrderByFileds); 221 | } 222 | 223 | /// 224 | /// 功能描述:分页查询 225 | /// 作  者:AZLinli.Blog.Core 226 | /// 227 | /// 条件 228 | /// 页码(下标0) 229 | /// 页大小 230 | /// 数据总量 231 | /// 排序字段,如name asc,age desc 232 | /// 数据列表 233 | public async Task> Query( 234 | string strWhere, 235 | int intPageIndex, 236 | int intPageSize, 237 | string strOrderByFileds) 238 | { 239 | return await baseDal.Query( 240 | strWhere, 241 | intPageIndex, 242 | intPageSize, 243 | strOrderByFileds); 244 | } 245 | 246 | public async Task> QueryPage(Expression> whereExpression, 247 | int intPageIndex = 0, int intPageSize = 20, string strOrderByFileds = null) 248 | { 249 | return await baseDal.QueryPage(whereExpression, 250 | intPageIndex = 0, intPageSize, strOrderByFileds); 251 | } 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Services/Services.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | ..\AppCore\bin\Debug\ 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Blog.Core_IOC&DI/Services/SysSampleServices.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using IServices; 5 | using IRepository; 6 | using Services.BASE; 7 | using Model; 8 | using System.Linq.Expressions; 9 | 10 | namespace Services 11 | { 12 | public class SysSampleServices : BaseServices, ISysSampleServices 13 | { 14 | //普通的仓储例子 15 | ISysSampleRepository dal; 16 | 17 | public SysSampleServices() 18 | { 19 | } 20 | 21 | public SysSampleServices(ISysSampleRepository dal) 22 | { 23 | this.dal = dal; 24 | base.baseDal = dal; 25 | } 26 | 27 | 28 | 29 | 30 | public int Sum(int i, int j) 31 | { 32 | return dal.Sum(i, j); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Blog.Core_JWT/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015/2017 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # Visual Studio 2017 auto generated files 34 | Generated\ Files/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # Benchmark Results 50 | BenchmarkDotNet.Artifacts/ 51 | 52 | # .NET Core 53 | project.lock.json 54 | project.fragment.lock.json 55 | artifacts/ 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_h.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *_wpftmp.csproj 81 | *.log 82 | *.vspscc 83 | *.vssscc 84 | .builds 85 | *.pidb 86 | *.svclog 87 | *.scc 88 | 89 | # Chutzpah Test files 90 | _Chutzpah* 91 | 92 | # Visual C++ cache files 93 | ipch/ 94 | *.aps 95 | *.ncb 96 | *.opendb 97 | *.opensdf 98 | *.sdf 99 | *.cachefile 100 | *.VC.db 101 | *.VC.VC.opendb 102 | 103 | # Visual Studio profiler 104 | *.psess 105 | *.vsp 106 | *.vspx 107 | *.sap 108 | 109 | # Visual Studio Trace Files 110 | *.e2e 111 | 112 | # TFS 2012 Local Workspace 113 | $tf/ 114 | 115 | # Guidance Automation Toolkit 116 | *.gpState 117 | 118 | # ReSharper is a .NET coding add-in 119 | _ReSharper*/ 120 | *.[Rr]e[Ss]harper 121 | *.DotSettings.user 122 | 123 | # JustCode is a .NET coding add-in 124 | .JustCode 125 | 126 | # TeamCity is a build add-in 127 | _TeamCity* 128 | 129 | # DotCover is a Code Coverage Tool 130 | *.dotCover 131 | 132 | # AxoCover is a Code Coverage Tool 133 | .axoCover/* 134 | !.axoCover/settings.json 135 | 136 | # Visual Studio code coverage results 137 | *.coverage 138 | *.coveragexml 139 | 140 | # NCrunch 141 | _NCrunch_* 142 | .*crunch*.local.xml 143 | nCrunchTemp_* 144 | 145 | # MightyMoose 146 | *.mm.* 147 | AutoTest.Net/ 148 | 149 | # Web workbench (sass) 150 | .sass-cache/ 151 | 152 | # Installshield output folder 153 | [Ee]xpress/ 154 | 155 | # DocProject is a documentation generator add-in 156 | DocProject/buildhelp/ 157 | DocProject/Help/*.HxT 158 | DocProject/Help/*.HxC 159 | DocProject/Help/*.hhc 160 | DocProject/Help/*.hhk 161 | DocProject/Help/*.hhp 162 | DocProject/Help/Html2 163 | DocProject/Help/html 164 | 165 | # Click-Once directory 166 | publish/ 167 | 168 | # Publish Web Output 169 | *.[Pp]ublish.xml 170 | *.azurePubxml 171 | # Note: Comment the next line if you want to checkin your web deploy settings, 172 | # but database connection strings (with potential passwords) will be unencrypted 173 | *.pubxml 174 | *.publishproj 175 | 176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 177 | # checkin your Azure Web App publish settings, but sensitive information contained 178 | # in these scripts will be unencrypted 179 | PublishScripts/ 180 | 181 | # NuGet Packages 182 | *.nupkg 183 | # The packages folder can be ignored because of Package Restore 184 | **/[Pp]ackages/* 185 | # except build/, which is used as an MSBuild target. 186 | !**/[Pp]ackages/build/ 187 | # Uncomment if necessary however generally it will be regenerated when needed 188 | #!**/[Pp]ackages/repositories.config 189 | # NuGet v3's project.json files produces more ignorable files 190 | *.nuget.props 191 | *.nuget.targets 192 | 193 | # Microsoft Azure Build Output 194 | csx/ 195 | *.build.csdef 196 | 197 | # Microsoft Azure Emulator 198 | ecf/ 199 | rcf/ 200 | 201 | # Windows Store app package directories and files 202 | AppPackages/ 203 | BundleArtifacts/ 204 | Package.StoreAssociation.xml 205 | _pkginfo.txt 206 | *.appx 207 | 208 | # Visual Studio cache files 209 | # files ending in .cache can be ignored 210 | *.[Cc]ache 211 | # but keep track of directories ending in .cache 212 | !*.[Cc]ache/ 213 | 214 | # Others 215 | ClientBin/ 216 | ~$* 217 | *~ 218 | *.dbmdl 219 | *.dbproj.schemaview 220 | *.jfm 221 | *.pfx 222 | *.publishsettings 223 | orleans.codegen.cs 224 | 225 | # Including strong name files can present a security risk 226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 227 | #*.snk 228 | 229 | # Since there are multiple workflows, uncomment next line to ignore bower_components 230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 231 | #bower_components/ 232 | 233 | # RIA/Silverlight projects 234 | Generated_Code/ 235 | 236 | # Backup & report files from converting an old project file 237 | # to a newer Visual Studio version. Backup files are not needed, 238 | # because we have git ;-) 239 | _UpgradeReport_Files/ 240 | Backup*/ 241 | UpgradeLog*.XML 242 | UpgradeLog*.htm 243 | ServiceFabricBackup/ 244 | *.rptproj.bak 245 | 246 | # SQL Server files 247 | *.mdf 248 | *.ldf 249 | *.ndf 250 | 251 | # Business Intelligence projects 252 | *.rdl.data 253 | *.bim.layout 254 | *.bim_*.settings 255 | *.rptproj.rsuser 256 | 257 | # Microsoft Fakes 258 | FakesAssemblies/ 259 | 260 | # GhostDoc plugin setting file 261 | *.GhostDoc.xml 262 | 263 | # Node.js Tools for Visual Studio 264 | .ntvs_analysis.dat 265 | node_modules/ 266 | 267 | # Visual Studio 6 build log 268 | *.plg 269 | 270 | # Visual Studio 6 workspace options file 271 | *.opt 272 | 273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 274 | *.vbw 275 | 276 | # Visual Studio LightSwitch build output 277 | **/*.HTMLClient/GeneratedArtifacts 278 | **/*.DesktopClient/GeneratedArtifacts 279 | **/*.DesktopClient/ModelManifest.xml 280 | **/*.Server/GeneratedArtifacts 281 | **/*.Server/ModelManifest.xml 282 | _Pvt_Extensions 283 | 284 | # Paket dependency manager 285 | .paket/paket.exe 286 | paket-files/ 287 | 288 | # FAKE - F# Make 289 | .fake/ 290 | 291 | # JetBrains Rider 292 | .idea/ 293 | *.sln.iml 294 | 295 | # CodeRush personal settings 296 | .cr/personal 297 | 298 | # Python Tools for Visual Studio (PTVS) 299 | __pycache__/ 300 | *.pyc 301 | 302 | # Cake - Uncomment if you are using it 303 | # tools/** 304 | # !tools/packages.config 305 | 306 | # Tabs Studio 307 | *.tss 308 | 309 | # Telerik's JustMock configuration file 310 | *.jmconfig 311 | 312 | # BizTalk build output 313 | *.btp.cs 314 | *.btm.cs 315 | *.odx.cs 316 | *.xsd.cs 317 | 318 | # OpenCover UI analysis results 319 | OpenCover/ 320 | 321 | # Azure Stream Analytics local run output 322 | ASALocalRun/ 323 | 324 | # MSBuild Binary and Structured Log 325 | *.binlog 326 | 327 | # NVidia Nsight GPU debugger configuration file 328 | *.nvuser 329 | 330 | # MFractors (Xamarin productivity tool) working folder 331 | .mfractor/ 332 | 333 | # Local History for Visual Studio 334 | .localhistory/ 335 | 336 | # wwwroot/images 337 | *images/ -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/Autho.JWT.Policy.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | InProcess 6 | 7 | 8 | 9 | ..\Autho.JWT.Policy\Autho.JWT.Policy.xml 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Always 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/Autho.JWT.Policy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Autho.JWT.Policy 5 | 6 | 7 | 8 | 9 | 这个需要授权,其他的不需要 10 | 11 | 12 | 13 | 14 | 15 | 登录接口:随便输入字符,获取token,然后添加 Authoritarian 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | JWTToken生成类 24 | 25 | 26 | 27 | 28 | 获取基于JWT的Token 29 | 30 | 需要在登陆的时候配置 31 | 在startup中定义的参数 32 | 33 | 34 | 35 | 36 | 权限授权处理器 37 | 38 | 39 | 40 | 41 | 验证方案提供对象 42 | 43 | 44 | 45 | 46 | 构造函数注入 47 | 48 | 49 | 50 | 51 | 52 | 53 | 用户或角色或其他凭据实体,就像是订单详情一样 54 | 之前的名字是 Permission 55 | 56 | 57 | 58 | 59 | 用户或角色或其他凭据名称 60 | 61 | 62 | 63 | 64 | 请求Url 65 | 66 | 67 | 68 | 69 | 必要参数类,类似一个订单信息 70 | 继承 IAuthorizationRequirement,用于设计自定义权限处理器PermissionHandler 71 | 因为AuthorizationHandler 中的泛型参数 TRequirement 必须继承 IAuthorizationRequirement 72 | 73 | 74 | 75 | 76 | 用户权限集合,一个订单包含了很多详情, 77 | 同理,一个网站的认证发行中,也有很多权限详情(这里是Role和URL的关系) 78 | 79 | 80 | 81 | 82 | 无权限action 83 | 84 | 85 | 86 | 87 | 认证授权类型 88 | 89 | 90 | 91 | 92 | 请求路径 93 | 94 | 95 | 96 | 97 | 发行人 98 | 99 | 100 | 101 | 102 | 订阅人 103 | 104 | 105 | 106 | 107 | 过期时间 108 | 109 | 110 | 111 | 112 | 签名验证 113 | 114 | 115 | 116 | 117 | 构造 118 | 119 | 拒约请求的url 120 | 权限集合 121 | 声明类型 122 | 发行人 123 | 订阅人 124 | 签名验证实体 125 | 过期时间 126 | 127 | 128 | 129 | v1 版本 130 | 131 | 132 | 133 | 134 | v2 版本 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/Controllers/ValuesController.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.Threading.Tasks; 7 | using Microsoft.AspNetCore.Authentication.JwtBearer; 8 | using Microsoft.AspNetCore.Authorization; 9 | using Microsoft.AspNetCore.Mvc; 10 | 11 | namespace Autho.JWT.Policy.Controllers 12 | { 13 | [Route("api/[controller]/[action]")] 14 | [ApiController] 15 | public class ValuesController : ControllerBase 16 | { 17 | PermissionRequirement _requirement; 18 | 19 | public ValuesController(PermissionRequirement requirement) 20 | { 21 | _requirement = requirement; 22 | } 23 | 24 | 25 | /// 26 | /// 这个需要授权,其他的不需要 27 | /// 28 | /// 29 | [HttpGet] 30 | [Authorize("Permission")] 31 | public ActionResult> Get() 32 | { 33 | return new string[] { "value1", "value2" }; 34 | } 35 | 36 | // GET api/values/5 37 | [HttpGet("{id}")] 38 | public ActionResult Get(int id) 39 | { 40 | return "value"; 41 | } 42 | 43 | 44 | /// 45 | /// 登录接口:随便输入字符,获取token,然后添加 Authoritarian 46 | /// 47 | /// 48 | /// 49 | /// 50 | [HttpGet] 51 | public async Task GetJWTToken3(string name = "", string pass = "") 52 | { 53 | string jwtStr = string.Empty; 54 | bool suc = false; 55 | 56 | if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass)) 57 | { 58 | return new JsonResult(new 59 | { 60 | Status = false, 61 | message = "用户名或密码不能为空" 62 | }); 63 | } 64 | 65 | var userRoles = "Admin"; 66 | //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色 67 | var claims = new List { 68 | new Claim(ClaimTypes.Name, name), 69 | new Claim(JwtRegisteredClaimNames.Jti, "1"), 70 | new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) }; 71 | claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); 72 | 73 | //用户标识 74 | var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme); 75 | identity.AddClaims(claims); 76 | 77 | var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement); 78 | return new JsonResult(token); 79 | 80 | } 81 | 82 | // POST api/values 83 | [HttpPost] 84 | public void Post([FromBody] string value) 85 | { 86 | } 87 | 88 | // PUT api/values/5 89 | [HttpPut("{id}")] 90 | public void Put(int id, [FromBody] string value) 91 | { 92 | } 93 | 94 | // DELETE api/values/5 95 | [HttpDelete("{id}")] 96 | public void Delete(int id) 97 | { 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/Policys/JwtToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IdentityModel.Tokens.Jwt; 3 | using System.Security.Claims; 4 | 5 | namespace Autho.JWT.Policy 6 | { 7 | /// 8 | /// JWTToken生成类 9 | /// 10 | public class JwtToken 11 | { 12 | /// 13 | /// 获取基于JWT的Token 14 | /// 15 | /// 需要在登陆的时候配置 16 | /// 在startup中定义的参数 17 | /// 18 | public static dynamic BuildJwtToken(Claim[] claims, PermissionRequirement permissionRequirement) 19 | { 20 | var now = DateTime.Now; 21 | // 实例化JwtSecurityToken 22 | var jwt = new JwtSecurityToken( 23 | issuer: permissionRequirement.Issuer, 24 | audience: permissionRequirement.Audience, 25 | claims: claims, 26 | notBefore: now, 27 | expires: now.Add(permissionRequirement.Expiration), 28 | signingCredentials: permissionRequirement.SigningCredentials 29 | ); 30 | // 生成 Token 31 | var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt); 32 | 33 | //打包返回前台 34 | var responseJson = new 35 | { 36 | success = true, 37 | token = encodedJwt, 38 | expires_in = permissionRequirement.Expiration.TotalSeconds, 39 | token_type = "Bearer" 40 | }; 41 | return responseJson; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/Policys/PermissionHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authentication; 2 | using Microsoft.AspNetCore.Authorization; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Security.Claims; 8 | using System.Text.RegularExpressions; 9 | using System.Threading.Tasks; 10 | 11 | namespace Autho.JWT.Policy 12 | { 13 | /// 14 | /// 权限授权处理器 15 | /// 16 | public class PermissionHandler : AuthorizationHandler 17 | { 18 | /// 19 | /// 验证方案提供对象 20 | /// 21 | public IAuthenticationSchemeProvider Schemes { get; set; } 22 | 23 | 24 | /// 25 | /// 构造函数注入 26 | /// 27 | /// 28 | /// 29 | public PermissionHandler(IAuthenticationSchemeProvider schemes) 30 | { 31 | Schemes = schemes; 32 | } 33 | 34 | // 重载异步处理程序 35 | protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) 36 | { 37 | 38 | requirement.Permissions = new List() { 39 | new PermissionItem (){Role="Admin",Url="/api/values/get" }, 40 | new PermissionItem (){Role="Admin",Url="/api/values/post" }, 41 | new PermissionItem (){Role="Admin",Url="/api/values/put" }, 42 | new PermissionItem (){Role="Admin",Url="/api/values/delete" }, 43 | }; 44 | 45 | 46 | //从AuthorizationHandlerContext转成HttpContext,以便取出表求信息 47 | var httpContext = (context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext).HttpContext; 48 | //请求Url 49 | var questUrl = httpContext.Request.Path.Value.ToLower(); 50 | //判断请求是否停止 51 | var handlers = httpContext.RequestServices.GetRequiredService(); 52 | foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync()) 53 | { 54 | var handler = await handlers.GetHandlerAsync(httpContext, scheme.Name) as IAuthenticationRequestHandler; 55 | if (handler != null && await handler.HandleRequestAsync()) 56 | { 57 | context.Fail(); 58 | return; 59 | } 60 | } 61 | //判断请求是否拥有凭据,即有没有登录 62 | var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync(); 63 | if (defaultAuthenticate != null) 64 | { 65 | var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name); 66 | //result?.Principal不为空即登录成功 67 | if (result?.Principal != null) 68 | { 69 | 70 | httpContext.User = result.Principal; 71 | 72 | var isMatchUrl = false; 73 | 74 | var permisssionGroup = requirement.Permissions.GroupBy(g => g.Url); 75 | foreach (var item in permisssionGroup) 76 | { 77 | try 78 | { 79 | if (Regex.Match(questUrl, item.Key?.ObjToString().ToLower())?.Value == questUrl) 80 | { 81 | isMatchUrl = true; 82 | break; 83 | } 84 | } 85 | catch (Exception) 86 | { 87 | 88 | } 89 | } 90 | 91 | 92 | //权限中是否存在请求的url 93 | //if (requirement.Permissions.GroupBy(g => g.Url).Where(w => w.Key?.ToLower() == questUrl).Count() > 0) 94 | if (isMatchUrl) 95 | { 96 | // 获取当前用户的角色信息 97 | var currentUserRoles = (from item in httpContext.User.Claims 98 | where item.Type == requirement.ClaimType 99 | select item.Value).ToList(); 100 | 101 | var isMatchRole = false; 102 | var permisssionRoles = requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role)); 103 | foreach (var item in permisssionRoles) 104 | { 105 | try 106 | { 107 | if (Regex.Match(questUrl, item.Url?.ObjToString().ToLower())?.Value == questUrl) 108 | { 109 | isMatchRole = true; 110 | break; 111 | } 112 | } 113 | catch (Exception) 114 | { 115 | } 116 | } 117 | 118 | //验证权限 119 | //if (currentUserRoles.Count <= 0 || requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role) && w.Url.ToLower() == questUrl).Count() <= 0) 120 | if (currentUserRoles.Count <= 0 || !isMatchRole) 121 | { 122 | 123 | context.Fail(); 124 | return; 125 | // 可以在这里设置跳转页面,不过还是会访问当前接口地址的 126 | httpContext.Response.Redirect(requirement.DeniedAction); 127 | } 128 | } 129 | else 130 | { 131 | context.Fail(); 132 | return; 133 | 134 | } 135 | //判断过期时间 136 | if ((httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) != null && DateTime.Parse(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now) 137 | { 138 | context.Succeed(requirement); 139 | } 140 | else 141 | { 142 | context.Fail(); 143 | return; 144 | } 145 | return; 146 | } 147 | } 148 | //判断没有登录时,是否访问登录的url,并且是Post请求,并且是form表单提交类型,否则为失败 149 | if (!questUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST") 150 | || !httpContext.Request.HasFormContentType)) 151 | { 152 | context.Fail(); 153 | return; 154 | } 155 | context.Succeed(requirement); 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/Policys/PermissionItem.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace Autho.JWT.Policy 3 | { 4 | /// 5 | /// 用户或角色或其他凭据实体,就像是订单详情一样 6 | /// 之前的名字是 Permission 7 | /// 8 | public class PermissionItem 9 | { 10 | /// 11 | /// 用户或角色或其他凭据名称 12 | /// 13 | public virtual string Role { get; set; } 14 | /// 15 | /// 请求Url 16 | /// 17 | public virtual string Url { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/Policys/PermissionRequirement.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.IdentityModel.Tokens; 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace Autho.JWT.Policy 7 | { 8 | /// 9 | /// 必要参数类,类似一个订单信息 10 | /// 继承 IAuthorizationRequirement,用于设计自定义权限处理器PermissionHandler 11 | /// 因为AuthorizationHandler 中的泛型参数 TRequirement 必须继承 IAuthorizationRequirement 12 | /// 13 | public class PermissionRequirement : IAuthorizationRequirement 14 | { 15 | /// 16 | /// 用户权限集合,一个订单包含了很多详情, 17 | /// 同理,一个网站的认证发行中,也有很多权限详情(这里是Role和URL的关系) 18 | /// 19 | public List Permissions { get; set; } 20 | /// 21 | /// 无权限action 22 | /// 23 | public string DeniedAction { get; set; } 24 | 25 | /// 26 | /// 认证授权类型 27 | /// 28 | public string ClaimType { internal get; set; } 29 | /// 30 | /// 请求路径 31 | /// 32 | public string LoginPath { get; set; } = "/Api/Login"; 33 | /// 34 | /// 发行人 35 | /// 36 | public string Issuer { get; set; } 37 | /// 38 | /// 订阅人 39 | /// 40 | public string Audience { get; set; } 41 | /// 42 | /// 过期时间 43 | /// 44 | public TimeSpan Expiration { get; set; } 45 | /// 46 | /// 签名验证 47 | /// 48 | public SigningCredentials SigningCredentials { get; set; } 49 | 50 | 51 | /// 52 | /// 构造 53 | /// 54 | /// 拒约请求的url 55 | /// 权限集合 56 | /// 声明类型 57 | /// 发行人 58 | /// 订阅人 59 | /// 签名验证实体 60 | /// 过期时间 61 | public PermissionRequirement(string deniedAction, List permissions, string claimType, string issuer, string audience, SigningCredentials signingCredentials, TimeSpan expiration) 62 | { 63 | ClaimType = claimType; 64 | DeniedAction = deniedAction; 65 | Permissions = permissions; 66 | Issuer = issuer; 67 | Audience = audience; 68 | Expiration = expiration; 69 | SigningCredentials = signingCredentials; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/Program.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; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace Autho.JWT.Policy 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | CreateWebHostBuilder(args).Build().Run(); 18 | } 19 | 20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "Autho.JWT.Policy": { 5 | "commandName": "Project", 6 | "launchBrowser": true, 7 | "applicationUrl": "http://localhost:5103", 8 | "environmentVariables": { 9 | "ASPNETCORE_ENVIRONMENT": "Development" 10 | } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Security.Claims; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using Microsoft.AspNetCore.Authentication.JwtBearer; 9 | using Microsoft.AspNetCore.Authorization; 10 | using Microsoft.AspNetCore.Builder; 11 | using Microsoft.AspNetCore.Hosting; 12 | using Microsoft.AspNetCore.Mvc; 13 | using Microsoft.Extensions.Configuration; 14 | using Microsoft.Extensions.DependencyInjection; 15 | using Microsoft.IdentityModel.Tokens; 16 | using Swashbuckle.AspNetCore.Swagger; 17 | 18 | namespace Autho.JWT.Policy 19 | { 20 | public class Startup 21 | { 22 | public Startup(IConfiguration configuration) 23 | { 24 | Configuration = configuration; 25 | } 26 | 27 | public IConfiguration Configuration { get; } 28 | private const string ApiName = "Autho.JWT.Policy"; 29 | 30 | // This method gets called by the runtime. Use this method to add services to the container. 31 | public void ConfigureServices(IServiceCollection services) 32 | { 33 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); 34 | 35 | #region Swagger UI Service 36 | 37 | var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath; 38 | services.AddSwaggerGen(c => 39 | { 40 | //遍历出全部的版本,做文档信息展示 41 | typeof(ApiVersions).GetEnumNames().ToList().ForEach(version => 42 | { 43 | c.SwaggerDoc(version, new Info 44 | { 45 | // {ApiName} 定义成全局变量,方便修改 46 | Version = version, 47 | Title = $"{ApiName} 接口文档", 48 | Description = $"{ApiName} HTTP API " + version, 49 | TermsOfService = "None", 50 | Contact = new Contact { Name = "Autho.JWT.Policy", Email = "Autho.JWT.Policy@xxx.com", Url = "https://www.jianshu.com/u/94102b59cc2a" } 51 | }); 52 | // 按相对路径排序,作者:Alby 53 | c.OrderActionsBy(o => o.RelativePath); 54 | }); 55 | 56 | 57 | //就是这里 58 | var xmlPath = Path.Combine(basePath, "Autho.JWT.Policy.xml");//这个就是刚刚配置的xml文件名 59 | c.IncludeXmlComments(xmlPath, true);//默认的第二个参数是false,这个是controller的注释,记得修改 60 | 61 | 62 | #region Token绑定到ConfigureServices 63 | 64 | //添加header验证信息 65 | //c.OperationFilter(); 66 | 67 | // 发行人 68 | var IssuerName = (Configuration.GetSection("Audience"))["Issuer"]; 69 | var security = new Dictionary> { { IssuerName, new string[] { } }, }; 70 | c.AddSecurityRequirement(security); 71 | 72 | //方案名称“Autho.JWT.Policy”可自定义,上下一致即可 73 | c.AddSecurityDefinition(IssuerName, new ApiKeyScheme 74 | { 75 | Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"", 76 | Name = "Authorization",//jwt默认的参数名称 77 | In = "header",//jwt默认存放Authorization信息的位置(请求头中) 78 | Type = "apiKey" 79 | }); 80 | #endregion 81 | }); 82 | 83 | #endregion 84 | 85 | 86 | 87 | 88 | #region 【授权】 89 | 90 | #region 参数 91 | //读取配置文件 92 | var audienceConfig = Configuration.GetSection("Audience"); 93 | var symmetricKeyAsBase64 = audienceConfig["Secret"]; 94 | var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64); 95 | var signingKey = new SymmetricSecurityKey(keyByteArray); 96 | 97 | // 令牌验证参数 98 | var tokenValidationParameters = new TokenValidationParameters 99 | { 100 | ValidateIssuerSigningKey = true, 101 | IssuerSigningKey = signingKey, 102 | ValidateIssuer = true, 103 | ValidIssuer = audienceConfig["Issuer"],//发行人 104 | ValidateAudience = true, 105 | ValidAudience = audienceConfig["Audience"],//订阅人 106 | ValidateLifetime = true, 107 | ClockSkew = TimeSpan.Zero, 108 | RequireExpirationTime = true, 109 | }; 110 | var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256); 111 | 112 | // 如果要数据库动态绑定,这里先留个空,后边处理器里动态赋值 113 | var permission = new List(); 114 | 115 | // 角色与接口的权限要求参数 116 | var permissionRequirement = new PermissionRequirement( 117 | "/api/denied",// 拒绝授权的跳转地址(目前无用) 118 | permission, 119 | ClaimTypes.Role,//基于角色的授权 120 | audienceConfig["Issuer"],//发行人 121 | audienceConfig["Audience"],//听众 122 | signingCredentials,//签名凭据 123 | expiration: TimeSpan.FromSeconds(60 * 2)//接口的过期时间 124 | ); 125 | #endregion 126 | //【授权】 127 | services.AddAuthorization(options => 128 | { 129 | options.AddPolicy("Permission", 130 | policy => policy.Requirements.Add(permissionRequirement)); 131 | }); 132 | #endregion 133 | 134 | 135 | #region 【认证】 136 | 137 | //2.1【认证】、官方JWT认证 138 | services.AddAuthentication(x => 139 | { 140 | x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 141 | x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 142 | }) 143 | .AddJwtBearer(o => 144 | { 145 | o.TokenValidationParameters = tokenValidationParameters; 146 | o.Events = new JwtBearerEvents 147 | { 148 | OnAuthenticationFailed = context => 149 | { 150 | // 如果过期,则把<是否过期>添加到,返回头信息中 151 | if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) 152 | { 153 | context.Response.Headers.Add("Token-Expired", "true"); 154 | } 155 | return Task.CompletedTask; 156 | } 157 | }; 158 | }); 159 | 160 | // 注入权限处理器 161 | services.AddSingleton(); 162 | services.AddSingleton(permissionRequirement); 163 | #endregion 164 | 165 | } 166 | 167 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 168 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 169 | { 170 | if (env.IsDevelopment()) 171 | { 172 | app.UseDeveloperExceptionPage(); 173 | } 174 | 175 | #region Swagger 176 | app.UseSwagger(); 177 | app.UseSwaggerUI(c => 178 | { 179 | //根据版本名称倒序 遍历展示 180 | typeof(ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(version => 181 | { 182 | c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{ApiName} {version}"); 183 | }); 184 | //c.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("Blog.Core.index.html"); 185 | c.RoutePrefix = ""; //路径配置,设置为空,表示直接在根域名(localhost:8001)访问该文件,注意localhost:8001/swagger是访问不到的,去launchSettings.json把launchUrl去掉 186 | }); 187 | #endregion 188 | 189 | app.UseAuthentication(); 190 | 191 | app.UseMvc(); 192 | } 193 | } 194 | 195 | public enum ApiVersions 196 | { 197 | /// 198 | /// v1 版本 199 | /// 200 | v1 = 1, 201 | /// 202 | /// v2 版本 203 | /// 204 | v2 = 2, 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/UtilConvert.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Autho.JWT.Policy 3 | { 4 | /// 5 | /// 6 | /// 7 | public static class UtilConvert 8 | { 9 | /// 10 | /// 11 | /// 12 | /// 13 | /// 14 | public static int ObjToInt(this object thisValue) 15 | { 16 | int reval = 0; 17 | if (thisValue == null) return 0; 18 | if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval)) 19 | { 20 | return reval; 21 | } 22 | return reval; 23 | } 24 | /// 25 | /// 26 | /// 27 | /// 28 | /// 29 | /// 30 | public static int ObjToInt(this object thisValue, int errorValue) 31 | { 32 | int reval = 0; 33 | if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval)) 34 | { 35 | return reval; 36 | } 37 | return errorValue; 38 | } 39 | /// 40 | /// 41 | /// 42 | /// 43 | /// 44 | public static double ObjToMoney(this object thisValue) 45 | { 46 | double reval = 0; 47 | if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval)) 48 | { 49 | return reval; 50 | } 51 | return 0; 52 | } 53 | /// 54 | /// 55 | /// 56 | /// 57 | /// 58 | /// 59 | public static double ObjToMoney(this object thisValue, double errorValue) 60 | { 61 | double reval = 0; 62 | if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval)) 63 | { 64 | return reval; 65 | } 66 | return errorValue; 67 | } 68 | /// 69 | /// 70 | /// 71 | /// 72 | /// 73 | public static string ObjToString(this object thisValue) 74 | { 75 | if (thisValue != null) return thisValue.ToString().Trim(); 76 | return ""; 77 | } 78 | /// 79 | /// 80 | /// 81 | /// 82 | /// 83 | /// 84 | public static string ObjToString(this object thisValue, string errorValue) 85 | { 86 | if (thisValue != null) return thisValue.ToString().Trim(); 87 | return errorValue; 88 | } 89 | /// 90 | /// 91 | /// 92 | /// 93 | /// 94 | public static Decimal ObjToDecimal(this object thisValue) 95 | { 96 | Decimal reval = 0; 97 | if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval)) 98 | { 99 | return reval; 100 | } 101 | return 0; 102 | } 103 | /// 104 | /// 105 | /// 106 | /// 107 | /// 108 | /// 109 | public static Decimal ObjToDecimal(this object thisValue, decimal errorValue) 110 | { 111 | Decimal reval = 0; 112 | if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval)) 113 | { 114 | return reval; 115 | } 116 | return errorValue; 117 | } 118 | /// 119 | /// 120 | /// 121 | /// 122 | /// 123 | public static DateTime ObjToDate(this object thisValue) 124 | { 125 | DateTime reval = DateTime.MinValue; 126 | if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) 127 | { 128 | reval = Convert.ToDateTime(thisValue); 129 | } 130 | return reval; 131 | } 132 | /// 133 | /// 134 | /// 135 | /// 136 | /// 137 | /// 138 | public static DateTime ObjToDate(this object thisValue, DateTime errorValue) 139 | { 140 | DateTime reval = DateTime.MinValue; 141 | if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) 142 | { 143 | return reval; 144 | } 145 | return errorValue; 146 | } 147 | /// 148 | /// 149 | /// 150 | /// 151 | /// 152 | public static bool ObjToBool(this object thisValue) 153 | { 154 | bool reval = false; 155 | if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval)) 156 | { 157 | return reval; 158 | } 159 | return reval; 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT.Policy/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "Debug": { 5 | "LogLevel": { 6 | "Default": "Warning" 7 | } 8 | }, 9 | "Console": { 10 | "LogLevel": { 11 | "Default": "Warning" 12 | } 13 | } 14 | }, 15 | "AllowedHosts": "*", 16 | "AppSettings": { 17 | "RedisCaching": { 18 | "Enabled": true, 19 | "ConnectionString": "127.0.0.1:6319" 20 | }, 21 | "SqlServer": { 22 | "SqlServerConnection": "Server=.;Database=WMBlogDB;User ID=sa;Password=123;", 23 | "ProviderName": "System.Data.SqlClient" 24 | }, 25 | "Date": "2018-08-28", 26 | "Author": "Blog.Core" 27 | }, 28 | "Audience": { 29 | "Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs", 30 | "Issuer": "Blog.Core", 31 | "Audience": "wr" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT/Autho.JWT.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | InProcess 6 | 7 | 8 | 9 | ..\Autho.JWT\Autho.JWT.xml 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Always 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT/Autho.JWT.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Autho.JWT 5 | 6 | 7 | 8 | 9 | 这个需要认证,角色必须是Admin,其他的不需要 10 | 11 | 12 | 13 | 14 | 15 | 这个也需要认证,只不过登录即可,不一定是Admin 16 | 17 | 18 | 19 | 20 | 21 | 22 | 登录接口:随便输入字符,获取token,然后添加 Authoritarian 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | appsettings.json操作类 31 | 32 | 33 | 34 | 35 | 封装要操作的字符 36 | 37 | 38 | 39 | 40 | 41 | 42 | 颁发JWT字符串 43 | 44 | 45 | 46 | 47 | 48 | 49 | 解析 50 | 51 | 52 | 53 | 54 | 55 | 56 | 令牌 57 | 58 | 59 | 60 | 61 | Id 62 | 63 | 64 | 65 | 66 | 角色 67 | 68 | 69 | 70 | 71 | 职能 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | v1 版本 100 | 101 | 102 | 103 | 104 | v2 版本 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT/Controllers/ValuesController.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.Mvc; 7 | 8 | namespace Autho.JWT.Controllers 9 | { 10 | [Route("api/[controller]/[action]")] 11 | [ApiController] 12 | public class ValuesController : ControllerBase 13 | { 14 | /// 15 | /// 这个需要认证,角色必须是Admin,其他的不需要 16 | /// 17 | /// 18 | [HttpGet] 19 | [Authorize(Policy = "SystemOrAdmin")] 20 | public ActionResult> Get() 21 | { 22 | return new string[] { "value1", "value2" }; 23 | } 24 | 25 | /// 26 | /// 这个也需要认证,只不过登录即可,不一定是Admin 27 | /// 28 | /// 29 | /// 30 | [HttpGet("{id}")] 31 | [Authorize] 32 | public ActionResult Get(int id) 33 | { 34 | return "value"; 35 | } 36 | 37 | /// 38 | /// 登录接口:随便输入字符,获取token,然后添加 Authoritarian 39 | /// 40 | /// 41 | /// 42 | /// 43 | [HttpGet] 44 | public async Task GetJWTToken(string name, string pass) 45 | { 46 | string jwtStr = string.Empty; 47 | bool suc = false; 48 | //这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作 49 | //这里直接写死了 50 | 51 | 52 | if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass)) 53 | { 54 | return new JsonResult(new 55 | { 56 | Status = false, 57 | message = "用户名或密码不能为空" 58 | }); 59 | } 60 | 61 | TokenModelJWT tokenModel = new TokenModelJWT(); 62 | tokenModel.Uid = 1; 63 | tokenModel.Role = "Admin"; 64 | 65 | jwtStr = JwtHelper.IssueJWT(tokenModel); 66 | suc = true; 67 | 68 | 69 | return Ok(new 70 | { 71 | success = suc, 72 | token = jwtStr 73 | }); 74 | } 75 | // POST api/values 76 | [HttpPost] 77 | public void Post([FromBody] string value) 78 | { 79 | } 80 | 81 | // PUT api/values/5 82 | [HttpPut("{id}")] 83 | public void Put(int id, [FromBody] string value) 84 | { 85 | } 86 | 87 | // DELETE api/values/5 88 | [HttpDelete("{id}")] 89 | public void Delete(int id) 90 | { 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT/Helper/Appsettings.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using Microsoft.Extensions.Configuration.Json; 3 | using System; 4 | 5 | namespace Autho.JWT 6 | { 7 | /// 8 | /// appsettings.json操作类 9 | /// 10 | public class Appsettings 11 | { 12 | static IConfiguration Configuration { get; set; } 13 | static Appsettings() 14 | { 15 | //ReloadOnChange = true 当appsettings.json被修改时重新加载 16 | Configuration = new ConfigurationBuilder() 17 | .Add(new JsonConfigurationSource { Path = "appsettings.json", ReloadOnChange = true })//请注意要把当前appsetting.json 文件->右键->属性->复制到输出目录->始终复制 18 | .Build(); 19 | } 20 | /// 21 | /// 封装要操作的字符 22 | /// 23 | /// 24 | /// 25 | public static string app(params string[] sections) 26 | { 27 | try 28 | { 29 | var val = string.Empty; 30 | for (int i = 0; i < sections.Length; i++) 31 | { 32 | val += sections[i] + ":"; 33 | } 34 | 35 | return Configuration[val.TrimEnd(':')]; 36 | } 37 | catch (Exception) 38 | { 39 | return ""; 40 | } 41 | 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT/Helper/JwtHelper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.IdentityModel.Tokens; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IdentityModel.Tokens.Jwt; 5 | using System.Linq; 6 | using System.Security.Claims; 7 | using System.Text; 8 | 9 | namespace Autho.JWT 10 | { 11 | public class JwtHelper 12 | { 13 | 14 | /// 15 | /// 颁发JWT字符串 16 | /// 17 | /// 18 | /// 19 | public static string IssueJWT(TokenModelJWT tokenModel) 20 | { 21 | var dateTime = DateTime.UtcNow; 22 | 23 | string iss = Appsettings.app(new string[] { "Audience", "Issuer" }); 24 | string aud = Appsettings.app(new string[] { "Audience", "Audience" }); 25 | string secret = Appsettings.app(new string[] { "Audience", "Secret" }); 26 | 27 | //var claims = new Claim[] //old 28 | var claims = new List 29 | { 30 | //下边为Claim的默认配置 31 | new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ToString()), 32 | new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), 33 | new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") , 34 | //这个就是过期时间,目前是过期100秒,可自定义,注意JWT有自己的缓冲过期时间 35 | new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(100)).ToUnixTimeSeconds()}"), 36 | new Claim(JwtRegisteredClaimNames.Iss,iss), 37 | new Claim(JwtRegisteredClaimNames.Aud,aud), 38 | 39 | //new Claim(ClaimTypes.Role,tokenModel.Role),//为了解决一个用户多个角色(比如:Admin,System),用下边的方法 40 | }; 41 | 42 | // 可以将一个用户的多个角色全部赋予; 43 | // 作者:DX 提供技术支持; 44 | claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); 45 | 46 | 47 | 48 | //秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常) 49 | var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)); 50 | var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); 51 | 52 | var jwt = new JwtSecurityToken( 53 | issuer: iss, 54 | claims: claims, 55 | signingCredentials: creds); 56 | 57 | var jwtHandler = new JwtSecurityTokenHandler(); 58 | var encodedJwt = jwtHandler.WriteToken(jwt); 59 | 60 | return encodedJwt; 61 | } 62 | 63 | /// 64 | /// 解析 65 | /// 66 | /// 67 | /// 68 | public static TokenModelJWT SerializeJWT(string jwtStr) 69 | { 70 | var jwtHandler = new JwtSecurityTokenHandler(); 71 | JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr); 72 | object role = new object(); ; 73 | try 74 | { 75 | jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role); 76 | } 77 | catch (Exception e) 78 | { 79 | Console.WriteLine(e); 80 | throw; 81 | } 82 | var tm = new TokenModelJWT 83 | { 84 | Uid = Convert.ToInt32(jwtToken.Id), 85 | Role = role != null ? role.ToString() : "", 86 | }; 87 | return tm; 88 | } 89 | } 90 | 91 | /// 92 | /// 令牌 93 | /// 94 | public class TokenModelJWT 95 | { 96 | /// 97 | /// Id 98 | /// 99 | public long Uid { get; set; } 100 | /// 101 | /// 角色 102 | /// 103 | public string Role { get; set; } 104 | /// 105 | /// 职能 106 | /// 107 | public string Work { get; set; } 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT/Helper/JwtTokenAuth.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Http; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Security.Claims; 6 | using System.Threading.Tasks; 7 | 8 | namespace Autho.JWT 9 | { 10 | /// 11 | /// 12 | /// 13 | public class JwtTokenAuth 14 | { 15 | /// 16 | /// 17 | /// 18 | private readonly RequestDelegate _next; 19 | /// 20 | /// 21 | /// 22 | /// 23 | public JwtTokenAuth(RequestDelegate next) 24 | { 25 | _next = next; 26 | } 27 | 28 | 29 | private void PreProceed(HttpContext next) 30 | { 31 | Console.WriteLine($"{DateTime.Now} middleware invoke preproceed"); 32 | //... 33 | } 34 | private void PostProceed(HttpContext next) 35 | { 36 | Console.WriteLine($"{DateTime.Now} middleware invoke postproceed"); 37 | //.... 38 | } 39 | 40 | /// 41 | /// 42 | /// 43 | /// 44 | /// 45 | public Task Invoke(HttpContext httpContext) 46 | { 47 | PreProceed(httpContext); 48 | 49 | 50 | //检测是否包含'Authorization'请求头 51 | if (!httpContext.Request.Headers.ContainsKey("Authorization")) 52 | { 53 | PostProceed(httpContext); 54 | 55 | return _next(httpContext); 56 | } 57 | //var tokenHeader = httpContext.Request.Headers["Authorization"].ToString(); 58 | var tokenHeader = httpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", ""); 59 | 60 | try 61 | { 62 | if (tokenHeader.Length >= 128) 63 | { 64 | TokenModelJWT tm = JwtHelper.SerializeJWT(tokenHeader); 65 | 66 | //授权 67 | var claimList = new List(); 68 | var claim = new Claim(ClaimTypes.Role, tm.Role); 69 | claimList.Add(claim); 70 | var identity = new ClaimsIdentity(claimList); 71 | var principal = new ClaimsPrincipal(identity); 72 | httpContext.User = principal; 73 | } 74 | 75 | } 76 | catch (Exception e) 77 | { 78 | Console.WriteLine($"{DateTime.Now} middleware wrong:{e.Message}"); 79 | } 80 | 81 | 82 | PostProceed(httpContext); 83 | 84 | 85 | return _next(httpContext); 86 | } 87 | 88 | } 89 | public static class MiddlewareHelpers 90 | { 91 | public static IApplicationBuilder UseJwtTokenAuth(this IApplicationBuilder app) 92 | { 93 | return app.UseMiddleware(); 94 | } 95 | } 96 | } 97 | 98 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace Autho.JWT 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateWebHostBuilder(args).Build().Run(); 11 | } 12 | 13 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 14 | WebHost.CreateDefaultBuilder(args) 15 | .UseStartup(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "Autho.JWT": { 5 | "commandName": "Project", 6 | "launchBrowser": true, 7 | "applicationUrl": "http://localhost:5102", 8 | "environmentVariables": { 9 | "ASPNETCORE_ENVIRONMENT": "Development" 10 | } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT/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.Authentication.JwtBearer; 8 | using Microsoft.AspNetCore.Builder; 9 | using Microsoft.AspNetCore.Hosting; 10 | using Microsoft.AspNetCore.Mvc; 11 | using Microsoft.Extensions.Configuration; 12 | using Microsoft.Extensions.DependencyInjection; 13 | using Microsoft.IdentityModel.Tokens; 14 | using Swashbuckle.AspNetCore.Swagger; 15 | 16 | namespace Autho.JWT 17 | { 18 | public class Startup 19 | { 20 | public Startup(IConfiguration configuration) 21 | { 22 | Configuration = configuration; 23 | } 24 | 25 | public IConfiguration Configuration { get; } 26 | private const string ApiName = "Autho.JWT"; 27 | 28 | // This method gets called by the runtime. Use this method to add services to the container. 29 | public void ConfigureServices(IServiceCollection services) 30 | { 31 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); 32 | 33 | #region Swagger UI Service 34 | 35 | var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath; 36 | services.AddSwaggerGen(c => 37 | { 38 | //遍历出全部的版本,做文档信息展示 39 | typeof(ApiVersions).GetEnumNames().ToList().ForEach(version => 40 | { 41 | c.SwaggerDoc(version, new Info 42 | { 43 | // {ApiName} 定义成全局变量,方便修改 44 | Version = version, 45 | Title = $"{ApiName} 接口文档", 46 | Description = $"{ApiName} HTTP API " + version, 47 | TermsOfService = "None", 48 | Contact = new Contact { Name = "Autho.JWT", Email = "Autho.JWT@xxx.com", Url = "https://www.jianshu.com/u/94102b59cc2a" } 49 | }); 50 | // 按相对路径排序,作者:Alby 51 | c.OrderActionsBy(o => o.RelativePath); 52 | }); 53 | 54 | 55 | //就是这里 56 | var xmlPath = Path.Combine(basePath, "Autho.JWT.xml");//这个就是刚刚配置的xml文件名 57 | c.IncludeXmlComments(xmlPath, true);//默认的第二个参数是false,这个是controller的注释,记得修改 58 | 59 | 60 | #region Token绑定到ConfigureServices 61 | 62 | //添加header验证信息 63 | //c.OperationFilter(); 64 | 65 | // 发行人 66 | var IssuerName = (Configuration.GetSection("Audience"))["Issuer"]; 67 | var security = new Dictionary> { { IssuerName, new string[] { } }, }; 68 | c.AddSecurityRequirement(security); 69 | 70 | //方案名称“Autho.JWT”可自定义,上下一致即可 71 | c.AddSecurityDefinition(IssuerName, new ApiKeyScheme 72 | { 73 | Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"", 74 | Name = "Authorization",//jwt默认的参数名称 75 | In = "header",//jwt默认存放Authorization信息的位置(请求头中) 76 | Type = "apiKey" 77 | }); 78 | #endregion 79 | }); 80 | 81 | #endregion 82 | 83 | 84 | #region 【简单授权】 85 | #region 1、基于角色的API授权 86 | 87 | // 1【授权】、这个很简单,其他什么都不用做, 88 | // 无需配置服务,只需要在API层的controller上边,增加特性即可,注意,只能是角色的: 89 | // [Authorize(Roles = "Admin")] 90 | 91 | // 2【认证】、然后在下边的configure里,配置中间件即可:app.UseMiddleware();但是这个方法,无法验证过期时间,所以如果需要验证过期时间,还是需要下边的第三种方法,官方认证 92 | 93 | #endregion 94 | 95 | #region 2、基于策略的授权(简单版) 96 | 97 | // 1【授权】、这个和上边的异曲同工,好处就是不用在controller中,写多个 roles 。 98 | // 然后这么写 [Authorize(Policy = "Admin")] 99 | services.AddAuthorization(options => 100 | { 101 | options.AddPolicy("Client", policy => policy.RequireRole("Client").Build()); 102 | options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build()); 103 | options.AddPolicy("SystemOrAdmin", policy => policy.RequireRole("Admin", "System")); 104 | }); 105 | 106 | 107 | // 2【认证】、然后在下边的configure里,配置中间件即可:app.UseMiddleware();但是这个方法,无法验证过期时间,所以如果需要验证过期时间,还是需要下边的第三种方法,官方认证 108 | #endregion 109 | #endregion 110 | 111 | 112 | #region 【认证】 113 | //读取配置文件 114 | var audienceConfig = Configuration.GetSection("Audience"); 115 | var symmetricKeyAsBase64 = audienceConfig["Secret"]; 116 | var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64); 117 | var signingKey = new SymmetricSecurityKey(keyByteArray); 118 | 119 | 120 | //2.1【认证】 121 | services.AddAuthentication(x => 122 | { 123 | x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 124 | x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 125 | }) 126 | .AddJwtBearer(o => 127 | { 128 | o.TokenValidationParameters = new TokenValidationParameters 129 | { 130 | ValidateIssuerSigningKey = true, 131 | IssuerSigningKey = signingKey, 132 | ValidateIssuer = true, 133 | ValidIssuer = audienceConfig["Issuer"],//发行人 134 | ValidateAudience = true, 135 | ValidAudience = audienceConfig["Audience"],//订阅人 136 | ValidateLifetime = true, 137 | ClockSkew = TimeSpan.Zero, 138 | RequireExpirationTime = true, 139 | }; 140 | 141 | }); 142 | 143 | 144 | 145 | 146 | 147 | #endregion 148 | 149 | } 150 | 151 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 152 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 153 | { 154 | if (env.IsDevelopment()) 155 | { 156 | app.UseDeveloperExceptionPage(); 157 | } 158 | 159 | #region Swagger 160 | app.UseSwagger(); 161 | app.UseSwaggerUI(c => 162 | { 163 | //根据版本名称倒序 遍历展示 164 | typeof(ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(version => 165 | { 166 | c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{ApiName} {version}"); 167 | }); 168 | //c.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("Blog.Core.index.html"); 169 | c.RoutePrefix = ""; //路径配置,设置为空,表示直接在根域名(localhost:8001)访问该文件,注意localhost:8001/swagger是访问不到的,去launchSettings.json把launchUrl去掉 170 | }); 171 | #endregion 172 | 173 | 174 | //此授权认证方法已经放弃,请使用下边的官方验证方法。但是如果你还想传User的全局变量,还是可以继续使用中间件 175 | //app.UseJwtTokenAuth(); //app.UseMiddleware(); 176 | 177 | //如果你想使用官方认证,必须在上边ConfigureService 中,配置JWT的认证服务 (.AddAuthentication 和 .AddJwtBearer 二者缺一不可) 178 | app.UseAuthentication(); 179 | 180 | app.UseMvc(); 181 | } 182 | } 183 | 184 | public enum ApiVersions 185 | { 186 | /// 187 | /// v1 版本 188 | /// 189 | v1 = 1, 190 | /// 191 | /// v2 版本 192 | /// 193 | v2 = 2, 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.JWT/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "Debug": { 5 | "LogLevel": { 6 | "Default": "Warning" 7 | } 8 | }, 9 | "Console": { 10 | "LogLevel": { 11 | "Default": "Warning" 12 | } 13 | } 14 | }, 15 | "AllowedHosts": "*", 16 | "AppSettings": { 17 | "RedisCaching": { 18 | "Enabled": true, 19 | "ConnectionString": "127.0.0.1:6319" 20 | }, 21 | "SqlServer": { 22 | "SqlServerConnection": "Server=.;Database=WMBlogDB;User ID=sa;Password=123;", 23 | "ProviderName": "System.Data.SqlClient" 24 | }, 25 | "Date": "2018-08-28", 26 | "Author": "Blog.Core" 27 | }, 28 | "Audience": { 29 | "Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs", 30 | "Issuer": "Blog.Core", 31 | "Audience": "wr" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Blog.Core_JWT/Autho.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.136 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Autho.JWT", "Autho.JWT\Autho.JWT.csproj", "{261A6B27-F7A8-4C12-954C-AA28FD2A927C}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Autho.JWT.Policy", "Autho.JWT.Policy\Autho.JWT.Policy.csproj", "{A7F11DEF-C8F0-4FE7-840D-191A989979C8}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {261A6B27-F7A8-4C12-954C-AA28FD2A927C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {261A6B27-F7A8-4C12-954C-AA28FD2A927C}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {261A6B27-F7A8-4C12-954C-AA28FD2A927C}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {261A6B27-F7A8-4C12-954C-AA28FD2A927C}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {A7F11DEF-C8F0-4FE7-840D-191A989979C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {A7F11DEF-C8F0-4FE7-840D-191A989979C8}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {A7F11DEF-C8F0-4FE7-840D-191A989979C8}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {A7F11DEF-C8F0-4FE7-840D-191A989979C8}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {626D3F32-CD10-4EA3-9F2B-0E4BB3890A65} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Blog.Core_JWT/README.md: -------------------------------------------------------------------------------- 1 | # BlogArti / Blog.Core_JWT 2 | 3 | 这里是将博客园《从壹开始前后端分离》的NetCore 后端项目Blog.Core 进行拆分,这是其中之一: 4 | ``` 5 | 6 | 3、Blog.Core_JWT -> JWT权限验证【文章对应:05-36-37】 7 | 8 | 9 | 10 | 11 | ``` 12 | -------------------------------------------------------------------------------- /Blog.Core_Repository/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015/2017 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # Visual Studio 2017 auto generated files 34 | Generated\ Files/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # Benchmark Results 50 | BenchmarkDotNet.Artifacts/ 51 | 52 | # .NET Core 53 | project.lock.json 54 | project.fragment.lock.json 55 | artifacts/ 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_h.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *_wpftmp.csproj 81 | *.log 82 | *.vspscc 83 | *.vssscc 84 | .builds 85 | *.pidb 86 | *.svclog 87 | *.scc 88 | 89 | # Chutzpah Test files 90 | _Chutzpah* 91 | 92 | # Visual C++ cache files 93 | ipch/ 94 | *.aps 95 | *.ncb 96 | *.opendb 97 | *.opensdf 98 | *.sdf 99 | *.cachefile 100 | *.VC.db 101 | *.VC.VC.opendb 102 | 103 | # Visual Studio profiler 104 | *.psess 105 | *.vsp 106 | *.vspx 107 | *.sap 108 | 109 | # Visual Studio Trace Files 110 | *.e2e 111 | 112 | # TFS 2012 Local Workspace 113 | $tf/ 114 | 115 | # Guidance Automation Toolkit 116 | *.gpState 117 | 118 | # ReSharper is a .NET coding add-in 119 | _ReSharper*/ 120 | *.[Rr]e[Ss]harper 121 | *.DotSettings.user 122 | 123 | # JustCode is a .NET coding add-in 124 | .JustCode 125 | 126 | # TeamCity is a build add-in 127 | _TeamCity* 128 | 129 | # DotCover is a Code Coverage Tool 130 | *.dotCover 131 | 132 | # AxoCover is a Code Coverage Tool 133 | .axoCover/* 134 | !.axoCover/settings.json 135 | 136 | # Visual Studio code coverage results 137 | *.coverage 138 | *.coveragexml 139 | 140 | # NCrunch 141 | _NCrunch_* 142 | .*crunch*.local.xml 143 | nCrunchTemp_* 144 | 145 | # MightyMoose 146 | *.mm.* 147 | AutoTest.Net/ 148 | 149 | # Web workbench (sass) 150 | .sass-cache/ 151 | 152 | # Installshield output folder 153 | [Ee]xpress/ 154 | 155 | # DocProject is a documentation generator add-in 156 | DocProject/buildhelp/ 157 | DocProject/Help/*.HxT 158 | DocProject/Help/*.HxC 159 | DocProject/Help/*.hhc 160 | DocProject/Help/*.hhk 161 | DocProject/Help/*.hhp 162 | DocProject/Help/Html2 163 | DocProject/Help/html 164 | 165 | # Click-Once directory 166 | publish/ 167 | 168 | # Publish Web Output 169 | *.[Pp]ublish.xml 170 | *.azurePubxml 171 | # Note: Comment the next line if you want to checkin your web deploy settings, 172 | # but database connection strings (with potential passwords) will be unencrypted 173 | *.pubxml 174 | *.publishproj 175 | 176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 177 | # checkin your Azure Web App publish settings, but sensitive information contained 178 | # in these scripts will be unencrypted 179 | PublishScripts/ 180 | 181 | # NuGet Packages 182 | *.nupkg 183 | # The packages folder can be ignored because of Package Restore 184 | **/[Pp]ackages/* 185 | # except build/, which is used as an MSBuild target. 186 | !**/[Pp]ackages/build/ 187 | # Uncomment if necessary however generally it will be regenerated when needed 188 | #!**/[Pp]ackages/repositories.config 189 | # NuGet v3's project.json files produces more ignorable files 190 | *.nuget.props 191 | *.nuget.targets 192 | 193 | # Microsoft Azure Build Output 194 | csx/ 195 | *.build.csdef 196 | 197 | # Microsoft Azure Emulator 198 | ecf/ 199 | rcf/ 200 | 201 | # Windows Store app package directories and files 202 | AppPackages/ 203 | BundleArtifacts/ 204 | Package.StoreAssociation.xml 205 | _pkginfo.txt 206 | *.appx 207 | 208 | # Visual Studio cache files 209 | # files ending in .cache can be ignored 210 | *.[Cc]ache 211 | # but keep track of directories ending in .cache 212 | !*.[Cc]ache/ 213 | 214 | # Others 215 | ClientBin/ 216 | ~$* 217 | *~ 218 | *.dbmdl 219 | *.dbproj.schemaview 220 | *.jfm 221 | *.pfx 222 | *.publishsettings 223 | orleans.codegen.cs 224 | 225 | # Including strong name files can present a security risk 226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 227 | #*.snk 228 | 229 | # Since there are multiple workflows, uncomment next line to ignore bower_components 230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 231 | #bower_components/ 232 | 233 | # RIA/Silverlight projects 234 | Generated_Code/ 235 | 236 | # Backup & report files from converting an old project file 237 | # to a newer Visual Studio version. Backup files are not needed, 238 | # because we have git ;-) 239 | _UpgradeReport_Files/ 240 | Backup*/ 241 | UpgradeLog*.XML 242 | UpgradeLog*.htm 243 | ServiceFabricBackup/ 244 | *.rptproj.bak 245 | 246 | # SQL Server files 247 | *.mdf 248 | *.ldf 249 | *.ndf 250 | 251 | # Business Intelligence projects 252 | *.rdl.data 253 | *.bim.layout 254 | *.bim_*.settings 255 | *.rptproj.rsuser 256 | 257 | # Microsoft Fakes 258 | FakesAssemblies/ 259 | 260 | # GhostDoc plugin setting file 261 | *.GhostDoc.xml 262 | 263 | # Node.js Tools for Visual Studio 264 | .ntvs_analysis.dat 265 | node_modules/ 266 | 267 | # Visual Studio 6 build log 268 | *.plg 269 | 270 | # Visual Studio 6 workspace options file 271 | *.opt 272 | 273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 274 | *.vbw 275 | 276 | # Visual Studio LightSwitch build output 277 | **/*.HTMLClient/GeneratedArtifacts 278 | **/*.DesktopClient/GeneratedArtifacts 279 | **/*.DesktopClient/ModelManifest.xml 280 | **/*.Server/GeneratedArtifacts 281 | **/*.Server/ModelManifest.xml 282 | _Pvt_Extensions 283 | 284 | # Paket dependency manager 285 | .paket/paket.exe 286 | paket-files/ 287 | 288 | # FAKE - F# Make 289 | .fake/ 290 | 291 | # JetBrains Rider 292 | .idea/ 293 | *.sln.iml 294 | 295 | # CodeRush personal settings 296 | .cr/personal 297 | 298 | # Python Tools for Visual Studio (PTVS) 299 | __pycache__/ 300 | *.pyc 301 | 302 | # Cake - Uncomment if you are using it 303 | # tools/** 304 | # !tools/packages.config 305 | 306 | # Tabs Studio 307 | *.tss 308 | 309 | # Telerik's JustMock configuration file 310 | *.jmconfig 311 | 312 | # BizTalk build output 313 | *.btp.cs 314 | *.btm.cs 315 | *.odx.cs 316 | *.xsd.cs 317 | 318 | # OpenCover UI analysis results 319 | OpenCover/ 320 | 321 | # Azure Stream Analytics local run output 322 | ASALocalRun/ 323 | 324 | # MSBuild Binary and Structured Log 325 | *.binlog 326 | 327 | # NVidia Nsight GPU debugger configuration file 328 | *.nvuser 329 | 330 | # MFractors (Xamarin productivity tool) working folder 331 | .mfractor/ 332 | 333 | # Local History for Visual Studio 334 | .localhistory/ 335 | 336 | # wwwroot/images 337 | *images/ -------------------------------------------------------------------------------- /Blog.Core_Repository/AppCore/AppCore.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | InProcess 6 | 7 | 8 | 9 | 10 | ..\AppCore\CoreAPIXml\AppCore.xml 11 | 1701;1702;1591 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Always 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Blog.Core_Repository/AppCore/Controllers/SysSampleController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Microsoft.AspNetCore.Mvc; 4 | using IServices; 5 | using Model; 6 | using Services; 7 | 8 | namespace AppCore.Controllers 9 | { 10 | [Route("api/[controller]")] 11 | [ApiController] 12 | public class SysSampleController : ControllerBase 13 | { 14 | 15 | /// 16 | /// 获取列表 17 | /// 18 | /// 根据id获取 19 | /// 20 | [HttpGet("{id}")] 21 | public async Task> Get(string id) 22 | { 23 | ISysSampleServices sysSampleServices = new SysSampleServices(); 24 | return await sysSampleServices.Query(d => d.id == id); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Blog.Core_Repository/AppCore/CoreAPIXml/AppCore.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AppCore 5 | 6 | 7 | 8 | 9 | 获取列表 10 | 11 | 根据id获取 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Blog.Core_Repository/AppCore/CoreAPIXml/model.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Model 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 | 操作是否成功 0成功 1失败 30 | 31 | 32 | 33 | 34 | 返回信息 35 | 36 | 37 | 38 | 39 | 返回数据集数量 40 | 41 | 42 | 43 | 44 | 返回数据集合 45 | 46 | 47 | 48 | 49 | 测试 50 | 51 | 52 | 53 | 54 | 标识 55 | 56 | 57 | 58 | 59 | 名称 60 | 61 | 62 | 63 | 64 | 年龄 65 | 66 | 67 | 68 | 69 | 生日 70 | 71 | 72 | 73 | 74 | 图片 75 | 76 | 77 | 78 | 79 | 说明 80 | 81 | 82 | 83 | 84 | 创建时间 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /Blog.Core_Repository/AppCore/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace AppCore 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateWebHostBuilder(args).Build().Run(); 11 | } 12 | 13 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 14 | WebHost.CreateDefaultBuilder(args) 15 | .UseStartup(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Blog.Core_Repository/AppCore/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "AppCore": { 5 | "commandName": "Project", 6 | "launchBrowser": true, 7 | "launchUrl": "swagger", 8 | "applicationUrl": "http://localhost:5101", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Blog.Core_Repository/AppCore/Startup.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using Microsoft.AspNetCore.Builder; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using Swashbuckle.AspNetCore.Swagger; 9 | 10 | namespace AppCore 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | 22 | 23 | // This method gets called by the runtime. Use this method to add services to the container. 24 | public void ConfigureServices(IServiceCollection services) 25 | { 26 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); 27 | 28 | var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath; 29 | 30 | #region Swagger 31 | 32 | services.AddSwaggerGen(c => 33 | { 34 | c.SwaggerDoc("v1", new Info 35 | { 36 | Version = "v0.1.0", 37 | Title = "AppCore API", 38 | Description = "框架说明文档", 39 | TermsOfService = "None", 40 | Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "AppCore", Email = "18732976928@163.com", Url = "https://www.jianshu.com/u/94102b59cc2a" } 41 | }); 42 | 43 | 44 | var xmlPath = Path.Combine(basePath, "AppCore.xml");//这个就是刚刚配置的xml文件名 45 | c.IncludeXmlComments(xmlPath, true);//默认的第二个参数是false,这个是controller的注释,记得修改 46 | 47 | var xmlModelPath = Path.Combine(basePath, "model.xml"); 48 | c.IncludeXmlComments(xmlModelPath); 49 | 50 | 51 | #region Token绑定到ConfigureServices 52 | //添加header验证信息 53 | //c.OperationFilter(); 54 | var security = new Dictionary> { { "AppCore", new string[] { } }, }; 55 | c.AddSecurityRequirement(security); 56 | //方案名称“Blog.Core”可自定义,上下一致即可 57 | c.AddSecurityDefinition("AppCore", new ApiKeyScheme 58 | { 59 | Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"", 60 | Name = "Authorization",//jwt默认的参数名称 61 | In = "header",//jwt默认存放Authorization信息的位置(请求头中) 62 | Type = "apiKey" 63 | }); 64 | #endregion 65 | 66 | 67 | }); 68 | 69 | #endregion 70 | 71 | 72 | 73 | } 74 | 75 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 76 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 77 | { 78 | if (env.IsDevelopment()) 79 | { 80 | app.UseDeveloperExceptionPage(); 81 | } 82 | 83 | app.UseSwagger(); 84 | app.UseSwaggerUI(c => 85 | { 86 | c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1"); 87 | }); 88 | 89 | 90 | app.UseMvc(); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Blog.Core_Repository/AppCore/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Blog.Core_Repository/AppCore/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*", 8 | "AppSettings": { 9 | "RedisCaching": { 10 | "Enabled": true, 11 | "ConnectionString": "127.0.0.1:6379" 12 | }, 13 | "SqlServer": { 14 | "SqlServerConnection": "Server=.;Database=AppsDB_new;User ID=sa;Password=sa;", 15 | "ProviderName": "System.Data.SqlClient" 16 | }, 17 | "Date": "2018-08-28", 18 | "Author": "AppCore" 19 | }, 20 | "Audience": { 21 | "Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs", 22 | "Issuer": "AppCore", 23 | "Audience": "wr" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Common/Common.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Common/Helper/Appsettings.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using Microsoft.Extensions.Configuration.Json; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Common 8 | { 9 | /// 10 | /// appsettings.json操作类 11 | /// 12 | public class Appsettings 13 | { 14 | static IConfiguration Configuration { get; set; } 15 | static Appsettings() 16 | { 17 | //ReloadOnChange = true; 当appsettings.json被修改时重新加载 18 | Configuration = new ConfigurationBuilder() 19 | .Add(new JsonConfigurationSource { Path = "appsettings.json", ReloadOnChange = true }) 20 | .Build(); 21 | } 22 | /// 23 | /// 封装要操作的字符 24 | /// 25 | /// 26 | /// 27 | public static string app(params string[] sections) 28 | { 29 | try 30 | { 31 | var val = string.Empty; 32 | for (int i = 0; i < sections.Length; i++) 33 | { 34 | val += sections[i] + ":"; 35 | } 36 | 37 | return Configuration[val.TrimEnd(':')]; 38 | } 39 | catch (Exception) 40 | { 41 | return ""; 42 | } 43 | 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Common/Helper/HtmlHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Blog.Core.Common.Helper 6 | { 7 | public static class HtmlHelper 8 | { 9 | #region 去除富文本中的HTML标签 10 | /// 11 | /// 去除富文本中的HTML标签 12 | /// 13 | /// 14 | /// 15 | /// 16 | public static string ReplaceHtmlTag(string html, int length = 0) 17 | { 18 | string strText = System.Text.RegularExpressions.Regex.Replace(html, "<[^>]+>", ""); 19 | strText = System.Text.RegularExpressions.Regex.Replace(strText, "&[^;]+;", ""); 20 | 21 | if (length > 0 && strText.Length > length) 22 | return strText.Substring(0, length); 23 | 24 | return strText; 25 | } 26 | #endregion 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Common/Helper/RecursionHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Blog.Core.Common.Helper 7 | { 8 | /// 9 | /// 泛型递归求树形结构 10 | /// 11 | public static class RecursionHelper 12 | { 13 | public static void LoopToAppendChildren(List all, PermissionTree curItem, int pid, bool needbtn) 14 | { 15 | 16 | var subItems = all.Where(ee => ee.Pid == curItem.value).ToList(); 17 | 18 | var btnItems = subItems.Where(ss => ss.isbtn == true).ToList(); 19 | if (subItems.Count > 0) 20 | { 21 | curItem.btns = new List(); 22 | curItem.btns.AddRange(btnItems); 23 | } 24 | else 25 | { 26 | curItem.btns = null; 27 | } 28 | 29 | if (!needbtn) 30 | { 31 | subItems = subItems.Where(ss => ss.isbtn == false).ToList(); 32 | } 33 | if (subItems.Count > 0) 34 | { 35 | curItem.children = new List(); 36 | curItem.children.AddRange(subItems); 37 | } 38 | else 39 | { 40 | curItem.children = null; 41 | } 42 | 43 | if (curItem.isbtn) 44 | { 45 | //curItem.label += "按钮"; 46 | } 47 | 48 | foreach (var subItem in subItems) 49 | { 50 | if (subItem.value == pid && pid > 0) 51 | { 52 | //subItem.disabled = true;//禁用当前节点 53 | } 54 | LoopToAppendChildren(all, subItem, pid, needbtn); 55 | } 56 | } 57 | 58 | 59 | 60 | public static void LoopNaviBarAppendChildren(List all, NavigationBar curItem) 61 | { 62 | 63 | var subItems = all.Where(ee => ee.pid == curItem.id).ToList(); 64 | 65 | if (subItems.Count > 0) 66 | { 67 | curItem.children = new List(); 68 | curItem.children.AddRange(subItems); 69 | } 70 | else 71 | { 72 | curItem.children = null; 73 | } 74 | 75 | 76 | foreach (var subItem in subItems) 77 | { 78 | LoopNaviBarAppendChildren(all, subItem); 79 | } 80 | } 81 | 82 | 83 | 84 | public static void LoopToAppendChildrenT(List all, T curItem, string parentIdName = "Pid", string idName = "value", string childrenName = "children") 85 | { 86 | var subItems = all.Where(ee => ee.GetType().GetProperty(parentIdName).GetValue(ee, null).ToString() == curItem.GetType().GetProperty(idName).GetValue(curItem, null).ToString()).ToList(); 87 | 88 | if (subItems.Count > 0) curItem.GetType().GetField(childrenName).SetValue(curItem, subItems); 89 | foreach (var subItem in subItems) 90 | { 91 | LoopToAppendChildrenT(all, subItem); 92 | } 93 | } 94 | } 95 | 96 | public class PermissionTree 97 | { 98 | public int value { get; set; } 99 | public int Pid { get; set; } 100 | public string label { get; set; } 101 | public int order { get; set; } 102 | public bool isbtn { get; set; } 103 | public bool disabled { get; set; } 104 | public List children { get; set; } 105 | public List btns { get; set; } 106 | } 107 | public class NavigationBar 108 | { 109 | public int id { get; set; } 110 | public int pid { get; set; } 111 | public int order { get; set; } 112 | public string name { get; set; } 113 | public string path { get; set; } 114 | public string iconCls { get; set; } 115 | public NavigationBarMeta meta { get; set; } 116 | public List children { get; set; } 117 | } 118 | 119 | public class NavigationBarMeta 120 | { 121 | public string title { get; set; } 122 | public bool requireAuth { get; set; } = true; 123 | 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Common/Helper/SerializeHelper.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Blog.Core.Common 9 | { 10 | public class SerializeHelper 11 | { 12 | /// 13 | /// 序列化 14 | /// 15 | /// 16 | /// 17 | public static byte[] Serialize(object item) 18 | { 19 | var jsonString = JsonConvert.SerializeObject(item); 20 | 21 | return Encoding.UTF8.GetBytes(jsonString); 22 | } 23 | /// 24 | /// 反序列化 25 | /// 26 | /// 27 | /// 28 | /// 29 | public static TEntity Deserialize(byte[] value) 30 | { 31 | if (value == null) 32 | { 33 | return default(TEntity); 34 | } 35 | var jsonString = Encoding.UTF8.GetString(value); 36 | return JsonConvert.DeserializeObject(jsonString); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Blog.Core_Repository/CoreAPIXml/AppCore.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AppCore 5 | 6 | 7 | 8 | 9 | 获取值 10 | 11 | 12 | 13 | 14 | 15 | 根据id获取 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 | -------------------------------------------------------------------------------- /Blog.Core_Repository/IRepository/BASE/IBaseRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace IRepository.BASE 8 | { 9 | public interface IBaseRepository where TEntity : class 10 | { 11 | Task QueryByID(object objId); 12 | Task QueryByID(object objId, bool blnUseCache = false); 13 | Task> QueryByIDs(object[] lstIds); 14 | 15 | Task Add(TEntity model); 16 | 17 | Task DeleteById(object id); 18 | 19 | Task Delete(TEntity model); 20 | 21 | Task DeleteByIds(object[] ids); 22 | 23 | Task Update(TEntity model); 24 | Task Update(TEntity entity, string strWhere); 25 | Task Update(TEntity entity, List lstColumns = null, List lstIgnoreColumns = null, string strWhere = ""); 26 | 27 | Task> Query(); 28 | Task> Query(string strWhere); 29 | Task> Query(Expression> whereExpression); 30 | Task> Query(Expression> whereExpression, string strOrderByFileds); 31 | Task> Query(Expression> whereExpression, Expression> orderByExpression, bool isAsc = true); 32 | Task> Query(string strWhere, string strOrderByFileds); 33 | Task> Query(Expression> whereExpression, int intTop, string strOrderByFileds); 34 | Task> Query(string strWhere, int intTop, string strOrderByFileds); 35 | Task> Query( 36 | Expression> whereExpression, int intPageIndex, int intPageSize, string strOrderByFileds); 37 | Task> Query(string strWhere, int intPageIndex, int intPageSize, string strOrderByFileds); 38 | Task> QueryPage(Expression> whereExpression, int intPageIndex = 0, int intPageSize = 20, string strOrderByFileds = null); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Blog.Core_Repository/IRepository/IRepository.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Blog.Core_Repository/IRepository/ISysSampleRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Text; 5 | using IRepository.BASE; 6 | using Model; 7 | 8 | 9 | namespace IRepository 10 | { 11 | public interface ISysSampleRepository: IBaseRepository 12 | { 13 | int Sum(int i,int j); 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Blog.Core_Repository/IServices/BASE/IBaseServices.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace IServices.BASE 8 | { 9 | public interface IBaseServices where TEntity : class 10 | { 11 | Task QueryByID(object objId); 12 | Task QueryByID(object objId, bool blnUseCache = false); 13 | Task> QueryByIDs(object[] lstIds); 14 | 15 | Task Add(TEntity model); 16 | 17 | Task DeleteById(object id); 18 | 19 | Task Delete(TEntity model); 20 | 21 | Task DeleteByIds(object[] ids); 22 | 23 | Task Update(TEntity model); 24 | Task Update(TEntity entity, string strWhere); 25 | 26 | Task Update(TEntity entity, List lstColumns = null, List lstIgnoreColumns = null, string strWhere = ""); 27 | 28 | Task> Query(); 29 | Task> Query(string strWhere); 30 | Task> Query(Expression> whereExpression); 31 | Task> Query(Expression> whereExpression, string strOrderByFileds); 32 | Task> Query(Expression> whereExpression, Expression> orderByExpression, bool isAsc = true); 33 | Task> Query(string strWhere, string strOrderByFileds); 34 | 35 | Task> Query(Expression> whereExpression, int intTop, string strOrderByFileds); 36 | Task> Query(string strWhere, int intTop, string strOrderByFileds); 37 | 38 | Task> Query( 39 | Expression> whereExpression, int intPageIndex, int intPageSize, string strOrderByFileds); 40 | Task> Query(string strWhere, int intPageIndex, int intPageSize, string strOrderByFileds); 41 | 42 | 43 | Task> QueryPage(Expression> whereExpression, int intPageIndex = 0, int intPageSize = 20, string strOrderByFileds = null); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Blog.Core_Repository/IServices/IServices.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Blog.Core_Repository/IServices/ISysSampleServices.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Text; 5 | using Model; 6 | using IServices.BASE; 7 | 8 | namespace IServices 9 | { 10 | public interface ISysSampleServices:IBaseServices 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Model/Common/MessageModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Model.Common 6 | { 7 | 8 | /// 9 | /// 消息实体类 10 | /// 11 | public class MessageModel 12 | { 13 | /// 14 | /// 操作是否成功 15 | /// 16 | public bool Success { get; set; } 17 | /// 18 | /// 返回信息 19 | /// 20 | public string Msg { get; set; } 21 | /// 22 | /// 返回数据集合 23 | /// 24 | public List Data { get; set; } 25 | 26 | } 27 | 28 | public class LayUITableModel 29 | { 30 | /// 31 | /// 操作是否成功 0成功 1失败 32 | /// 33 | public int code { get; set; } 34 | /// 35 | /// 返回信息 36 | /// 37 | public string msg { get; set; } 38 | /// 39 | /// 返回数据集数量 40 | /// 41 | public int count { get; set; } 42 | /// 43 | /// 返回数据集合 44 | /// 45 | public List data { get; set; } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Model/Model.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 1701;1702;1591 9 | ..\AppCore\CoreAPIXml\model.xml 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Model/SysSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Model 4 | { 5 | /// 6 | /// 测试 7 | /// 8 | public class SysSample 9 | { 10 | /// 11 | /// 标识 12 | /// 13 | public string id { get; set; } 14 | 15 | /// 16 | /// 名称 17 | /// 18 | public string name { get; set; } 19 | 20 | /// 21 | /// 年龄 22 | /// 23 | public int age { get; set; } 24 | 25 | /// 26 | /// 生日 27 | /// 28 | public DateTime bir { get; set; } 29 | 30 | /// 31 | /// 图片 32 | /// 33 | public string photo { get; set; } 34 | 35 | /// 36 | /// 说明 37 | /// 38 | public string note { get; set; } 39 | 40 | /// 41 | /// 创建时间 42 | /// 43 | public DateTime createtime { get; set; } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Model/UtilConvert.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | namespace Model 6 | { 7 | /// 8 | /// 9 | /// 10 | public static class UtilConvert 11 | { 12 | /// 13 | /// 14 | /// 15 | /// 16 | /// 17 | public static int ObjToInt(this object thisValue) 18 | { 19 | int reval = 0; 20 | if (thisValue == null) return 0; 21 | if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval)) 22 | { 23 | return reval; 24 | } 25 | return reval; 26 | } 27 | /// 28 | /// 29 | /// 30 | /// 31 | /// 32 | /// 33 | public static int ObjToInt(this object thisValue, int errorValue) 34 | { 35 | int reval = 0; 36 | if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval)) 37 | { 38 | return reval; 39 | } 40 | return errorValue; 41 | } 42 | /// 43 | /// 44 | /// 45 | /// 46 | /// 47 | public static double ObjToMoney(this object thisValue) 48 | { 49 | double reval = 0; 50 | if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval)) 51 | { 52 | return reval; 53 | } 54 | return 0; 55 | } 56 | /// 57 | /// 58 | /// 59 | /// 60 | /// 61 | /// 62 | public static double ObjToMoney(this object thisValue, double errorValue) 63 | { 64 | double reval = 0; 65 | if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval)) 66 | { 67 | return reval; 68 | } 69 | return errorValue; 70 | } 71 | /// 72 | /// 73 | /// 74 | /// 75 | /// 76 | public static string ObjToString(this object thisValue) 77 | { 78 | if (thisValue != null) return thisValue.ToString().Trim(); 79 | return ""; 80 | } 81 | /// 82 | /// 83 | /// 84 | /// 85 | /// 86 | /// 87 | public static string ObjToString(this object thisValue, string errorValue) 88 | { 89 | if (thisValue != null) return thisValue.ToString().Trim(); 90 | return errorValue; 91 | } 92 | /// 93 | /// 94 | /// 95 | /// 96 | /// 97 | public static Decimal ObjToDecimal(this object thisValue) 98 | { 99 | Decimal reval = 0; 100 | if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval)) 101 | { 102 | return reval; 103 | } 104 | return 0; 105 | } 106 | /// 107 | /// 108 | /// 109 | /// 110 | /// 111 | /// 112 | public static Decimal ObjToDecimal(this object thisValue, decimal errorValue) 113 | { 114 | Decimal reval = 0; 115 | if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval)) 116 | { 117 | return reval; 118 | } 119 | return errorValue; 120 | } 121 | /// 122 | /// 123 | /// 124 | /// 125 | /// 126 | public static DateTime ObjToDate(this object thisValue) 127 | { 128 | DateTime reval = DateTime.MinValue; 129 | if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) 130 | { 131 | reval = Convert.ToDateTime(thisValue); 132 | } 133 | return reval; 134 | } 135 | /// 136 | /// 137 | /// 138 | /// 139 | /// 140 | /// 141 | public static DateTime ObjToDate(this object thisValue, DateTime errorValue) 142 | { 143 | DateTime reval = DateTime.MinValue; 144 | if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) 145 | { 146 | return reval; 147 | } 148 | return errorValue; 149 | } 150 | /// 151 | /// 152 | /// 153 | /// 154 | /// 155 | public static bool ObjToBool(this object thisValue) 156 | { 157 | bool reval = false; 158 | if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval)) 159 | { 160 | return reval; 161 | } 162 | return reval; 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /Blog.Core_Repository/ProjectCore.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.421 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppCore", "AppCore\AppCore.csproj", "{76AADD4B-FAAD-4C11-938F-E99C534A64E8}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model", "Model\Model.csproj", "{35584B6F-2C03-4E6B-B582-3A955166CACD}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common", "Common\Common.csproj", "{F2776822-08CF-4369-897B-FF34403087AE}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRepository", "IRepository\IRepository.csproj", "{97B9568F-C07A-44A4-9F6F-82B0FCFCF72F}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Repository", "Repository\Repository.csproj", "{E61E1EED-EB17-47F8-B162-C937B6424F3B}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IServices", "IServices\IServices.csproj", "{CAD4A598-9BD8-4A5A-971A-D8A4531E9993}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Services", "Services\Services.csproj", "{0079EBEA-223D-43AA-A8A0-E62635962620}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {76AADD4B-FAAD-4C11-938F-E99C534A64E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {76AADD4B-FAAD-4C11-938F-E99C534A64E8}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {76AADD4B-FAAD-4C11-938F-E99C534A64E8}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {76AADD4B-FAAD-4C11-938F-E99C534A64E8}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {35584B6F-2C03-4E6B-B582-3A955166CACD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {35584B6F-2C03-4E6B-B582-3A955166CACD}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {35584B6F-2C03-4E6B-B582-3A955166CACD}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {35584B6F-2C03-4E6B-B582-3A955166CACD}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {F2776822-08CF-4369-897B-FF34403087AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {F2776822-08CF-4369-897B-FF34403087AE}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {F2776822-08CF-4369-897B-FF34403087AE}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {F2776822-08CF-4369-897B-FF34403087AE}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {97B9568F-C07A-44A4-9F6F-82B0FCFCF72F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {97B9568F-C07A-44A4-9F6F-82B0FCFCF72F}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {97B9568F-C07A-44A4-9F6F-82B0FCFCF72F}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {97B9568F-C07A-44A4-9F6F-82B0FCFCF72F}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {E61E1EED-EB17-47F8-B162-C937B6424F3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {E61E1EED-EB17-47F8-B162-C937B6424F3B}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {E61E1EED-EB17-47F8-B162-C937B6424F3B}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {E61E1EED-EB17-47F8-B162-C937B6424F3B}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {CAD4A598-9BD8-4A5A-971A-D8A4531E9993}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {CAD4A598-9BD8-4A5A-971A-D8A4531E9993}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {CAD4A598-9BD8-4A5A-971A-D8A4531E9993}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {CAD4A598-9BD8-4A5A-971A-D8A4531E9993}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {0079EBEA-223D-43AA-A8A0-E62635962620}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {0079EBEA-223D-43AA-A8A0-E62635962620}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {0079EBEA-223D-43AA-A8A0-E62635962620}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {0079EBEA-223D-43AA-A8A0-E62635962620}.Release|Any CPU.Build.0 = Release|Any CPU 54 | EndGlobalSection 55 | GlobalSection(SolutionProperties) = preSolution 56 | HideSolutionNode = FALSE 57 | EndGlobalSection 58 | GlobalSection(ExtensibilityGlobals) = postSolution 59 | SolutionGuid = {0B09EA65-CB9C-48AD-9BC8-8A39F471995A} 60 | EndGlobalSection 61 | EndGlobal 62 | -------------------------------------------------------------------------------- /Blog.Core_Repository/README.md: -------------------------------------------------------------------------------- 1 | # BlogArti / Blog.Core_Repository 2 | 3 | 这里是将博客园《从壹开始前后端分离》的NetCore 后端项目Blog.Core 进行拆分,这是其中之一: 4 | ``` 5 | 6 | 1、Blog.Core_Repository -> API项目整体搭建 仓储模式【文章对应:06-07-08】 7 | 8 | 9 | 10 | 11 | ``` 12 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Repository/Repository.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | ..\AppCore\bin\Debug\ 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Repository/SysSampleRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Text; 5 | using SqlSugar; 6 | using IRepository; 7 | //using IRepository.BASE; 8 | using Model; 9 | using Repository.sugar; 10 | using Repository.BASE; 11 | 12 | 13 | namespace Repository 14 | { 15 | public class SysSampleRepository : BaseRepository, ISysSampleRepository 16 | { 17 | 18 | //private DbContext context; 19 | //private SqlSugarClient db; 20 | //private SimpleClient entityDB; 21 | 22 | //internal SqlSugarClient Db 23 | //{ 24 | // get { return db; } 25 | // private set { db = value; } 26 | //} 27 | //public DbContext Context 28 | //{ 29 | // get { return context; } 30 | // set { context = value; } 31 | //} 32 | //public SysSampleRepository() 33 | //{ 34 | // DbContext.Init(BaseDBConfig.ConnectionString); 35 | // context = DbContext.GetDbContext(); 36 | // db = context.Db; 37 | // entityDB = context.GetEntityDB(db); 38 | //} 39 | //public int Add(SysSample model) 40 | //{ 41 | // //返回的i是long类型,这里你可以根据你的业务需要进行处理 42 | // var i = db.Insertable(model).ExecuteReturnBigIdentity(); 43 | // //return i.ObjToInt(); 44 | // return Convert.ToInt32(i); 45 | //} 46 | 47 | //public bool Delete(SysSample model) 48 | //{ 49 | // var i = db.Deleteable(model).ExecuteCommand(); 50 | // return i > 0; 51 | //} 52 | 53 | //public List Query(Expression> whereExpression) 54 | //{ 55 | // return entityDB.GetList(whereExpression); 56 | 57 | //} 58 | 59 | public int Sum(int i, int j) 60 | { 61 | return i + j; 62 | } 63 | 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Repository/sugar/BaseDBConfig.cs: -------------------------------------------------------------------------------- 1 | using Common; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Text; 6 | 7 | namespace Repository.sugar 8 | { 9 | public class BaseDBConfig 10 | { 11 | //public static string ConnectionString = File.ReadAllText(@"D:\my-file\dbCountPsw1.txt").Trim(); 12 | 13 | //正常格式 - 因ioc注入所以不能使用 14 | //public static string ConnectionString = "server=.;uid=sa;pwd=sa;database=AppsDB_new"; 15 | 16 | //ioc注入使用 17 | public static string ConnectionString = Appsettings.app(new string[] { "AppSettings", "SqlServer", "SqlServerConnection" });//获取连接字符串 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Services/BASE/BaseServices.cs: -------------------------------------------------------------------------------- 1 | using IRepository.BASE; 2 | using IServices.BASE; 3 | using Repository.BASE; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq.Expressions; 7 | using System.Threading.Tasks; 8 | 9 | namespace Services.BASE 10 | { 11 | public class BaseServices: IBaseServices where TEntity : class, new() 12 | { 13 | public IBaseRepository baseDal = new BaseRepository(); 14 | 15 | public async Task QueryByID(object objId) 16 | { 17 | return await baseDal.QueryByID(objId); 18 | } 19 | /// 20 | /// 功能描述:根据ID查询一条数据 21 | /// 作  者:AZLinli.Blog.Core 22 | /// 23 | /// id(必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]),如果是联合主键,请使用Where条件 24 | /// 是否使用缓存 25 | /// 数据实体 26 | public async Task QueryByID(object objId, bool blnUseCache = false) 27 | { 28 | return await baseDal.QueryByID(objId, blnUseCache); 29 | } 30 | 31 | /// 32 | /// 功能描述:根据ID查询数据 33 | /// 作  者:AZLinli.Blog.Core 34 | /// 35 | /// id列表(必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]),如果是联合主键,请使用Where条件 36 | /// 数据实体列表 37 | public async Task> QueryByIDs(object[] lstIds) 38 | { 39 | return await baseDal.QueryByIDs(lstIds); 40 | } 41 | 42 | /// 43 | /// 写入实体数据 44 | /// 45 | /// 博文实体类 46 | /// 47 | public async Task Add(TEntity entity) 48 | { 49 | return await baseDal.Add(entity); 50 | } 51 | 52 | /// 53 | /// 更新实体数据 54 | /// 55 | /// 博文实体类 56 | /// 57 | public async Task Update(TEntity entity) 58 | { 59 | return await baseDal.Update(entity); 60 | } 61 | public async Task Update(TEntity entity, string strWhere) 62 | { 63 | return await baseDal.Update(entity, strWhere); 64 | } 65 | 66 | public async Task Update( 67 | TEntity entity, 68 | List lstColumns = null, 69 | List lstIgnoreColumns = null, 70 | string strWhere = "" 71 | ) 72 | { 73 | return await baseDal.Update(entity, lstColumns, lstIgnoreColumns, strWhere); 74 | } 75 | 76 | 77 | /// 78 | /// 根据实体删除一条数据 79 | /// 80 | /// 博文实体类 81 | /// 82 | public async Task Delete(TEntity entity) 83 | { 84 | return await baseDal.Delete(entity); 85 | } 86 | 87 | /// 88 | /// 删除指定ID的数据 89 | /// 90 | /// 主键ID 91 | /// 92 | public async Task DeleteById(object id) 93 | { 94 | return await baseDal.DeleteById(id); 95 | } 96 | 97 | /// 98 | /// 删除指定ID集合的数据(批量删除) 99 | /// 100 | /// 主键ID集合 101 | /// 102 | public async Task DeleteByIds(object[] ids) 103 | { 104 | return await baseDal.DeleteByIds(ids); 105 | } 106 | 107 | 108 | 109 | /// 110 | /// 功能描述:查询所有数据 111 | /// 作  者:AZLinli.Blog.Core 112 | /// 113 | /// 数据列表 114 | public async Task> Query() 115 | { 116 | return await baseDal.Query(); 117 | } 118 | 119 | /// 120 | /// 功能描述:查询数据列表 121 | /// 作  者:AZLinli.Blog.Core 122 | /// 123 | /// 条件 124 | /// 数据列表 125 | public async Task> Query(string strWhere) 126 | { 127 | return await baseDal.Query(strWhere); 128 | } 129 | 130 | /// 131 | /// 功能描述:查询数据列表 132 | /// 作  者:AZLinli.Blog.Core 133 | /// 134 | /// whereExpression 135 | /// 数据列表 136 | public async Task> Query(Expression> whereExpression) 137 | { 138 | return await baseDal.Query(whereExpression); 139 | } 140 | /// 141 | /// 功能描述:查询一个列表 142 | /// 作  者:AZLinli.Blog.Core 143 | /// 144 | /// 条件表达式 145 | /// 排序字段,如name asc,age desc 146 | /// 数据列表 147 | public async Task> Query(Expression> whereExpression, Expression> orderByExpression, bool isAsc = true) 148 | { 149 | return await baseDal.Query(whereExpression, orderByExpression, isAsc); 150 | } 151 | 152 | public async Task> Query(Expression> whereExpression, string strOrderByFileds) 153 | { 154 | return await baseDal.Query(whereExpression, strOrderByFileds); 155 | } 156 | 157 | /// 158 | /// 功能描述:查询一个列表 159 | /// 作  者:AZLinli.Blog.Core 160 | /// 161 | /// 条件 162 | /// 排序字段,如name asc,age desc 163 | /// 数据列表 164 | public async Task> Query(string strWhere, string strOrderByFileds) 165 | { 166 | return await baseDal.Query(strWhere, strOrderByFileds); 167 | } 168 | 169 | /// 170 | /// 功能描述:查询前N条数据 171 | /// 作  者:AZLinli.Blog.Core 172 | /// 173 | /// 条件表达式 174 | /// 前N条 175 | /// 排序字段,如name asc,age desc 176 | /// 数据列表 177 | public async Task> Query(Expression> whereExpression, int intTop, string strOrderByFileds) 178 | { 179 | return await baseDal.Query(whereExpression, intTop, strOrderByFileds); 180 | } 181 | 182 | /// 183 | /// 功能描述:查询前N条数据 184 | /// 作  者:AZLinli.Blog.Core 185 | /// 186 | /// 条件 187 | /// 前N条 188 | /// 排序字段,如name asc,age desc 189 | /// 数据列表 190 | public async Task> Query( 191 | string strWhere, 192 | int intTop, 193 | string strOrderByFileds) 194 | { 195 | return await baseDal.Query(strWhere, intTop, strOrderByFileds); 196 | } 197 | 198 | /// 199 | /// 功能描述:分页查询 200 | /// 作  者:AZLinli.Blog.Core 201 | /// 202 | /// 条件表达式 203 | /// 页码(下标0) 204 | /// 页大小 205 | /// 数据总量 206 | /// 排序字段,如name asc,age desc 207 | /// 数据列表 208 | public async Task> Query( 209 | Expression> whereExpression, 210 | int intPageIndex, 211 | int intPageSize, 212 | string strOrderByFileds) 213 | { 214 | return await baseDal.Query( 215 | whereExpression, 216 | intPageIndex, 217 | intPageSize, 218 | strOrderByFileds); 219 | } 220 | 221 | /// 222 | /// 功能描述:分页查询 223 | /// 作  者:AZLinli.Blog.Core 224 | /// 225 | /// 条件 226 | /// 页码(下标0) 227 | /// 页大小 228 | /// 数据总量 229 | /// 排序字段,如name asc,age desc 230 | /// 数据列表 231 | public async Task> Query( 232 | string strWhere, 233 | int intPageIndex, 234 | int intPageSize, 235 | string strOrderByFileds) 236 | { 237 | return await baseDal.Query( 238 | strWhere, 239 | intPageIndex, 240 | intPageSize, 241 | strOrderByFileds); 242 | } 243 | 244 | public async Task> QueryPage(Expression> whereExpression, 245 | int intPageIndex = 0, int intPageSize = 20, string strOrderByFileds = null) 246 | { 247 | return await baseDal.QueryPage(whereExpression, 248 | intPageIndex = 0, intPageSize, strOrderByFileds); 249 | } 250 | } 251 | } 252 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Services/Services.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | ..\AppCore\bin\Debug\ 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Blog.Core_Repository/Services/SysSampleServices.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using IServices; 5 | using IRepository; 6 | using Services.BASE; 7 | using Model; 8 | using System.Linq.Expressions; 9 | 10 | namespace Services 11 | { 12 | public class SysSampleServices : BaseServices, ISysSampleServices 13 | { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BlogArti 2 | 这里是将博客园《[从壹开始前后端分离](https://www.cnblogs.com/laozhang-is-phi/p/9495618.html#autoid-1-0-0)》的NetCore 后端项目Blog.Core 进行拆分,目前是三个部分: 3 | ``` 4 | 5 | 1、Blog.Core_Repository -> API项目整体搭建 仓储模式【文章对应:06-07-08】 6 | 7 | 2、Blog.Core_IOC&DI -> 依赖注入IoC学习【文章对应:09】 8 | 9 | 3、Blog.Core_JWT -> JWT权限验证【文章对应:05-36-37】 10 | 11 | 4、如果你还有其他的问题,或者想让我单写出来的,请联系我,我补上。 12 | 13 | ``` 14 | --------------------------------------------------------------------------------