Browse Source

feat: 优化代码

aspnetcore
HanPaoPao 8 months ago
parent
commit
0e8f816f5a
  1. 23
      aspnet-core/Lion.AbpPro.sln
  2. 24
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/GlobalUsings.cs
  3. 14
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion.AbpPro.AspNetCore.csproj
  4. 44
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/AbpProAspNetCoreConsts.cs
  5. 22
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/AbpProAspNetCoreModule.cs
  6. 14
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProAuditOptions.cs
  7. 14
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProCorsOptions.cs
  8. 24
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProGatewayOptions.cs
  9. 28
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProJwtOptions.cs
  10. 14
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProMiniProfilerOptions.cs
  11. 9
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProMultiTenancyOptions.cs
  12. 9
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProSwaggerOptions.cs
  13. 143
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Microsoft/AspNetCore/Builder/ApplicationBuilderExtensions.cs
  14. 4
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Microsoft/AspNetCore/Localization/AbpProAcceptLanguageHeaderRequestCultureProvider.cs
  15. 0
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Microsoft/AspNetCore/Mvc/Filters/AbpProExceptionFilter.cs
  16. 35
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Microsoft/AspNetCore/Mvc/Filters/AbpProResultFilter.cs
  17. 338
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Microsoft/Extensions/DependencyInjection/ServiceCollectionExtensions.cs
  18. 118
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Serilog/SerilogToEsExtensions.cs
  19. 0
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Swagger/CachingSwaggerProvider.cs
  20. 0
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Swagger/EnumSchemaFilter.cs
  21. 48
      aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Swagger/HiddenAbpDefaultApiFilter.cs
  22. 10
      aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProCapServiceCollectionExtensions.cs
  23. 4
      aspnet-core/gateways/Lion.AbpPro.WebGateway/AbpProWebGatewayModule.cs
  24. 3
      aspnet-core/gateways/Lion.AbpPro.WebGateway/Lion.AbpPro.WebGateway.csproj
  25. 3
      aspnet-core/modules/BasicManagement/host/Lion.AbpPro.BasicManagement.HttpApi.Host/BasicManagementHttpApiHostModule.cs
  26. 2
      aspnet-core/modules/BasicManagement/host/Lion.AbpPro.BasicManagement.HttpApi.Host/Lion.AbpPro.BasicManagement.HttpApi.Host.csproj
  27. 5
      aspnet-core/modules/DataDictionaryManagement/host/Lion.AbpPro.DataDictionaryManagement.HttpApi.Host/DataDictionaryManagementHttpApiHostModule.cs
  28. 2
      aspnet-core/modules/DataDictionaryManagement/host/Lion.AbpPro.DataDictionaryManagement.HttpApi.Host/Lion.AbpPro.DataDictionaryManagement.HttpApi.Host.csproj
  29. 5
      aspnet-core/modules/FileManagement/host/Lion.AbpPro.FileManagement.HttpApi.Host/FileManagementHttpApiHostModule.cs
  30. 2
      aspnet-core/modules/FileManagement/host/Lion.AbpPro.FileManagement.HttpApi.Host/Lion.AbpPro.FileManagement.HttpApi.Host.csproj
  31. 5
      aspnet-core/modules/LanguageManagement/host/Lion.AbpPro.LanguageManagement.HttpApi.Host/LanguageManagementHttpApiHostModule.cs
  32. 2
      aspnet-core/modules/LanguageManagement/host/Lion.AbpPro.LanguageManagement.HttpApi.Host/Lion.AbpPro.LanguageManagement.HttpApi.Host.csproj
  33. 2
      aspnet-core/modules/NotificationManagement/host/Lion.AbpPro.NotificationManagement.HttpApi.Host/Lion.AbpPro.NotificationManagement.HttpApi.Host.csproj
  34. 5
      aspnet-core/modules/NotificationManagement/host/Lion.AbpPro.NotificationManagement.HttpApi.Host/NotificationManagementHttpApiHostModule.cs
  35. 293
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/AbpProHttpApiHostModule.Configure.cs
  36. 122
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/AbpProHttpApiHostModule.cs
  37. 12
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/GlobalUsings.cs
  38. 2
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Lion.AbpPro.HttpApi.Host.csproj
  39. 113
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Microsoft/Extensions/DependencyInjection/ServiceCollectionExtensions.cs
  40. 27
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/appsettings.json
  41. 9
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Gateways/GlobalUsings.cs
  42. 21
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Gateways/Lion.AbpPro.Shared.Hosting.Gateways.csproj
  43. 32
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Gateways/Lion/AbpPro/AbpProSharedHostingGatewayModule.cs
  44. 140
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Lion/AbpPro/AbpProSharedHostingMicroserviceModule.cs
  45. 79
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/AspNetCore/Builder/ApplicationBuilderExtensions.cs
  46. 38
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/AspNetCore/Mvc/Filters/AbpProResultFilter.cs
  47. 77
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/AspNetCore/RequestLog/RequestLogMiddleware.cs
  48. 15
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/Extensions/DependencyInjection/ServiceCollectionExtensions.cs
  49. 122
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Serilog/SerilogToEsExtensions.cs
  50. 49
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Swagger/HiddenAbpDefaultApiFilter.cs
  51. 64
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Volo/Abp/DefaultHttpExceptionStatusCodeFinder.cs

23
aspnet-core/Lion.AbpPro.sln

@ -113,12 +113,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{8C1B8C6C-C
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.HttpApi.Host", "services\host\Lion.AbpPro.HttpApi.Host\Lion.AbpPro.HttpApi.Host.csproj", "{FB20372D-6C96-4733-9AAC-12522F15CAA6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{6434E3F2-B352-4B30-839A-88C2BA166D96}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.Shared.Hosting.Microservices", "shared\Lion.AbpPro.Shared.Hosting.Microservices\Lion.AbpPro.Shared.Hosting.Microservices.csproj", "{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.Shared.Hosting.Gateways", "shared\Lion.AbpPro.Shared.Hosting.Gateways\Lion.AbpPro.Shared.Hosting.Gateways.csproj", "{C018EFF9-579E-43B3-9181-543BE95E2E03}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gateways", "gateways", "{5C304CBC-F30D-413C-A0AF-8B6814A2D4A3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.WebGateway", "gateways\Lion.AbpPro.WebGateway\Lion.AbpPro.WebGateway.csproj", "{D9108313-8D05-4F5F-9AA0-B443EC3374B6}"
@ -255,6 +249,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lion.AbpPro.Starter", "fram
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lion.AbpPro.HttpClient", "frameworks\src\Lion.AbpPro.HttpClient\Lion.AbpPro.HttpClient.csproj", "{9C88C5AE-21A1-4A62-9FA3-173806CD9EE3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lion.AbpPro.AspNetCore", "frameworks\src\Lion.AbpPro.AspNetCore\Lion.AbpPro.AspNetCore.csproj", "{89CCAEA6-8176-4E4B-8D84-A2ACE2715F88}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -409,14 +405,6 @@ Global
{FB20372D-6C96-4733-9AAC-12522F15CAA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FB20372D-6C96-4733-9AAC-12522F15CAA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FB20372D-6C96-4733-9AAC-12522F15CAA6}.Release|Any CPU.Build.0 = Release|Any CPU
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}.Release|Any CPU.Build.0 = Release|Any CPU
{C018EFF9-579E-43B3-9181-543BE95E2E03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C018EFF9-579E-43B3-9181-543BE95E2E03}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C018EFF9-579E-43B3-9181-543BE95E2E03}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C018EFF9-579E-43B3-9181-543BE95E2E03}.Release|Any CPU.Build.0 = Release|Any CPU
{D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -625,6 +613,10 @@ Global
{9C88C5AE-21A1-4A62-9FA3-173806CD9EE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C88C5AE-21A1-4A62-9FA3-173806CD9EE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C88C5AE-21A1-4A62-9FA3-173806CD9EE3}.Release|Any CPU.Build.0 = Release|Any CPU
{89CCAEA6-8176-4E4B-8D84-A2ACE2715F88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89CCAEA6-8176-4E4B-8D84-A2ACE2715F88}.Debug|Any CPU.Build.0 = Debug|Any CPU
{89CCAEA6-8176-4E4B-8D84-A2ACE2715F88}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89CCAEA6-8176-4E4B-8D84-A2ACE2715F88}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -677,8 +669,6 @@ Global
{8D196E3D-6F95-4793-B948-79669AF09017} = {5AACD0EE-F2B2-49F6-868F-8FE08D7243C0}
{8C1B8C6C-C518-4290-B070-622CCA6004DA} = {2C861ADD-76E9-4B3B-8A3C-638EBB67D683}
{FB20372D-6C96-4733-9AAC-12522F15CAA6} = {8C1B8C6C-C518-4290-B070-622CCA6004DA}
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D} = {6434E3F2-B352-4B30-839A-88C2BA166D96}
{C018EFF9-579E-43B3-9181-543BE95E2E03} = {6434E3F2-B352-4B30-839A-88C2BA166D96}
{D9108313-8D05-4F5F-9AA0-B443EC3374B6} = {5C304CBC-F30D-413C-A0AF-8B6814A2D4A3}
{F604F9BE-CAAB-4D94-8989-22DE4D966C7A} = {F8A8EB2A-2D4B-464F-9A13-F8F7B6A8FAA3}
{C188A1F4-9601-42E5-9A0A-B282E13EAC41} = {F604F9BE-CAAB-4D94-8989-22DE4D966C7A}
@ -746,6 +736,7 @@ Global
{2B2110E1-4C29-41AF-ADB5-C1B5F3C3C1D0} = {EFC415F8-872F-4C7E-8645-31A51481BCFC}
{A70659A2-91F4-4FE7-80D0-DA12430543FD} = {7BE85EBC-99AD-4CDE-957E-4BDD087FC4E3}
{9C88C5AE-21A1-4A62-9FA3-173806CD9EE3} = {7BE85EBC-99AD-4CDE-957E-4BDD087FC4E3}
{89CCAEA6-8176-4E4B-8D84-A2ACE2715F88} = {7BE85EBC-99AD-4CDE-957E-4BDD087FC4E3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F}

24
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/GlobalUsings.cs → aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/GlobalUsings.cs

@ -1,25 +1,32 @@
// Global using directives
global using Microsoft.Extensions.DependencyInjection;
global using Ocelot.DependencyInjection;
global using Ocelot.Provider.Consul;
global using Ocelot.Provider.Polly;
global using Volo.Abp.Modularity;
global using System;
global using System.Collections.Concurrent;
global using System.Collections.Generic;
global using System.Diagnostics.CodeAnalysis;
global using System.Linq;
global using System.Net;
global using System.Reflection;
global using System.Text;
global using System.Text.RegularExpressions;
global using Consul;
global using System.Text.Json;
global using System.Threading.Tasks;
global using Lion.AbpPro;
global using Lion.AbpPro.Core;
global using Lion.AbpPro.Localization;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Cors;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.AspNetCore.Http;
global using Microsoft.AspNetCore.Localization;
global using Microsoft.AspNetCore.HttpsPolicy;
global using Microsoft.AspNetCore.Mvc;
global using Microsoft.AspNetCore.Mvc.Abstractions;
global using Microsoft.AspNetCore.Mvc.ApiExplorer;
global using Microsoft.AspNetCore.Mvc.Filters;
global using Microsoft.EntityFrameworkCore;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
@ -28,10 +35,9 @@ global using Microsoft.Extensions.Localization;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Logging.Abstractions;
global using Microsoft.Extensions.Options;
global using Microsoft.Extensions.Primitives;
global using Microsoft.OpenApi.Any;
global using Microsoft.OpenApi.Models;
global using Serilog;
global using Ocelot.Middleware;
global using Serilog.Exceptions;
global using Serilog.Sinks.Elasticsearch;
global using Swashbuckle.AspNetCore.Swagger;
@ -39,18 +45,12 @@ global using Swashbuckle.AspNetCore.SwaggerGen;
global using Volo.Abp;
global using Volo.Abp.AspNetCore.ExceptionHandling;
global using Volo.Abp.AspNetCore.Mvc;
global using Volo.Abp.AspNetCore.Mvc.AntiForgery;
global using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
global using Volo.Abp.Authorization;
global using Volo.Abp.Autofac;
global using Volo.Abp.DependencyInjection;
global using Volo.Abp.Domain.Entities;
global using Volo.Abp.ExceptionHandling;
global using Volo.Abp.Http;
global using Volo.Abp.Json;
global using Volo.Abp.Localization;
global using Volo.Abp.Localization.ExceptionHandling;
global using Volo.Abp.Modularity;
global using Volo.Abp.Swashbuckle;
global using Volo.Abp.UI.Navigation.Urls;
global using Volo.Abp.Validation;

14
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Lion.AbpPro.Shared.Hosting.Microservices.csproj → aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion.AbpPro.AspNetCore.csproj

@ -1,8 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace />
<PackageId>Lion.AbpPro.AspNetCore</PackageId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Ocelot.Provider.Polly" />
@ -22,7 +23,7 @@
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Serilog" />
<PackageReference Include="Serilog.AspNetCore" />
@ -34,7 +35,7 @@
<PackageReference Include="Serilog.Sinks.File" />
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" />
@ -43,9 +44,10 @@
<PackageReference Include="MiniProfiler.EntityFrameworkCore" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\frameworks\src\Lion.AbpPro.Core\Lion.AbpPro.Core.csproj" />
<Content Remove="$(UserProfile)\.nuget\packages\*\*\contentFiles\any\*\*.abppkg*.json" />
</ItemGroup>
<ItemGroup>
<Content Remove="$(UserProfile)\.nuget\packages\*\*\contentFiles\any\*\*.abppkg*.json" />
<ProjectReference Include="..\Lion.AbpPro.Core\Lion.AbpPro.Core.csproj" />
</ItemGroup>
</Project>

44
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/AbpProAspNetCoreConsts.cs

@ -0,0 +1,44 @@
namespace Lion.AbpPro.AspNetCore;
public class AbpProAspNetCoreConsts
{
/// <summary>
/// 默认跨域策略名称
/// </summary>
public const string DefaultCorsPolicyName = "Default";
/// <summary>
/// Cookies名称
/// </summary>
public const string DefaultCookieName = "Lion.AbpPro.Http.Api";
/// <summary>
/// 网关配置节名称
/// </summary>
public const string Gateway = "Gateway";
/// <summary>
/// 跨域配置节名称
/// </summary>
public const string Cors = "Cors";
/// <summary>
/// MiniProfiler配置节名称
/// </summary>
public const string MiniProfiler = "MiniProfiler";
/// <summary>
/// 多租户配置节名称
/// </summary>
public const string MultiTenancy = "MultiTenancy";
/// <summary>
/// Swagger配置节名称
/// </summary>
public const string Swagger = "Swagger";
/// <summary>
/// 审计配置节名称
/// </summary>
public const string Audit = "Audit";
}

22
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/AbpProAspNetCoreModule.cs

@ -0,0 +1,22 @@
using Lion.AbpPro.AspNetCore.Options;
namespace Lion.AbpPro.AspNetCore;
public class AbpProAspNetCoreModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var s = context.Configuration.GetSection(AbpProAspNetCoreConsts.Cors);
context.Services.Configure<AbpProGatewayOptions>(context.Configuration.GetSection(AbpProAspNetCoreConsts.Gateway));
context.Services.Configure<AbpProCorsOptions>(context.Configuration.GetSection(AbpProAspNetCoreConsts.Cors));
context.Services.Configure<AbpProMiniProfilerOptions>(context.Configuration.GetSection(AbpProAspNetCoreConsts.MiniProfiler));
context.Services.Configure<AbpProMultiTenancyOptions>(context.Configuration.GetSection(AbpProAspNetCoreConsts.MultiTenancy));
context.Services.Configure<AbpProSwaggerOptions>(context.Configuration.GetSection(AbpProAspNetCoreConsts.Swagger));
context.Services.Configure<AbpProAuditOptions>(context.Configuration.GetSection(AbpProAspNetCoreConsts.Audit));
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
}
}

