FBW.DotNet.AspNetCore 1.0.7

dotnet add package FBW.DotNet.AspNetCore --version 1.0.7
                    
NuGet\Install-Package FBW.DotNet.AspNetCore -Version 1.0.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FBW.DotNet.AspNetCore" Version="1.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FBW.DotNet.AspNetCore" Version="1.0.7" />
                    
Directory.Packages.props
<PackageReference Include="FBW.DotNet.AspNetCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FBW.DotNet.AspNetCore --version 1.0.7
                    
#r "nuget: FBW.DotNet.AspNetCore, 1.0.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FBW.DotNet.AspNetCore@1.0.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FBW.DotNet.AspNetCore&version=1.0.7
                    
Install as a Cake Addin
#tool nuget:?package=FBW.DotNet.AspNetCore&version=1.0.7
                    
Install as a Cake Tool

FBW.DotNet.AspNetCore

ASP.NET Core扩展包,目前支持.NET3.1,.NET5,.NET6,.NET7,.NET8,.NET9

如何使用

1、安装FBW.DotNet.AspNetCore依赖。
Cmd install:

dotnet add package FBW.DotNet.AspNetCore

2、在Startup.cs中配置

//Mvc相关配置
builder.Services.AddDotNetDefaultMvc();

//Identity相关配置
builder.Services.AddDotNetIdentityServer(options => {
    options.PrivateKey = builder.Configuration["SystemConfig:PrivateKey"];
}).AddResourceOwnerValidator<ResourceOwnerPasswordValidator>();

//数据库配置
builder.Services.AddDotNetDbContextPool<IdentityContext>(options =>
{
    options.ConfigureDbContext = op =>
    {
         op.UseNpgsql(builder.Configuration["SystemConfig:DBConnectionString"],
            //看实际情况指定迁移程序集
            b => b.MigrationsAssembly("DotNet.AspNetCore.WebApi"))
        .UseSnakeCaseNamingConvention()
#if !DEBUG
        .EnableSensitiveDataLogging()
#endif
            .UseLoggerFactory(LoggerFactory.Create(builder => builder.AddSerilog()));
        //.EnableSensitiveDataLogging();
        // 配置日志输出
        //op.LogTo(Console.WriteLine);
    };
    options.UseRepository<IdentityContext>();
    options.UseUnitOfWork<IdentityContext>();
    options.UseDotNetRedisCache(builder.Configuration.GetSection("RedisConfig").Get<RedisOptions>(), 100,100);
});

#region 多租户
builder.Services.AddDotNetTenantDbContext<TenantDbContext>(options =>
{
    var provider = builder.Configuration.GetValue("Provider", "PostgreSql");
    var tenantDBConfig = builder.Configuration.GetSection("SystemConfig:MultiTenantDBConfig")
        .Get<List<MultiTenantDBConfig>>()?.FirstOrDefault(t => t.DBProvider.ToString() == provider);
    options.ConfigureDbContext = op =>
    {
        op.UseNpgsql(builder.Configuration["SystemConfig:DBConnectionString"])
        .UseSnakeCaseNamingConvention()
        .UseLoggerFactory(LoggerFactory.Create(builder => builder.AddSimpleConsole()));
    };
    options.TenantDBConfig = tenantDBConfig;
    options.UseRepository<TenantDbContext>();
    options.AddDatabaseProvider<PostgreSqlProvider>();
    options.AddDatabaseProvider<SqlServerProvider>();
    options.AddDatabaseProvider<MySqlProvider>();
});
builder.Services.UseMultiTenancy();
#endregion

//jwt相关配置
builder.Services.AddDotNetJwtBearerAuthentication(builder.Configuration["SystemConfig:PublicKey"],builder.Configuration["SystemConfig:ValidIssuer"]);


//SwaggerDoc配置
builder.Services.Configure<SwaggerConfig>(builder.Configuration.GetSection("SwaggerConfig"));
builder.Services.AddSwaggerDoc(builder.Configuration.GetSection("SwaggerConfig").Get<SwaggerConfig>());

