()
24 | .ConfigureLogging(logging =>
25 | {
26 | logging.ClearProviders();
27 | logging.SetMinimumLevel(LogLevel.Trace);
28 | })
29 | .UseNLog();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/Views/Home/About.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewData["Title"] = "About";
3 | }
4 | @ViewData["Title"]
5 | @ViewData["Message"]
6 |
7 | Use this area to provide additional information.
8 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/Views/Home/Contact.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewData["Title"] = "Contact";
3 | }
4 | @ViewData["Title"]
5 | @ViewData["Message"]
6 |
7 |
8 | One Microsoft Way
9 | Redmond, WA 98052-6399
10 | P:
11 | 425.555.0100
12 |
13 |
14 |
15 | Support: Support@example.com
16 | Marketing: Marketing@example.com
17 |
18 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/Views/Home/Privacy.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewData["Title"] = "Privacy Policy";
3 | }
4 | @ViewData["Title"]
5 |
6 | Use this page to detail your site's privacy policy.
7 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/Views/Shared/Error.cshtml:
--------------------------------------------------------------------------------
1 | @model ErrorViewModel
2 | @{
3 | ViewData["Title"] = "Error";
4 | }
5 |
6 | Error.
7 | An error occurred while processing your request.
8 |
9 | @if (Model.ShowRequestId)
10 | {
11 |
12 | Request ID: @Model.RequestId
13 |
14 | }
15 |
16 | Development Mode
17 |
18 | Swapping to Development environment will display more detailed information about the error that occurred.
19 |
20 |
21 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application.
22 |
23 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/Views/Shared/_ValidationScriptsPartial.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
18 |
19 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/Views/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @using LogDemo
2 | @using LogDemo.Models
3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
4 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/Views/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "_Layout";
3 | }
4 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
9 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/nlog.config:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
18 |
19 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/css/site.css:
--------------------------------------------------------------------------------
1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\
2 | for details on configuring this project to bundle and minify static web assets. */
3 | body {
4 | padding-top: 50px;
5 | padding-bottom: 20px;
6 | }
7 |
8 | /* Wrapping element */
9 | /* Set some basic padding to keep content from hitting the edges */
10 | .body-content {
11 | padding-left: 15px;
12 | padding-right: 15px;
13 | }
14 |
15 | /* Carousel */
16 | .carousel-caption p {
17 | font-size: 20px;
18 | line-height: 1.4;
19 | }
20 |
21 | /* Make .svg files in the carousel display properly in older browsers */
22 | .carousel-inner .item img[src$=".svg"] {
23 | width: 100%;
24 | }
25 |
26 | /* QR code generator */
27 | #qrCode {
28 | margin: 15px;
29 | }
30 |
31 | /* Hide/rearrange for smaller screens */
32 | @media screen and (max-width: 767px) {
33 | /* Hide captions */
34 | .carousel-caption {
35 | display: none;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/css/site.min.css:
--------------------------------------------------------------------------------
1 | body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}}
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zdz72113/NETCore_BasicKnowledge.Examples/812e7801f015642d02aa19b327b7f692a98d1bec/LogDemo/LogDemo/wwwroot/favicon.ico
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/js/site.js:
--------------------------------------------------------------------------------
1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
2 | // for details on configuring this project to bundle and minify static web assets.
3 |
4 | // Write your JavaScript code.
5 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/js/site.min.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zdz72113/NETCore_BasicKnowledge.Examples/812e7801f015642d02aa19b327b7f692a98d1bec/LogDemo/LogDemo/wwwroot/js/site.min.js
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/bootstrap/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bootstrap",
3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
4 | "keywords": [
5 | "css",
6 | "js",
7 | "less",
8 | "mobile-first",
9 | "responsive",
10 | "front-end",
11 | "framework",
12 | "web"
13 | ],
14 | "homepage": "http://getbootstrap.com",
15 | "license": "MIT",
16 | "moduleType": "globals",
17 | "main": [
18 | "less/bootstrap.less",
19 | "dist/js/bootstrap.js"
20 | ],
21 | "ignore": [
22 | "/.*",
23 | "_config.yml",
24 | "CNAME",
25 | "composer.json",
26 | "CONTRIBUTING.md",
27 | "docs",
28 | "js/tests",
29 | "test-infra"
30 | ],
31 | "dependencies": {
32 | "jquery": "1.9.1 - 3"
33 | },
34 | "version": "3.3.7",
35 | "_release": "3.3.7",
36 | "_resolution": {
37 | "type": "version",
38 | "tag": "v3.3.7",
39 | "commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
40 | },
41 | "_source": "https://github.com/twbs/bootstrap.git",
42 | "_target": "v3.3.7",
43 | "_originalSource": "bootstrap",
44 | "_direct": true
45 | }
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/bootstrap/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2011-2016 Twitter, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zdz72113/NETCore_BasicKnowledge.Examples/812e7801f015642d02aa19b327b7f692a98d1bec/LogDemo/LogDemo/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zdz72113/NETCore_BasicKnowledge.Examples/812e7801f015642d02aa19b327b7f692a98d1bec/LogDemo/LogDemo/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zdz72113/NETCore_BasicKnowledge.Examples/812e7801f015642d02aa19b327b7f692a98d1bec/LogDemo/LogDemo/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zdz72113/NETCore_BasicKnowledge.Examples/812e7801f015642d02aa19b327b7f692a98d1bec/LogDemo/LogDemo/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/bootstrap/dist/js/npm.js:
--------------------------------------------------------------------------------
1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
2 | require('../../js/transition.js')
3 | require('../../js/alert.js')
4 | require('../../js/button.js')
5 | require('../../js/carousel.js')
6 | require('../../js/collapse.js')
7 | require('../../js/dropdown.js')
8 | require('../../js/modal.js')
9 | require('../../js/tooltip.js')
10 | require('../../js/popover.js')
11 | require('../../js/scrollspy.js')
12 | require('../../js/tab.js')
13 | require('../../js/affix.js')
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/jquery-validation-unobtrusive/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-validation-unobtrusive",
3 | "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive",
4 | "version": "3.2.9",
5 | "_release": "3.2.9",
6 | "_resolution": {
7 | "type": "version",
8 | "tag": "v3.2.9",
9 | "commit": "a91f5401898e125f10771c5f5f0909d8c4c82396"
10 | },
11 | "_source": "https://github.com/aspnet/jquery-validation-unobtrusive.git",
12 | "_target": "^3.2.9",
13 | "_originalSource": "jquery-validation-unobtrusive",
14 | "_direct": true
15 | }
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) .NET Foundation. All rights reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4 | these files except in compliance with the License. You may obtain a copy of the
5 | License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software distributed
10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
12 | specific language governing permissions and limitations under the License.
13 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/jquery-validation/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-validation",
3 | "homepage": "https://jqueryvalidation.org/",
4 | "repository": {
5 | "type": "git",
6 | "url": "git://github.com/jquery-validation/jquery-validation.git"
7 | },
8 | "authors": [
9 | "Jörn Zaefferer "
10 | ],
11 | "description": "Form validation made easy",
12 | "main": "dist/jquery.validate.js",
13 | "keywords": [
14 | "forms",
15 | "validation",
16 | "validate"
17 | ],
18 | "license": "MIT",
19 | "ignore": [
20 | "**/.*",
21 | "node_modules",
22 | "bower_components",
23 | "test",
24 | "demo",
25 | "lib"
26 | ],
27 | "dependencies": {
28 | "jquery": ">= 1.7.2"
29 | },
30 | "version": "1.17.0",
31 | "_release": "1.17.0",
32 | "_resolution": {
33 | "type": "version",
34 | "tag": "1.17.0",
35 | "commit": "fc9b12d3bfaa2d0c04605855b896edb2934c0772"
36 | },
37 | "_source": "https://github.com/jzaefferer/jquery-validation.git",
38 | "_target": "^1.17.0",
39 | "_originalSource": "jquery-validation",
40 | "_direct": true
41 | }
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/jquery-validation/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | =====================
3 |
4 | Copyright Jörn Zaefferer
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/jquery/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery",
3 | "main": "dist/jquery.js",
4 | "license": "MIT",
5 | "ignore": [
6 | "package.json"
7 | ],
8 | "keywords": [
9 | "jquery",
10 | "javascript",
11 | "browser",
12 | "library"
13 | ],
14 | "homepage": "https://github.com/jquery/jquery-dist",
15 | "version": "3.3.1",
16 | "_release": "3.3.1",
17 | "_resolution": {
18 | "type": "version",
19 | "tag": "3.3.1",
20 | "commit": "9e8ec3d10fad04748176144f108d7355662ae75e"
21 | },
22 | "_source": "https://github.com/jquery/jquery-dist.git",
23 | "_target": "^3.3.1",
24 | "_originalSource": "jquery",
25 | "_direct": true
26 | }
--------------------------------------------------------------------------------
/LogDemo/LogDemo/wwwroot/lib/jquery/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright JS Foundation and other contributors, https://js.foundation/
2 |
3 | This software consists of voluntary contributions made by many
4 | individuals. For exact contribution history, see the revision history
5 | available at https://github.com/jquery/jquery
6 |
7 | The following license applies to all parts of this software except as
8 | documented below:
9 |
10 | ====
11 |
12 | Permission is hereby granted, free of charge, to any person obtaining
13 | a copy of this software and associated documentation files (the
14 | "Software"), to deal in the Software without restriction, including
15 | without limitation the rights to use, copy, modify, merge, publish,
16 | distribute, sublicense, and/or sell copies of the Software, and to
17 | permit persons to whom the Software is furnished to do so, subject to
18 | the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be
21 | included in all copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 |
31 | ====
32 |
33 | All files located in the node_modules and external directories are
34 | externally maintained libraries used by this software which have their
35 | own licenses; we recommend you read them, as their terms may differ from
36 | the terms above.
37 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.AutoMapperTest/ORMDemo.AutoMapperTest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.1
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper.Test/ORMDemo.Dapper.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.1
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Common/DBConfig.cs:
--------------------------------------------------------------------------------
1 | using MySql.Data.MySqlClient;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Data;
5 | using System.Data.Common;
6 | using System.Data.SqlClient;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 | using System.Configuration;
10 |
11 | namespace ORMDemo.Dapper
12 | {
13 | public class DBConfig
14 | {
15 | //ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
16 | private static string DefaultSqlConnectionString = @"server=127.0.0.1;database=ormdemo;uid=root;pwd=Open0001;SslMode=none;";
17 |
18 | public static IDbConnection GetSqlConnection(string sqlConnectionString = null)
19 | {
20 | if (string.IsNullOrWhiteSpace(sqlConnectionString))
21 | {
22 | sqlConnectionString = DefaultSqlConnectionString;
23 | }
24 | IDbConnection conn = new MySqlConnection(sqlConnectionString);
25 | conn.Open();
26 | return conn;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Common/TestDBContext.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Options;
2 | using MySql.Data.MySqlClient;
3 | using ORMDemo.Dapper.Infrastructure.Data;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Data;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 |
10 | namespace ORMDemo.Dapper.Common
11 | {
12 | public class TestDBContext : DapperDBContext
13 | {
14 | public TestDBContext(IOptions optionsAccessor) : base(optionsAccessor)
15 | {
16 | }
17 |
18 | protected override IDbConnection CreateConnection(string connectionString)
19 | {
20 | IDbConnection conn = new MySqlConnection(connectionString);
21 | return conn;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Infrastructure/Data/DapperDBContextOptions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Options;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace ORMDemo.Dapper.Infrastructure.Data
8 | {
9 | public class DapperDBContextOptions : IOptions
10 | {
11 | public string Configuration { get; set; }
12 |
13 | DapperDBContextOptions IOptions.Value
14 | {
15 | get { return this; }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Infrastructure/Data/DapperDBContextServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace ORMDemo.Dapper.Infrastructure.Data
8 | {
9 | public static class DapperDBContextServiceCollectionExtensions
10 | {
11 | public static IServiceCollection AddDapperDBContext(this IServiceCollection services, Action setupAction) where T : DapperDBContext
12 | {
13 | if (services == null)
14 | {
15 | throw new ArgumentNullException(nameof(services));
16 | }
17 |
18 | if (setupAction == null)
19 | {
20 | throw new ArgumentNullException(nameof(setupAction));
21 | }
22 |
23 | services.AddOptions();
24 | services.Configure(setupAction);
25 | services.AddScoped();
26 | services.AddScoped();
27 |
28 | return services;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Infrastructure/Data/DapperUnitOfWorkFactory.cs:
--------------------------------------------------------------------------------
1 | using ORMDemo.Dapper.Infrastructure.Data;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace ORMDemo.Dapper.Infrastructure.Data
8 | {
9 | public class DapperUnitOfWorkFactory : IUnitOfWorkFactory
10 | {
11 | private readonly DapperDBContext _context;
12 |
13 | public DapperUnitOfWorkFactory(DapperDBContext context)
14 | {
15 | _context = context;
16 | }
17 |
18 | public IUnitOfWork Create()
19 | {
20 | return new UnitOfWork(_context);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Infrastructure/Data/IContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace ORMDemo.Dapper.Infrastructure.Data
7 | {
8 | public interface IContext : IDisposable
9 | {
10 | bool IsTransactionStarted { get; }
11 |
12 | void BeginTransaction();
13 |
14 | void Commit();
15 |
16 | void Rollback();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Infrastructure/Data/IUnitOfWork.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace ORMDemo.Dapper.Infrastructure.Data
8 | {
9 | public interface IUnitOfWork : IDisposable
10 | {
11 | void SaveChanges();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Infrastructure/Data/IUnitOfWorkFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace ORMDemo.Dapper.Infrastructure.Data
7 | {
8 | public interface IUnitOfWorkFactory
9 | {
10 | IUnitOfWork Create();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Infrastructure/Data/UnitOfWork.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data;
3 |
4 | namespace ORMDemo.Dapper.Infrastructure.Data
5 | {
6 | public class UnitOfWork : IUnitOfWork
7 | {
8 | private readonly IContext _context;
9 |
10 | public UnitOfWork(IContext context)
11 | {
12 | _context = context;
13 | _context.BeginTransaction();
14 | }
15 |
16 | public void SaveChanges()
17 | {
18 | if (!_context.IsTransactionStarted)
19 | throw new InvalidOperationException("Transaction have already been commited or disposed.");
20 |
21 | _context.Commit();
22 | }
23 |
24 | public void Dispose()
25 | {
26 | if (_context.IsTransactionStarted)
27 | _context.Rollback();
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Model/Category.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace ORMDemo.Dapper.Model
7 | {
8 | public class Category
9 | {
10 | public int Id { get; set; }
11 |
12 | public string Name { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Model/Product.cs:
--------------------------------------------------------------------------------
1 | using Dapper.Contrib.Extensions;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace ORMDemo.Dapper.Model
8 | {
9 | [Table("Product")]
10 | public class Product
11 | {
12 | [Key]
13 | public int Id { get; set; }
14 |
15 | public string Name { get; set; }
16 |
17 | public int Quantity { get; set; }
18 |
19 | public decimal Price { get; set; }
20 |
21 | public int CategoryId { get; set; }
22 |
23 | public virtual Category Category { get; set; }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/ORMDemo.Dapper.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 | 89e852ea-c7e1-45c5-9c66-0f93bebf365f
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/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 ORMDemo.Dapper
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 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Repository/ContribProductRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Dapper.Contrib.Extensions;
7 | using ORMDemo.Dapper.Model;
8 |
9 | namespace ORMDemo.Dapper.Repository
10 | {
11 | public class ContribProductRepository : IProductRepository
12 | {
13 | public async Task AddAsync(Product prod)
14 | {
15 | using (IDbConnection conn = DBConfig.GetSqlConnection())
16 | {
17 | return await conn.InsertAsync(prod) > 0;
18 | }
19 | }
20 |
21 | public async Task> GetAllAsync()
22 | {
23 | using (IDbConnection conn = DBConfig.GetSqlConnection())
24 | {
25 | return await conn.GetAllAsync();
26 | }
27 | }
28 |
29 | public async Task GetByIDAsync(int id)
30 | {
31 | using (IDbConnection conn = DBConfig.GetSqlConnection())
32 | {
33 | return await conn.GetAsync(id);
34 | }
35 | }
36 |
37 | public async Task DeleteAsync(int id)
38 | {
39 | using (IDbConnection conn = DBConfig.GetSqlConnection())
40 | {
41 | var entity = await conn.GetAsync(id);
42 | return await conn.DeleteAsync(entity);
43 | }
44 | }
45 |
46 | public async Task UpdateAsync(Product prod)
47 | {
48 | using (IDbConnection conn = DBConfig.GetSqlConnection())
49 | {
50 | return await conn.UpdateAsync(prod);
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Repository/ICategoryRepository.cs:
--------------------------------------------------------------------------------
1 | using ORMDemo.Dapper.Model;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 |
5 | namespace ORMDemo.Dapper.Repository
6 | {
7 | public interface ICategoryRepository
8 | {
9 | Task AddAsync(Category prod);
10 | Task> GetAllAsync();
11 | Task GetByIDAsync(int id);
12 | Task DeleteAsync(int id);
13 | Task UpdateAsync(Category prod);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/Repository/IProductRepository.cs:
--------------------------------------------------------------------------------
1 | using ORMDemo.Dapper.Model;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace ORMDemo.Dapper.Repository
8 | {
9 | public interface IProductRepository
10 | {
11 | Task AddAsync(Product prod);
12 | Task> GetAllAsync();
13 | Task GetByIDAsync(int id);
14 | Task DeleteAsync(int id);
15 | Task UpdateAsync(Product prod);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.Dapper/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
9 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/BloggingContext .cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.Extensions.Logging;
3 | using ORMDemo.EF.Model;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 |
9 | namespace ORMDemo.EF
10 | {
11 | public class BloggingContext : DbContext
12 | {
13 | public BloggingContext(DbContextOptions options)
14 | : base(options)
15 | {
16 | //Database.Migrate();
17 | }
18 |
19 | public DbSet Blogs { get; set; }
20 | public DbSet Tags { get; set; }
21 | public DbSet BlogTags { get; set; }
22 | public DbSet Posts { get; set; }
23 | public DbSet PostExtensions { get; set; }
24 |
25 | //private static ILoggerFactory Mlogger => new LoggerFactory()
26 | // .AddDebug((categoryName, logLevel) => (logLevel == LogLevel.Information) && (categoryName == DbLoggerCategory.Database.Command.Name))
27 | // .AddConsole((categoryName, logLevel) => (logLevel == LogLevel.Information) && (categoryName == DbLoggerCategory.Database.Command.Name));
28 |
29 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
30 | {
31 | //optionsBuilder.UseLoggerFactory(Mlogger);
32 | //optionsBuilder.EnableSensitiveDataLogging();
33 | }
34 |
35 | protected override void OnModelCreating(ModelBuilder modelBuilder)
36 | {
37 | base.OnModelCreating(modelBuilder);
38 |
39 | modelBuilder.ApplyConfiguration(new BlogConfiguration());
40 | modelBuilder.ApplyConfiguration(new TagConfiguration());
41 | modelBuilder.ApplyConfiguration(new BlogTagConfiguration());
42 | modelBuilder.ApplyConfiguration(new PostConfiguration());
43 | modelBuilder.ApplyConfiguration(new PostExtensionConfiguration());
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/Controllers/ValuesController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace ORMDemo.EF.Controllers
8 | {
9 | [Route("api/[controller]")]
10 | [ApiController]
11 | public class ValuesController : ControllerBase
12 | {
13 | // GET api/values
14 | [HttpGet]
15 | public ActionResult> Get()
16 | {
17 | return new string[] { "value1", "value2" };
18 | }
19 |
20 | // GET api/values/5
21 | [HttpGet("{id}")]
22 | public ActionResult Get(int id)
23 | {
24 | return "value";
25 | }
26 |
27 | // POST api/values
28 | [HttpPost]
29 | public void Post([FromBody] string value)
30 | {
31 | }
32 |
33 | // PUT api/values/5
34 | [HttpPut("{id}")]
35 | public void Put(int id, [FromBody] string value)
36 | {
37 | }
38 |
39 | // DELETE api/values/5
40 | [HttpDelete("{id}")]
41 | public void Delete(int id)
42 | {
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/Migrations/20180914063208_TestSeedData.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore.Migrations;
2 |
3 | namespace ORMDemo.EF.Migrations
4 | {
5 | public partial class TestSeedData : Migration
6 | {
7 | protected override void Up(MigrationBuilder migrationBuilder)
8 | {
9 | migrationBuilder.InsertData(
10 | table: "Blogs",
11 | columns: new[] { "BlogId", "Rating", "Url" },
12 | values: new object[] { 1, 0, "http://sample.com/1" });
13 | }
14 |
15 | protected override void Down(MigrationBuilder migrationBuilder)
16 | {
17 | migrationBuilder.DeleteData(
18 | table: "Blogs",
19 | keyColumn: "BlogId",
20 | keyValue: 1);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/Migrations/20180917023248_TestConcurrencyCheck.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore.Migrations;
2 |
3 | namespace ORMDemo.EF.Migrations
4 | {
5 | public partial class TestConcurrencyCheck : Migration
6 | {
7 | protected override void Up(MigrationBuilder migrationBuilder)
8 | {
9 |
10 | }
11 |
12 | protected override void Down(MigrationBuilder migrationBuilder)
13 | {
14 |
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/Migrations/20180917063249_TestTimestamp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.EntityFrameworkCore.Migrations;
3 |
4 | namespace ORMDemo.EF.Migrations
5 | {
6 | public partial class TestTimestamp : Migration
7 | {
8 | protected override void Up(MigrationBuilder migrationBuilder)
9 | {
10 | migrationBuilder.AddColumn(
11 | name: "Timestamp",
12 | table: "Blogs",
13 | rowVersion: true,
14 | nullable: true);
15 | }
16 |
17 | protected override void Down(MigrationBuilder migrationBuilder)
18 | {
19 | migrationBuilder.DropColumn(
20 | name: "Timestamp",
21 | table: "Blogs");
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/Model/Blog.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.ComponentModel.DataAnnotations;
6 | using System.ComponentModel.DataAnnotations.Schema;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 |
10 | namespace ORMDemo.EF.Model
11 | {
12 | public class Blog
13 | {
14 | [Key]
15 | [Column("BlogId")]
16 | public int BlogId { get; set; }
17 | [Required]
18 | [MaxLength(500)]
19 | public string Url { get; set; }
20 |
21 | //[ConcurrencyCheck]
22 | public int Rating { get; set; }
23 |
24 | [Timestamp]
25 | public byte[] Timestamp { get; set; }
26 |
27 | public virtual IList Posts { get; set; }
28 |
29 | public virtual IList BlogTags { get; set; }
30 | }
31 |
32 | public class BlogConfiguration : IEntityTypeConfiguration
33 | {
34 | public void Configure(EntityTypeBuilder builder)
35 | {
36 | builder.HasKey(t => t.BlogId);
37 |
38 | builder.Property(t => t.Url).HasColumnName("Url").HasMaxLength(500).IsRequired();
39 |
40 | //Data Seeding
41 | builder.HasData(new Blog { BlogId = 1, Url = "http://sample.com/1", Rating = 0 });
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/Model/BlogTag.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 | namespace ORMDemo.EF.Model
9 | {
10 | public class BlogTag
11 | {
12 | public int BlogId { get; set; }
13 | public virtual Blog Blog { get; set; }
14 |
15 | public int TagId { get; set; }
16 | public virtual Tag Tag { get; set; }
17 | }
18 |
19 | public class BlogTagConfiguration : IEntityTypeConfiguration
20 | {
21 | public void Configure(EntityTypeBuilder builder)
22 | {
23 | builder.HasKey(bt => new { bt.BlogId, bt.TagId });
24 |
25 | builder.HasOne(bt => bt.Blog)
26 | .WithMany(b => b.BlogTags)
27 | .HasForeignKey(bt => bt.BlogId);
28 |
29 | builder.HasOne(bt => bt.Tag)
30 | .WithMany(t => t.BlogTags)
31 | .HasForeignKey(bt => bt.TagId);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/Model/Post.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 | namespace ORMDemo.EF.Model
9 | {
10 | public class Post
11 | {
12 | public int PostId { get; set; }
13 | public string Title { get; set; }
14 | public string Content { get; set; }
15 |
16 | public int BlogId { get; set; }
17 | public virtual Blog Blog { get; set; }
18 |
19 | public virtual PostExtension Extension { get; set; }
20 | }
21 |
22 | public class PostConfiguration : IEntityTypeConfiguration
23 | {
24 | public PostConfiguration()
25 | {
26 |
27 | }
28 |
29 | public void Configure(EntityTypeBuilder builder)
30 | {
31 | builder.HasKey(t => t.PostId);
32 |
33 | builder.Property(t => t.Title).HasMaxLength(100).IsRequired();
34 |
35 | builder.Property(t => t.Content).HasMaxLength(500);
36 |
37 | builder.HasOne(p => p.Blog)
38 | .WithMany(b => b.Posts)
39 | .HasForeignKey(p => p.BlogId)
40 | .OnDelete(DeleteBehavior.Cascade);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/Model/PostExtension.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 | namespace ORMDemo.EF.Model
9 | {
10 | public class PostExtension
11 | {
12 | public int PostId { get; set; }
13 | public string ExtensionField1 { get; set; }
14 |
15 | public virtual Post Post { get; set; }
16 | }
17 |
18 | public class PostExtensionConfiguration : IEntityTypeConfiguration
19 | {
20 | public PostExtensionConfiguration()
21 | {
22 |
23 | }
24 |
25 | public void Configure(EntityTypeBuilder builder)
26 | {
27 | builder.HasKey(t => t.PostId);
28 |
29 | //builder.HasOne(e => e.Post)
30 | // .WithOne(p => p.Extension)
31 | // .HasForeignKey(e => e.PostId)
32 | // .OnDelete(DeleteBehavior.Cascade);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/Model/Tag.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 | namespace ORMDemo.EF.Model
9 | {
10 | public class Tag
11 | {
12 | public int TagId { get; set; }
13 | public string TagName { get; set; }
14 |
15 | public virtual IList BlogTags { get; set; }
16 | }
17 |
18 | public class TagConfiguration : IEntityTypeConfiguration
19 | {
20 | public void Configure(EntityTypeBuilder builder)
21 | {
22 | builder.Property(t => t.TagName).HasMaxLength(20).IsRequired();
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/ORMDemo.EF.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/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.DependencyInjection;
10 | using Microsoft.Extensions.Logging;
11 |
12 | namespace ORMDemo.EF
13 | {
14 | public class Program
15 | {
16 | public static void Main(string[] args)
17 | {
18 | //CreateWebHostBuilder(args).Build().Run();
19 | var host = CreateWebHostBuilder(args).Build();
20 |
21 | using (var scope = host.Services.CreateScope())
22 | {
23 | var services = scope.ServiceProvider;
24 | try
25 | {
26 | SeedData.Initialize(services);
27 | }
28 | catch (Exception ex)
29 | {
30 | var logger = services.GetRequiredService>();
31 | logger.LogError(ex, "An error occurred seeding the DB.");
32 | }
33 | }
34 |
35 | host.Run();
36 | }
37 |
38 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
39 | WebHost.CreateDefaultBuilder(args)
40 | .UseStartup();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/SeedData.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using ORMDemo.EF.Model;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 |
9 | namespace ORMDemo.EF
10 | {
11 | public static class SeedData
12 | {
13 | public static void Initialize(IServiceProvider serviceProvider)
14 | {
15 | using (var context = new BloggingContext(
16 | serviceProvider.GetRequiredService>()))
17 | {
18 | if (context.Blogs.Any())
19 | return; // DB has been seeded
20 |
21 | var blogs = new List
22 | {
23 | new Blog
24 | {
25 | Url = "http://sample.com/2",
26 | Rating = 0
27 | },
28 | new Blog
29 | {
30 | Url = "http://sample.com/3",
31 | Rating = 0
32 | },
33 | new Blog
34 | {
35 | Url = "http://sample.com/4",
36 | Rating = 0
37 | }
38 | };
39 |
40 | context.Blogs.AddRange(blogs);
41 | context.SaveChanges();
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EF/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
9 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFDBFirst/Controllers/ValuesController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace ORMDemo.EFDBFirst.Controllers
8 | {
9 | [Route("api/[controller]")]
10 | [ApiController]
11 | public class ValuesController : ControllerBase
12 | {
13 | // GET api/values
14 | [HttpGet]
15 | public ActionResult> Get()
16 | {
17 | return new string[] { "value1", "value2" };
18 | }
19 |
20 | // GET api/values/5
21 | [HttpGet("{id}")]
22 | public ActionResult Get(int id)
23 | {
24 | return "value";
25 | }
26 |
27 | // POST api/values
28 | [HttpPost]
29 | public void Post([FromBody] string value)
30 | {
31 | }
32 |
33 | // PUT api/values/5
34 | [HttpPut("{id}")]
35 | public void Put(int id, [FromBody] string value)
36 | {
37 | }
38 |
39 | // DELETE api/values/5
40 | [HttpDelete("{id}")]
41 | public void Delete(int id)
42 | {
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFDBFirst/Models/Blogs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace ORMDemo.EFDBFirst.Models
5 | {
6 | public partial class Blogs
7 | {
8 | public Blogs()
9 | {
10 | Posts = new HashSet();
11 | }
12 |
13 | public int Id { get; set; }
14 | public string Url { get; set; }
15 | public int Rating { get; set; }
16 |
17 | public virtual ICollection Posts { get; set; }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFDBFirst/Models/Posts.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace ORMDemo.EFDBFirst.Models
5 | {
6 | public partial class Posts
7 | {
8 | public int Id { get; set; }
9 | public string Title { get; set; }
10 | public string Content { get; set; }
11 | public int BlogId { get; set; }
12 |
13 | public virtual Blogs Blog { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFDBFirst/ORMDemo.EFDBFirst.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFDBFirst/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 ORMDemo.EFDBFirst
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 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFDBFirst/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Builder;
6 | using Microsoft.AspNetCore.Hosting;
7 | using Microsoft.AspNetCore.Mvc;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.DependencyInjection;
10 | using Microsoft.Extensions.Logging;
11 | using Microsoft.Extensions.Options;
12 |
13 | namespace ORMDemo.EFDBFirst
14 | {
15 | public class Startup
16 | {
17 | public Startup(IConfiguration configuration)
18 | {
19 | Configuration = configuration;
20 | }
21 |
22 | public IConfiguration Configuration { get; }
23 |
24 | // This method gets called by the runtime. Use this method to add services to the container.
25 | public void ConfigureServices(IServiceCollection services)
26 | {
27 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
28 | }
29 |
30 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
31 | public void Configure(IApplicationBuilder app, IHostingEnvironment env)
32 | {
33 | if (env.IsDevelopment())
34 | {
35 | app.UseDeveloperExceptionPage();
36 | }
37 |
38 | app.UseMvc();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFDBFirst/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFDBFirst/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
9 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/BlogggingRepositoryBase.cs:
--------------------------------------------------------------------------------
1 | using ORMDemo.EFWithRepository.Infrastructure;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace ORMDemo.EFWithRepository
8 | {
9 | public class BlogggingRepositoryBase : EFRepository, IBlogggingRepositoryBase where TEntity : BaseEntity
10 | {
11 | public BlogggingRepositoryBase(BloggingContext dbContext) : base(dbContext)
12 | {
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/BloggingContext.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using ORMDemo.EFWithRepository.Model;
3 |
4 | namespace ORMDemo.EFWithRepository
5 | {
6 | public class BloggingContext : DbContext
7 | {
8 | public BloggingContext(DbContextOptions options)
9 | : base(options)
10 | {
11 | }
12 |
13 | public DbSet Blogs { get; set; }
14 | public DbSet Posts { get; set; }
15 |
16 | protected override void OnModelCreating(ModelBuilder modelBuilder)
17 | {
18 | base.OnModelCreating(modelBuilder);
19 |
20 | modelBuilder.ApplyConfiguration(new BlogConfiguration());
21 | modelBuilder.ApplyConfiguration(new PostConfiguration());
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/BloggingUnitOfWork.cs:
--------------------------------------------------------------------------------
1 | using ORMDemo.EFWithRepository.Infrastructure;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace ORMDemo.EFWithRepository
8 | {
9 | public class BloggingUnitOfWork : UnitOfWork
10 | {
11 | public BloggingUnitOfWork(BloggingContext dbContext) : base(dbContext)
12 | {
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/Controllers/ValuesController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace ORMDemo.EFWithRepository.Controllers
8 | {
9 | [Route("api/[controller]")]
10 | [ApiController]
11 | public class ValuesController : ControllerBase
12 | {
13 | // GET api/values
14 | [HttpGet]
15 | public ActionResult> Get()
16 | {
17 | return new string[] { "value1", "value2" };
18 | }
19 |
20 | // GET api/values/5
21 | [HttpGet("{id}")]
22 | public ActionResult Get(int id)
23 | {
24 | return "value";
25 | }
26 |
27 | // POST api/values
28 | [HttpPost]
29 | public void Post([FromBody] string value)
30 | {
31 | }
32 |
33 | // PUT api/values/5
34 | [HttpPut("{id}")]
35 | public void Put(int id, [FromBody] string value)
36 | {
37 | }
38 |
39 | // DELETE api/values/5
40 | [HttpDelete("{id}")]
41 | public void Delete(int id)
42 | {
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/IBlogggingRepositoryBase.cs:
--------------------------------------------------------------------------------
1 | using ORMDemo.EFWithRepository.Infrastructure;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace ORMDemo.EFWithRepository
8 | {
9 | public interface IBlogggingRepositoryBase : IRepository where TEntity : BaseEntity
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/Infrastructure/Data/BaseEntity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace ORMDemo.EFWithRepository.Infrastructure
7 | {
8 | public abstract class BaseEntity
9 | {
10 | public virtual TKey Id { get; set; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/Infrastructure/Data/IRepository.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Linq.Expressions;
6 | using System.Threading.Tasks;
7 |
8 | namespace ORMDemo.EFWithRepository.Infrastructure
9 | {
10 | public interface IRepository where TEntity : BaseEntity where TDbContext : DbContext
11 | {
12 | Task GetByKeyAsync(TKey id);
13 |
14 | Task> GetAsync(
15 | Expression> predicate = null,
16 | Func, IOrderedQueryable> orderBy = null,
17 | List>> includes = null);
18 |
19 | Task AddAsync(TEntity entity);
20 |
21 | TEntity Update(TEntity entity);
22 |
23 | void Delete(TKey id);
24 |
25 | void Delete(TEntity entity);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/Infrastructure/Data/IUnitOfWork.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace ORMDemo.EFWithRepository.Infrastructure
8 | {
9 | public interface IUnitOfWork where TDbContext : DbContext
10 | {
11 | Task SaveChangesAsync();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/Infrastructure/Data/Page.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace ORMDemo.EFWithRepository.Infrastructure
7 | {
8 | public class Page
9 | {
10 | ///
11 | /// the current page index.
12 | ///
13 | public long CurrentPage { get; set; }
14 |
15 | ///
16 | /// the total pages count.
17 | ///
18 | public long TotalPages { get; set; }
19 |
20 | ///
21 | /// the total items count.
22 | ///
23 | public long TotalItems { get; set; }
24 |
25 | ///
26 | /// the items count per page.
27 | ///
28 | public long ItemsPerPage { get; set; }
29 |
30 | ///
31 | /// the items.
32 | ///
33 | public List Items { get; set; }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/Infrastructure/Data/UnitOfWork.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Storage;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 | namespace ORMDemo.EFWithRepository.Infrastructure
9 | {
10 | public class UnitOfWork : IUnitOfWork where TDbContext : DbContext
11 | {
12 | private readonly TDbContext _dbContext;
13 |
14 | public UnitOfWork(TDbContext context)
15 | {
16 | _dbContext = context ?? throw new ArgumentNullException(nameof(context));
17 | }
18 |
19 | public async Task SaveChangesAsync()
20 | {
21 | return await _dbContext.SaveChangesAsync();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/Model/Blog.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 | using ORMDemo.EFWithRepository.Infrastructure;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 |
9 | namespace ORMDemo.EFWithRepository.Model
10 | {
11 | public class Blog : BaseEntity
12 | {
13 | public string Url { get; set; }
14 | public int Rating { get; set; }
15 |
16 | public List Posts { get; set; }
17 | }
18 |
19 | public class BlogConfiguration : IEntityTypeConfiguration
20 | {
21 | public void Configure(EntityTypeBuilder builder)
22 | {
23 | builder.Property(t => t.Url).HasColumnName("Url").HasMaxLength(500).IsRequired();
24 |
25 | //Data Seeding
26 | builder.HasData(new Blog { Id = 1, Url = "http://sample.com/1", Rating = 0 });
27 | builder.HasData(new Blog { Id = 2, Url = "http://sample.com/2", Rating = 100 });
28 | builder.HasData(new Blog { Id = 3, Url = "http://sample.com/3", Rating = 100 });
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/Model/Post.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 | using ORMDemo.EFWithRepository.Infrastructure;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 |
9 | namespace ORMDemo.EFWithRepository.Model
10 | {
11 | public class Post : BaseEntity
12 | {
13 | public string Title { get; set; }
14 | public string Content { get; set; }
15 |
16 | public int BlogId { get; set; }
17 | public Blog Blog { get; set; }
18 | }
19 |
20 | public class PostConfiguration : IEntityTypeConfiguration
21 | {
22 | public void Configure(EntityTypeBuilder builder)
23 | {
24 | builder.Property(t => t.Title).HasMaxLength(100).IsRequired();
25 | builder.Property(t => t.Content).HasMaxLength(500);
26 |
27 | builder.HasOne(p => p.Blog)
28 | .WithMany(b => b.Posts)
29 | .HasForeignKey(p => p.BlogId)
30 | .OnDelete(DeleteBehavior.Cascade);
31 |
32 | //Data Seeding
33 | builder.HasData(new Post { Id = 1, Title = "Title1", Content = "BlogId_1 Post_1", BlogId = 1 });
34 | builder.HasData(new Post { Id = 2, Title = "Title2", Content = "BlogId_1 Post_2", BlogId = 1 });
35 | builder.HasData(new Post { Id = 3, Title = "Title3", Content = "BlogId_2 Post_1", BlogId = 2 });
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/ORMDemo.EFWithRepository.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/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 ORMDemo.EFWithRepository
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 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.EFWithRepository/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
9 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/Controllers/ValuesController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace ORMDemo.MultiTenancy.Controllers
8 | {
9 | [Route("api/[controller]")]
10 | [ApiController]
11 | public class ValuesController : ControllerBase
12 | {
13 | // GET api/values
14 | [HttpGet]
15 | public ActionResult> Get()
16 | {
17 | return new string[] { "value1", "value2" };
18 | }
19 |
20 | // GET api/values/5
21 | [HttpGet("{id}")]
22 | public ActionResult Get(int id)
23 | {
24 | return "value";
25 | }
26 |
27 | // POST api/values
28 | [HttpPost]
29 | public void Post([FromBody] string value)
30 | {
31 | }
32 |
33 | // PUT api/values/5
34 | [HttpPut("{id}")]
35 | public void Put(int id, [FromBody] string value)
36 | {
37 | }
38 |
39 | // DELETE api/values/5
40 | [HttpDelete("{id}")]
41 | public void Delete(int id)
42 | {
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/Migrations/Tenants/20181114050902_InitialCreate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.EntityFrameworkCore.Migrations;
3 |
4 | namespace ORMDemo.MultiTenancy.Migrations.Tenants
5 | {
6 | public partial class InitialCreate : Migration
7 | {
8 | protected override void Up(MigrationBuilder migrationBuilder)
9 | {
10 | migrationBuilder.CreateTable(
11 | name: "Tenants",
12 | columns: table => new
13 | {
14 | Id = table.Column(nullable: false),
15 | Name = table.Column(maxLength: 100, nullable: false),
16 | Host = table.Column(maxLength: 100, nullable: false)
17 | },
18 | constraints: table =>
19 | {
20 | table.PrimaryKey("PK_Tenants", x => x.Id);
21 | });
22 |
23 | migrationBuilder.InsertData(
24 | table: "Tenants",
25 | columns: new[] { "Id", "Host", "Name" },
26 | values: new object[] { new Guid("b992d195-56ce-49bf-bfdd-4145ba9a0c13"), "localhost:5200", "Customer A" });
27 |
28 | migrationBuilder.InsertData(
29 | table: "Tenants",
30 | columns: new[] { "Id", "Host", "Name" },
31 | values: new object[] { new Guid("f55ae0c8-4573-4a0a-9ef9-32f66a828d0e"), "localhost:5300", "Customer B" });
32 | }
33 |
34 | protected override void Down(MigrationBuilder migrationBuilder)
35 | {
36 | migrationBuilder.DropTable(
37 | name: "Tenants");
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/Migrations/Tenants/TenantsContextModelSnapshot.cs:
--------------------------------------------------------------------------------
1 | //
2 | using System;
3 | using Microsoft.EntityFrameworkCore;
4 | using Microsoft.EntityFrameworkCore.Infrastructure;
5 | using Microsoft.EntityFrameworkCore.Metadata;
6 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
7 | using ORMDemo.MultiTenancy;
8 |
9 | namespace ORMDemo.MultiTenancy.Migrations.Tenants
10 | {
11 | [DbContext(typeof(TenantsContext))]
12 | partial class TenantsContextModelSnapshot : ModelSnapshot
13 | {
14 | protected override void BuildModel(ModelBuilder modelBuilder)
15 | {
16 | #pragma warning disable 612, 618
17 | modelBuilder
18 | .HasAnnotation("ProductVersion", "2.1.4-rtm-31024")
19 | .HasAnnotation("Relational:MaxIdentifierLength", 128)
20 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
21 |
22 | modelBuilder.Entity("ORMDemo.MultiTenancy.Models.Tenant", b =>
23 | {
24 | b.Property("Id")
25 | .ValueGeneratedOnAdd();
26 |
27 | b.Property("Host")
28 | .IsRequired()
29 | .HasMaxLength(100);
30 |
31 | b.Property("Name")
32 | .IsRequired()
33 | .HasMaxLength(100);
34 |
35 | b.HasKey("Id");
36 |
37 | b.ToTable("Tenants");
38 |
39 | b.HasData(
40 | new { Id = new Guid("b992d195-56ce-49bf-bfdd-4145ba9a0c13"), Host = "localhost:5200", Name = "Customer A" },
41 | new { Id = new Guid("f55ae0c8-4573-4a0a-9ef9-32f66a828d0e"), Host = "localhost:5300", Name = "Customer B" }
42 | );
43 | });
44 | #pragma warning restore 612, 618
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/Models/BaseEntity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace ORMDemo.MultiTenancy.Models
7 | {
8 | public abstract class BaseEntity
9 | {
10 | public int Id { get; set; }
11 | public Guid TenantId { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/Models/Blog.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 | namespace ORMDemo.MultiTenancy.Models
9 | {
10 | public class Blog : BaseEntity
11 | {
12 | public string Name { get; set; }
13 | public string Url { get; set; }
14 |
15 | public virtual IList Posts { get; set; }
16 | }
17 |
18 | public class BlogConfiguration : IEntityTypeConfiguration
19 | {
20 | public void Configure(EntityTypeBuilder builder)
21 | {
22 | builder.HasKey(t => t.Id);
23 | builder.Property(t => t.Name).HasMaxLength(100).IsRequired();
24 | builder.Property(t => t.Url).HasMaxLength(100).IsRequired();
25 |
26 | builder.HasData(
27 | new Blog { Id = 1, Name = "Blog1 by A", Url = "http://sample.com/1", TenantId= Guid.Parse("B992D195-56CE-49BF-BFDD-4145BA9A0C13") },
28 | new Blog { Id = 2, Name = "Blog2 by A", Url = "http://sample.com/2", TenantId = Guid.Parse("B992D195-56CE-49BF-BFDD-4145BA9A0C13") },
29 | new Blog { Id = 3, Name = "Blog1 by B", Url = "http://sample.com/3", TenantId = Guid.Parse("F55AE0C8-4573-4A0A-9EF9-32F66A828D0E") });
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/Models/Post.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 | namespace ORMDemo.MultiTenancy.Models
9 | {
10 | public class Post : BaseEntity
11 | {
12 | public string Title { get; set; }
13 | public string Content { get; set; }
14 |
15 | public int BlogId { get; set; }
16 | public virtual Blog Blog { get; set; }
17 | }
18 |
19 | public class PostConfiguration : IEntityTypeConfiguration
20 | {
21 | public void Configure(EntityTypeBuilder builder)
22 | {
23 | builder.HasKey(t => t.Id);
24 | builder.Property(t => t.Title).HasMaxLength(100).IsRequired();
25 | builder.Property(t => t.Content).HasMaxLength(500);
26 |
27 | builder.HasOne(p => p.Blog)
28 | .WithMany(b => b.Posts)
29 | .HasForeignKey(p => p.BlogId)
30 | .OnDelete(DeleteBehavior.Cascade);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/Models/Tenant.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 | namespace ORMDemo.MultiTenancy.Models
9 | {
10 | public class Tenant
11 | {
12 | public Guid Id { get; set; }
13 | public string Name { get; set; }
14 | public string Host { get; set; }
15 | }
16 |
17 | public class TenantConfiguration : IEntityTypeConfiguration
18 | {
19 | public void Configure(EntityTypeBuilder builder)
20 | {
21 | builder.HasKey(t => t.Id);
22 | builder.Property(t => t.Name).HasMaxLength(100).IsRequired();
23 | builder.Property(t => t.Host).HasMaxLength(100).IsRequired();
24 |
25 | builder.HasData(
26 | new Tenant { Id = Guid.Parse("B992D195-56CE-49BF-BFDD-4145BA9A0C13"), Name = "Customer A", Host = "localhost:5200" },
27 | new Tenant { Id = Guid.Parse("F55AE0C8-4573-4A0A-9EF9-32F66A828D0E"), Name = "Customer B", Host = "localhost:5300" });
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/ORMDemo.MultiTenancy.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/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 ORMDemo.MultiTenancy
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 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/TenantProviders/ITenantProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace ORMDemo.MultiTenancy.TenantProviders
7 | {
8 | public interface ITenantProvider
9 | {
10 | Guid GetTenantId();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/TenantProviders/TenantProvider.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Http;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace ORMDemo.MultiTenancy.TenantProviders
8 | {
9 | public class TenantProvider : ITenantProvider
10 | {
11 | private Guid _tenantId;
12 |
13 | public TenantProvider(IHttpContextAccessor accessor, TenantsContext context)
14 | {
15 | var host = accessor.HttpContext.Request.Host.Value;
16 | _tenantId = context.GetTenantId(host);
17 | }
18 |
19 | public Guid GetTenantId()
20 | {
21 | return _tenantId;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/TenantsContext.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using ORMDemo.MultiTenancy.Models;
7 |
8 | namespace ORMDemo.MultiTenancy
9 | {
10 | public class TenantsContext : DbContext
11 | {
12 | public TenantsContext(DbContextOptions options)
13 | : base(options)
14 | {
15 | }
16 |
17 | private DbSet Tenants { get; set; }
18 |
19 | protected override void OnModelCreating(ModelBuilder modelBuilder)
20 | {
21 | modelBuilder.ApplyConfiguration(new TenantConfiguration());
22 |
23 | base.OnModelCreating(modelBuilder);
24 | }
25 |
26 | public Guid GetTenantId(string host)
27 | {
28 | var tenant = Tenants.FirstOrDefault(t => t.Host == host);
29 | return tenant == null ? Guid.Empty : tenant.Id;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ORMDemo/ORMDemo.MultiTenancy/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
9 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/AuthHelper/Authentication/IJwtFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Claims;
2 | using System.Threading.Tasks;
3 |
4 | namespace SecurityDemo.Authentication.JWT.AuthHelper
5 | {
6 | public interface IJwtFactory
7 | {
8 | Task GenerateEncodedToken(string userName, string refreshToken, ClaimsIdentity identity);
9 | ClaimsIdentity GenerateClaimsIdentity(User user);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/AuthHelper/Authorization/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.Threading.Tasks;
8 |
9 | namespace SecurityDemo.Authentication.JWT.AuthHelper
10 | {
11 | public class PermissionHandler : AuthorizationHandler
12 | {
13 | private readonly IUserService _userService;
14 |
15 | public PermissionHandler(IUserService userService)
16 | {
17 | _userService = userService;
18 | }
19 |
20 | protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
21 | {
22 | var httpContext = (context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext).HttpContext;
23 |
24 | var isAuthenticated = httpContext.User.Identity.IsAuthenticated;
25 | if (isAuthenticated)
26 | {
27 | Guid userId;
28 | if (!Guid.TryParse(httpContext.User.Claims.SingleOrDefault(s => s.Type == "id").Value, out userId))
29 | {
30 | return Task.CompletedTask;
31 | }
32 | var functions = _userService.GetFunctionsByUserId(userId);
33 | var requestUrl = httpContext.Request.Path.Value.ToLower();
34 | if (functions != null && functions.Count > 0 && functions.Contains(requestUrl))
35 | {
36 | context.Succeed(requirement);
37 | }
38 | }
39 | return Task.CompletedTask;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/AuthHelper/Authorization/PermissionRequirement.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authorization;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace SecurityDemo.Authentication.JWT.AuthHelper
8 | {
9 | public class PermissionRequirement : IAuthorizationRequirement
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/AuthHelper/Authorization/ResourceAuthorizationHandler.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authorization;
2 | using Microsoft.AspNetCore.Authorization.Infrastructure;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 | namespace SecurityDemo.Authentication.JWT.AuthHelper
9 | {
10 | public class ResourceAuthorizationHandler : AuthorizationHandler
11 | {
12 | protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement, IResourceWithCreator resource)
13 | {
14 | //if (context.User.IsInRole("admin"))
15 | //{
16 | // context.Succeed(requirement);
17 | //}
18 |
19 | if (requirement == ResourceOperations.Create || requirement == ResourceOperations.Read)
20 | {
21 | context.Succeed(requirement);
22 | }
23 | else
24 | {
25 | if (context.User.Identity.Name == resource.Creator)
26 | {
27 | context.Succeed(requirement);
28 | }
29 | }
30 | return Task.CompletedTask;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/AuthHelper/Authorization/ResourceOperations.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authorization.Infrastructure;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace SecurityDemo.Authentication.JWT.AuthHelper
8 | {
9 | public static class ResourceOperations
10 | {
11 | public static OperationAuthorizationRequirement Create = new OperationAuthorizationRequirement { Name = "Create" };
12 | public static OperationAuthorizationRequirement Read = new OperationAuthorizationRequirement { Name = "Read" };
13 | public static OperationAuthorizationRequirement Update = new OperationAuthorizationRequirement { Name = "Update" };
14 | public static OperationAuthorizationRequirement Delete = new OperationAuthorizationRequirement { Name = "Delete" };
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.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 SecurityDemo.Authentication.JWT.Controllers
9 | {
10 | [Route("api/[controller]")]
11 | [ApiController]
12 | public class ValuesController : ControllerBase
13 | {
14 | [HttpGet("[action]")]
15 | [Authorize(Policy = "APIAccess")]
16 | public ActionResult> GetValueByGuestPolicy()
17 | {
18 | return new string[] { "use policy = APIAccess" };
19 | }
20 |
21 | [HttpGet("[action]")]
22 | [Authorize(Policy = "Administrator")]
23 | public ActionResult> GetValueByAdminPolicy()
24 | {
25 | return new string[] { "use policy = Administrator" };
26 | }
27 |
28 | [HttpGet("[action]")]
29 | [Authorize(Roles = "administrator")]
30 | public ActionResult> GetValueByAdminRole()
31 | {
32 | return new string[] { "use Roles = administrator" };
33 | }
34 |
35 | [HttpGet("[action]")]
36 | [Authorize(Policy = "Permission")]
37 | public ActionResult> GetAdminValue()
38 | {
39 | return new string[] { "use Policy = Permission" };
40 | }
41 |
42 | [HttpGet("[action]")]
43 | [Authorize(Policy = "Permission")]
44 | public ActionResult> GetGuestValue()
45 | {
46 | return new string[] { "use Policy = Permission" };
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/Models/LoginRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace SecurityDemo.Authentication.JWT.Models
8 | {
9 | public class LoginRequest
10 | {
11 | [Required(ErrorMessage = "{0} is required.")]
12 | public string UserName { get; set; }
13 |
14 | [Required(ErrorMessage = "{0} is required.")]
15 | [StringLength(128, MinimumLength = 6, ErrorMessage = "minimum Length of {0} is 6.")]
16 | public string Password { get; set; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/Models/RefreshTokenRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace SecurityDemo.Authentication.JWT.Models
8 | {
9 | public class RefreshTokenRequest
10 | {
11 | [Required(ErrorMessage = "{0} is required.")]
12 | public string UserName { get; set; }
13 |
14 | [Required(ErrorMessage = "{0} is required.")]
15 | public string RefreshToken { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/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 SecurityDemo.Authentication.JWT
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 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/SecurityDemo.Authentication.JWT.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 |
6 |
7 |
8 | bin\Debug\netcoreapp2.1\SecurityDemo.Authentication.JWT.xml
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/Test/BlogService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace SecurityDemo.Authentication.JWT
7 | {
8 | public interface IBlogService
9 | {
10 | IList GetAllBlogs();
11 | Blog GetBlogById(Guid id);
12 | bool Add(Blog blog);
13 | bool Update(Blog blog);
14 | bool Delete(Blog blog);
15 | }
16 |
17 | public class BlogService : IBlogService
18 | {
19 | public bool Add(Blog blog)
20 | {
21 | return true;
22 | }
23 |
24 | public bool Delete(Blog blog)
25 | {
26 | return true;
27 | }
28 |
29 | public IList GetAllBlogs()
30 | {
31 | return TestBlogs.Blogs;
32 | }
33 |
34 | public Blog GetBlogById(Guid id)
35 | {
36 | return TestBlogs.Blogs.SingleOrDefault(r => r.Id.Equals(id));
37 | }
38 |
39 | public bool Update(Blog blog)
40 | {
41 | return true;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/Test/TestBlogs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace SecurityDemo.Authentication.JWT
7 | {
8 | public static class TestBlogs
9 | {
10 | public static List Blogs = new List
11 | {
12 | new Blog{ Id = Guid.Parse("CA4A3FC9-42CA-47F4-B651-36A863023E75"), Name = "Paul_Blog_1", BlogUrl = "blogs/paul/1", Creator = "Paul" },
13 | new Blog{ Id = Guid.Parse("9C03EDA8-FBCD-4C33-B5C8-E4DFC40258D7"), Name = "Paul_Blog_2", BlogUrl = "blogs/paul/2", Creator = "Paul" },
14 | new Blog{ Id = Guid.Parse("E05E3625-1885-49A5-87D0-54F7EAF90C88"), Name = "Young_Blog_1", BlogUrl = "blogs/young/1", Creator = "Young" },
15 | new Blog{ Id = Guid.Parse("E97D5DF4-AE50-4258-84F8-0B3052EB2CB8"), Name = "Roy_Blog_1", BlogUrl = "blogs/roy/1", Creator = "Roy" },
16 | };
17 | }
18 |
19 | public class Blog : IResourceWithCreator
20 | {
21 | public Guid Id { get; set; }
22 | public string Name { get; set; }
23 | public string BlogUrl { get; set; }
24 |
25 | public string Creator { get; set; }
26 | }
27 |
28 | public interface IResourceWithCreator
29 | {
30 | string Creator { get; set; }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/Test/TestUsers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace SecurityDemo.Authentication.JWT
7 | {
8 | public static class TestUsers
9 | {
10 | public static List Users = new List
11 | {
12 | new User{ Id = Guid.NewGuid(), UserName = "Paul", Password = "Paul123", Roles = new List{ "administrator", "api_access" }, Urls = new List{ "/api/values/getadminvalue", "/api/values/getguestvalue" }},
13 | new User{ Id = Guid.NewGuid(), UserName = "Young", Password = "Young123", Roles = new List{ "api_access" }, Urls = new List{ "/api/values/getguestvalue" }},
14 | new User{ Id = Guid.NewGuid(), UserName = "Roy", Password = "Roy123", Roles = new List{ "administrator" }, Urls = new List{ "/api/values/getadminvalue" }},
15 | };
16 | }
17 |
18 | public class User
19 | {
20 | public Guid Id { get; set; }
21 | public string UserName { get; set; }
22 | public string Password { get; set; }
23 | public List Roles { get; set; }
24 | public List Urls { get; set; }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/Test/UserService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace SecurityDemo.Authentication.JWT
7 | {
8 | public interface IUserService
9 | {
10 | User GetUserByName(string name);
11 | List GetFunctionsByUserId(Guid id);
12 | }
13 |
14 | public class UserService : IUserService
15 | {
16 | public List GetFunctionsByUserId(Guid id)
17 | {
18 | var user = TestUsers.Users.SingleOrDefault(r => r.Id.Equals(id));
19 | return user?.Urls;
20 | }
21 |
22 | public User GetUserByName(string name)
23 | {
24 | var user = TestUsers.Users.SingleOrDefault(r => r.UserName.Equals(name));
25 | return user;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.Authentication.JWT/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "JwtIssuerOptions": {
8 | "Issuer": "SecurityDemo.Authentication.JWT",
9 | "Audience": "http://localhost:5000/"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/SecurityDemo/SecurityDemo.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27703.2018
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecurityDemo.Authentication.JWT", "SecurityDemo.Authentication.JWT\SecurityDemo.Authentication.JWT.csproj", "{C11BFB39-0D89-42C4-BEC2-1093BC5D814F}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {C11BFB39-0D89-42C4-BEC2-1093BC5D814F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {C11BFB39-0D89-42C4-BEC2-1093BC5D814F}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {C11BFB39-0D89-42C4-BEC2-1093BC5D814F}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {C11BFB39-0D89-42C4-BEC2-1093BC5D814F}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {6BC7AD13-09EA-4C9B-B59D-B13E25CB4D5D}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRChatDemo/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 SignalRChatDemo
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 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRChatDemo/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:49345",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "SignalRChatDemo": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "applicationUrl": "http://localhost:5000",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/SignalRDemo/SignalRChatDemo/SignalRChatDemo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRChatDemo/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Builder;
6 | using Microsoft.AspNetCore.Hosting;
7 | using Microsoft.AspNetCore.Http;
8 | using Microsoft.Extensions.DependencyInjection;
9 | using SignalRChatDemo.Hubs;
10 |
11 | namespace SignalRChatDemo
12 | {
13 | public class Startup
14 | {
15 | // This method gets called by the runtime. Use this method to add services to the container.
16 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
17 | public void ConfigureServices(IServiceCollection services)
18 | {
19 | services.AddSignalR();
20 | }
21 |
22 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
23 | public void Configure(IApplicationBuilder app, IHostingEnvironment env)
24 | {
25 | app.UseStaticFiles();
26 | app.UseSignalR(routes =>
27 | {
28 | routes.MapHub("/chatHub");
29 | });
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRDemo.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27703.2018
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SignalRChatDemo", "SignalRChatDemo\SignalRChatDemo.csproj", "{3935FB3C-3317-493B-93B5-CB75D0B6AD58}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SignalRJWTDemo", "SignalRJWTDemo\SignalRJWTDemo.csproj", "{EBFA487A-0B12-42F1-A4B4-540BFEF77102}"
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 | {3935FB3C-3317-493B-93B5-CB75D0B6AD58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {3935FB3C-3317-493B-93B5-CB75D0B6AD58}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {3935FB3C-3317-493B-93B5-CB75D0B6AD58}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {3935FB3C-3317-493B-93B5-CB75D0B6AD58}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {EBFA487A-0B12-42F1-A4B4-540BFEF77102}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {EBFA487A-0B12-42F1-A4B4-540BFEF77102}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {EBFA487A-0B12-42F1-A4B4-540BFEF77102}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {EBFA487A-0B12-42F1-A4B4-540BFEF77102}.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 = {442F08BE-6C2E-401D-8AA4-C04FF92F8D30}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRJWTDemo/Authentication/IJwtFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Claims;
2 | using System.Threading.Tasks;
3 | using SignalRJWTDemo.Test;
4 |
5 | namespace SignalRJWTDemo.Authentication
6 | {
7 | public interface IJwtFactory
8 | {
9 | Task GenerateEncodedToken(string userName, string refreshToken, ClaimsIdentity identity);
10 | ClaimsIdentity GenerateClaimsIdentity(User user);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRJWTDemo/Controllers/ValuesController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace SignalRJWTDemo.Controllers
8 | {
9 | [Route("api/[controller]")]
10 | [ApiController]
11 | public class ValuesController : ControllerBase
12 | {
13 | // GET api/values
14 | [HttpGet]
15 | public ActionResult> Get()
16 | {
17 | return new string[] { "value1", "value2" };
18 | }
19 |
20 | // GET api/values/5
21 | [HttpGet("{id}")]
22 | public ActionResult Get(int id)
23 | {
24 | return "value";
25 | }
26 |
27 | // POST api/values
28 | [HttpPost]
29 | public void Post([FromBody] string value)
30 | {
31 | }
32 |
33 | // PUT api/values/5
34 | [HttpPut("{id}")]
35 | public void Put(int id, [FromBody] string value)
36 | {
37 | }
38 |
39 | // DELETE api/values/5
40 | [HttpDelete("{id}")]
41 | public void Delete(int id)
42 | {
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRJWTDemo/Hubs/ChatHub.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authentication.JwtBearer;
2 | using Microsoft.AspNetCore.Authorization;
3 | using Microsoft.AspNetCore.SignalR;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 |
9 | namespace SignalRJWTDemo.Hubs
10 | {
11 | [Authorize]
12 | public class ChatHub : Hub
13 | {
14 | public Task Send(string message)
15 | {
16 | return Clients.All.SendAsync("ReceiveMessage", $"{Context.UserIdentifier}: {message}");
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRJWTDemo/Models/LoginRequest.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace SignalRJWTDemo.Models
4 | {
5 | public class LoginRequest
6 | {
7 | [Required(ErrorMessage = "{0} is required.")]
8 | public string UserName { get; set; }
9 |
10 | [Required(ErrorMessage = "{0} is required.")]
11 | [StringLength(128, MinimumLength = 6, ErrorMessage = "minimum Length of {0} is 6.")]
12 | public string Password { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRJWTDemo/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 SignalRJWTDemo
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 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRJWTDemo/SignalRJWTDemo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRJWTDemo/Test/TestUsers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace SignalRJWTDemo.Test
7 | {
8 | public static class TestUsers
9 | {
10 | public static List Users = new List
11 | {
12 | new User{ Id = Guid.NewGuid(), UserName = "Paul", Password = "Paul123", Roles = new List{ "administrator", "api_access" }, Urls = new List{ "/api/values/getadminvalue", "/api/values/getguestvalue" }},
13 | new User{ Id = Guid.NewGuid(), UserName = "Young", Password = "Young123", Roles = new List{ "api_access" }, Urls = new List{ "/api/values/getguestvalue" }},
14 | new User{ Id = Guid.NewGuid(), UserName = "Roy", Password = "Roy123", Roles = new List{ "administrator" }, Urls = new List{ "/api/values/getadminvalue" }},
15 | };
16 | }
17 |
18 | public class User
19 | {
20 | public Guid Id { get; set; }
21 | public string UserName { get; set; }
22 | public string Password { get; set; }
23 | public List Roles { get; set; }
24 | public List Urls { get; set; }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRJWTDemo/Test/UserService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace SignalRJWTDemo.Test
6 | {
7 | public interface IUserService
8 | {
9 | User GetUserByName(string name);
10 | List GetFunctionsByUserId(Guid id);
11 | }
12 |
13 | public class UserService : IUserService
14 | {
15 | public List GetFunctionsByUserId(Guid id)
16 | {
17 | var user = TestUsers.Users.SingleOrDefault(r => r.Id.Equals(id));
18 | return user?.Urls;
19 | }
20 |
21 | public User GetUserByName(string name)
22 | {
23 | var user = TestUsers.Users.SingleOrDefault(r => r.UserName.Equals(name));
24 | return user;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRJWTDemo/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/SignalRDemo/SignalRJWTDemo/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "JwtIssuerOptions": {
8 | "Issuer": "SecurityDemo.Authentication.JWT",
9 | "Audience": "http://localhost:5000/"
10 | }
11 | }
--------------------------------------------------------------------------------