14
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProAuditOptions.cs

@ -0,0 +1,14 @@
namespace Lion.AbpPro.AspNetCore.Options;
public class AbpProAuditOptions
{
/// <summary>
/// 是否启用
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// 应用名称
/// </summary>
public string ApplicationName { get; set; }
}

14
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProCorsOptions.cs

@ -0,0 +1,14 @@
namespace Lion.AbpPro.AspNetCore.Options;
public class AbpProCorsOptions
{
/// <summary>
/// 是否启用
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// 跨越设置,多个用英文逗号隔开。
/// </summary>
public string CorsOrigins { get; set; }
}

24
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProGatewayOptions.cs

@ -0,0 +1,24 @@
namespace Lion.AbpPro.AspNetCore.Options;
public class AbpProGatewayOptions
{
/// <summary>
/// 是否启用
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// consul服务地址
/// </summary>
public string ConsulServiceUrl { get; set; }
/// <summary>
/// consul服务名称
/// </summary>
public string ServiceName { get; set; }
/// <summary>
/// 健康检查地址
/// </summary>
public string HealthUrl { get; set; }
}

28
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProJwtOptions.cs

@ -0,0 +1,28 @@
namespace Lion.AbpPro.AspNetCore.Options;
public class AbpProJwtOptions
{
/// <summary>
/// JWT令牌颁发者(Issuer)
/// 用于标识令牌的颁发机构
/// </summary>
public string Issuer { get; set; }
/// <summary>
/// JWT令牌受众(Audience)
/// 指定令牌的目标接收方
/// </summary>
public string Audience { get; set; }
/// <summary>
/// JWT安全密钥
/// 用于签名和验证JWT令牌的密钥
/// </summary>
public string SecurityKey { get; set; }
/// <summary>
/// JWT令牌过期时间(分钟)
/// 令牌在颁发后多少分钟过期
/// </summary>
public int ExpirationTime { get; set; }
}

14
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProMiniProfilerOptions.cs

@ -0,0 +1,14 @@
namespace Lion.AbpPro.AspNetCore.Options;
public class AbpProMiniProfilerOptions
{
/// <summary>
/// 是否启用
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// path
/// </summary>
public string RouteBasePath { get; set; } = "/profiler";
}

9
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProMultiTenancyOptions.cs

@ -0,0 +1,9 @@
namespace Lion.AbpPro.AspNetCore.Options;
public class AbpProMultiTenancyOptions
{
/// <summary>
/// 是否启用
/// </summary>
public bool Enabled { get; set; }
}

9
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Lion/AbpPro/AspNetCore/Options/AbpProSwaggerOptions.cs

@ -0,0 +1,9 @@
namespace Lion.AbpPro.AspNetCore.Options;
public class AbpProSwaggerOptions
{
/// <summary>
/// 是否启用
/// </summary>
public bool Enabled { get; set; }
}

143
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Microsoft/AspNetCore/Builder/ApplicationBuilderExtensions.cs

@ -0,0 +1,143 @@
using Consul;
using Lion.AbpPro.AspNetCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Volo.Abp.Timing;
using System.Threading.Tasks;
using Lion.AbpPro.AspNetCore.Options;
using Microsoft.AspNetCore.Localization;
using Swashbuckle.AspNetCore.SwaggerUI;
namespace Microsoft.AspNetCore.Builder;
public static class ApplicationBuilderExtensions
{
/// <summary>
/// consul服务
/// </summary>
public static IApplicationBuilder UseAbpProConsul(this IApplicationBuilder app)
{
// 获取 AbpProGatewayOptions 配置
var consulOptions = app.ApplicationServices.GetRequiredService<IOptions<AbpProGatewayOptions>>().Value;
if (!consulOptions.Enabled)
return app;
var appLifetime = app.ApplicationServices.GetService<IHostApplicationLifetime>();
using var scope = app.ApplicationServices.CreateScope();
var clock = scope.ServiceProvider.GetService<IClock>();
var appUrl = new Uri(consulOptions.ConsulServiceUrl, UriKind.Absolute);
var client = scope.ServiceProvider.GetService<IConsulClient>();
var consulServiceRegistration = new AgentServiceRegistration
{
Name = consulOptions.ServiceName,
ID = $"{consulOptions.ServiceName}:{clock.Now:yyyyMMddHHmmssfff}",
Address = appUrl.Host,
Port = appUrl.Port,
Check = new AgentServiceCheck
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), //服务停止多久后注销
Interval = TimeSpan.FromSeconds(3), //健康检查时间间隔,或者称为心跳 间隔
HTTP = consulOptions.HealthUrl, //健康检查地址
Timeout = TimeSpan.FromSeconds(15) //超时时间
}
};
client.Agent.ServiceRegister(consulServiceRegistration);
appLifetime.ApplicationStopping.Register(() => { client.Agent.ServiceDeregister(consulServiceRegistration.ID); });
return app;
}
/// <summary>
/// Ocelot服务
/// </summary>
public static IApplicationBuilder UseAbpProOcelot(this IApplicationBuilder app)
{
// 获取 AbpProGatewayOptions 配置
var consulOptions = app.ApplicationServices.GetRequiredService<IOptions<AbpProGatewayOptions>>().Value;
if (!consulOptions.Enabled)
return app;
app.UseOcelot().Wait();
return app;
}
/// <summary>
/// 多语言中间件
/// <remarks>浏览器传递的请求头:Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6而abp钟简体中文为:zh-Hans</remarks>
/// </summary>
public static IApplicationBuilder UseAbpProRequestLocalization(this IApplicationBuilder app)
{
return app.UseAbpRequestLocalization(options =>
{
// 移除自带header解析器
options.RequestCultureProviders.RemoveAll(provider => provider is AcceptLanguageHeaderRequestCultureProvider);
// 添加header解析器
options.RequestCultureProviders.Add(new AbpProAcceptLanguageHeaderRequestCultureProvider());
});
}
/// <summary>
/// SwaggerUI
/// </summary>
// ReSharper disable once InconsistentNaming
public static IApplicationBuilder UseAbpProSwaggerUI(this IApplicationBuilder app, string endpoint, string name)
{
var swaggerOptions = app.ApplicationServices.GetRequiredService<IOptions<AbpProSwaggerOptions>>().Value;
if (!swaggerOptions.Enabled) return app;
app.UseSwagger();
app.UseAbpSwaggerUI(options =>
{
options.SwaggerEndpoint(endpoint, name);
options.DocExpansion(DocExpansion.None);
options.DefaultModelsExpandDepth(-1);
});
return app;
}
/// <summary>
/// MiniProfiler
/// </summary>
public static IApplicationBuilder UseAbpProMiniProfiler(this IApplicationBuilder app)
{
var miniProfilerOptions = app.ApplicationServices.GetRequiredService<IOptions<AbpProMiniProfilerOptions>>().Value;
if (!miniProfilerOptions.Enabled) return app;
app.UseMiniProfiler();
return app;
}
/// <summary>
/// MultiTenancy
/// </summary>
public static IApplicationBuilder UseAbpProMultiTenancy(this IApplicationBuilder app)
{
var abpProMultiTenancyOptions = app.ApplicationServices.GetRequiredService<IOptions<AbpProMultiTenancyOptions>>().Value;
if (!abpProMultiTenancyOptions.Enabled) return app;
app.UseMultiTenancy();
return app;
}
/// <summary>
/// 跨域设置
/// </summary>
public static IApplicationBuilder UseAbpProCors(this IApplicationBuilder app)
{
var corsOptions = app.ApplicationServices.GetRequiredService<IOptions<AbpProCorsOptions>>().Value;
if (!corsOptions.Enabled) return app;
app.UseCors(AbpProAspNetCoreConsts.DefaultCorsPolicyName);
return app;
}
/// <summary>
/// 审计日志
/// </summary>
public static IApplicationBuilder UseAbpProAuditing(this IApplicationBuilder app)
{
var auditOptions = app.ApplicationServices.GetRequiredService<IOptions<AbpProAuditOptions>>().Value;
if (!auditOptions.Enabled) return app;
app.UseAuditing();
return app;
}
}