var app = builder.Build();


app.UseDotNetDefaultWebApi();
app.UseSwaggerUI(builder.Configuration.GetSection("SwaggerConfig").Get<SwaggerConfig>());
app.UseIdentityServer();

//初始化多租户数据库
app.Services.InitTenantDatabase<TenantDbContext>();

  • 必须 你需要创建ResourceOwnerPasswordValidator继承IResourceOwnerPasswordValidator接口实现ValidateAsync方法参考下图

ResourceOwnerPasswordValidator.png

  • 多租户支持id隔离和库隔离
  • 多租户支持从token中解析TenantId字段(CurrentTokenTenantResolveContributor),请求头中解析TenantId字段(CurrentHeaderTenantResolveContributor),地址栏中解析TenantId字段(CurrentQueryTenantResolveContributor)
  • 扩展解析策略继承TenantResolveContributorBase抽象类型 ,以单例模式注入租户访问器ICurrentTenantAccessor
  • 安装合适版本的Microsoft.EntityFrameworkCore.Design,在web程序目录创建MyMigrationsScaffolder,MyMigrationDesignTimeServices
  • 必须修改DotNet.AspNetCore.WebApi.csproj的配置 参考如下图

Microsoft.EntityFrameworkCore.Design_config.png

  • MyMigrationsScaffolder,MyMigrationDesignTimeServices代码参考
//重写GetDirectory 不进行深度检查
public class MyMigrationsScaffolder: MigrationsScaffolder
{
    private readonly Type _contextType;
    public MyMigrationsScaffolder(MigrationsScaffolderDependencies dependencies) : base(dependencies)
    {
        _contextType = dependencies.CurrentContext.Context.GetType();
    }
    protected override string GetDirectory(string projectDir, string? siblingFileName, string subnamespace)
    {
        var defaultDirectory = Path.Combine(projectDir, Path.Combine(subnamespace.Split('.')));

        if (siblingFileName != null)
        {
            if (!siblingFileName.StartsWith(_contextType.Name + "ModelSnapshot."))
            {
                var siblingPath = TryGetProjectFile(projectDir, siblingFileName);
                if (siblingPath != null)
                {
                    var lastDirectory = Path.GetDirectoryName(siblingPath)!;
                    if (!defaultDirectory.Equals(lastDirectory, StringComparison.OrdinalIgnoreCase))
                    {
                        Dependencies.OperationReporter.WriteVerbose(DesignStrings.ReusingNamespace(siblingFileName));

                        return lastDirectory;
                    }
                }
            }
        }

        return defaultDirectory;
    }

/// <summary>
/// https://docs.microsoft.com/en-us/ef/core/cli/services
/// </summary>
public class MyMigrationDesignTimeServices: IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
    {
        serviceCollection.AddSingleton<IMigrationsScaffolder, MyMigrationsScaffolder>();
    }
}
  • PostgreSqlProvider/SqlServerProvider 代码参考 按需扩展支持不同的数据库*

PostgreSqlProvider.png

SqlServerProvider.png 3、 appsettings.json配置文件实例:

{
   //接口文档配置
  "SwaggerConfig": {
    "Title": "DotNet.Admin.Web",
    "Version": "v1",
    "Description": "DotNet.Admin.Web",
    "Name": "DotNet",
    "Email": "2231030106@qq.com",
    "ProxyRoutes": {
      //"localhost": "http://127.0.0.1:6033/IdentityServer"
    },
    "RoutePrefix": "help",
    "IsAdminHelpUI": true,
    "AdminSecret": "admin",
    "IsSwaggerBasicAuth": false
  },
  //redis 配置 (启用redis时配置)
  "RedisConfig": {
    "Connection": "127.0.0.1:6379,password=123456",
    "KeyPrefix": "dotnetadminweb",
    "DataProtecteKey": "dataprotectionkeys",
    "IsSentinel": false, // 是否哨兵模式
    "SentinelConfig": {
        "EndPoints": [ // 哨兵端口
        // "10.10.0.124:26380"
        ],
        "Password": "123456",
        "SentinelPassword": "123456",
        "ServiceName": "dotnetadminweb",
        "DefaultDatabase": 0,
        "Password": "123456",
        "SentinelPassword": null,
        "ConnectionSelectionStrategy": "RoundRobin" //LeastLoaded  RoundRobin
    }
  },
   //系统配置
  "SystemConfig": {
    "ValidIssuer": "https://localhost:44354",
    "DatabaseVisitLogSleep": 10000,//系统日志入库时间
    "DBConnectionString": "Host=127.0.0.1;Username=postgres;Password=123456;Database=DotNet_Template",
    //多租户模式下同时支持不同的数据库集合,仅开发迁移多租户不同数据库时需要配置
    "MultiTenantDBConfig": [
      {
        "DBProvider": "PostgreSql",
        "DBConnectionString": "Host=127.0.0.1;Username=postgres;Password=123456;Database=DotNet_Template_470786554998853"
      },
      {
        "DBProvider": "SqlServer",
        "DBConnectionString": "Data Source=.;Initial Catalog=DotNet_Template_470786554998853;User Id=sa;Password=123456;Encrypt=True;TrustServerCertificate=True"
      }
    ],
    "PublicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQPMKq+BQIhoImH30v8FH02x8S8Bz6+ROwzidBEk8C2BidnnMFs2OeXQeHRW7HSJRAhTVTBwhWoJ+3G/C2L6FiMLYPgaKpWsacqZPkbcgpHKfQLJn1weXeZqLNeZKi+aebOX27JOt9cph/YVb5hBTgVzl5q7yASOEg9+wV/y1d8Jq4EAlzXdAux+JRgMGQgj8CSPSSY1z2PO4iZProdgFa/dto8AlVRabVCTx6BoCnMrImy2XRHdF0Ue0eY5mtAAsnLudjKqm8AUopMOivNCLVI5eXzMIoMmpa0bUj7IluoushYVLY0dw7flyKldiDbyvi4w/jrxHRruNMb11fNEFQIDAQAB",
    "PrivateKey": "MIIEowIBAAKCAQEAiQPMKq+BQIhoImH30v8FH02x8S8Bz6+ROwzidBEk8C2BidnnMFs2OeXQeHRW7HSJRAhTVTBwhWoJ+3G/C2L6FiMLYPgaKpWsacqZPkbcgpHKfQLJn1weXeZqLNeZKi+aebOX27JOt9cph/YVb5hBTgVzl5q7yASOEg9+wV/y1d8Jq4EAlzXdAux+JRgMGQgj8CSPSSY1z2PO4iZProdgFa/dto8AlVRabVCTx6BoCnMrImy2XRHdF0Ue0eY5mtAAsnLudjKqm8AUopMOivNCLVI5eXzMIoMmpa0bUj7IluoushYVLY0dw7flyKldiDbyvi4w/jrxHRruNMb11fNEFQIDAQABAoIBADoBSpETpfONDBDqSsGfxypeeSOzE+A54pEOPlyG2Y14pmuWvYJCSy2ttlkYX6hRGb+cirL5A9nnb3xsxkVqzJdMlMejoWg/3zMWW1P7KeV5FTFhWbxGgnCcWHzNdYFfj9VQC80tqpe31lRCAQcyfQsr0ajwD+l4zDCnMLFrDmIuICDFz29wMQC72t8TPCE4dykw8vr5LnKf3aJyh5ScrsNyry73Oiq2X48xadZ2Dh4TW9v5DgBDTiOlsWmXaZbNg8nlJh6MjMTbe7CO9w3ge95liz5XE/CrhR5RWJmiOY8MudvIEov1CQlVMUI11RG8mRKV5qs0Ma+5E2QEMtPWzEECgYEAzc1NxqDoqO9IgGOWRheT2i6vOJEsaeeN4u/E9bm0nYDtsLS9Dg1liSJkze2nTqpEAA1iFt79n3M0fD8CXDWcleGxF7ZeDM0xuN91FAoY4XkZFZaEi8hlsOmZ6A7qusgQQi19Win50CSdgp1Snc7Y0UBXLnvjMZJ8CjQQItL9hhECgYEAqm9IxO9pm+OdrwYD/ZpKypDzm2w7EqZi7LD4J8d63H0t/tIO1Zrxy5qKQOu8XMbkwQjVykPyZJHOd+8ICrKFbfn7xjxqPvW9h809/9jfYY3RLMhKtaDJ7ktwJxVtGmjO+PEft4RGoLmEfbrTSnarasBY99njhKNG8FtTc75cicUCgYEAwdGdcvhtxVP9SvT/PKnN1Ahteu+2DVNG3DgFnYo0oLUgpW/CMO7K9jjPCOXN0JcoDYiNHY8K+tUL1AufVGolOz7fgr58mr/RGRRR9fqAbjCXQC6OS/sCUnfeO594z0nFjh27VWP84lrpgG5btUVuCrv2n0+Lq08SxKU9oR5mJ5ECgYBnPEs2xtIQlBoCV0F5jsj41D5LCY7qqBBJ0JQv/DumbMi8jl5f8p+9tVlDI8eP5wXPC1v8TZX4Zv1KVmZnnGUIDaD9HcE5a76nEKIaZDJCtBVc6+GdDMzj45wGgIr6sTuVPPD6R0xEtLrVMaIke6cvXV1GnBudTw18L8Vn2YnSBQKBgG/NxXjh+urIa+qsIzNHbrTCt+qGsix8z1f7s1OwTlVksFW3otaNK2hIDMlslUgRnVzjZfPyzKME/EuA/WjqAn/ZxqDR1TYvgxil8EaBn9jTEL7LO06ggCuh1dnmPrzC06no5E6Gj4m+6tknO5K5/NU/2HqQnaR6IB514ut7URba"
  }
}