4
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/AspNetCore/Localization/AbpProAcceptLanguageHeaderRequestCultureProvider.cs → aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Microsoft/AspNetCore/Localization/AbpProAcceptLanguageHeaderRequestCultureProvider.cs

@ -1,4 +1,6 @@
namespace Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Localization;
public class AbpProAcceptLanguageHeaderRequestCultureProvider : AcceptLanguageHeaderRequestCultureProvider
{

0
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/AspNetCore/Mvc/Filters/AbpProExceptionFilter.cs → aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Microsoft/AspNetCore/Mvc/Filters/AbpProExceptionFilter.cs

35
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Microsoft/AspNetCore/Mvc/Filters/AbpProResultFilter.cs

@ -0,0 +1,35 @@
namespace Microsoft.AspNetCore.Mvc.Filters;
public class AbpProResultFilter : IResultFilter, ITransientDependency
{
public void OnResultExecuting(ResultExecutingContext context)
{
// 如果是page 直接return
if (context.ActionDescriptor.IsPageAction()) return;
var controllerHasDontWrapResultAttribute =
context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.GetCustomAttributes(typeof(WrapResultAttribute), true).Any();
var controllerActionHasDontWrapResultAttribute = context.ActionDescriptor.GetMethodInfo().GetCustomAttributes(typeof(WrapResultAttribute), true).Any();
if (!controllerHasDontWrapResultAttribute && !controllerActionHasDontWrapResultAttribute) return;
context.HttpContext.Response.StatusCode = 200;
var result = new WrapResult<object>();
if (context.Result is not EmptyResult)
{
result.SetSuccess(((ObjectResult)context.Result).Value);
}
var jsonSerializer = context.GetRequiredService<IJsonSerializer>();
context.Result = new ContentResult()
{
StatusCode = (int)HttpStatusCode.OK,
ContentType = "application/json;charset=utf-8",
Content = jsonSerializer.Serialize(result)
};
}
public void OnResultExecuted(ResultExecutedContext context)
{
}
}

338
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Microsoft/Extensions/DependencyInjection/ServiceCollectionExtensions.cs

@ -0,0 +1,338 @@
using Consul;
using Lion.AbpPro.AspNetCore;
using Lion.AbpPro.AspNetCore.Options;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.IdentityModel.Tokens;
using Swagger;
using Volo.Abp.AspNetCore.Auditing;
using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
using Volo.Abp.Auditing;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
namespace Microsoft.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
/// <summary>
/// Ocelot配置
/// </summary>
public static IServiceCollection AddAbpProOcelot(this IServiceCollection service)
{
var configuration = service.GetConfiguration();
service.AddOcelot(configuration).AddConsul().AddPolly();
return service;
}
public static IServiceCollection AddAbpProConsul(this IServiceCollection service)
{
var consulOptions = service.GetRequiredService<IOptions<AbpProGatewayOptions>>().Value;
if (!consulOptions.Enabled)
return service;
service.AddSingleton<IConsulClient>(p => new ConsulClient(config => { config.Address = new Uri(consulOptions.ConsulServiceUrl); }));
return service;
}
/// <summary>
/// 健康检查
/// </summary>
public static IServiceCollection AddAbpProHealthChecks(this IServiceCollection service)
{
// TODO 检查数据库和redis是否正常 AspNetCore.HealthChecks.Redis AspNetCore.HealthChecks.MySql
// context.Services.AddHealthChecks().AddRedis(redisConnectionString).AddMySql(connectString);
return service;
}
/// <summary>
/// 配置租户解析
/// </summary>
public static IServiceCollection AddAbpProTenantResolvers(this IServiceCollection service)
{
service.Configure<AbpTenantResolveOptions>(options =>
{
options.TenantResolvers.Clear();
// 只保留通过请求头解析租户
// options.TenantResolvers.Add(new QueryStringTenantResolveContributor());
// options.TenantResolvers.Add(new RouteTenantResolveContributor());
options.TenantResolvers.Add(new HeaderTenantResolveContributor());
// options.TenantResolvers.Add(new CookieTenantResolveContributor());
});
return service;
}
/// <summary>
/// 多语言配置
/// </summary>
public static IServiceCollection AddAbpProLocalization(this IServiceCollection service)
{
service.Configure<AbpLocalizationOptions>(options =>
{
options.Languages.Add(new LanguageInfo("ar", "ar", "العربية"));
options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
});
return service;
}
/// <summary>
/// 配置跨域
/// </summary>
public static IServiceCollection AddAbpProCors(this IServiceCollection service)
{
var corsOptions = service.GetRequiredService<IOptions<AbpProCorsOptions>>().Value;
if (!corsOptions.Enabled) return service;
service.AddCors(options =>
{
options.AddPolicy(AbpProAspNetCoreConsts.DefaultCorsPolicyName, builder =>
{
builder
.WithOrigins(
corsOptions.CorsOrigins
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray()
)
//.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
//.AllowCredentials()
// https://www.cnblogs.com/JulianHuang/p/14225515.html
// https://learn.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-7.0
.SetPreflightMaxAge((TimeSpan.FromHours(24)));
});
});
return service;
}
/// <summary>
/// 阻止跨站点请求伪造
/// https://docs.microsoft.com/zh-cn/aspnet/core/security/anti-request-forgery?view=aspnetcore-6.0
/// </summary>
public static IServiceCollection AddAbpProAntiForgery(this IServiceCollection service)
{
service.Configure<AbpAntiForgeryOptions>(options => { options.AutoValidate = false; });
return service;
}
/// <summary>
/// 异常处理
/// </summary>
public static IServiceCollection AddAbpProExceptions(this IServiceCollection service)
{
service.AddMvc(options =>
{
options.Filters.Add(typeof(AbpProExceptionFilter));
options.Filters.Add(typeof(AbpProResultFilter));
}
);
return service;
}
/// <summary>
/// 添加swagger
/// </summary>
public static IServiceCollection AddAbpProSwagger(this IServiceCollection service, string name, string version = "v1")
{
var swaggerOptions = service.GetRequiredService<IOptions<AbpProSwaggerOptions>>().Value;
if (!swaggerOptions.Enabled) return service;
service.AddSwaggerGen(options =>
{
// 文件下载类型
options.MapType<FileContentResult>(() => new OpenApiSchema() { Type = "file" });
options.SwaggerDoc(name, new OpenApiInfo { Title = name, Version = version });
options.DocInclusionPredicate((docName, description) => true);
options.EnableAnnotations(); // 启用注解
options.DocumentFilter<HiddenAbpDefaultApiFilter>();
options.SchemaFilter<EnumSchemaFilter>();
// 加载所有xml注释,这里会导致swagger加载有点缓慢
var xmlPaths = Directory.GetFiles(AppContext.BaseDirectory, "*.xml");
foreach (var xml in xmlPaths)
{
options.IncludeXmlComments(xml, true);
}
options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme,
new OpenApiSecurityScheme()
{
Description = "直接在下框输入JWT生成的Token",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = JwtBearerDefaults.AuthenticationScheme,
BearerFormat = "JWT"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme, Id = "Bearer"
}
},
new List<string>()
}
});
options.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme()
{
Type = SecuritySchemeType.ApiKey,
In = ParameterLocation.Header,
Name = "Accept-Language",
Description = "多语言设置,系统预设语言有zh-Hans、en,默认为zh-Hans",
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{ Type = ReferenceType.SecurityScheme, Id = "ApiKey" }
},
Array.Empty<string>()
}
});
});
return service;
}
/// <summary>
/// 配置MiniProfiler
/// </summary>
public static IServiceCollection AddAbpProMiniProfiler(this IServiceCollection service)
{
var options = service.GetRequiredService<IOptions<AbpProMiniProfilerOptions>>().Value;
if (!options.Enabled) return service;
service.AddMiniProfiler(opt => opt.RouteBasePath = "/profiler").AddEntityFramework();
return service;
}
/// <summary>
/// 添加多租户支持
/// </summary>
public static IServiceCollection AddAbpProMultiTenancy(this IServiceCollection service)
{
var multiTenancyOptions = service.GetRequiredService<IOptions<AbpProMultiTenancyOptions>>().Value;
service.Configure<AbpMultiTenancyOptions>(options => { options.IsEnabled = multiTenancyOptions.Enabled; });
return service;
}
/// <summary>
/// 配置JWT
/// </summary>
public static IServiceCollection AddAbpProAuthentication(this IServiceCollection service)
{
var jwtOptions = service.GetRequiredService<IOptions<AbpProJwtOptions>>().Value;
service.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters =
new TokenValidationParameters()
{
// 是否开启签名认证
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
ValidIssuer = jwtOptions.Issuer,
ValidAudience = jwtOptions.Audience,
IssuerSigningKey =
new SymmetricSecurityKey(
Encoding.ASCII.GetBytes(jwtOptions.SecurityKey))
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = currentContext =>
{
var path = currentContext.HttpContext.Request.Path;
if (path.StartsWithSegments("/login"))
{
return Task.CompletedTask;
}
var accessToken = string.Empty;
if (currentContext.HttpContext.Request.Headers.ContainsKey("Authorization"))
{
accessToken = currentContext.HttpContext.Request.Headers["Authorization"];
if (!string.IsNullOrWhiteSpace(accessToken))
{
accessToken = accessToken.Split(" ").LastOrDefault();
}
}
if (accessToken.IsNullOrWhiteSpace())
{
accessToken = currentContext.Request.Query["access_token"].FirstOrDefault();
}
if (accessToken.IsNullOrWhiteSpace())
{
accessToken = currentContext.Request.Cookies[AbpProAspNetCoreConsts.DefaultCookieName];
}
currentContext.Token = accessToken;
currentContext.Request.Headers.Remove("Authorization");
currentContext.Request.Headers.Append("Authorization", $"Bearer {accessToken}");
return Task.CompletedTask;
}
};
});
return service;
}
/// <summary>
/// 审计日志
/// </summary>
public static IServiceCollection AddAbpProAuditLog(this IServiceCollection service)
{
var auditOptions = service.GetRequiredService<IOptions<AbpProAuditOptions>>().Value;
service.Configure<AbpAuditingOptions>
(options =>
{
options.IsEnabled = auditOptions.Enabled;
options.EntityHistorySelectors.AddAllEntities();
options.ApplicationName = auditOptions.ApplicationName;
}
);
service.Configure<AbpAspNetCoreAuditingOptions>(options =>
{
options.IgnoredUrls.Add("/AuditLogs/page");
options.IgnoredUrls.Add("/hangfire/stats");
options.IgnoredUrls.Add("/hangfire/recurring/trigger");
options.IgnoredUrls.Add("/cap");
options.IgnoredUrls.Add("/");
});
return service;
}
}

118
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Serilog/SerilogToEsExtensions.cs

@ -0,0 +1,118 @@
namespace Serilog;
public static class SerilogToEsExtensions
{
public static void SetSerilogConfiguration(LoggerConfiguration loggerConfiguration, IConfiguration configuration)
{
// 默认读取 configuration 中 "Serilog" 节点下的配置
loggerConfiguration
.ReadFrom.Configuration(configuration)
.Enrich.FromLogContext();
var writeToElasticSearch = configuration.GetValue("ElasticSearch:Enabled", false);
// LogToElasticSearch:Enabled = true 才输出至ES
if (!writeToElasticSearch)
return;
var applicationName = "Lion.AbpPro.HttpApi.Host";
var esUrl = configuration["ElasticSearch:Url"];
// 需要设置ES URL
if (string.IsNullOrEmpty(esUrl))
return;
var indexFormat = configuration["ElasticSearch:IndexFormat"];
// 需要设置ES URL
if (string.IsNullOrEmpty(indexFormat))
return;
var esUserName = configuration["ElasticSearch:UserName"];
var esPassword = configuration["ElasticSearch:Password"];
loggerConfiguration.Enrich.FromLogContext().Enrich.WithExceptionDetails().WriteTo
.Elasticsearch(BuildElasticSearchSinkOptions(esUrl, indexFormat, esUserName, esPassword));
loggerConfiguration.Enrich.WithProperty("Application", applicationName);
}
// 创建Es连接
private static ElasticsearchSinkOptions BuildElasticSearchSinkOptions(
string url,
string indexFormat,
string userName,
string password)
{
if (string.IsNullOrEmpty(userName))
{
return new ElasticsearchSinkOptions(new Uri(url))
{
AutoRegisterTemplate = true,
AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
IndexFormat = indexFormat
};
}
return new ElasticsearchSinkOptions(new Uri(url))
{
AutoRegisterTemplate = true,
AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
IndexFormat = indexFormat,
ModifyConnectionSettings = x => x.BasicAuthentication(userName, password)
};
}
public static void EnrichFromRequest(IDiagnosticContext diagnosticContext, HttpContext httpContext)
{
var request = httpContext.Request;
// 为每个请求都设置通用的属性
diagnosticContext.Set("Host", request.Host);
diagnosticContext.Set("Protocol", request.Protocol);
diagnosticContext.Set("Scheme", request.Scheme);
diagnosticContext.Set("RemoteIpAddress", httpContext.Connection.RemoteIpAddress);
// 如果要记录 Request Body 或 Response Body
// 参考 https://stackoverflow.com/questions/60076922/serilog-logging-web-api-methods-adding-context-properties-inside-middleware
string requestBody = ReadRequestBody(httpContext.Request).Result;
if (!string.IsNullOrEmpty(requestBody))
{
diagnosticContext.Set("RequestBody", requestBody);
}
// string responseBody = ReadResponseBody(httpContext.Response).Result;
// if (!string.IsNullOrEmpty(responseBody))
// {
// diagnosticContext.Set("ResponseBody", requestBody);
// }
if (request.QueryString.HasValue)
{
diagnosticContext.Set("QueryString", request?.QueryString.Value ?? string.Empty);
}
}
private static async Task<string> ReadRequestBody(HttpRequest request)
{
HttpRequestRewindExtensions.EnableBuffering(request);
var body = request.Body;
var buffer = new byte[Convert.ToInt32(request.ContentLength)];
await request.Body.ReadAsync(buffer, 0, buffer.Length);
string requestBody = Encoding.UTF8.GetString(buffer);
body.Seek(0, SeekOrigin.Begin);
request.Body = body;
return $"{requestBody}";
}
private static async Task<string> ReadResponseBody(HttpResponse response)
{
response.Body.Seek(0, SeekOrigin.Begin);
string responseBody = await new StreamReader(response.Body).ReadToEndAsync();
response.Body.Seek(0, SeekOrigin.Begin);
return $"{responseBody}";
}
}

0
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Swagger/CachingSwaggerProvider.cs → aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Swagger/CachingSwaggerProvider.cs

0
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Swagger/EnumSchemaFilter.cs → aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Swagger/EnumSchemaFilter.cs

48
aspnet-core/frameworks/src/Lion.AbpPro.AspNetCore/Swagger/HiddenAbpDefaultApiFilter.cs

@ -0,0 +1,48 @@
namespace Swagger;
/// <summary>
/// 在使用nswag的时候,原生默认的api导致生产的代理类存在问题
/// 所有隐藏原生的api,重写路由
/// </summary>
public class HiddenAbpDefaultApiFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
foreach (ApiDescription apiDescription in context.ApiDescriptions)
{
if (apiDescription.TryGetMethodInfo(out MethodInfo method))
{
string key = "/" + apiDescription.RelativePath;
var reuslt = IsHidden(key);
if (reuslt) swaggerDoc.Paths.Remove(key);
}
}
}
private bool IsHidden(string key)
{
var list = GetHiddenAbpDefaultApiList();
foreach (var item in list)
{
if (key.Contains(item)) return true;
}
return false;
}
private List<string> GetHiddenAbpDefaultApiList()
{
return new List<string>() {
"/api/abp/multi-tenancy/tenants",
"/api/account",
"/api/feature-management/features",
"/api/permission-management/permissions",
"/api/identity/my-profile",
"/api/identity",
"/api/multi-tenancy/tenants",
"/api/setting-management/emailing",
"/configuration",
"/outputcache"
};
}
}

10
aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProCapServiceCollectionExtensions.cs

@ -11,4 +11,14 @@ public static class AbpProCapServiceCollectionExtensions
context.Services.AddCap(capAction);
return context;
}
public static IServiceCollection AddAbpCap(this IServiceCollection service, Action<CapOptions> capAction)
{
service.Replace(ServiceDescriptor.Transient<IUnitOfWork, AbpProCapUnitOfWork>());
service.Replace(ServiceDescriptor.Transient<UnitOfWork, AbpProCapUnitOfWork>());
service.AddSingleton<ISubscribeInvoker, AbpProCAPSubscribeInvoker>();
service.AddTransient<AbpProCapUnitOfWork>();
service.AddCap(capAction);
return service;
}
}

4
aspnet-core/gateways/Lion.AbpPro.WebGateway/AbpProWebGatewayModule.cs