4、Efcore迁移 需要安装 Microsoft.EntityFrameworkCore.Design,Microsoft.EntityFrameworkCore.Tools

add-migration Ids4Config001 -c IdentityContext -o Migrations/Ids4Config 

成功示例:

Ids4Config001_Migrations.png

5、迁移多租户上下文

//Add-Migration InitialCreate -Context TenantDbContext -OutputDir Migrations\SqlServer -Args "--provider SqlServer"
//Add-Migration InitialCreate -Context TenantDbContext -OutputDir Migrations\MySql -Args "--provider MySql"
Add-Migration InitialCreate -Context TenantDbContext -OutputDir Migrations\PostgreSql -Args "--provider PostgreSql"
//update-database -Args "--provider MySql"
//update-database -Args "--provider SqlServer"
update-database -Args "--provider PostgreSql"

成功示例:

TenantDbContext_Migrations.png

6、运行项目

run.png

运行成功打开swagger

run_swagger.png

自动生成数据库

run_database.png

需要配置库隔离的租户连接字符串 支持pgsql,sqlserver,mysql

Tenant_config.png

在重新启动程序迁移多租户数据库

TenantDb.png

至此基本的配置使用完成

7、DotNetDbContext<> 自定义的DbContext继承DotNetDbContext<> 内置实现了软删除(IDeleteFilter)和 多租户(IMultiTenant)的启用和禁用,但需要继承相关的Domain接口,提供了一些审计 字段的实体定义,数据库表的实体必须继承实体接口标识(IEntity)如下图:

Domain.png

更多用法参考文档

![web api认证方式(对外).docx](../../doc/web api认证方式(对外).docx)

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.1 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.7 82 8/23/2025
1.0.6 184 10/18/2024
1.0.5 174 8/22/2024
1.0.4 180 8/22/2024 1.0.4 is deprecated because it has critical bugs.
1.0.3 188 8/21/2024 1.0.3 is deprecated because it is no longer maintained.
1.0.2 161 5/22/2024
1.0.1 201 1/12/2024
1.0.0 137 1/12/2024