@ -1,7 +1,9 @@
using Lion.AbpPro.AspNetCore;
namespace Lion.AbpPro.WebGateway
{
[DependsOn(
typeof(AbpProSharedHostingGatewayModule))]
typeof(AbpProAspNetCoreModule))]
public class AbpProWebGatewayModule : AbpModule
{
private const string DefaultCorsPolicyName = "Default";

3
aspnet-core/gateways/Lion.AbpPro.WebGateway/Lion.AbpPro.WebGateway.csproj

@ -4,9 +4,8 @@
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\shared\Lion.AbpPro.Shared.Hosting.Gateways\Lion.AbpPro.Shared.Hosting.Gateways.csproj" />
<ProjectReference Include="..\..\frameworks\src\Lion.AbpPro.AspNetCore\Lion.AbpPro.AspNetCore.csproj" />
</ItemGroup>
</Project>

3
aspnet-core/modules/BasicManagement/host/Lion.AbpPro.BasicManagement.HttpApi.Host/BasicManagementHttpApiHostModule.cs

@ -1,4 +1,5 @@
using System.Text;
using Lion.AbpPro.AspNetCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.DataProtection;
using Lion.AbpPro.BasicManagement.EntityFrameworkCore;
@ -34,7 +35,7 @@ namespace Lion.AbpPro.BasicManagement;
typeof(AbpEntityFrameworkCoreMySQLModule),
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpSwashbuckleModule),
typeof(AbpProSharedHostingMicroserviceModule)
typeof(AbpProAspNetCoreModule)
)]
public class BasicManagementHttpApiHostModule : AbpModule
{

2
aspnet-core/modules/BasicManagement/host/Lion.AbpPro.BasicManagement.HttpApi.Host/Lion.AbpPro.BasicManagement.HttpApi.Host.csproj

@ -26,7 +26,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\shared\Lion.AbpPro.Shared.Hosting.Microservices\Lion.AbpPro.Shared.Hosting.Microservices.csproj" />
<ProjectReference Include="..\..\..\..\frameworks\src\Lion.AbpPro.AspNetCore\Lion.AbpPro.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.BasicManagement.HttpApi\Lion.AbpPro.BasicManagement.HttpApi.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.BasicManagement.Application\Lion.AbpPro.BasicManagement.Application.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.BasicManagement.EntityFrameworkCore\Lion.AbpPro.BasicManagement.EntityFrameworkCore.csproj" />

5
aspnet-core/modules/DataDictionaryManagement/host/Lion.AbpPro.DataDictionaryManagement.HttpApi.Host/DataDictionaryManagementHttpApiHostModule.cs

@ -1,3 +1,5 @@
using Lion.AbpPro.AspNetCore;
namespace Lion.AbpPro.DataDictionaryManagement
{
[DependsOn(
@ -12,7 +14,8 @@ namespace Lion.AbpPro.DataDictionaryManagement
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpSwashbuckleModule)
typeof(AbpSwashbuckleModule),
typeof(AbpProAspNetCoreModule)
)]
public class DataDictionaryManagementHttpApiHostModule : AbpModule
{

2
aspnet-core/modules/DataDictionaryManagement/host/Lion.AbpPro.DataDictionaryManagement.HttpApi.Host/Lion.AbpPro.DataDictionaryManagement.HttpApi.Host.csproj

@ -26,7 +26,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\shared\Lion.AbpPro.Shared.Hosting.Microservices\Lion.AbpPro.Shared.Hosting.Microservices.csproj" />
<ProjectReference Include="..\..\..\..\frameworks\src\Lion.AbpPro.AspNetCore\Lion.AbpPro.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.DataDictionaryManagement.HttpApi\Lion.AbpPro.DataDictionaryManagement.HttpApi.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.DataDictionaryManagement.Application\Lion.AbpPro.DataDictionaryManagement.Application.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore\Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore.csproj" />

5
aspnet-core/modules/FileManagement/host/Lion.AbpPro.FileManagement.HttpApi.Host/FileManagementHttpApiHostModule.cs

@ -1,3 +1,5 @@
using Lion.AbpPro.AspNetCore;
namespace Lion.AbpPro.FileManagement;
[DependsOn(
@ -8,7 +10,8 @@ namespace Lion.AbpPro.FileManagement;
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpSwashbuckleModule),
typeof(AbpEntityFrameworkCoreMySQLModule)
typeof(AbpEntityFrameworkCoreMySQLModule),
typeof(AbpProAspNetCoreModule)
)]
public class FileManagementHttpApiHostModule : AbpModule
{

2
aspnet-core/modules/FileManagement/host/Lion.AbpPro.FileManagement.HttpApi.Host/Lion.AbpPro.FileManagement.HttpApi.Host.csproj

@ -32,7 +32,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\shared\Lion.AbpPro.Shared.Hosting.Microservices\Lion.AbpPro.Shared.Hosting.Microservices.csproj" />
<ProjectReference Include="..\..\..\..\frameworks\src\Lion.AbpPro.AspNetCore\Lion.AbpPro.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.FileManagement.HttpApi\Lion.AbpPro.FileManagement.HttpApi.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.FileManagement.Application\Lion.AbpPro.FileManagement.Application.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.FileManagement.EntityFrameworkCore\Lion.AbpPro.FileManagement.EntityFrameworkCore.csproj" />

5
aspnet-core/modules/LanguageManagement/host/Lion.AbpPro.LanguageManagement.HttpApi.Host/LanguageManagementHttpApiHostModule.cs

@ -1,3 +1,5 @@
using Lion.AbpPro.AspNetCore;
namespace Lion.AbpPro.LanguageManagement
{
[DependsOn(
@ -12,7 +14,8 @@ namespace Lion.AbpPro.LanguageManagement
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpSwashbuckleModule)
typeof(AbpSwashbuckleModule),
typeof(AbpProAspNetCoreModule)
)]
public class LanguageManagementHttpApiHostModule : AbpModule
{

2
aspnet-core/modules/LanguageManagement/host/Lion.AbpPro.LanguageManagement.HttpApi.Host/Lion.AbpPro.LanguageManagement.HttpApi.Host.csproj

@ -26,7 +26,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\shared\Lion.AbpPro.Shared.Hosting.Microservices\Lion.AbpPro.Shared.Hosting.Microservices.csproj" />
<ProjectReference Include="..\..\..\..\frameworks\src\Lion.AbpPro.AspNetCore\Lion.AbpPro.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.LanguageManagement.HttpApi\Lion.AbpPro.LanguageManagement.HttpApi.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.LanguageManagement.Application\Lion.AbpPro.LanguageManagement.Application.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.LanguageManagement.EntityFrameworkCore\Lion.AbpPro.LanguageManagement.EntityFrameworkCore.csproj" />

2
aspnet-core/modules/NotificationManagement/host/Lion.AbpPro.NotificationManagement.HttpApi.Host/Lion.AbpPro.NotificationManagement.HttpApi.Host.csproj

@ -31,8 +31,8 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\frameworks\src\Lion.AbpPro.AspNetCore\Lion.AbpPro.AspNetCore.csproj" />
<ProjectReference Include="..\..\..\..\frameworks\src\Lion.AbpPro.CAP\Lion.AbpPro.CAP.csproj"/>
<ProjectReference Include="..\..\..\..\shared\Lion.AbpPro.Shared.Hosting.Microservices\Lion.AbpPro.Shared.Hosting.Microservices.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.NotificationManagement.HttpApi\Lion.AbpPro.NotificationManagement.HttpApi.csproj"/>
<ProjectReference Include="..\..\src\Lion.AbpPro.NotificationManagement.Application\Lion.AbpPro.NotificationManagement.Application.csproj"/>
<ProjectReference Include="..\..\src\Lion.AbpPro.NotificationManagement.EntityFrameworkCore\Lion.AbpPro.NotificationManagement.EntityFrameworkCore.csproj"/>

5
aspnet-core/modules/NotificationManagement/host/Lion.AbpPro.NotificationManagement.HttpApi.Host/NotificationManagementHttpApiHostModule.cs

@ -1,3 +1,5 @@
using Lion.AbpPro.AspNetCore;
namespace Lion.AbpPro.NotificationManagement;
[DependsOn(
@ -9,7 +11,8 @@ namespace Lion.AbpPro.NotificationManagement;
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpSwashbuckleModule),
typeof(AbpProCapModule),
typeof(AbpEntityFrameworkCoreMySQLModule)
typeof(AbpEntityFrameworkCoreMySQLModule),
typeof(AbpProAspNetCoreModule)
)]
public class NotificationManagementHttpApiHostModule : AbpModule
{

293
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/AbpProHttpApiHostModule.Configure.cs

@ -1,293 +0,0 @@
using Medallion.Threading;
using Medallion.Threading.Redis;
using Volo.Abp.BlobStoring;
using Volo.Abp.BlobStoring.FileSystem;
#pragma warning disable CS0618 // Type or member is obsolete
namespace Lion.AbpPro;
public partial class AbpProHttpApiHostModule
{
private void ConfigureHangfire(ServiceConfigurationContext context)
{
var redisStorageOptions = new RedisStorageOptions()
{
Db = context.Services.GetConfiguration().GetValue<int>("Hangfire:Redis:DB")
};
Configure<AbpBackgroundJobOptions>(options => { options.IsJobExecutionEnabled = true; });
context.Services.AddHangfire(config =>
{
config.UseRedisStorage(
context.Services.GetConfiguration().GetValue<string>("Hangfire:Redis:Host"), redisStorageOptions)
.WithJobExpirationTimeout(TimeSpan.FromDays(7));
var delaysInSeconds = new[] { 10, 60, 60 * 3 }; // 重试时间间隔
const int Attempts = 3; // 重试次数
config.UseFilter(new AutomaticRetryAttribute() { Attempts = Attempts, DelaysInSeconds = delaysInSeconds });
//config.UseFilter(new AutoDeleteAfterSuccessAttribute(TimeSpan.FromDays(7)));
config.UseFilter(new JobRetryLastFilter(Attempts));
});
}
/// <summary>
/// 配置MiniProfiler
/// </summary>
private void ConfigureMiniProfiler(ServiceConfigurationContext context)
{
if (context.Services.GetConfiguration().GetValue("MiniProfiler:Enabled", false))
{
context.Services.AddMiniProfiler(options => options.RouteBasePath = "/profiler").AddEntityFramework();
}
}
/// <summary>
/// 配置JWT
/// </summary>
private void ConfigureJwtAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters =
new TokenValidationParameters()
{
// 是否开启签名认证
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
ValidIssuer = configuration["Jwt:Issuer"],
ValidAudience = configuration["Jwt:Audience"],
IssuerSigningKey =
new SymmetricSecurityKey(
Encoding.ASCII.GetBytes(configuration["Jwt:SecurityKey"]))
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = currentContext =>
{
var path = currentContext.HttpContext.Request.Path;
if (path.StartsWithSegments("/login"))
{
return Task.CompletedTask;
}
var accessToken = string.Empty;
if (currentContext.HttpContext.Request.Headers.ContainsKey("Authorization"))
{
accessToken = currentContext.HttpContext.Request.Headers["Authorization"];
if (!string.IsNullOrWhiteSpace(accessToken))
{
accessToken = accessToken.Split(" ").LastOrDefault();
}
}
if (accessToken.IsNullOrWhiteSpace())
{
accessToken = currentContext.Request.Query["access_token"].FirstOrDefault();
}
if (accessToken.IsNullOrWhiteSpace())
{
accessToken = currentContext.Request.Cookies[AbpProHttpApiHostConst.DefaultCookieName];
}
currentContext.Token = accessToken;
currentContext.Request.Headers.Remove("Authorization");
currentContext.Request.Headers.Append("Authorization", $"Bearer {accessToken}");
return Task.CompletedTask;
}
};
});
}
/// <summary>
/// Redis缓存
/// </summary>
private void ConfigureCache(ServiceConfigurationContext context)
{
Configure<AbpDistributedCacheOptions>(
options => { options.KeyPrefix = "AbpPro:"; });
var configuration = context.Services.GetConfiguration();
var redis = ConnectionMultiplexer.Connect(configuration.GetValue<string>("Redis:Configuration"));
context.Services
.AddDataProtection()
.PersistKeysToStackExchangeRedis(redis, "AbpPro-Protection-Keys");
}
/// <summary>
/// 配置Identity
/// </summary>
private void ConfigureIdentity(ServiceConfigurationContext context)
{
context.Services.Configure<IdentityOptions>(options => { options.Lockout = new LockoutOptions() { AllowedForNewUsers = false }; });
}
private void ConfigurationSignalR(ServiceConfigurationContext context)
{
context.Services
.AddSignalR()
.AddStackExchangeRedis(context.Services.GetConfiguration().GetValue<string>("Redis:Configuration"),
options => { options.Configuration.ChannelPrefix = "Lion.AbpPro"; });
}
private void ConfigureSwaggerServices(ServiceConfigurationContext context)
{
context.Services.AddSwaggerGen(
options =>
{
// 文件下载类型
options.MapType<FileContentResult>(() => new OpenApiSchema() { Type = "file" });
options.SwaggerDoc("AbpPro",
new OpenApiInfo { Title = "AbpPro API", Version = "v1" });
options.DocInclusionPredicate((docName, description) => true);
options.EnableAnnotations(); // 启用注解
options.DocumentFilter<HiddenAbpDefaultApiFilter>();
options.SchemaFilter<EnumSchemaFilter>();
// 加载所有xml注释,这里会导致swagger加载有点缓慢
var xmlPaths = Directory.GetFiles(AppContext.BaseDirectory, "*.xml");
foreach (var xml in xmlPaths)
{
options.IncludeXmlComments(xml, true);
}
options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme,
new OpenApiSecurityScheme()
{
Description = "直接在下框输入JWT生成的Token",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = JwtBearerDefaults.AuthenticationScheme,
BearerFormat = "JWT"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme, Id = "Bearer"
}
},
new List<string>()
}
});
options.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme()
{
Type = SecuritySchemeType.ApiKey,
In = ParameterLocation.Header,
Name = "Accept-Language",
Description = "多语言设置,系统预设语言有zh-Hans、en,默认为zh-Hans",
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{ Type = ReferenceType.SecurityScheme, Id = "ApiKey" }
},
Array.Empty<string>()
}
});
});
}
private void ConfigureCap(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
context.AddAbpCap(capOptions =>
{
capOptions.SetCapDbConnectionString(configuration["ConnectionStrings:Default"]);
capOptions.UseEntityFramework<AbpProDbContext>();
capOptions.UseRabbitMQ(option =>
{
option.HostName = configuration.GetValue<string>("Cap:RabbitMq:HostName");
option.UserName = configuration.GetValue<string>("Cap:RabbitMq:UserName");
option.Password = configuration.GetValue<string>("Cap:RabbitMq:Password");
option.Port = configuration.GetValue<int>("Cap:RabbitMq:Port");
});
capOptions.UseDashboard(options =>
{
options.AuthorizationPolicy = AbpProCapPermissions.CapManagement.Cap;
});
});
}
/// <summary>
/// 审计日志
/// </summary>
private void ConfigureAuditLog(ServiceConfigurationContext context)
{
Configure<AbpAuditingOptions>
(
options =>
{
options.IsEnabled = true;
options.EntityHistorySelectors.AddAllEntities();
options.ApplicationName = "Lion.AbpPro";
}
);
Configure<AbpAspNetCoreAuditingOptions>(
options =>
{
options.IgnoredUrls.Add("/AuditLogs/page");
options.IgnoredUrls.Add("/hangfire/stats");
options.IgnoredUrls.Add("/hangfire/recurring/trigger");
options.IgnoredUrls.Add("/cap");
options.IgnoredUrls.Add("/");
});
}
private void ConfigurationMultiTenancy()
{
Configure<AbpMultiTenancyOptions>(options => { options.IsEnabled = MultiTenancyConsts.IsEnabled; });
}
/// <summary>
/// 配置redis分布式锁
/// </summary>
private void ConfigurationDistributedLocking(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
var connectionString = configuration.GetValue<string>("Redis:Configuration");
context.Services.AddSingleton<IDistributedLockProvider>(sp =>
{
var connection = ConnectionMultiplexer.Connect(connectionString);
return new RedisDistributedSynchronizationProvider(connection.GetDatabase());
});
}
/// <summary>
/// 配置blob设置
/// </summary>
private void ConfigureBlobStorage()
{
Configure<AbpBlobStoringOptions>(options =>
{
options.Containers.ConfigureDefault(container =>
{
container.UseFileSystem(fileSystem =>
{
fileSystem.BasePath = "C:\\my-files";
});
});
});
}
}

122
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/AbpProHttpApiHostModule.cs

@ -1,12 +1,8 @@
using Lion.AbpPro.Starter;
using Volo.Abp.BlobStoring.FileSystem;
using Volo.Abp.DistributedLocking;
namespace Lion.AbpPro
{
[DependsOn(
typeof(AbpProHttpApiModule),
typeof(AbpProSharedHostingMicroserviceModule),
typeof(AbpProAspNetCoreModule),
typeof(AbpAspNetCoreMvcUiMultiTenancyModule),
typeof(AbpProEntityFrameworkCoreModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
@ -33,55 +29,102 @@ namespace Lion.AbpPro
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
ConfigureCache(context);
ConfigurationDistributedLocking(context);
ConfigureSwaggerServices(context);
ConfigureJwtAuthentication(context, configuration);
//ConfigureHangfire(context);
ConfigureMiniProfiler(context);
ConfigureIdentity(context);
//ConfigureCap(context);
ConfigureAuditLog(context);
ConfigurationSignalR(context);
ConfigurationMultiTenancy();
ConfigureBlobStorage();
context.Services
.AddAbpProAuditLog()
.AddAbpProAuthentication()
.AddAbpProMultiTenancy()
.AddAbpProRedis()
.AddAbpProRedisDistributedLocking()
.AddAbpProMiniProfiler()
.AddAbpProCors()
.AddAbpProAntiForgery()
.AddAbpProIdentity()
.AddAbpProBlobStorage()
.AddAbpProSignalR()
.AddAbpProHealthChecks()
.AddAbpProTenantResolvers()
.AddAbpProLocalization()
.AddAbpProExceptions()
.AddAbpProSwagger("AbpPro");
// //ConfigureCache(context);
// context.Services.AddAbpProRedis();
//
// //ConfigurationDistributedLocking(context);
// context.Services.AddAbpProRedisDistributedLocking();
//
//
// //ConfigureSwaggerServices(context);
// context.Services.AddAbpProSwagger("AbpPro");
//
// //ConfigureJwtAuthentication(context, configuration);
// context.Services.AddAbpProAuthentication();
//
// //ConfigureHangfire(context);
//
// //ConfigureMiniProfiler(context);
// context.Services.AddAbpProMiniProfiler();
//
// //ConfigureIdentity(context);
// context.Services.AddAbpProIdentity();
//
// //ConfigureCap(context);
//
// //ConfigureAuditLog(context);
// context.Services.AddAbpProAuditLog();
//
// //ConfigurationSignalR(context);
// context.Services.AddAbpProSignalR();
//
// //ConfigurationMultiTenancy();
// context.Services.AddAbpProMultiTenancy();
//
// //ConfigureBlobStorage();
// context.Services.AddAbpProBlobStorage();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var configuration = context.GetConfiguration();
//var configuration = context.GetConfiguration();
app.UseAbpProRequestLocalization();
app.UseCorrelationId();
app.MapAbpStaticAssets();
if (configuration.GetValue("MiniProfiler:Enabled", false))
{
app.UseMiniProfiler();
}
// if (configuration.GetValue("MiniProfiler:Enabled", false))
// {
// app.UseMiniProfiler();
// }
app.UseAbpProMiniProfiler();
app.UseRouting();
app.UseCors(AbpProHttpApiHostConst.DefaultCorsPolicyName);
//app.UseCors(AbpProHttpApiHostConst.DefaultCorsPolicyName);
app.UseAbpProCors();
app.UseAuthentication();
if (MultiTenancyConsts.IsEnabled)
{
app.UseMultiTenancy();
}
// if (MultiTenancyConsts.IsEnabled)
// {
// app.UseMultiTenancy();
// }
app.UseAbpProMultiTenancy();
app.UseAuthorization();
app.UseSwagger();
app.UseAbpSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/AbpPro/swagger.json", "AbpPro API");
options.DocExpansion(DocExpansion.None);
options.DefaultModelsExpandDepth(-1);
});
// app.UseSwagger();
// app.UseAbpSwaggerUI(options =>
// {
// options.SwaggerEndpoint("/swagger/AbpPro/swagger.json", "AbpPro API");
// options.DocExpansion(DocExpansion.None);
// options.DefaultModelsExpandDepth(-1);
// });
app.UseAuditing();
app.UseAbpProSwaggerUI("/swagger/AbpPro/swagger.json","AbpPro");
//app.UseAuditing();
app.UseAbpProAuditing();
app.UseAbpSerilogEnrichers();
app.UseUnitOfWork();
app.UseConfiguredEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
@ -94,10 +137,7 @@ namespace Lion.AbpPro
});
if (configuration.GetValue("Consul:Enabled", false))
{
app.UseConsul();
}
app.UseAbpProConsul();
}
}
}

12
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/GlobalUsings.cs

@ -7,6 +7,7 @@ global using System.Linq;
global using System.Text;
global using System.Text.RegularExpressions;
global using System.Threading.Tasks;
global using Consul;
global using Hangfire;
global using Hangfire.Common;
global using Hangfire.Dashboard;
@ -14,6 +15,8 @@ global using Hangfire.Redis;
global using Hangfire.Redis.StackExchange;
global using Hangfire.States;
global using Hangfire.Storage;
global using Lion.AbpPro.AspNetCore;
global using Lion.AbpPro.AspNetCore.Options;
global using Lion.AbpPro.CAP;
global using Lion.AbpPro.CAP.EntityFrameworkCore;
global using Lion.AbpPro.EntityFrameworkCore;
@ -21,8 +24,11 @@ global using Lion.AbpPro.Core;
global using Lion.AbpPro.Extensions;
global using Lion.AbpPro.Extensions.Hangfire;
global using Lion.AbpPro.MultiTenancy;
global using Lion.AbpPro.Starter;
global using Magicodes.ExporterAndImporter.Core;
global using Magicodes.ExporterAndImporter.Excel;
global using Medallion.Threading;
global using Medallion.Threading.Redis;
global using Microsoft.AspNetCore.Authentication.JwtBearer;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.DataProtection;
@ -51,7 +57,9 @@ global using Volo.Abp.Account.Web;
global using Volo.Abp.AspNetCore.Auditing;
global using Volo.Abp.AspNetCore.Authentication.JwtBearer;
global using Volo.Abp.AspNetCore.ExceptionHandling;
global using Volo.Abp.AspNetCore.MultiTenancy;
global using Volo.Abp.AspNetCore.Mvc;
global using Volo.Abp.AspNetCore.Mvc.AntiForgery;
global using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy;
global using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic;
global using Volo.Abp.AspNetCore.Serilog;
@ -59,13 +67,17 @@ global using Volo.Abp.Auditing;
global using Volo.Abp.Authorization;
global using Volo.Abp.BackgroundJobs;
global using Volo.Abp.BackgroundJobs.Hangfire;
global using Volo.Abp.BlobStoring;
global using Volo.Abp.BlobStoring.FileSystem;
global using Volo.Abp.Caching;
global using Volo.Abp.Caching.StackExchangeRedis;
global using Volo.Abp.DependencyInjection;
global using Volo.Abp.DistributedLocking;
global using Volo.Abp.Domain.Entities;
global using Volo.Abp.ExceptionHandling;
global using Volo.Abp.Http;
global using Volo.Abp.Json;
global using Volo.Abp.Localization;
global using Volo.Abp.Modularity;
global using Volo.Abp.MultiTenancy;
global using Volo.Abp.Users;

2
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Lion.AbpPro.HttpApi.Host.csproj

@ -44,10 +44,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\frameworks\src\Lion.AbpPro.AspNetCore\Lion.AbpPro.AspNetCore.csproj" />
<ProjectReference Include="..\..\..\frameworks\src\Lion.AbpPro.CAP.EntityFrameworkCore\Lion.AbpPro.CAP.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\frameworks\src\Lion.AbpPro.CAP\Lion.AbpPro.CAP.csproj" />
<ProjectReference Include="..\..\..\frameworks\src\Lion.AbpPro.Starter\Lion.AbpPro.Starter.csproj" />
<ProjectReference Include="..\..\..\shared\Lion.AbpPro.Shared.Hosting.Microservices\Lion.AbpPro.Shared.Hosting.Microservices.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.Application\Lion.AbpPro.Application.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.EntityFrameworkCore\Lion.AbpPro.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\src\Lion.AbpPro.HttpApi\Lion.AbpPro.HttpApi.csproj" />

113
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Microsoft/Extensions/DependencyInjection/ServiceCollectionExtensions.cs

@ -0,0 +1,113 @@
#pragma warning disable CS0618 // Type or member is obsolete
namespace Microsoft.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
/// <summary>
/// 注册Redis缓存
/// </summary>
public static IServiceCollection AddAbpProRedis(this IServiceCollection service)
{
service.Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "AbpPro:"; });
var configuration = service.GetConfiguration();
var redis = ConnectionMultiplexer.Connect(configuration.GetValue<string>("Redis:Configuration"));
service
.AddDataProtection()
.PersistKeysToStackExchangeRedis(redis, "AbpPro-Protection-Keys");
return service;
}
/// <summary>
/// 注册redis分布式锁
/// </summary>
public static IServiceCollection AddAbpProRedisDistributedLocking(this IServiceCollection service)
{
var configuration = service.GetConfiguration();
var connectionString = configuration.GetValue<string>("Redis:Configuration");
service.AddSingleton<IDistributedLockProvider>(sp =>
{
var connection = ConnectionMultiplexer.Connect(connectionString);
return new RedisDistributedSynchronizationProvider(connection.GetDatabase());
});
return service;
}
/// <summary>
/// 注册Identity
/// </summary>
public static IServiceCollection AddAbpProIdentity(this IServiceCollection service)
{
service.Configure<IdentityOptions>(options => { options.Lockout = new LockoutOptions() { AllowedForNewUsers = false }; });
return service;
}
/// <summary>
/// 注册SignalR
/// </summary>
public static IServiceCollection AddAbpProSignalR(this IServiceCollection service)
{
service
.AddSignalR()
.AddStackExchangeRedis(service.GetConfiguration().GetValue<string>("Redis:Configuration"),
options => { options.Configuration.ChannelPrefix = "Lion.AbpPro"; });
return service;
}
/// <summary>
/// 注册blob设置
/// </summary>
public static IServiceCollection AddAbpProBlobStorage(this IServiceCollection service)
{
service.Configure<AbpBlobStoringOptions>(options => { options.Containers.ConfigureDefault(container => { container.UseFileSystem(fileSystem => { fileSystem.BasePath = "C:\\my-files"; }); }); });
return service;
}
/// <summary>
/// 注册cap
/// </summary>
public static IServiceCollection AddAbpProCap(this IServiceCollection service)
{
var configuration = service.GetConfiguration();
service.AddAbpCap(capOptions =>
{
capOptions.SetCapDbConnectionString(configuration["ConnectionStrings:Default"]);
capOptions.UseEntityFramework<AbpProDbContext>();
capOptions.UseRabbitMQ(option =>
{
option.HostName = configuration.GetValue<string>("Cap:RabbitMq:HostName");
option.UserName = configuration.GetValue<string>("Cap:RabbitMq:UserName");
option.Password = configuration.GetValue<string>("Cap:RabbitMq:Password");
option.Port = configuration.GetValue<int>("Cap:RabbitMq:Port");
});
capOptions.UseDashboard(options => { options.AuthorizationPolicy = AbpProCapPermissions.CapManagement.Cap; });
});
return service;
}
/// <summary>
/// 注册hangfire
/// </summary>
public static IServiceCollection AddAbpProHangfire(this IServiceCollection service)
{
var redisStorageOptions = new RedisStorageOptions()
{
Db = service.GetConfiguration().GetValue<int>("Hangfire:Redis:DB")
};
service.Configure<AbpBackgroundJobOptions>(options => { options.IsJobExecutionEnabled = true; });
service.AddHangfire(config =>
{
config.UseRedisStorage(
service.GetConfiguration().GetValue<string>("Hangfire:Redis:Host"), redisStorageOptions)
.WithJobExpirationTimeout(TimeSpan.FromDays(7));
var delaysInSeconds = new[] { 10, 60, 60 * 3 }; // 重试时间间隔
const int attempts = 3; // 重试次数
config.UseFilter(new AutomaticRetryAttribute() { Attempts = 3, DelaysInSeconds = delaysInSeconds });
//config.UseFilter(new AutoDeleteAfterSuccessAttribute(TimeSpan.FromDays(7)));
config.UseFilter(new JobRetryLastFilter(attempts));
});
return service;
}
}

27
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/appsettings.json

@ -38,12 +38,12 @@
},
"Hangfire": {
"Redis": {
"Host": "localhost:6379,password=1q2w3E*",
"Host": "117.72.203.231:6379,password=1q2w3E*",
"DB": "2"
}
},
"Redis": {
"Configuration": "localhost:6379,password=1q2w3E*,defaultdatabase=9"
"Configuration": "117.72.203.231:6379,password=75He82bB5jFA84XZ1,defaultdatabase=2"
},
"Jwt": {
"Audience": "Lion.AbpPro",
@ -67,14 +67,27 @@
"Password": "aVVhjQ95RP7nbwNy",
"SearchIndexFormat": "Lion.AbpPro.development*"
},
"Consul": {
"Enabled": false,
"Host": "http://localhost:8500",
"Service": "LionAbpPro-Service"
},
"MiniProfiler": {
"Enabled": true,
"RouteBasePath": "profiler"
},
"Swagger": {
"Enabled": true
},
"Audit": {
"Enabled": true,
"ApplicationName": "Lion.AbpPro"
},
"Cors": {
"Enabled": true,
"CorsOrigins": "http://localhost:4200,http://localhost:4201"
},
"Gateway": {
"Enabled": false
},
"MultiTenancy": {
"Enabled": true
},
"Preheat": {
"Enabled": true,
"RequestUrl": "http://localhost:44315/api/abp/application-configuration?IncludeLocalizationResources=false"

9
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Gateways/GlobalUsings.cs

@ -1,9 +0,0 @@
// Global using directives
global using Microsoft.Extensions.DependencyInjection;
global using Ocelot.DependencyInjection;
global using Ocelot.Provider.Consul;
global using Ocelot.Provider.Polly;
global using Volo.Abp.Autofac;
global using Volo.Abp.Modularity;
global using Volo.Abp.Swashbuckle;

21
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Gateways/Lion.AbpPro.Shared.Hosting.Gateways.csproj

@ -1,21 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Ocelot" />
<PackageReference Include="Ocelot.Provider.Consul" />
<PackageReference Include="Ocelot.Provider.Polly" />
<PackageReference Include="Volo.Abp" />
<PackageReference Include="Volo.Abp.AspNetCore" />
<PackageReference Include="Volo.Abp.Autofac" />
<PackageReference Include="Volo.Abp.Core" />
<PackageReference Include="Volo.Abp.Swashbuckle" />
<PackageReference Include="Swashbuckle.AspNetCore" />
</ItemGroup>
<ItemGroup>
<Content Remove="$(UserProfile)\.nuget\packages\*\*\contentFiles\any\*\*.abppkg*.json" />
</ItemGroup>
</Project>

32
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Gateways/Lion/AbpPro/AbpProSharedHostingGatewayModule.cs

@ -1,32 +0,0 @@
namespace Lion.AbpPro
{
[DependsOn(
typeof(AbpSwashbuckleModule),
typeof(AbpAutofacModule))]
public class AbpProSharedHostingGatewayModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
ConfigureOcelot(context);
ConfigureHealthChecks(context);
}
/// <summary>
/// Ocelot配置
/// </summary>
private static void ConfigureOcelot(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
context.Services.AddOcelot(configuration).AddConsul().AddPolly();
}
/// <summary>
/// 健康检查
/// </summary>
/// <param name="context"></param>
private void ConfigureHealthChecks(ServiceConfigurationContext context)
{
context.Services.AddHealthChecks();
}
}
}

140
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Lion/AbpPro/AbpProSharedHostingMicroserviceModule.cs

@ -1,140 +0,0 @@
using Microsoft.AspNetCore.DataProtection;
using StackExchange.Redis;
using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.Caching;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Settings;
namespace Lion.AbpPro;
[DependsOn(
typeof(AbpSwashbuckleModule),
typeof(AbpAutofacModule),
typeof(AbpProCoreModule))]
public class AbpProSharedHostingMicroserviceModule : AbpModule
{
private const string DefaultCorsPolicyName = "Default";
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
context.Services.AddConsulConfig(configuration);
ConfigureHealthChecks(context);
ConfigureLocalization();
ConfigureCors(context);
ConfigureConsul(context, configuration);
ConfigAntiForgery();
ConfigureAbpExceptions(context);
ConfigureTenantResolvers();
}
/// <summary>
/// 异常处理
/// </summary>
private void ConfigureAbpExceptions(ServiceConfigurationContext context)
{
context.Services.AddMvc
(
options =>
{
options.Filters.Add(typeof(AbpProExceptionFilter));
options.Filters.Add(typeof(AbpProResultFilter));
}
);
}
/// <summary>
/// 阻止跨站点请求伪造
/// https://docs.microsoft.com/zh-cn/aspnet/core/security/anti-request-forgery?view=aspnetcore-6.0
/// </summary>
private void ConfigAntiForgery()
{
Configure<AbpAntiForgeryOptions>(options => { options.AutoValidate = false; });
}
private void ConfigureConsul(ServiceConfigurationContext context, IConfiguration configuration)
{
if (configuration.GetValue<bool>("Consul:Enabled", false))
{
context.Services.AddConsulConfig(configuration);
}
}
/// <summary>
/// 配置跨域
/// </summary>
private void ConfigureCors(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
context.Services.AddCors(options =>
{
options.AddPolicy(DefaultCorsPolicyName, builder =>
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray()
)
//.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
//.AllowCredentials()
// https://www.cnblogs.com/JulianHuang/p/14225515.html
// https://learn.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-7.0
.SetPreflightMaxAge((TimeSpan.FromHours(24)));
});
});
}
/// <summary>
/// 多语言配置
/// </summary>
private void ConfigureLocalization()
{
Configure<AbpLocalizationOptions>(options =>
{
options.Languages.Add(new LanguageInfo("ar", "ar", "العربية"));
options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
});
}
/// <summary>
/// 健康检查
/// </summary>
private void ConfigureHealthChecks(ServiceConfigurationContext context)
{
// TODO 检查数据库和redis是否正常 AspNetCore.HealthChecks.Redis AspNetCore.HealthChecks.MySql
// context.Services.AddHealthChecks().AddRedis(redisConnectionString).AddMySql(connectString);
context.Services.AddHealthChecks();
}
/// <summary>
/// 配置租户解析
/// </summary>
private void ConfigureTenantResolvers()
{
Configure<AbpTenantResolveOptions>(options =>
{
options.TenantResolvers.Clear();
// 只保留通过请求头解析租户
// options.TenantResolvers.Add(new QueryStringTenantResolveContributor());
// options.TenantResolvers.Add(new RouteTenantResolveContributor());
options.TenantResolvers.Add(new HeaderTenantResolveContributor());
// options.TenantResolvers.Add(new CookieTenantResolveContributor());
});
}
}

79
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/AspNetCore/Builder/ApplicationBuilderExtensions.cs

@ -1,79 +0,0 @@
using Microsoft.AspNetCore.RequestLog;
namespace Microsoft.AspNetCore.Builder
{
public static class ApplicationBuilderExtensions
{
public static string UseConsul(this IApplicationBuilder app)
{
var appLifetime = app.ApplicationServices.GetService<IHostApplicationLifetime>();
using var scope = app.ApplicationServices.CreateScope();
var configuration = scope.ServiceProvider.GetService<IConfiguration>();
bool isEnabled = configuration.GetValue<bool>("Consul:Enabled");
string serviceName = configuration.GetValue<string>("Consul:Service");
var appString = configuration.GetValue<string>("App:SelfUrl");
Uri appUrl = new Uri(appString, UriKind.Absolute);
if (!isEnabled)
return String.Empty;
Guid serviceId = Guid.NewGuid();
string consulServiceId = $"{serviceName}:{serviceId}";
var client = scope.ServiceProvider.GetService<IConsulClient>();
var consulServiceRegistration = new AgentServiceRegistration
{
Name = serviceName,
ID = consulServiceId,
Address = appUrl.Host,
Port = appUrl.Port,
Check = new AgentServiceCheck
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), //服务停止多久后注销
Interval = TimeSpan.FromSeconds(3), //健康检查时间间隔,或者称为心跳 间隔
HTTP = $"http://{appUrl.Host}:{appUrl.Port}/health", //健康检查地址
Timeout = TimeSpan.FromSeconds(15) //超时时间
}
};
client.Agent.ServiceRegister(consulServiceRegistration);
appLifetime.ApplicationStopping.Register(() => { client.Agent.ServiceDeregister(consulServiceRegistration.ID); });
return consulServiceId;
}
/// <summary>
/// 记录请求响应日志
/// </summary>
/// <returns></returns>
public static IApplicationBuilder UseRequestLog(this IApplicationBuilder app)
{
return app.UseMiddleware<RequestLogMiddleware>();
}
/// <summary>
/// 多语言中间件
/// <remarks>浏览器传递的请求头:Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6而abp钟简体中文为:zh-Hans</remarks>
/// <example>
/// app.UseAbpProRequestLocalization();
/// </example>
/// </summary>
public static IApplicationBuilder UseAbpProRequestLocalization(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
return app.UseAbpRequestLocalization(options =>
{
// 移除自带header解析器
options.RequestCultureProviders.RemoveAll(provider=> provider is AcceptLanguageHeaderRequestCultureProvider);
// 添加header解析器
options.RequestCultureProviders.Add(new AbpProAcceptLanguageHeaderRequestCultureProvider());
});
}
}
}

38
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/AspNetCore/Mvc/Filters/AbpProResultFilter.cs

@ -1,38 +0,0 @@
using System.Text.Json;
namespace Microsoft.AspNetCore.Mvc.Filters;
public class AbpProResultFilter : IResultFilter, ITransientDependency
{
public void OnResultExecuting(ResultExecutingContext context)
{
// 如果是page 直接return
if (context.ActionDescriptor.IsPageAction()) return;
var controllerHasDontWrapResultAttribute =
context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.GetCustomAttributes(typeof(WrapResultAttribute), true).Any();
var controllerActionHasDontWrapResultAttribute = context.ActionDescriptor.GetMethodInfo().GetCustomAttributes(typeof(WrapResultAttribute), true).Any();
if (controllerHasDontWrapResultAttribute || controllerActionHasDontWrapResultAttribute)
{
context.HttpContext.Response.StatusCode = 200;
var result = new WrapResult<object>();
if (context.Result is not EmptyResult)
{
result.SetSuccess(((ObjectResult)context.Result).Value);
}
var jsonSerializer = context.GetService<IJsonSerializer>();
context.Result = new ContentResult()
{
StatusCode = (int)HttpStatusCode.OK,
ContentType = "application/json;charset=utf-8",
Content = jsonSerializer.Serialize(result)
};
}
}
public void OnResultExecuted(ResultExecutedContext context)
{
}
}

77
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/AspNetCore/RequestLog/RequestLogMiddleware.cs

@ -1,77 +0,0 @@
namespace Microsoft.AspNetCore.RequestLog;
public class RequestLogMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestLogMiddleware> _logger;
public RequestLogMiddleware(RequestDelegate next,
ILogger<RequestLogMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
context.Request.EnableBuffering();
var originalBody = context.Response.Body;
if (context.Request.Path.ToString().ToLower().Contains("swagger")
|| context.Request.Path.ToString().ToLower().Contains("login")
|| context.Request.Path.ToString().ToLower().Contains("monitor")
|| context.Request.Path.ToString().ToLower().Contains("cap")
|| context.Request.Path.ToString().ToLower().Contains("hangfire")
|| context.Request.Path.ToString() == "/"
)
{
await _next(context);
}
else
{
try
{
var logRequestId = Guid.NewGuid().ToString();
await RequestDataLog(context, logRequestId);
using (var ms = new MemoryStream())
{
context.Response.Body = ms;
await _next(context);
ResponseDataLog(ms, logRequestId);
ms.Position = 0;
await ms.CopyToAsync(originalBody);
}
}
catch (Exception ex)
{
// 记录异常
_logger.LogError(ex.Message + "" + ex.InnerException);
}
finally
{
context.Response.Body = originalBody;
}
}
}
private async Task RequestDataLog(HttpContext context,
string requestId)
{
var request = context.Request;
var body = new StreamReader(request.Body);
var requestData = $" 请求路径:{request.Path}\r\n 请求Body参数:{await body.ReadToEndAsync()}";
_logger.LogInformation($"日志中间件[Request],LogRequestId:{requestId}:请求接口信息:{requestData}");
request.Body.Position = 0;
}
private void ResponseDataLog(MemoryStream ms, string requestId)
{
ms.Position = 0;
var responseBody = new StreamReader(ms).ReadToEnd();
// 去除 Html
var isHtml = Regex.IsMatch(responseBody, "<[^>]+>");
if (!isHtml && !string.IsNullOrEmpty(responseBody))
{
_logger.LogInformation($"日志中间件[Response],LogRequestId:{requestId}:响应接口信息:{responseBody}");
}
}
}

15
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/Extensions/DependencyInjection/ServiceCollectionExtensions.cs

@ -1,15 +0,0 @@
namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddConsulConfig(this IServiceCollection services, IConfiguration configuration)
{
services.AddSingleton<IConsulClient>(p => new ConsulClient(consulConfig =>
{
var address = configuration.GetValue<string>("Consul:Host");
consulConfig.Address = new Uri(address);
}));
return services;
}
}
}

122
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Serilog/SerilogToEsExtensions.cs

@ -1,122 +0,0 @@
using System.Diagnostics.CodeAnalysis;
namespace Serilog
{
[SuppressMessage("Reliability", "CA2022:避免使用 \"Stream.Read\" 进行不准确读取")]
public static class SerilogToEsExtensions
{
public static void SetSerilogConfiguration(LoggerConfiguration loggerConfiguration, IConfiguration configuration)
{
// 默认读取 configuration 中 "Serilog" 节点下的配置
loggerConfiguration
.ReadFrom.Configuration(configuration)
.Enrich.FromLogContext();
var writeToElasticSearch = configuration.GetValue("ElasticSearch:Enabled", false);
// LogToElasticSearch:Enabled = true 才输出至ES
if (!writeToElasticSearch)
return;
var applicationName = "Lion.AbpPro.HttpApi.Host";
var esUrl = configuration["ElasticSearch:Url"];
// 需要设置ES URL
if (string.IsNullOrEmpty(esUrl))
return;
var indexFormat = configuration["ElasticSearch:IndexFormat"];
// 需要设置ES URL
if (string.IsNullOrEmpty(indexFormat))
return;
var esUserName = configuration["ElasticSearch:UserName"];
var esPassword = configuration["ElasticSearch:Password"];
loggerConfiguration.Enrich.FromLogContext().Enrich.WithExceptionDetails().WriteTo
.Elasticsearch(BuildElasticSearchSinkOptions(esUrl, indexFormat, esUserName, esPassword));
loggerConfiguration.Enrich.WithProperty("Application", applicationName);
}
// 创建Es连接
private static ElasticsearchSinkOptions BuildElasticSearchSinkOptions(
string url,
string indexFormat,
string userName,
string password)
{
if (string.IsNullOrEmpty(userName))
{
return new ElasticsearchSinkOptions(new Uri(url))
{
AutoRegisterTemplate = true,
AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
IndexFormat = indexFormat
};
}
return new ElasticsearchSinkOptions(new Uri(url))
{
AutoRegisterTemplate = true,
AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
IndexFormat = indexFormat,
ModifyConnectionSettings = x => x.BasicAuthentication(userName, password)
};
}
public static void EnrichFromRequest(IDiagnosticContext diagnosticContext, HttpContext httpContext)
{
var request = httpContext.Request;
// 为每个请求都设置通用的属性
diagnosticContext.Set("Host", request.Host);
diagnosticContext.Set("Protocol", request.Protocol);
diagnosticContext.Set("Scheme", request.Scheme);
diagnosticContext.Set("RemoteIpAddress", httpContext.Connection.RemoteIpAddress);
// 如果要记录 Request Body 或 Response Body
// 参考 https://stackoverflow.com/questions/60076922/serilog-logging-web-api-methods-adding-context-properties-inside-middleware
string requestBody = ReadRequestBody(httpContext.Request).Result;
if (!string.IsNullOrEmpty(requestBody))
{
diagnosticContext.Set("RequestBody", requestBody);
}
// string responseBody = ReadResponseBody(httpContext.Response).Result;
// if (!string.IsNullOrEmpty(responseBody))
// {
// diagnosticContext.Set("ResponseBody", requestBody);
// }
if (request.QueryString.HasValue)
{
diagnosticContext.Set("QueryString", request.QueryString.Value);
}
}
private static async Task<string> ReadRequestBody(HttpRequest request)
{
HttpRequestRewindExtensions.EnableBuffering(request);
var body = request.Body;
var buffer = new byte[Convert.ToInt32(request.ContentLength)];
await request.Body.ReadAsync(buffer, 0, buffer.Length);
string requestBody = Encoding.UTF8.GetString(buffer);
body.Seek(0, SeekOrigin.Begin);
request.Body = body;
return $"{requestBody}";
}
private static async Task<string> ReadResponseBody(HttpResponse response)
{
response.Body.Seek(0, SeekOrigin.Begin);
string responseBody = await new StreamReader(response.Body).ReadToEndAsync();
response.Body.Seek(0, SeekOrigin.Begin);
return $"{responseBody}";
}
}
}

49
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Swagger/HiddenAbpDefaultApiFilter.cs

@ -1,49 +0,0 @@
namespace Swagger
{
/// <summary>
/// 在使用nswag的时候,原生默认的api导致生产的代理类存在问题
/// 所有隐藏原生的api,重写路由
/// </summary>
public class HiddenAbpDefaultApiFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
foreach (ApiDescription apiDescription in context.ApiDescriptions)
{
if (apiDescription.TryGetMethodInfo(out MethodInfo method))
{
string key = "/" + apiDescription.RelativePath;
var reuslt = IsHidden(key);
if (reuslt) swaggerDoc.Paths.Remove(key);
}
}
}
private bool IsHidden(string key)
{
var list = GetHiddenAbpDefaultApiList();
foreach (var item in list)
{
if (key.Contains(item)) return true;
}
return false;
}
private List<string> GetHiddenAbpDefaultApiList()
{
return new List<string>() {
"/api/abp/multi-tenancy/tenants",
"/api/account",
"/api/feature-management/features",
"/api/permission-management/permissions",
"/api/identity/my-profile",
"/api/identity",
"/api/multi-tenancy/tenants",
"/api/setting-management/emailing",
"/configuration",
"/outputcache"
};
}
}
}

64
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Volo/Abp/DefaultHttpExceptionStatusCodeFinder.cs

@ -1,64 +0,0 @@
namespace Volo.Abp
{
/// <summary>
/// 修改Abp 返回状态码
/// 原因: 抛出BusinessException异常 不应该抛403异常
/// </summary>
public class DefaultHttpExceptionStatusCodeFinder : IHttpExceptionStatusCodeFinder, ITransientDependency
{
protected AbpExceptionHttpStatusCodeOptions Options { get; }
public DefaultHttpExceptionStatusCodeFinder(
IOptions<AbpExceptionHttpStatusCodeOptions> options)
{
Options = options.Value;
}
public HttpStatusCode GetStatusCode(HttpContext httpContext, Exception exception)
{
if (exception is IHasHttpStatusCode exceptionWithHttpStatusCode &&
exceptionWithHttpStatusCode.HttpStatusCode > 0)
{
return (HttpStatusCode)exceptionWithHttpStatusCode.HttpStatusCode;
}
if (exception is IHasErrorCode exceptionWithErrorCode &&
!exceptionWithErrorCode.Code.IsNullOrWhiteSpace())
{
if (Options.ErrorCodeToHttpStatusCodeMappings.TryGetValue(exceptionWithErrorCode.Code, out var status))
{
return status;
}
}
if (exception is AbpAuthorizationException)
{
return HttpStatusCode.Forbidden;
}
//TODO: Handle SecurityException..?
if (exception is AbpValidationException)
{
return HttpStatusCode.BadRequest;
}
if (exception is EntityNotFoundException)
{
return HttpStatusCode.NotFound;
}
if (exception is NotImplementedException)
{
return HttpStatusCode.NotImplemented;
}
if (exception is IBusinessException)
{
return HttpStatusCode.InternalServerError;
}
return HttpStatusCode.InternalServerError;
}
}
}
Loading…
Cancel
Save