From 712d547c4b2ca4f90d0254dab4483454596afb5b Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 11 Dec 2023 10:56:11 +0800 Subject: [PATCH 01/58] Add `NormalizedName` property to `Tenant`. Resolve #18394 --- .../MauiBlazor/MauiBlazorRemoteTenantStore.cs | 14 +++--- .../Mvc/Client/MvcRemoteTenantStore.cs | 12 ++--- .../Mvc/MultiTenancy/FindTenantResultDto.cs | 2 + .../Abp/MultiTenancy/AbpTenantAppService.cs | 8 +++- .../MultiTenancy/TenantSwitchModal.cshtml.cs | 5 ++- .../Abp/MultiTenancy/ITenantNormalizer.cs | 6 +++ .../Volo/Abp/MultiTenancy/ITenantStore.cs | 4 +- .../Abp/MultiTenancy/TenantConfiguration.cs | 10 +++++ .../UpperInvariantTenantNormalizer.cs | 11 +++++ .../ConfigurationStore/DefaultTenantStore.cs | 8 ++-- .../TenantConfigurationProvider.cs | 7 ++- ...reMultiTenancy_WithDomainResolver_Tests.cs | 3 +- ...ltiTenancy_Without_DomainResolver_Tests.cs | 3 +- .../Serilog/Serilog_Enrichers_Tests.cs | 3 +- .../Abp/TenantManagement/ITenantRepository.cs | 4 +- .../Volo/Abp/TenantManagement/Tenant.cs | 12 ++++- ...TenantConfigurationCacheItemInvalidator.cs | 8 ++-- .../Abp/TenantManagement/TenantManager.cs | 24 ++++++---- .../Volo/Abp/TenantManagement/TenantStore.cs | 28 ++++++------ ...agementDbContextModelCreatingExtensions.cs | 1 + .../EfCoreTenantRepository.cs | 8 ++-- .../MongoDb/MongoTenantRepository.cs | 8 ++-- .../TenantCacheItemInvalidator_Tests.cs | 44 ++++++++++--------- .../TenantManagement/TenantManager_Tests.cs | 11 +++-- .../Abp/TenantManagement/TenantStore_Tests.cs | 7 ++- .../Volo/Abp/TenantManagement/Tenant_Tests.cs | 7 ++- .../Abp/TenantManagement/LazyLoad_Tests.cs | 5 ++- .../TenantRepository_Tests.cs | 17 ++++--- 28 files changed, 178 insertions(+), 102 deletions(-) create mode 100644 framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantNormalizer.cs create mode 100644 framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/UpperInvariantTenantNormalizer.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs index d17a2b6f87..d06eb60566 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs @@ -23,13 +23,13 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency Cache = cache; } - public async Task FindAsync(string name) + public async Task FindAsync(string normalizedName) { - var cacheKey = CreateCacheKey(name); + var cacheKey = CreateCacheKey(normalizedName); var tenantConfiguration = await Cache.GetOrAddAsync( cacheKey, - async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name))!, + async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(normalizedName))!, () => new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = @@ -57,13 +57,13 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency return tenantConfiguration; } - public TenantConfiguration? Find(string name) + public TenantConfiguration? Find(string normalizedName) { - var cacheKey = CreateCacheKey(name); + var cacheKey = CreateCacheKey(normalizedName); var tenantConfiguration = Cache.GetOrAdd( cacheKey, - () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name)))!, + () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(normalizedName)))!, () => new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = @@ -110,4 +110,4 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency { return $"RemoteTenantStore_Id_{tenantId:N}"; } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs index e0c450b8b4..1bc7856ca6 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs @@ -29,9 +29,9 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency Options = options.Value; } - public async Task FindAsync(string name) + public async Task FindAsync(string normalizedName) { - var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(name); + var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(normalizedName); var httpContext = HttpContextAccessor?.HttpContext; if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext) @@ -42,7 +42,7 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency var tenantConfiguration = await Cache.GetAsync(cacheKey); if (tenantConfiguration == null) { - await TenantAppService.FindTenantByNameAsync(name); + await TenantAppService.FindTenantByNameAsync(normalizedName); tenantConfiguration = await Cache.GetAsync(cacheKey); } @@ -79,9 +79,9 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency return tenantConfiguration?.Value; } - public TenantConfiguration? Find(string name) + public TenantConfiguration? Find(string normalizedName) { - var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(name); + var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(normalizedName); var httpContext = HttpContextAccessor?.HttpContext; if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext) @@ -92,7 +92,7 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency var tenantConfiguration = Cache.Get(cacheKey); if (tenantConfiguration == null) { - AsyncHelper.RunSync(async () => await TenantAppService.FindTenantByNameAsync(name)); + AsyncHelper.RunSync(async () => await TenantAppService.FindTenantByNameAsync(normalizedName)); tenantConfiguration = Cache.Get(cacheKey); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs index 599b0b8a67..1de5f942dc 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs @@ -11,5 +11,7 @@ public class FindTenantResultDto public string? Name { get; set; } + public string? NormalizedName { get; set; } + public bool IsActive { get; set; } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs index 279bcee8ad..75649c1f6b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs @@ -9,15 +9,17 @@ namespace Pages.Abp.MultiTenancy; public class AbpTenantAppService : ApplicationService, IAbpTenantAppService { protected ITenantStore TenantStore { get; } + protected ITenantNormalizer TenantNormalizer { get; } - public AbpTenantAppService(ITenantStore tenantStore) + public AbpTenantAppService(ITenantStore tenantStore, ITenantNormalizer tenantNormalizer) { TenantStore = tenantStore; + TenantNormalizer = tenantNormalizer; } public virtual async Task FindTenantByNameAsync(string name) { - var tenant = await TenantStore.FindAsync(name); + var tenant = await TenantStore.FindAsync(TenantNormalizer.NormalizeName(name)!); if (tenant == null) { @@ -29,6 +31,7 @@ public class AbpTenantAppService : ApplicationService, IAbpTenantAppService Success = true, TenantId = tenant.Id, Name = tenant.Name, + NormalizedName = tenant.NormalizedName, IsActive = tenant.IsActive }; } @@ -47,6 +50,7 @@ public class AbpTenantAppService : ApplicationService, IAbpTenantAppService Success = true, TenantId = tenant.Id, Name = tenant.Name, + NormalizedName = tenant.NormalizedName, IsActive = tenant.IsActive }; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs index f6711be826..94a6760df3 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs @@ -18,13 +18,16 @@ public class TenantSwitchModalModel : AbpPageModel public TenantInfoModel Input { get; set; } = default!; protected ITenantStore TenantStore { get; } + protected ITenantNormalizer TenantNormalizer { get; } protected AbpAspNetCoreMultiTenancyOptions Options { get; } public TenantSwitchModalModel( ITenantStore tenantStore, + ITenantNormalizer tenantNormalizer, IOptions options) { TenantStore = tenantStore; + TenantNormalizer = tenantNormalizer; Options = options.Value; LocalizationResourceType = typeof(AbpUiMultiTenancyResource); } @@ -45,7 +48,7 @@ public class TenantSwitchModalModel : AbpPageModel Guid? tenantId = null; if (!Input.Name.IsNullOrEmpty()) { - var tenant = await TenantStore.FindAsync(Input.Name!); + var tenant = await TenantStore.FindAsync(TenantNormalizer.NormalizeName(Input.Name!)!); if (tenant == null) { throw new UserFriendlyException(L["GivenTenantIsNotExist", Input.Name!]); diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantNormalizer.cs b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantNormalizer.cs new file mode 100644 index 0000000000..1c5f0859f5 --- /dev/null +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantNormalizer.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp.MultiTenancy; + +public interface ITenantNormalizer +{ + string? NormalizeName(string? name); +} diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantStore.cs b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantStore.cs index 93dd609cc4..d97d438b01 100644 --- a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantStore.cs +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantStore.cs @@ -5,12 +5,12 @@ namespace Volo.Abp.MultiTenancy; public interface ITenantStore { - Task FindAsync(string name); + Task FindAsync(string normalizedName); Task FindAsync(Guid id); [Obsolete("Use FindAsync method.")] - TenantConfiguration? Find(string name); + TenantConfiguration? Find(string normalizedName); [Obsolete("Use FindAsync method.")] TenantConfiguration? Find(Guid id); diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfiguration.cs b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfiguration.cs index 0e5faf9386..29b0971708 100644 --- a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfiguration.cs +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfiguration.cs @@ -11,6 +11,8 @@ public class TenantConfiguration public string Name { get; set; } = default!; + public string NormalizedName { get; set; } = default!; + public ConnectionStrings? ConnectionStrings { get; set; } public bool IsActive { get; set; } @@ -30,4 +32,12 @@ public class TenantConfiguration ConnectionStrings = new ConnectionStrings(); } + + public TenantConfiguration(Guid id, [NotNull] string name, [NotNull] string normalizedName) + : this(id, name) + { + Check.NotNull(normalizedName, nameof(normalizedName)); + + NormalizedName = normalizedName; + } } diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/UpperInvariantTenantNormalizer.cs b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/UpperInvariantTenantNormalizer.cs new file mode 100644 index 0000000000..cba6b32349 --- /dev/null +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/UpperInvariantTenantNormalizer.cs @@ -0,0 +1,11 @@ +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.MultiTenancy; + +public class UpperInvariantTenantNormalizer : ITenantNormalizer, ITransientDependency +{ + public virtual string? NormalizeName(string? name) + { + return name?.Normalize().ToUpperInvariant(); + } +} diff --git a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs index d86d810d11..e91e749fe3 100644 --- a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs +++ b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs @@ -16,9 +16,9 @@ public class DefaultTenantStore : ITenantStore, ITransientDependency _options = options.CurrentValue; } - public Task FindAsync(string name) + public Task FindAsync(string normalizedName) { - return Task.FromResult(Find(name)); + return Task.FromResult(Find(normalizedName)); } public Task FindAsync(Guid id) @@ -26,9 +26,9 @@ public class DefaultTenantStore : ITenantStore, ITransientDependency return Task.FromResult(Find(id)); } - public TenantConfiguration? Find(string name) + public TenantConfiguration? Find(string normalizedName) { - return _options.Tenants?.FirstOrDefault(t => t.Name == name); + return _options.Tenants?.FirstOrDefault(t => t.NormalizedName == normalizedName); } public TenantConfiguration? Find(Guid id) diff --git a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs index 7e93cf888a..79f07deb4a 100644 --- a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs +++ b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs @@ -10,6 +10,7 @@ public class TenantConfigurationProvider : ITenantConfigurationProvider, ITransi { protected virtual ITenantResolver TenantResolver { get; } protected virtual ITenantStore TenantStore { get; } + protected virtual ITenantNormalizer TenantNormalizer { get; } protected virtual ITenantResolveResultAccessor TenantResolveResultAccessor { get; } protected virtual IStringLocalizer StringLocalizer { get; } @@ -17,10 +18,12 @@ public class TenantConfigurationProvider : ITenantConfigurationProvider, ITransi ITenantResolver tenantResolver, ITenantStore tenantStore, ITenantResolveResultAccessor tenantResolveResultAccessor, - IStringLocalizer stringLocalizer) + IStringLocalizer stringLocalizer, + ITenantNormalizer tenantNormalizer) { TenantResolver = tenantResolver; TenantStore = tenantStore; + TenantNormalizer = tenantNormalizer; TenantResolveResultAccessor = tenantResolveResultAccessor; StringLocalizer = stringLocalizer; } @@ -69,7 +72,7 @@ public class TenantConfigurationProvider : ITenantConfigurationProvider, ITransi } else { - return await TenantStore.FindAsync(tenantIdOrName); + return await TenantStore.FindAsync(TenantNormalizer.NormalizeName(tenantIdOrName)!); } } } diff --git a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_WithDomainResolver_Tests.cs b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_WithDomainResolver_Tests.cs index e80b47b2a5..02d0288b4b 100644 --- a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_WithDomainResolver_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_WithDomainResolver_Tests.cs @@ -16,6 +16,7 @@ public class AspNetCoreMultiTenancy_WithDomainResolver_Tests : AspNetCoreMultiTe { private readonly Guid _testTenantId = Guid.NewGuid(); private readonly string _testTenantName = "acme"; + private readonly string _testTenantNormalizedName = "ACME"; private readonly AbpAspNetCoreMultiTenancyOptions _options; @@ -30,7 +31,7 @@ public class AspNetCoreMultiTenancy_WithDomainResolver_Tests : AspNetCoreMultiTe { options.Tenants = new[] { - new TenantConfiguration(_testTenantId, _testTenantName) + new TenantConfiguration(_testTenantId, _testTenantName, _testTenantNormalizedName) }; }); diff --git a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_Without_DomainResolver_Tests.cs b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_Without_DomainResolver_Tests.cs index 56da287ef8..71ee5f11df 100644 --- a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_Without_DomainResolver_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_Without_DomainResolver_Tests.cs @@ -17,6 +17,7 @@ public class AspNetCoreMultiTenancy_Without_DomainResolver_Tests : AspNetCoreMul { private readonly Guid _testTenantId = Guid.NewGuid(); private readonly string _testTenantName = "acme"; + private readonly string _testTenantNormalizedName = "ACME"; private readonly AbpAspNetCoreMultiTenancyOptions _options; @@ -31,7 +32,7 @@ public class AspNetCoreMultiTenancy_Without_DomainResolver_Tests : AspNetCoreMul { options.Tenants = new[] { - new TenantConfiguration(_testTenantId, _testTenantName) + new TenantConfiguration(_testTenantId, _testTenantName, _testTenantNormalizedName) }; }); diff --git a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/Serilog_Enrichers_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/Serilog_Enrichers_Tests.cs index 4782a5e768..1fb1402b26 100644 --- a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/Serilog_Enrichers_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/Serilog_Enrichers_Tests.cs @@ -20,6 +20,7 @@ public class Serilog_Enrichers_Tests : AbpSerilogTestBase private readonly Guid _testTenantId = Guid.NewGuid(); private readonly string _testTenantName = "acme"; + private readonly string _testTenantNormalizedName = "ACME"; private readonly AbpAspNetCoreMultiTenancyOptions _tenancyOptions; private readonly AbpAspNetCoreSerilogOptions _serilogOptions; @@ -39,7 +40,7 @@ public class Serilog_Enrichers_Tests : AbpSerilogTestBase { options.Tenants = new[] { - new TenantConfiguration(_testTenantId, _testTenantName) + new TenantConfiguration(_testTenantId, _testTenantName, _testTenantNormalizedName) }; }); base.ConfigureServices(services); diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/ITenantRepository.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/ITenantRepository.cs index 6412993d14..41ea978524 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/ITenantRepository.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/ITenantRepository.cs @@ -9,13 +9,13 @@ namespace Volo.Abp.TenantManagement; public interface ITenantRepository : IBasicRepository { Task FindByNameAsync( - string name, + string normalizedName, bool includeDetails = true, CancellationToken cancellationToken = default); [Obsolete("Use FindByNameAsync method.")] Tenant FindByName( - string name, + string normalizedName, bool includeDetails = true ); diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs index 5275e39ab3..6567cf8efd 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs @@ -10,7 +10,9 @@ namespace Volo.Abp.TenantManagement; public class Tenant : FullAuditedAggregateRoot, IHasEntityVersion { public virtual string Name { get; protected set; } - + + public virtual string NormalizedName { get; protected set; } + public virtual int EntityVersion { get; protected set; } public virtual List ConnectionStrings { get; protected set; } @@ -20,10 +22,11 @@ public class Tenant : FullAuditedAggregateRoot, IHasEntityVersion } - protected internal Tenant(Guid id, [NotNull] string name) + protected internal Tenant(Guid id, [NotNull] string name, [CanBeNull] string normalizedTenantName) : base(id) { SetName(name); + SetNormalizedTenantName(normalizedTenantName); ConnectionStrings = new List(); } @@ -78,4 +81,9 @@ public class Tenant : FullAuditedAggregateRoot, IHasEntityVersion { Name = Check.NotNullOrWhiteSpace(name, nameof(name), TenantConsts.MaxNameLength); } + + protected internal virtual void SetNormalizedTenantName([CanBeNull] string normalizedTenantName) + { + NormalizedName = normalizedTenantName; + } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConfigurationCacheItemInvalidator.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConfigurationCacheItemInvalidator.cs index e629186e20..09c1a9368f 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConfigurationCacheItemInvalidator.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConfigurationCacheItemInvalidator.cs @@ -22,21 +22,21 @@ public class TenantConfigurationCacheItemInvalidator : public virtual async Task HandleEventAsync(EntityChangedEventData eventData) { - await ClearCacheAsync(eventData.Entity.Id, eventData.Entity.Name); + await ClearCacheAsync(eventData.Entity.Id, eventData.Entity.NormalizedName); } public virtual async Task HandleEventAsync(EntityDeletedEventData eventData) { - await ClearCacheAsync(eventData.Entity.Id, eventData.Entity.Name); + await ClearCacheAsync(eventData.Entity.Id, eventData.Entity.NormalizedName); } - protected virtual async Task ClearCacheAsync(Guid? id, string name) + protected virtual async Task ClearCacheAsync(Guid? id, string normalizedName) { await Cache.RemoveManyAsync( new[] { TenantConfigurationCacheItem.CalculateCacheKey(id, null), - TenantConfigurationCacheItem.CalculateCacheKey(null, name), + TenantConfigurationCacheItem.CalculateCacheKey(null, normalizedName), }); } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs index 1ad7324c35..43594dfde7 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs @@ -11,19 +11,22 @@ public class TenantManager : DomainService, ITenantManager protected ITenantRepository TenantRepository { get; } protected IDistributedCache Cache { get; } - public TenantManager(ITenantRepository tenantRepository, - IDistributedCache cache) + protected ITenantNormalizer TenantNormalizer { get; } + + public TenantManager(ITenantRepository tenantRepository, IDistributedCache cache, ITenantNormalizer tenantNormalizer) { TenantRepository = tenantRepository; Cache = cache; + TenantNormalizer = tenantNormalizer; } public virtual async Task CreateAsync(string name) { Check.NotNull(name, nameof(name)); - await ValidateNameAsync(name); - return new Tenant(GuidGenerator.Create(), name); + var normalizedTenantName = TenantNormalizer.NormalizeName(name); + await ValidateNameAsync(normalizedTenantName); + return new Tenant(GuidGenerator.Create(), name, normalizedTenantName); } public virtual async Task ChangeNameAsync(Tenant tenant, string name) @@ -31,17 +34,20 @@ public class TenantManager : DomainService, ITenantManager Check.NotNull(tenant, nameof(tenant)); Check.NotNull(name, nameof(name)); - await ValidateNameAsync(name, tenant.Id); - await Cache.RemoveAsync(TenantConfigurationCacheItem.CalculateCacheKey(tenant.Name)); + var normalizedTenantName = TenantNormalizer.NormalizeName(name); + + await ValidateNameAsync(normalizedTenantName, tenant.Id); + await Cache.RemoveAsync(TenantConfigurationCacheItem.CalculateCacheKey(tenant.NormalizedName)); tenant.SetName(name); + tenant.SetNormalizedTenantName(normalizedTenantName); } - protected virtual async Task ValidateNameAsync(string name, Guid? expectedId = null) + protected virtual async Task ValidateNameAsync(string normalizeName, Guid? expectedId = null) { - var tenant = await TenantRepository.FindByNameAsync(name); + var tenant = await TenantRepository.FindByNameAsync(normalizeName); if (tenant != null && tenant.Id != expectedId) { - throw new BusinessException("Volo.Abp.TenantManagement:DuplicateTenantName").WithData("Name", name); + throw new BusinessException("Volo.Abp.TenantManagement:DuplicateTenantName").WithData("Name", normalizeName); } } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs index 5fd23add6b..f2ef1ed066 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs @@ -27,9 +27,9 @@ public class TenantStore : ITenantStore, ITransientDependency Cache = cache; } - public virtual async Task FindAsync(string name) + public virtual async Task FindAsync(string normalizedName) { - return (await GetCacheItemAsync(null, name)).Value; + return (await GetCacheItemAsync(null, normalizedName)).Value; } public virtual async Task FindAsync(Guid id) @@ -38,9 +38,9 @@ public class TenantStore : ITenantStore, ITransientDependency } [Obsolete("Use FindAsync method.")] - public virtual TenantConfiguration Find(string name) + public virtual TenantConfiguration Find(string normalizedName) { - return (GetCacheItem(null, name)).Value; + return (GetCacheItem(null, normalizedName)).Value; } [Obsolete("Use FindAsync method.")] @@ -49,9 +49,9 @@ public class TenantStore : ITenantStore, ITransientDependency return (GetCacheItem(id, null)).Value; } - protected virtual async Task GetCacheItemAsync(Guid? id, string name) + protected virtual async Task GetCacheItemAsync(Guid? id, string normalizedName) { - var cacheKey = CalculateCacheKey(id, name); + var cacheKey = CalculateCacheKey(id, normalizedName); var cacheItem = await Cache.GetAsync(cacheKey, considerUow: true); if (cacheItem != null) @@ -68,11 +68,11 @@ public class TenantStore : ITenantStore, ITransientDependency } } - if (!name.IsNullOrWhiteSpace()) + if (!normalizedName.IsNullOrWhiteSpace()) { using (CurrentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities! { - var tenant = await TenantRepository.FindByNameAsync(name); + var tenant = await TenantRepository.FindByNameAsync(normalizedName); return await SetCacheAsync(cacheKey, tenant); } } @@ -89,9 +89,9 @@ public class TenantStore : ITenantStore, ITransientDependency } [Obsolete("Use GetCacheItemAsync method.")] - protected virtual TenantConfigurationCacheItem GetCacheItem(Guid? id, string name) + protected virtual TenantConfigurationCacheItem GetCacheItem(Guid? id, string normalizedName) { - var cacheKey = CalculateCacheKey(id, name); + var cacheKey = CalculateCacheKey(id, normalizedName); var cacheItem = Cache.Get(cacheKey, considerUow: true); if (cacheItem != null) @@ -108,11 +108,11 @@ public class TenantStore : ITenantStore, ITransientDependency } } - if (!name.IsNullOrWhiteSpace()) + if (!normalizedName.IsNullOrWhiteSpace()) { using (CurrentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities! { - var tenant = TenantRepository.FindByName(name); + var tenant = TenantRepository.FindByName(normalizedName); return SetCache(cacheKey, tenant); } } @@ -129,8 +129,8 @@ public class TenantStore : ITenantStore, ITransientDependency return cacheItem; } - protected virtual string CalculateCacheKey(Guid? id, string name) + protected virtual string CalculateCacheKey(Guid? id, string normalizedName) { - return TenantConfigurationCacheItem.CalculateCacheKey(id, name); + return TenantConfigurationCacheItem.CalculateCacheKey(id, normalizedName); } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs index 6b1d7f7e8e..bb189e72a1 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs @@ -23,6 +23,7 @@ public static class AbpTenantManagementDbContextModelCreatingExtensions b.ConfigureByConvention(); b.Property(t => t.Name).IsRequired().HasMaxLength(TenantConsts.MaxNameLength); + b.Property(t => t.NormalizedName).IsRequired().HasMaxLength(TenantConsts.MaxNameLength); b.HasMany(u => u.ConnectionStrings).WithOne().HasForeignKey(uc => uc.TenantId).IsRequired(); diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/EfCoreTenantRepository.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/EfCoreTenantRepository.cs index 34d350d242..e58512dc13 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/EfCoreTenantRepository.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/EfCoreTenantRepository.cs @@ -19,23 +19,23 @@ public class EfCoreTenantRepository : EfCoreRepository FindByNameAsync( - string name, + string normalizedName, bool includeDetails = true, CancellationToken cancellationToken = default) { return await (await GetDbSetAsync()) .IncludeDetails(includeDetails) .OrderBy(t => t.Id) - .FirstOrDefaultAsync(t => t.Name == name, GetCancellationToken(cancellationToken)); + .FirstOrDefaultAsync(t => t.NormalizedName == normalizedName, GetCancellationToken(cancellationToken)); } [Obsolete("Use FindByNameAsync method.")] - public virtual Tenant FindByName(string name, bool includeDetails = true) + public virtual Tenant FindByName(string normalizedName, bool includeDetails = true) { return DbSet .IncludeDetails(includeDetails) .OrderBy(t => t.Id) - .FirstOrDefault(t => t.Name == name); + .FirstOrDefault(t => t.NormalizedName == normalizedName); } [Obsolete("Use FindAsync method.")] diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.MongoDB/Volo/Abp/TenantManagement/MongoDb/MongoTenantRepository.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.MongoDB/Volo/Abp/TenantManagement/MongoDb/MongoTenantRepository.cs index 321dcf365f..049dc5e57c 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.MongoDB/Volo/Abp/TenantManagement/MongoDb/MongoTenantRepository.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.MongoDB/Volo/Abp/TenantManagement/MongoDb/MongoTenantRepository.cs @@ -20,19 +20,19 @@ public class MongoTenantRepository : MongoDbRepository FindByNameAsync( - string name, + string normalizedName, bool includeDetails = true, CancellationToken cancellationToken = default) { return await (await GetMongoQueryableAsync(cancellationToken)) - .FirstOrDefaultAsync(t => t.Name == name, GetCancellationToken(cancellationToken)); + .FirstOrDefaultAsync(t => t.NormalizedName == normalizedName, GetCancellationToken(cancellationToken)); } [Obsolete("Use FindByNameAsync method.")] - public virtual Tenant FindByName(string name, bool includeDetails = true) + public virtual Tenant FindByName(string normalizedName, bool includeDetails = true) { return GetMongoQueryable() - .FirstOrDefault(t => t.Name == name); + .FirstOrDefault(t => t.NormalizedName == normalizedName); } [Obsolete("Use FindAsync method.")] diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs index 9671402560..2dc844d71e 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs @@ -12,6 +12,7 @@ public class TenantConfigurationCacheItemInvalidator_Tests : AbpTenantManagement private readonly ITenantStore _tenantStore; private readonly ITenantRepository _tenantRepository; private readonly ITenantManager _tenantManager; + private readonly ITenantNormalizer _tenantNormalizer; public TenantConfigurationCacheItemInvalidator_Tests() { @@ -19,86 +20,87 @@ public class TenantConfigurationCacheItemInvalidator_Tests : AbpTenantManagement _tenantStore = GetRequiredService(); _tenantRepository = GetRequiredService(); _tenantManager = GetRequiredService(); + _tenantNormalizer = GetRequiredService(); } [Fact] public async Task Get_Tenant_Should_Cached() { - var acme = await _tenantRepository.FindByNameAsync("acme"); + var acme = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("acme")); acme.ShouldNotBeNull(); (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(acme.Id, null))).ShouldBeNull(); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.Name))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.NormalizedName))).ShouldBeNull(); await _tenantStore.FindAsync(acme.Id); (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(acme.Id, null))).ShouldNotBeNull(); - await _tenantStore.FindAsync(acme.Name); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.Name))).ShouldNotBeNull(); + await _tenantStore.FindAsync(acme.NormalizedName); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.NormalizedName))).ShouldNotBeNull(); - var volosoft = _tenantRepository.FindByName("volosoft"); + var volosoft = _tenantRepository.FindByName(_tenantNormalizer.NormalizeName("volosoft")); volosoft.ShouldNotBeNull(); (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldBeNull(); - (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.NormalizedName))).ShouldBeNull(); _tenantStore.Find(volosoft.Id); (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldNotBeNull(); - _tenantStore.Find(volosoft.Name); - (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldNotBeNull(); + _tenantStore.Find(volosoft.NormalizedName); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.NormalizedName))).ShouldNotBeNull(); } [Fact] public async Task Cache_Should_Invalidator_When_Tenant_Changed() { - var acme = await _tenantRepository.FindByNameAsync("acme"); + var acme = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("acme")); acme.ShouldNotBeNull(); // FindAsync will cache tenant. await _tenantStore.FindAsync(acme.Id); - await _tenantStore.FindAsync(acme.Name); + await _tenantStore.FindAsync(acme.NormalizedName); (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(acme.Id, null))).ShouldNotBeNull(); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.Name))).ShouldNotBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.NormalizedName))).ShouldNotBeNull(); await _tenantRepository.DeleteAsync(acme); (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(acme.Id, null))).ShouldBeNull(); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.Name))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.NormalizedName))).ShouldBeNull(); - var volosoft = await _tenantRepository.FindByNameAsync("volosoft"); + var volosoft = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("volosoft")); volosoft.ShouldNotBeNull(); // Find will cache tenant. _tenantStore.Find(volosoft.Id); - _tenantStore.Find(volosoft.Name); + _tenantStore.Find(volosoft.NormalizedName); (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldNotBeNull(); - (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldNotBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.NormalizedName))).ShouldNotBeNull(); await _tenantRepository.DeleteAsync(volosoft); (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldBeNull(); - (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.NormalizedName))).ShouldBeNull(); - var abp = await _tenantRepository.FindByNameAsync("abp"); + var abp = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("abp")); abp.ShouldNotBeNull(); // Find will cache tenant. await _tenantStore.FindAsync(abp.Id); - await _tenantStore.FindAsync(abp.Name); + await _tenantStore.FindAsync(abp.NormalizedName); (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(abp.Id, null))).ShouldNotBeNull(); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, abp.Name))).ShouldNotBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, abp.NormalizedName))).ShouldNotBeNull(); await _tenantManager.ChangeNameAsync(abp, "abp2"); await _tenantRepository.UpdateAsync(abp); (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(abp.Id, null))).ShouldBeNull(); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, "abp"))).ShouldBeNull(); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, "abp2"))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, _tenantNormalizer.NormalizeName("abp")))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, _tenantNormalizer.NormalizeName("abp2")))).ShouldBeNull(); } } diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantManager_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantManager_Tests.cs index 161882e412..f46bcf8573 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantManager_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantManager_Tests.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Shouldly; +using Volo.Abp.MultiTenancy; using Xunit; namespace Volo.Abp.TenantManagement; @@ -8,19 +9,21 @@ public class TenantManager_Tests : AbpTenantManagementDomainTestBase { private readonly ITenantManager _tenantManager; private readonly ITenantRepository _tenantRepository; + private readonly ITenantNormalizer _tenantNormalizer; public TenantManager_Tests() { _tenantManager = GetRequiredService(); _tenantRepository = GetRequiredService(); + _tenantNormalizer = GetRequiredService(); } - [Fact] public async Task CreateAsync() { var tenant = await _tenantManager.CreateAsync("Test"); tenant.Name.ShouldBe("Test"); + tenant.NormalizedName.ShouldBe(_tenantNormalizer.NormalizeName("Test")); } [Fact] @@ -32,18 +35,20 @@ public class TenantManager_Tests : AbpTenantManagementDomainTestBase [Fact] public async Task ChangeNameAsync() { - var tenant = await _tenantRepository.FindByNameAsync("volosoft"); + var tenant = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("volosoft")); tenant.ShouldNotBeNull(); + tenant.NormalizedName.ShouldBe(_tenantNormalizer.NormalizeName("volosoft")); await _tenantManager.ChangeNameAsync(tenant, "newVolosoft"); tenant.Name.ShouldBe("newVolosoft"); + tenant.NormalizedName.ShouldBe(_tenantNormalizer.NormalizeName("newVolosoft")); } [Fact] public async Task ChangeName_Tenant_Name_Can_Not_Duplicate() { - var tenant = await _tenantRepository.FindByNameAsync("acme"); + var tenant = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("acme")); tenant.ShouldNotBeNull(); await Assert.ThrowsAsync(async () => await _tenantManager.ChangeNameAsync(tenant, "volosoft")); diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantStore_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantStore_Tests.cs index 1af4ebd1ea..10f203eb43 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantStore_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantStore_Tests.cs @@ -9,25 +9,28 @@ public class TenantStore_Tests : AbpTenantManagementDomainTestBase { private readonly ITenantStore _tenantStore; private readonly ITenantRepository _tenantRepository; + private readonly ITenantNormalizer _tenantNormalizer; public TenantStore_Tests() { _tenantStore = GetRequiredService(); _tenantRepository = GetRequiredService(); + _tenantNormalizer = GetRequiredService(); } [Fact] public async Task FindAsyncByName() { - var acme = await _tenantStore.FindAsync("acme"); + var acme = await _tenantStore.FindAsync(_tenantNormalizer.NormalizeName("acme")!); acme.ShouldNotBeNull(); acme.Name.ShouldBe("acme"); + acme.NormalizedName.ShouldBe(_tenantNormalizer.NormalizeName("acme")!); } [Fact] public async Task FindAsyncById() { - var acme = await _tenantRepository.FindByNameAsync("acme"); + var acme = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("acme")); acme.ShouldNotBeNull(); (await _tenantStore.FindAsync(acme.Id)).ShouldNotBeNull(); diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/Tenant_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/Tenant_Tests.cs index dbe631d431..bcefc527e6 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/Tenant_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/Tenant_Tests.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Shouldly; +using Volo.Abp.MultiTenancy; using Xunit; namespace Volo.Abp.TenantManagement; @@ -7,16 +8,18 @@ namespace Volo.Abp.TenantManagement; public class Tenant_Tests : AbpTenantManagementDomainTestBase { private readonly ITenantRepository _tenantRepository; + private readonly ITenantNormalizer _tenantNormalizer; public Tenant_Tests() { _tenantRepository = GetRequiredService(); + _tenantNormalizer = GetRequiredService(); } [Fact] public async Task FindDefaultConnectionString() { - var acme = await _tenantRepository.FindByNameAsync("acme"); + var acme = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("acme")); acme.ShouldNotBeNull(); acme.FindDefaultConnectionString().ShouldBe("DefaultConnString-Value"); @@ -25,7 +28,7 @@ public class Tenant_Tests : AbpTenantManagementDomainTestBase [Fact] public async Task FindConnectionString() { - var acme = await _tenantRepository.FindByNameAsync("acme"); + var acme = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("acme")); acme.ShouldNotBeNull(); acme.FindConnectionString(Data.ConnectionStrings.DefaultConnectionStringName).ShouldBe("DefaultConnString-Value"); diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/LazyLoad_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/LazyLoad_Tests.cs index 049d93cf65..9fe123d73b 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/LazyLoad_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/LazyLoad_Tests.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Shouldly; using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy; using Volo.Abp.Uow; using Xunit; @@ -11,10 +12,12 @@ public abstract class LazyLoad_Tests : TenantManagementTestBase< where TStartupModule : IAbpModule { public ITenantRepository TenantRepository { get; } + public ITenantNormalizer TenantNormalizer { get; } protected LazyLoad_Tests() { TenantRepository = GetRequiredService(); + TenantNormalizer = GetRequiredService(); } [Fact] @@ -22,7 +25,7 @@ public abstract class LazyLoad_Tests : TenantManagementTestBase< { using (var uow = GetRequiredService().Begin()) { - var role = await TenantRepository.FindByNameAsync("acme", includeDetails: false); + var role = await TenantRepository.FindByNameAsync(TenantNormalizer.NormalizeName("acme"), includeDetails: false); role.ConnectionStrings.ShouldNotBeNull(); role.ConnectionStrings.Any().ShouldBeTrue(); diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/TenantRepository_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/TenantRepository_Tests.cs index c8ff94d069..6e4c3c8db5 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/TenantRepository_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/TenantRepository_Tests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using Shouldly; using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy; using Xunit; namespace Volo.Abp.TenantManagement; @@ -11,22 +12,24 @@ public abstract class TenantRepository_Tests : TenantManagementT where TStartupModule : IAbpModule { public ITenantRepository TenantRepository { get; } + public ITenantNormalizer TenantNormalizer { get; } protected TenantRepository_Tests() { TenantRepository = GetRequiredService(); + TenantNormalizer = GetRequiredService(); } [Fact] public async Task FindByNameAsync() { - var tenant = await TenantRepository.FindByNameAsync("acme"); + var tenant = await TenantRepository.FindByNameAsync(TenantNormalizer.NormalizeName("acme")); tenant.ShouldNotBeNull(); - tenant = await TenantRepository.FindByNameAsync("undefined-tenant"); + tenant = await TenantRepository.FindByNameAsync(TenantNormalizer.NormalizeName("undefined-tenant")); tenant.ShouldBeNull(); - tenant = await TenantRepository.FindByNameAsync("acme", includeDetails: true); + tenant = await TenantRepository.FindByNameAsync(TenantNormalizer.NormalizeName("acme"), includeDetails: true); tenant.ShouldNotBeNull(); tenant.ConnectionStrings.Count.ShouldBeGreaterThanOrEqualTo(2); } @@ -34,7 +37,7 @@ public abstract class TenantRepository_Tests : TenantManagementT [Fact] public async Task FindAsync() { - var tenantId = (await TenantRepository.FindByNameAsync("acme")).Id; + var tenantId = (await TenantRepository.FindByNameAsync(TenantNormalizer.NormalizeName("acme"))).Id; var tenant = await TenantRepository.FindAsync(tenantId); tenant.ShouldNotBeNull(); @@ -51,14 +54,14 @@ public abstract class TenantRepository_Tests : TenantManagementT public async Task GetListAsync() { var tenants = await TenantRepository.GetListAsync(); - tenants.ShouldContain(t => t.Name == "acme"); - tenants.ShouldContain(t => t.Name == "volosoft"); + tenants.ShouldContain(t => t.Name == "acme" && t.NormalizedName == TenantNormalizer.NormalizeName("acme")); + tenants.ShouldContain(t => t.Name == "volosoft" && t.NormalizedName == TenantNormalizer.NormalizeName("volosoft")); } [Fact] public async Task Should_Eager_Load_Tenant_Collections() { - var role = await TenantRepository.FindByNameAsync("acme"); + var role = await TenantRepository.FindByNameAsync(TenantNormalizer.NormalizeName("acme")); role.ConnectionStrings.ShouldNotBeNull(); role.ConnectionStrings.Any().ShouldBeTrue(); } From ecc0562c7c5d649f3c70ca7acdbf9d1eac7f6ced Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 11 Dec 2023 15:08:13 +0800 Subject: [PATCH 02/58] Rename `NormalizedTenantName` to `NormalizedName`. --- .../MauiBlazor/MauiBlazorRemoteTenantStore.cs | 6 +++--- .../Volo/Abp/TenantManagement/Tenant.cs | 8 ++++---- .../Volo/Abp/TenantManagement/TenantManager.cs | 13 ++++++------- .../Volo/Abp/TenantManagement/TenantStore.cs | 4 ++-- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs index d06eb60566..3873b48db3 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs @@ -98,12 +98,12 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency return null; } - return new TenantConfiguration(tenantResultDto.TenantId.Value, tenantResultDto.Name!); + return new TenantConfiguration(tenantResultDto.TenantId.Value, tenantResultDto.Name!, tenantResultDto.NormalizedName!); } - protected virtual string CreateCacheKey(string tenantName) + protected virtual string CreateCacheKey(string normalizedName) { - return $"RemoteTenantStore_Name_{tenantName}"; + return $"RemoteTenantStore_Name_{normalizedName}"; } protected virtual string CreateCacheKey(Guid tenantId) diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs index 6567cf8efd..c6c5c3edee 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs @@ -22,11 +22,11 @@ public class Tenant : FullAuditedAggregateRoot, IHasEntityVersion } - protected internal Tenant(Guid id, [NotNull] string name, [CanBeNull] string normalizedTenantName) + protected internal Tenant(Guid id, [NotNull] string name, [CanBeNull] string normalizedName) : base(id) { SetName(name); - SetNormalizedTenantName(normalizedTenantName); + SetNormalizedName(normalizedName); ConnectionStrings = new List(); } @@ -82,8 +82,8 @@ public class Tenant : FullAuditedAggregateRoot, IHasEntityVersion Name = Check.NotNullOrWhiteSpace(name, nameof(name), TenantConsts.MaxNameLength); } - protected internal virtual void SetNormalizedTenantName([CanBeNull] string normalizedTenantName) + protected internal virtual void SetNormalizedName([CanBeNull] string normalizedName) { - NormalizedName = normalizedTenantName; + NormalizedName = normalizedName; } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs index 43594dfde7..648e02d381 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs @@ -10,7 +10,6 @@ public class TenantManager : DomainService, ITenantManager { protected ITenantRepository TenantRepository { get; } protected IDistributedCache Cache { get; } - protected ITenantNormalizer TenantNormalizer { get; } public TenantManager(ITenantRepository tenantRepository, IDistributedCache cache, ITenantNormalizer tenantNormalizer) @@ -24,9 +23,9 @@ public class TenantManager : DomainService, ITenantManager { Check.NotNull(name, nameof(name)); - var normalizedTenantName = TenantNormalizer.NormalizeName(name); - await ValidateNameAsync(normalizedTenantName); - return new Tenant(GuidGenerator.Create(), name, normalizedTenantName); + var normalizedName = TenantNormalizer.NormalizeName(name); + await ValidateNameAsync(normalizedName); + return new Tenant(GuidGenerator.Create(), name, normalizedName); } public virtual async Task ChangeNameAsync(Tenant tenant, string name) @@ -34,12 +33,12 @@ public class TenantManager : DomainService, ITenantManager Check.NotNull(tenant, nameof(tenant)); Check.NotNull(name, nameof(name)); - var normalizedTenantName = TenantNormalizer.NormalizeName(name); + var normalizedName = TenantNormalizer.NormalizeName(name); - await ValidateNameAsync(normalizedTenantName, tenant.Id); + await ValidateNameAsync(normalizedName, tenant.Id); await Cache.RemoveAsync(TenantConfigurationCacheItem.CalculateCacheKey(tenant.NormalizedName)); tenant.SetName(name); - tenant.SetNormalizedTenantName(normalizedTenantName); + tenant.SetNormalizedName(normalizedName); } protected virtual async Task ValidateNameAsync(string normalizeName, Guid? expectedId = null) diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs index f2ef1ed066..d334c124a6 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs @@ -77,7 +77,7 @@ public class TenantStore : ITenantStore, ITransientDependency } } - throw new AbpException("Both id and name can't be invalid."); + throw new AbpException("Both id and normalizedName can't be invalid."); } protected virtual async Task SetCacheAsync(string cacheKey, [CanBeNull] Tenant tenant) @@ -117,7 +117,7 @@ public class TenantStore : ITenantStore, ITransientDependency } } - throw new AbpException("Both id and name can't be invalid."); + throw new AbpException("Both id and normalizedName can't be invalid."); } [Obsolete("Use SetCacheAsync method.")] From 8810906cdcb2132fbc8df81a9d2894270e29c79c Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 20 Dec 2023 10:09:16 +0800 Subject: [PATCH 03/58] Update the migrations for template projects. --- ...tial.Designer.cs => 20231220020330_Initial.Designer.cs} | 7 ++++++- ...20231207053812_Initial.cs => 20231220020330_Initial.cs} | 1 + .../Migrations/MyProjectNameDbContextModelSnapshot.cs | 5 +++++ ...tial.Designer.cs => 20231220020415_Initial.Designer.cs} | 7 ++++++- .../Server/Migrations/20231220020415_Initial.cs} | 1 + .../Migrations/MyProjectNameDbContextModelSnapshot.cs | 5 +++++ ...tial.Designer.cs => 20231220020502_Initial.Designer.cs} | 7 ++++++- ...20231207053820_Initial.cs => 20231220020502_Initial.cs} | 1 + .../Migrations/MyProjectNameDbContextModelSnapshot.cs | 5 +++++ ...tial.Designer.cs => 20231220020554_Initial.Designer.cs} | 7 ++++++- ...20231207053825_Initial.cs => 20231220020554_Initial.cs} | 1 + .../Migrations/MyProjectNameDbContextModelSnapshot.cs | 5 +++++ ...tial.Designer.cs => 20231220020240_Initial.Designer.cs} | 7 ++++++- ...20231207053523_Initial.cs => 20231220020240_Initial.cs} | 1 + .../Migrations/MyProjectNameDbContextModelSnapshot.cs | 5 +++++ ...tial.Designer.cs => 20231220020703_Initial.Designer.cs} | 7 ++++++- .../Migrations/20231220020703_Initial.cs} | 1 + .../Migrations/AuthServerDbContextModelSnapshot.cs | 5 +++++ ...tial.Designer.cs => 20231220020754_Initial.Designer.cs} | 7 ++++++- ...20231115065621_Initial.cs => 20231220020754_Initial.cs} | 1 + .../Migrations/UnifiedDbContextModelSnapshot.cs | 5 +++++ ...tial.Designer.cs => 20231220020817_Initial.Designer.cs} | 7 ++++++- ...20231115065707_Initial.cs => 20231220020817_Initial.cs} | 1 + .../Migrations/UnifiedDbContextModelSnapshot.cs | 5 +++++ 24 files changed, 96 insertions(+), 8 deletions(-) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/{20231207053812_Initial.Designer.cs => 20231220020330_Initial.Designer.cs} (99%) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/{20231207053812_Initial.cs => 20231220020330_Initial.cs} (99%) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/{20231207053830_Initial.Designer.cs => 20231220020415_Initial.Designer.cs} (99%) rename templates/{module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231207053828_Initial.cs => app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231220020415_Initial.cs} (99%) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/{20231207053820_Initial.Designer.cs => 20231220020502_Initial.Designer.cs} (99%) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/{20231207053820_Initial.cs => 20231220020502_Initial.cs} (99%) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/{20231207053825_Initial.Designer.cs => 20231220020554_Initial.Designer.cs} (99%) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/{20231207053825_Initial.cs => 20231220020554_Initial.cs} (99%) rename templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/{20231207053523_Initial.Designer.cs => 20231220020240_Initial.Designer.cs} (99%) rename templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/{20231207053523_Initial.cs => 20231220020240_Initial.cs} (99%) rename templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/{20231207053828_Initial.Designer.cs => 20231220020703_Initial.Designer.cs} (99%) rename templates/{app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231207053830_Initial.cs => module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231220020703_Initial.cs} (99%) rename templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/{20231115065621_Initial.Designer.cs => 20231220020754_Initial.Designer.cs} (99%) rename templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/{20231115065621_Initial.cs => 20231220020754_Initial.cs} (99%) rename templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/{20231115065707_Initial.Designer.cs => 20231220020817_Initial.Designer.cs} (99%) rename templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/{20231115065707_Initial.cs => 20231220020817_Initial.cs} (99%) diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20231207053812_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20231220020330_Initial.Designer.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20231207053812_Initial.Designer.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20231220020330_Initial.Designer.cs index 333df53077..b6afd36542 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20231207053812_Initial.Designer.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20231220020330_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20231207053812_Initial")] + [Migration("20231220020330_Initial")] partial class Initial { /// @@ -1687,6 +1687,11 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20231207053812_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20231220020330_Initial.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20231207053812_Initial.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20231220020330_Initial.cs index e993702885..8ce8dba759 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20231207053812_Initial.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20231220020330_Initial.cs @@ -296,6 +296,7 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations { Id = table.Column(type: "uniqueidentifier", nullable: false), Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + NormalizedName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), EntityVersion = table.Column(type: "int", nullable: false), ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false), diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs index 1def4a0ee9..d65c2397b7 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -1684,6 +1684,11 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231207053830_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231220020415_Initial.Designer.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231207053830_Initial.Designer.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231220020415_Initial.Designer.cs index ac18b045c6..83eb21746a 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231207053830_Initial.Designer.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231220020415_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20231207053830_Initial")] + [Migration("20231220020415_Initial")] partial class Initial { /// @@ -1687,6 +1687,11 @@ namespace MyCompanyName.MyProjectName.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231207053828_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231220020415_Initial.cs similarity index 99% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231207053828_Initial.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231220020415_Initial.cs index 7a0019fbf6..da36f3081f 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231207053828_Initial.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231220020415_Initial.cs @@ -296,6 +296,7 @@ namespace MyCompanyName.MyProjectName.Migrations { Id = table.Column(type: "uniqueidentifier", nullable: false), Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + NormalizedName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), EntityVersion = table.Column(type: "int", nullable: false), ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false), diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs index 20542b282c..3c61917830 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -1684,6 +1684,11 @@ namespace MyCompanyName.MyProjectName.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20231207053820_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20231220020502_Initial.Designer.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20231207053820_Initial.Designer.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20231220020502_Initial.Designer.cs index 333258a426..249957c93c 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20231207053820_Initial.Designer.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20231220020502_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Host.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20231207053820_Initial")] + [Migration("20231220020502_Initial")] partial class Initial { /// @@ -1687,6 +1687,11 @@ namespace MyCompanyName.MyProjectName.Host.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20231207053820_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20231220020502_Initial.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20231207053820_Initial.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20231220020502_Initial.cs index 08eca1feca..ace742cda5 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20231207053820_Initial.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20231220020502_Initial.cs @@ -296,6 +296,7 @@ namespace MyCompanyName.MyProjectName.Host.Migrations { Id = table.Column(type: "uniqueidentifier", nullable: false), Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + NormalizedName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), EntityVersion = table.Column(type: "int", nullable: false), ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false), diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs index 6475d362fa..a972acadeb 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -1684,6 +1684,11 @@ namespace MyCompanyName.MyProjectName.Host.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20231207053825_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20231220020554_Initial.Designer.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20231207053825_Initial.Designer.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20231220020554_Initial.Designer.cs index 11234086f3..143044a16c 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20231207053825_Initial.Designer.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20231220020554_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Mvc.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20231207053825_Initial")] + [Migration("20231220020554_Initial")] partial class Initial { /// @@ -1687,6 +1687,11 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20231207053825_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20231220020554_Initial.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20231207053825_Initial.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20231220020554_Initial.cs index ef1ec2fdd6..32fb8b2358 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20231207053825_Initial.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20231220020554_Initial.cs @@ -296,6 +296,7 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations { Id = table.Column(type: "uniqueidentifier", nullable: false), Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + NormalizedName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), EntityVersion = table.Column(type: "int", nullable: false), ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false), diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs index 1e8916ad04..bab3848fb5 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -1684,6 +1684,11 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231207053523_Initial.Designer.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231220020240_Initial.Designer.cs similarity index 99% rename from templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231207053523_Initial.Designer.cs rename to templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231220020240_Initial.Designer.cs index c52403afd3..cddfa265f4 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231207053523_Initial.Designer.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231220020240_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20231207053523_Initial")] + [Migration("20231220020240_Initial")] partial class Initial { /// @@ -1739,6 +1739,11 @@ namespace MyCompanyName.MyProjectName.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231207053523_Initial.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231220020240_Initial.cs similarity index 99% rename from templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231207053523_Initial.cs rename to templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231220020240_Initial.cs index a5027f58de..6c052b9dea 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231207053523_Initial.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231220020240_Initial.cs @@ -317,6 +317,7 @@ namespace MyCompanyName.MyProjectName.Migrations { Id = table.Column(type: "uniqueidentifier", nullable: false), Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + NormalizedName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), EntityVersion = table.Column(type: "int", nullable: false), ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false), diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs index 8a0febed15..17dcf3ad28 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -1736,6 +1736,11 @@ namespace MyCompanyName.MyProjectName.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231207053828_Initial.Designer.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231220020703_Initial.Designer.cs similarity index 99% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231207053828_Initial.Designer.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231220020703_Initial.Designer.cs index 389a2a8cc3..5b9f7049d4 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231207053828_Initial.Designer.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231220020703_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(AuthServerDbContext))] - [Migration("20231207053828_Initial")] + [Migration("20231220020703_Initial")] partial class Initial { /// @@ -1687,6 +1687,11 @@ namespace MyCompanyName.MyProjectName.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231207053830_Initial.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231220020703_Initial.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231207053830_Initial.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231220020703_Initial.cs index 7a0019fbf6..da36f3081f 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20231207053830_Initial.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20231220020703_Initial.cs @@ -296,6 +296,7 @@ namespace MyCompanyName.MyProjectName.Migrations { Id = table.Column(type: "uniqueidentifier", nullable: false), Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + NormalizedName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), EntityVersion = table.Column(type: "int", nullable: false), ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false), diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/AuthServerDbContextModelSnapshot.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/AuthServerDbContextModelSnapshot.cs index c63e7d13e1..780558fcbc 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/AuthServerDbContextModelSnapshot.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/AuthServerDbContextModelSnapshot.cs @@ -1684,6 +1684,11 @@ namespace MyCompanyName.MyProjectName.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20231115065621_Initial.Designer.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20231220020754_Initial.Designer.cs similarity index 99% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20231115065621_Initial.Designer.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20231220020754_Initial.Designer.cs index 86eca8fe53..cd7ee4b230 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20231115065621_Initial.Designer.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20231220020754_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations { [DbContext(typeof(UnifiedDbContext))] - [Migration("20231115065621_Initial")] + [Migration("20231220020754_Initial")] partial class Initial { /// @@ -1328,6 +1328,11 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20231115065621_Initial.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20231220020754_Initial.cs similarity index 99% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20231115065621_Initial.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20231220020754_Initial.cs index b21456cc73..6e5ae88b9f 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20231115065621_Initial.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20231220020754_Initial.cs @@ -296,6 +296,7 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations { Id = table.Column(type: "uniqueidentifier", nullable: false), Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + NormalizedName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), EntityVersion = table.Column(type: "int", nullable: false), ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false), diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/UnifiedDbContextModelSnapshot.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/UnifiedDbContextModelSnapshot.cs index 92a676f756..c32f89f163 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/UnifiedDbContextModelSnapshot.cs @@ -1325,6 +1325,11 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20231115065707_Initial.Designer.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20231220020817_Initial.Designer.cs similarity index 99% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20231115065707_Initial.Designer.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20231220020817_Initial.Designer.cs index 16bf3345ff..ad8d576878 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20231115065707_Initial.Designer.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20231220020817_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(UnifiedDbContext))] - [Migration("20231115065707_Initial")] + [Migration("20231220020817_Initial")] partial class Initial { /// @@ -1328,6 +1328,11 @@ namespace MyCompanyName.MyProjectName.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20231115065707_Initial.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20231220020817_Initial.cs similarity index 99% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20231115065707_Initial.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20231220020817_Initial.cs index d19146cde5..695c5fc0ac 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20231115065707_Initial.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20231220020817_Initial.cs @@ -296,6 +296,7 @@ namespace MyCompanyName.MyProjectName.Migrations { Id = table.Column(type: "uniqueidentifier", nullable: false), Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + NormalizedName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), EntityVersion = table.Column(type: "int", nullable: false), ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false), diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs index 56d7b7e9bd..bb83f23368 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs @@ -1325,6 +1325,11 @@ namespace MyCompanyName.MyProjectName.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.HasKey("Id"); b.HasIndex("Name"); From bc13da3e9f4ce609dc8cab7dba5166f7c4044349 Mon Sep 17 00:00:00 2001 From: maliming Date: Sat, 30 Dec 2023 17:54:45 +0800 Subject: [PATCH 04/58] Provide a way for the controller to skip all interceptors and filters. Resolve #18635 --- .../MultiTenancy/MultiTenancyMiddleware.cs | 5 ++-- .../AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs | 5 +++- .../Mvc/AbpMvcActionDescriptorProvider.cs | 30 +++++++++++++++++++ .../Mvc/Auditing/AbpAuditActionFilter.cs | 3 +- .../Mvc/Auditing/AbpAuditPageFilter.cs | 3 +- .../ExceptionHandling/AbpExceptionFilter.cs | 3 +- .../AbpExceptionPageFilter.cs | 3 +- .../Mvc/Features/AbpFeatureActionFilter.cs | 3 +- .../Mvc/Features/AbpFeaturePageFilter.cs | 3 +- .../GlobalFeatureActionFilter.cs | 3 +- .../GlobalFeatures/GlobalFeaturePageFilter.cs | 3 +- .../Mvc/Response/AbpNoContentActionFilter.cs | 3 +- .../AspNetCore/Mvc/Uow/AbpUowActionFilter.cs | 3 +- .../AspNetCore/Mvc/Uow/AbpUowPageFilter.cs | 3 +- .../Validation/AbpValidationActionFilter.cs | 3 +- .../Serilog/AbpSerilogMiddleware.cs | 5 ++-- .../AbpRequestLocalizationMiddleware.cs | 5 ++-- .../Auditing/AbpAuditingMiddleware.cs | 7 +++-- .../AbpExceptionHandlingMiddleware.cs | 5 ++-- .../Filters/DisableAbpFilterAttribute.cs | 19 ++++++++++++ .../Volo/Abp/AspNetCore/Filters/IAbpFilter.cs | 6 ++++ .../Middleware/AbpMiddlewareBase.cs | 20 +++++++++++++ .../Security/AbpSecurityHeadersMiddleware.cs | 5 ++-- .../Security/Claims/AbpClaimsMapMiddleware.cs | 5 ++-- .../Claims/AbpDynamicClaimsMiddleware.cs | 5 ++-- .../Tracing/AbpCorrelationIdMiddleware.cs | 5 ++-- .../AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs | 7 +++-- .../AbpRegistrationBuilderExtensions.cs | 4 ++- .../DisableInterceptorAttribute.cs | 9 ++++++ .../Mvc/FakeAuthenticationMiddleware.cs | 5 ++-- 30 files changed, 150 insertions(+), 38 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcActionDescriptorProvider.cs create mode 100644 framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/DisableAbpFilterAttribute.cs create mode 100644 framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs create mode 100644 framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableInterceptorAttribute.cs diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs index 310add4bfc..520e2944f6 100644 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Middleware; using Volo.Abp.DependencyInjection; using Volo.Abp.Localization; using Volo.Abp.MultiTenancy; @@ -15,7 +16,7 @@ using Volo.Abp.Settings; namespace Volo.Abp.AspNetCore.MultiTenancy; -public class MultiTenancyMiddleware : IMiddleware, ITransientDependency +public class MultiTenancyMiddleware : AbpMiddlewareBase, ITransientDependency { public ILogger Logger { get; set; } @@ -38,7 +39,7 @@ public class MultiTenancyMiddleware : IMiddleware, ITransientDependency _options = options.Value; } - public async Task InvokeAsync(HttpContext context, RequestDelegate next) + public async override Task InvokeAsync(HttpContext context, RequestDelegate next) { TenantConfiguration? tenant = null; try diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs index c9b5984843..a2f2c1c989 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs @@ -14,6 +14,7 @@ using System.Linq; using System.Net; using System.Reflection; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.AspNetCore.Mvc.DataAnnotations; using Microsoft.AspNetCore.Mvc.RazorPages; @@ -25,6 +26,7 @@ using Volo.Abp.ApiVersioning; using Volo.Abp.Application; using Volo.Abp.AspNetCore.Mvc.AntiForgery; using Volo.Abp.AspNetCore.Mvc.ApiExploring; +using Volo.Abp.AspNetCore.Mvc.ApplicationModels; using Volo.Abp.AspNetCore.Mvc.Conventions; using Volo.Abp.AspNetCore.Mvc.DataAnnotations; using Volo.Abp.AspNetCore.Mvc.DependencyInjection; @@ -176,6 +178,7 @@ public class AbpAspNetCoreMvcModule : AbpModule context.Services.Replace(ServiceDescriptor.Singleton()); context.Services.AddSingleton(); + context.Services.TryAddEnumerable(ServiceDescriptor.Transient()); context.Services.AddOptions() .Configure((mvcOptions, serviceProvider) => { @@ -247,7 +250,7 @@ public class AbpAspNetCoreMvcModule : AbpModule .Distinct(); AddToApplicationParts(partManager, controllerAssemblies); - + var additionalAssemblies = moduleContainer .Modules .SelectMany(m => m.GetAdditionalAssemblies()) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcActionDescriptorProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcActionDescriptorProvider.cs new file mode 100644 index 0000000000..9131cd44d6 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcActionDescriptorProvider.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Controllers; +using Volo.Abp.AspNetCore.Filters; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationModels; + +public class AbpMvcActionDescriptorProvider : IActionDescriptorProvider +{ + public virtual int Order => -1000 + 10; + + public virtual void OnProvidersExecuting(ActionDescriptorProviderContext context) + { + } + + public virtual void OnProvidersExecuted(ActionDescriptorProviderContext context) + { + foreach (var action in context.Results.Where(x => x is ControllerActionDescriptor).Cast()) + { + var disableFilterAttribute = action.ControllerTypeInfo.GetCustomAttribute(true); + if (disableFilterAttribute != null) + { + action.FilterDescriptors.RemoveAll(x => x.Filter is ServiceFilterAttribute serviceFilterAttribute && typeof(IAbpFilter).IsAssignableFrom(serviceFilterAttribute.ServiceType)); + } + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs index 07101da0cb..d982adb12a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs @@ -5,12 +5,13 @@ using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Options; using Volo.Abp.Aspects; +using Volo.Abp.AspNetCore.Filters; using Volo.Abp.Auditing; using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Mvc.Auditing; -public class AbpAuditActionFilter : IAsyncActionFilter, ITransientDependency +public class AbpAuditActionFilter : IAsyncActionFilter, IAbpFilter, ITransientDependency { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs index 8445be60ae..6b97ac980a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs @@ -5,12 +5,13 @@ using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Options; using Volo.Abp.Aspects; +using Volo.Abp.AspNetCore.Filters; using Volo.Abp.Auditing; using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Mvc.Auditing; -public class AbpAuditPageFilter : IAsyncPageFilter, ITransientDependency +public class AbpAuditPageFilter : IAsyncPageFilter, IAbpFilter, ITransientDependency { public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs index 61e37104ee..a63e557198 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.ExceptionHandling; +using Volo.Abp.AspNetCore.Filters; using Volo.Abp.Authorization; using Volo.Abp.DependencyInjection; using Volo.Abp.ExceptionHandling; @@ -18,7 +19,7 @@ using Volo.Abp.Json; namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling; -public class AbpExceptionFilter : IAsyncExceptionFilter, ITransientDependency +public class AbpExceptionFilter : IAsyncExceptionFilter, IAbpFilter, ITransientDependency { public virtual async Task OnExceptionAsync(ExceptionContext context) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs index 31784cb6ea..97c21268fe 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.ExceptionHandling; +using Volo.Abp.AspNetCore.Filters; using Volo.Abp.Authorization; using Volo.Abp.DependencyInjection; using Volo.Abp.ExceptionHandling; @@ -18,7 +19,7 @@ using Volo.Abp.Json; namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling; -public class AbpExceptionPageFilter : IAsyncPageFilter, ITransientDependency +public class AbpExceptionPageFilter : IAsyncPageFilter, IAbpFilter, ITransientDependency { public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs index b4b70a5e1a..35bb9ba572 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs @@ -2,12 +2,13 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Abstractions; using Volo.Abp.Aspects; +using Volo.Abp.AspNetCore.Filters; using Volo.Abp.DependencyInjection; using Volo.Abp.Features; namespace Volo.Abp.AspNetCore.Mvc.Features; -public class AbpFeatureActionFilter : IAsyncActionFilter, ITransientDependency +public class AbpFeatureActionFilter : IAsyncActionFilter, IAbpFilter, ITransientDependency { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs index 3c586f762b..a35764c43c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs @@ -2,12 +2,13 @@ using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; using Volo.Abp.Aspects; +using Volo.Abp.AspNetCore.Filters; using Volo.Abp.DependencyInjection; using Volo.Abp.Features; namespace Volo.Abp.AspNetCore.Mvc.Features; -public class AbpFeaturePageFilter : IAsyncPageFilter, ITransientDependency +public class AbpFeaturePageFilter : IAsyncPageFilter, IAbpFilter, ITransientDependency { public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs index aae85e4d25..34f125f228 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs @@ -6,12 +6,13 @@ using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.Aspects; +using Volo.Abp.AspNetCore.Filters; using Volo.Abp.DependencyInjection; using Volo.Abp.GlobalFeatures; namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures; -public class GlobalFeatureActionFilter : IAsyncActionFilter, ITransientDependency +public class GlobalFeatureActionFilter : IAsyncActionFilter, IAbpFilter, ITransientDependency { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs index 46455730a4..3c43301221 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs @@ -6,12 +6,13 @@ using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.Aspects; +using Volo.Abp.AspNetCore.Filters; using Volo.Abp.DependencyInjection; using Volo.Abp.GlobalFeatures; namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures; -public class GlobalFeaturePageFilter : IAsyncPageFilter, ITransientDependency +public class GlobalFeaturePageFilter : IAsyncPageFilter, IAbpFilter, ITransientDependency { public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Response/AbpNoContentActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Response/AbpNoContentActionFilter.cs index b0565cbc4d..455dd52f24 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Response/AbpNoContentActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Response/AbpNoContentActionFilter.cs @@ -2,11 +2,12 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; +using Volo.Abp.AspNetCore.Filters; using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Mvc.Response; -public class AbpNoContentActionFilter : IAsyncActionFilter, ITransientDependency +public class AbpNoContentActionFilter : IAsyncActionFilter, IAbpFilter, ITransientDependency { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs index 14032b52d5..4a6a04a554 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs @@ -4,12 +4,13 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Filters; using Volo.Abp.DependencyInjection; using Volo.Abp.Uow; namespace Volo.Abp.AspNetCore.Mvc.Uow; -public class AbpUowActionFilter : IAsyncActionFilter, ITransientDependency +public class AbpUowActionFilter : IAsyncActionFilter, IAbpFilter, ITransientDependency { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs index 7cfc1f0492..f4a7be3333 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs @@ -4,13 +4,14 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Filters; using Volo.Abp.AspNetCore.Uow; using Volo.Abp.DependencyInjection; using Volo.Abp.Uow; namespace Volo.Abp.AspNetCore.Mvc.Uow; -public class AbpUowPageFilter : IAsyncPageFilter, ITransientDependency +public class AbpUowPageFilter : IAsyncPageFilter, IAbpFilter, ITransientDependency { public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs index e88cee4eb6..f866c85585 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs @@ -3,13 +3,14 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Filters; using Volo.Abp.DependencyInjection; using Volo.Abp.Reflection; using Volo.Abp.Validation; namespace Volo.Abp.AspNetCore.Mvc.Validation; -public class AbpValidationActionFilter : IAsyncActionFilter, ITransientDependency +public class AbpValidationActionFilter : IAsyncActionFilter, IAbpFilter, ITransientDependency { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { diff --git a/framework/src/Volo.Abp.AspNetCore.Serilog/Volo/Abp/AspNetCore/Serilog/AbpSerilogMiddleware.cs b/framework/src/Volo.Abp.AspNetCore.Serilog/Volo/Abp/AspNetCore/Serilog/AbpSerilogMiddleware.cs index 1df327b742..52ee2e6b76 100644 --- a/framework/src/Volo.Abp.AspNetCore.Serilog/Volo/Abp/AspNetCore/Serilog/AbpSerilogMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore.Serilog/Volo/Abp/AspNetCore/Serilog/AbpSerilogMiddleware.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Options; using Serilog.Context; using Serilog.Core; using Serilog.Core.Enrichers; +using Volo.Abp.AspNetCore.Middleware; using Volo.Abp.Clients; using Volo.Abp.DependencyInjection; using Volo.Abp.MultiTenancy; @@ -13,7 +14,7 @@ using Volo.Abp.Users; namespace Volo.Abp.AspNetCore.Serilog; -public class AbpSerilogMiddleware : IMiddleware, ITransientDependency +public class AbpSerilogMiddleware : AbpMiddlewareBase, ITransientDependency { private readonly ICurrentClient _currentClient; private readonly ICurrentTenant _currentTenant; @@ -35,7 +36,7 @@ public class AbpSerilogMiddleware : IMiddleware, ITransientDependency _options = options.Value; } - public async Task InvokeAsync(HttpContext context, RequestDelegate next) + public async override Task InvokeAsync(HttpContext context, RequestDelegate next) { var enrichers = new List(); diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs index 6fd02a0470..cb531762ba 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs @@ -4,11 +4,12 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Middleware; using Volo.Abp.DependencyInjection; namespace Microsoft.AspNetCore.RequestLocalization; -public class AbpRequestLocalizationMiddleware : IMiddleware, ITransientDependency +public class AbpRequestLocalizationMiddleware : AbpMiddlewareBase, ITransientDependency { public const string HttpContextItemName = "__AbpSetCultureCookie"; @@ -23,7 +24,7 @@ public class AbpRequestLocalizationMiddleware : IMiddleware, ITransientDependenc _loggerFactory = loggerFactory; } - public async Task InvokeAsync(HttpContext context, RequestDelegate next) + public async override Task InvokeAsync(HttpContext context, RequestDelegate next) { var middleware = new RequestLocalizationMiddleware( next, diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs index 0987a8fd8f..86cc997ae7 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Middleware; using Volo.Abp.Auditing; using Volo.Abp.DependencyInjection; using Volo.Abp.Uow; @@ -11,7 +12,7 @@ using Volo.Abp.Users; namespace Volo.Abp.AspNetCore.Auditing; -public class AbpAuditingMiddleware : IMiddleware, ITransientDependency +public class AbpAuditingMiddleware : AbpMiddlewareBase, ITransientDependency { private readonly IAuditingManager _auditingManager; protected AbpAuditingOptions AuditingOptions { get; } @@ -34,9 +35,9 @@ public class AbpAuditingMiddleware : IMiddleware, ITransientDependency AspNetCoreAuditingOptions = aspNetCoreAuditingOptions.Value; } - public async Task InvokeAsync(HttpContext context, RequestDelegate next) + public async override Task InvokeAsync(HttpContext context, RequestDelegate next) { - if (!AuditingOptions.IsEnabled || IsIgnoredUrl(context)) + if (await ShouldSkipAsync(context, next) || !AuditingOptions.IsEnabled || IsIgnoredUrl(context)) { await next(context); return; diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs index b9d3b83068..7d5ef610e5 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.Net.Http.Headers; +using Volo.Abp.AspNetCore.Middleware; using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.Authorization; using Volo.Abp.DependencyInjection; @@ -14,7 +15,7 @@ using Volo.Abp.Json; namespace Volo.Abp.AspNetCore.ExceptionHandling; -public class AbpExceptionHandlingMiddleware : IMiddleware, ITransientDependency +public class AbpExceptionHandlingMiddleware : AbpMiddlewareBase, ITransientDependency { private readonly ILogger _logger; @@ -27,7 +28,7 @@ public class AbpExceptionHandlingMiddleware : IMiddleware, ITransientDependency _clearCacheHeadersDelegate = ClearCacheHeaders; } - public async Task InvokeAsync(HttpContext context, RequestDelegate next) + public async override Task InvokeAsync(HttpContext context, RequestDelegate next) { try { diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/DisableAbpFilterAttribute.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/DisableAbpFilterAttribute.cs new file mode 100644 index 0000000000..035c7b288f --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/DisableAbpFilterAttribute.cs @@ -0,0 +1,19 @@ +using System; + +namespace Volo.Abp.AspNetCore.Filters; + +[AttributeUsage(AttributeTargets.Class)] +public class DisableAbpFilterAttribute : Attribute +{ + public bool SkipInMiddleware { get; set; } + + public DisableAbpFilterAttribute() + { + SkipInMiddleware = true; + } + + public DisableAbpFilterAttribute(bool skipInMiddleware) + { + SkipInMiddleware = skipInMiddleware; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs new file mode 100644 index 0000000000..dbd55a8ed4 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp.AspNetCore.Filters; + +public interface IAbpFilter +{ + +} diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs new file mode 100644 index 0000000000..bbf79ba22e --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Controllers; +using Volo.Abp.AspNetCore.Filters; + +namespace Volo.Abp.AspNetCore.Middleware; + +public abstract class AbpMiddlewareBase : IMiddleware +{ + protected Task ShouldSkipAsync(HttpContext context, RequestDelegate next) + { + var endpoint = context.GetEndpoint(); + var controllerActionDescriptor = endpoint?.Metadata.GetMetadata(); + var disableAbpFilterAttribute = controllerActionDescriptor?.ControllerTypeInfo.GetCustomAttribute(); + return Task.FromResult(disableAbpFilterAttribute != null && disableAbpFilterAttribute.SkipInMiddleware); + } + + public abstract Task InvokeAsync(HttpContext context, RequestDelegate next); +} diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersMiddleware.cs index ae2e3b173b..4542dd32e1 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersMiddleware.cs @@ -5,11 +5,12 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; using Microsoft.Extensions.Primitives; +using Volo.Abp.AspNetCore.Middleware; using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Security; -public class AbpSecurityHeadersMiddleware : IMiddleware, ITransientDependency +public class AbpSecurityHeadersMiddleware : AbpMiddlewareBase, ITransientDependency { public IOptions Options { get; set; } protected const string ScriptSrcKey = "script-src"; @@ -20,7 +21,7 @@ public class AbpSecurityHeadersMiddleware : IMiddleware, ITransientDependency Options = options; } - public async Task InvokeAsync(HttpContext context, RequestDelegate next) + public async override Task InvokeAsync(HttpContext context, RequestDelegate next) { /*X-Content-Type-Options header tells the browser to not try and “guess” what a mimetype of a resource might be, and to just take what mimetype the server has returned as fact.*/ AddHeader(context, "X-Content-Type-Options", "nosniff"); diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs index ab23bdb944..bb2bedf901 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs @@ -4,14 +4,15 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Middleware; using Volo.Abp.DependencyInjection; using Volo.Abp.Security.Claims; namespace Volo.Abp.AspNetCore.Security.Claims; -public class AbpClaimsMapMiddleware : IMiddleware, ITransientDependency +public class AbpClaimsMapMiddleware : AbpMiddlewareBase, ITransientDependency { - public async Task InvokeAsync(HttpContext context, RequestDelegate next) + public async override Task InvokeAsync(HttpContext context, RequestDelegate next) { var currentPrincipalAccessor = context.RequestServices .GetRequiredService(); diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs index 777ca7744a..9c62fa8b25 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs @@ -2,14 +2,15 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Middleware; using Volo.Abp.DependencyInjection; using Volo.Abp.Security.Claims; namespace Volo.Abp.AspNetCore.Security.Claims; -public class AbpDynamicClaimsMiddleware : IMiddleware, ITransientDependency +public class AbpDynamicClaimsMiddleware : AbpMiddlewareBase, ITransientDependency { - public async Task InvokeAsync(HttpContext context, RequestDelegate next) + public async override Task InvokeAsync(HttpContext context, RequestDelegate next) { if (context.User.Identity?.IsAuthenticated == true) { diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AbpCorrelationIdMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AbpCorrelationIdMiddleware.cs index a5f954c260..38356f8151 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AbpCorrelationIdMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AbpCorrelationIdMiddleware.cs @@ -3,12 +3,13 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Middleware; using Volo.Abp.DependencyInjection; using Volo.Abp.Tracing; namespace Volo.Abp.AspNetCore.Tracing; -public class AbpCorrelationIdMiddleware : IMiddleware, ITransientDependency +public class AbpCorrelationIdMiddleware : AbpMiddlewareBase, ITransientDependency { private readonly AbpCorrelationIdOptions _options; private readonly ICorrelationIdProvider _correlationIdProvider; @@ -20,7 +21,7 @@ public class AbpCorrelationIdMiddleware : IMiddleware, ITransientDependency _correlationIdProvider = correlationIdProvider; } - public async Task InvokeAsync(HttpContext context, RequestDelegate next) + public async override Task InvokeAsync(HttpContext context, RequestDelegate next) { var correlationId = GetCorrelationIdFromRequest(context); using (_correlationIdProvider.Change(correlationId)) diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs index 186501b4ac..013b3dad98 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs @@ -3,12 +3,13 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Middleware; using Volo.Abp.DependencyInjection; using Volo.Abp.Uow; namespace Volo.Abp.AspNetCore.Uow; -public class AbpUnitOfWorkMiddleware : IMiddleware, ITransientDependency +public class AbpUnitOfWorkMiddleware : AbpMiddlewareBase, ITransientDependency { private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly AbpAspNetCoreUnitOfWorkOptions _options; @@ -21,9 +22,9 @@ public class AbpUnitOfWorkMiddleware : IMiddleware, ITransientDependency _options = options.Value; } - public async Task InvokeAsync(HttpContext context, RequestDelegate next) + public async override Task InvokeAsync(HttpContext context, RequestDelegate next) { - if (IsIgnoredUrl(context)) + if (await ShouldSkipAsync(context, next) || IsIgnoredUrl(context)) { await next(context); return; diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs index 043f824b1a..9a2b1fa43a 100644 --- a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Autofac; using Volo.Abp.Castle.DynamicProxy; using Volo.Abp.DependencyInjection; +using Volo.Abp.DynamicProxy; using Volo.Abp.Modularity; namespace Autofac.Builder; @@ -73,7 +74,8 @@ public static class AbpRegistrationBuilderExtensions registrationAction.Invoke(serviceRegistredArgs); } - if (serviceRegistredArgs.Interceptors.Any()) + if (serviceRegistredArgs.Interceptors.Any() && + !serviceRegistredArgs.ImplementationType.IsDefined(typeof(DisableInterceptorAttribute), true)) { registrationBuilder = registrationBuilder.AddInterceptors( registrationActionList, diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableInterceptorAttribute.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableInterceptorAttribute.cs new file mode 100644 index 0000000000..7d3bf5bcc5 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableInterceptorAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace Volo.Abp.DynamicProxy; + +[AttributeUsage(AttributeTargets.Class)] +public class DisableInterceptorAttribute : Attribute +{ + +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs index 41a9b56fe5..a3cd4a57e6 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs @@ -3,11 +3,12 @@ using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; +using Volo.Abp.AspNetCore.Middleware; using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Mvc; -public class FakeAuthenticationMiddleware : IMiddleware, ITransientDependency +public class FakeAuthenticationMiddleware : AbpMiddlewareBase, ITransientDependency { private readonly FakeUserClaims _fakeUserClaims; @@ -16,7 +17,7 @@ public class FakeAuthenticationMiddleware : IMiddleware, ITransientDependency _fakeUserClaims = fakeUserClaims; } - public async Task InvokeAsync(HttpContext context, RequestDelegate next) + public async override Task InvokeAsync(HttpContext context, RequestDelegate next) { if (_fakeUserClaims.Claims.Any()) { From cb7e441a71e54a6bc03b65955a8cb266ca096dba Mon Sep 17 00:00:00 2001 From: maliming Date: Sat, 30 Dec 2023 17:57:32 +0800 Subject: [PATCH 05/58] Rename `DisableInterceptorAttribute` to `DisableAbpInterceptorAttribute`. --- .../Autofac/Builder/AbpRegistrationBuilderExtensions.cs | 2 +- ...nterceptorAttribute.cs => DisableAbpInterceptorAttribute.cs} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/{DisableInterceptorAttribute.cs => DisableAbpInterceptorAttribute.cs} (62%) diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs index 9a2b1fa43a..de5effd86c 100644 --- a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs @@ -75,7 +75,7 @@ public static class AbpRegistrationBuilderExtensions } if (serviceRegistredArgs.Interceptors.Any() && - !serviceRegistredArgs.ImplementationType.IsDefined(typeof(DisableInterceptorAttribute), true)) + !serviceRegistredArgs.ImplementationType.IsDefined(typeof(DisableAbpInterceptorAttribute), true)) { registrationBuilder = registrationBuilder.AddInterceptors( registrationActionList, diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableInterceptorAttribute.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableAbpInterceptorAttribute.cs similarity index 62% rename from framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableInterceptorAttribute.cs rename to framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableAbpInterceptorAttribute.cs index 7d3bf5bcc5..be7b773c87 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableInterceptorAttribute.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableAbpInterceptorAttribute.cs @@ -3,7 +3,7 @@ using System; namespace Volo.Abp.DynamicProxy; [AttributeUsage(AttributeTargets.Class)] -public class DisableInterceptorAttribute : Attribute +public class DisableAbpInterceptorAttribute : Attribute { } From b10761d99708e54246daba6c680c3ae044496dab Mon Sep 17 00:00:00 2001 From: maliming Date: Sat, 30 Dec 2023 20:23:29 +0800 Subject: [PATCH 06/58] Add `DisableAbpFeaturesAttribute`. --- .../Mvc/AbpMvcActionDescriptorProvider.cs | 7 +++--- .../Filters/DisableAbpFilterAttribute.cs | 19 -------------- .../Middleware/AbpMiddlewareBase.cs | 5 ++-- .../AbpRegistrationBuilderExtensions.cs | 19 ++++++++------ .../Volo/Abp/DisableAbpFeaturesAttribute.cs | 25 +++++++++++++++++++ .../DisableAbpInterceptorAttribute.cs | 9 ------- 6 files changed, 43 insertions(+), 41 deletions(-) delete mode 100644 framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/DisableAbpFilterAttribute.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/DisableAbpFeaturesAttribute.cs delete mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableAbpInterceptorAttribute.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcActionDescriptorProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcActionDescriptorProvider.cs index 9131cd44d6..1ae2180e47 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcActionDescriptorProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcActionDescriptorProvider.cs @@ -20,10 +20,11 @@ public class AbpMvcActionDescriptorProvider : IActionDescriptorProvider { foreach (var action in context.Results.Where(x => x is ControllerActionDescriptor).Cast()) { - var disableFilterAttribute = action.ControllerTypeInfo.GetCustomAttribute(true); - if (disableFilterAttribute != null) + var disableAbpFeaturesAttribute = action.ControllerTypeInfo.GetCustomAttribute(true); + if (disableAbpFeaturesAttribute != null && disableAbpFeaturesAttribute.DisableMvcFilters) { - action.FilterDescriptors.RemoveAll(x => x.Filter is ServiceFilterAttribute serviceFilterAttribute && typeof(IAbpFilter).IsAssignableFrom(serviceFilterAttribute.ServiceType)); + action.FilterDescriptors.RemoveAll(x => x.Filter is ServiceFilterAttribute serviceFilterAttribute && + typeof(IAbpFilter).IsAssignableFrom(serviceFilterAttribute.ServiceType)); } } } diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/DisableAbpFilterAttribute.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/DisableAbpFilterAttribute.cs deleted file mode 100644 index 035c7b288f..0000000000 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/DisableAbpFilterAttribute.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace Volo.Abp.AspNetCore.Filters; - -[AttributeUsage(AttributeTargets.Class)] -public class DisableAbpFilterAttribute : Attribute -{ - public bool SkipInMiddleware { get; set; } - - public DisableAbpFilterAttribute() - { - SkipInMiddleware = true; - } - - public DisableAbpFilterAttribute(bool skipInMiddleware) - { - SkipInMiddleware = skipInMiddleware; - } -} diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs index bbf79ba22e..f41578da33 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs @@ -2,7 +2,6 @@ using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Controllers; -using Volo.Abp.AspNetCore.Filters; namespace Volo.Abp.AspNetCore.Middleware; @@ -12,8 +11,8 @@ public abstract class AbpMiddlewareBase : IMiddleware { var endpoint = context.GetEndpoint(); var controllerActionDescriptor = endpoint?.Metadata.GetMetadata(); - var disableAbpFilterAttribute = controllerActionDescriptor?.ControllerTypeInfo.GetCustomAttribute(); - return Task.FromResult(disableAbpFilterAttribute != null && disableAbpFilterAttribute.SkipInMiddleware); + var disableAbpFeaturesAttribute = controllerActionDescriptor?.ControllerTypeInfo.GetCustomAttribute(); + return Task.FromResult(disableAbpFeaturesAttribute != null && disableAbpFeaturesAttribute.DisableMiddlewares); } public abstract Task InvokeAsync(HttpContext context, RequestDelegate next); diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs index de5effd86c..53216b03b9 100644 --- a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using Autofac.Core; using Autofac.Extras.DynamicProxy; using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; using Volo.Abp.Autofac; using Volo.Abp.Castle.DynamicProxy; using Volo.Abp.DependencyInjection; @@ -74,14 +76,17 @@ public static class AbpRegistrationBuilderExtensions registrationAction.Invoke(serviceRegistredArgs); } - if (serviceRegistredArgs.Interceptors.Any() && - !serviceRegistredArgs.ImplementationType.IsDefined(typeof(DisableAbpInterceptorAttribute), true)) + if (serviceRegistredArgs.Interceptors.Any()) { - registrationBuilder = registrationBuilder.AddInterceptors( - registrationActionList, - serviceType, - serviceRegistredArgs.Interceptors - ); + var disableAbpFeaturesAttribute = serviceRegistredArgs.ImplementationType.GetCustomAttribute(true); + if (disableAbpFeaturesAttribute == null || !disableAbpFeaturesAttribute.DisableInterceptors) + { + registrationBuilder = registrationBuilder.AddInterceptors( + registrationActionList, + serviceType, + serviceRegistredArgs.Interceptors + ); + } } return registrationBuilder; diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DisableAbpFeaturesAttribute.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DisableAbpFeaturesAttribute.cs new file mode 100644 index 0000000000..69f80446a6 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DisableAbpFeaturesAttribute.cs @@ -0,0 +1,25 @@ +using System; + +namespace Volo.Abp; + +[AttributeUsage(AttributeTargets.Class)] +public class DisableAbpFeaturesAttribute : Attribute +{ + /// + /// The framework will not register any interceptors for the class. + /// This will cause the all features that depend on interceptors to not work. + /// + public bool DisableInterceptors { get; set; } = true; + + /// + /// The framework middleware will skip the class. + /// This will cause the all features that depend on middleware to not work. + /// + public bool DisableMiddlewares { get; set; } = true; + + /// + /// The framework will not remove all built-in filters for the class. + /// This will cause the all features that depend on filters to not work. + /// + public bool DisableMvcFilters { get; set; } = true; +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableAbpInterceptorAttribute.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableAbpInterceptorAttribute.cs deleted file mode 100644 index be7b773c87..0000000000 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DisableAbpInterceptorAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace Volo.Abp.DynamicProxy; - -[AttributeUsage(AttributeTargets.Class)] -public class DisableAbpInterceptorAttribute : Attribute -{ - -} From 2823596497cecaa5c91ac2e568b5524607da7ff4 Mon Sep 17 00:00:00 2001 From: maliming Date: Sat, 30 Dec 2023 21:27:54 +0800 Subject: [PATCH 07/58] Add unit tests. --- .../Middleware/AbpMiddlewareBase.cs | 2 +- .../Volo/Abp/DisableAbpFeaturesAttribute.cs | 2 +- .../MvcDisableAbpFeaturesAttribute_Tests.cs | 74 +++++++++++++++++++ .../DynamicProxy/AbpInterceptionTestBase.cs | 31 ++++++++ .../AlwaysExceptionAsyncInterceptor.cs | 11 +++ .../DisableInterceptionTargetClass.cs | 41 ++++++++++ 6 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Filters/MvcDisableAbpFeaturesAttribute_Tests.cs create mode 100644 framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/AlwaysExceptionAsyncInterceptor.cs create mode 100644 framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/DisableInterceptionTargetClass.cs diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs index f41578da33..52c9990a4f 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs @@ -12,7 +12,7 @@ public abstract class AbpMiddlewareBase : IMiddleware var endpoint = context.GetEndpoint(); var controllerActionDescriptor = endpoint?.Metadata.GetMetadata(); var disableAbpFeaturesAttribute = controllerActionDescriptor?.ControllerTypeInfo.GetCustomAttribute(); - return Task.FromResult(disableAbpFeaturesAttribute != null && disableAbpFeaturesAttribute.DisableMiddlewares); + return Task.FromResult(disableAbpFeaturesAttribute != null && disableAbpFeaturesAttribute.DisableMiddleware); } public abstract Task InvokeAsync(HttpContext context, RequestDelegate next); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DisableAbpFeaturesAttribute.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DisableAbpFeaturesAttribute.cs index 69f80446a6..28c92b7463 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DisableAbpFeaturesAttribute.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DisableAbpFeaturesAttribute.cs @@ -15,7 +15,7 @@ public class DisableAbpFeaturesAttribute : Attribute /// The framework middleware will skip the class. /// This will cause the all features that depend on middleware to not work. /// - public bool DisableMiddlewares { get; set; } = true; + public bool DisableMiddleware { get; set; } = true; /// /// The framework will not remove all built-in filters for the class. diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Filters/MvcDisableAbpFeaturesAttribute_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Filters/MvcDisableAbpFeaturesAttribute_Tests.cs new file mode 100644 index 0000000000..7ff181c645 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Filters/MvcDisableAbpFeaturesAttribute_Tests.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.AspNetCore.Mvc.Filters; +using Shouldly; +using Volo.Abp.AspNetCore.Mvc.Auditing; +using Volo.Abp.AspNetCore.Mvc.ExceptionHandling; +using Volo.Abp.AspNetCore.Mvc.Features; +using Volo.Abp.AspNetCore.Mvc.GlobalFeatures; +using Volo.Abp.AspNetCore.Mvc.Response; +using Volo.Abp.AspNetCore.Mvc.Uow; +using Volo.Abp.AspNetCore.Mvc.Validation; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Filters; + +[Route("api/enabled-features-test")] +public class EnabledAbpFeaturesController : AbpController, IRemoteService +{ + [HttpGet] + public Task> GetAsync() + { + var filters = HttpContext.GetEndpoint().Metadata.GetMetadata() + .FilterDescriptors.Where(x => x.Filter is ServiceFilterAttribute) + .Select(x => x.Filter.As().ServiceType.FullName).ToList(); + + return Task.FromResult(filters); + } +} + +[Route("api/disabled-features-test")] +[DisableAbpFeatures] +public class DisabledAbpFeaturesController : AbpController, IRemoteService +{ + [HttpGet] + public Task> GetAsync() + { + var filters = HttpContext.GetEndpoint().Metadata.GetMetadata() + .FilterDescriptors.Where(x => x.Filter is ServiceFilterAttribute) + .Select(x => x.Filter.As().ServiceType.FullName).ToList(); + + return Task.FromResult(filters); + } +} + +public class MvcDisableAbpFeaturesAttribute_Tests : AspNetCoreMvcTestBase +{ + [Fact] + public async Task Should_Disable_MVC_Filters() + { + var filters = await GetResponseAsObjectAsync>("/api/enabled-features-test"); + filters.ShouldContain(typeof(GlobalFeatureActionFilter).FullName); + filters.ShouldContain(typeof(AbpAuditActionFilter).FullName); + filters.ShouldContain(typeof(AbpNoContentActionFilter).FullName); + filters.ShouldContain(typeof(AbpFeatureActionFilter).FullName); + filters.ShouldContain(typeof(AbpValidationActionFilter).FullName); + filters.ShouldContain(typeof(AbpUowActionFilter).FullName); + filters.ShouldContain(typeof(AbpExceptionFilter).FullName); + + filters = await GetResponseAsObjectAsync>("/api/disabled-features-test"); + filters.ShouldNotContain(typeof(GlobalFeatureActionFilter).FullName); + filters.ShouldNotContain(typeof(AbpAuditActionFilter).FullName); + filters.ShouldNotContain(typeof(AbpNoContentActionFilter).FullName); + filters.ShouldNotContain(typeof(AbpFeatureActionFilter).FullName); + filters.ShouldNotContain(typeof(AbpValidationActionFilter).FullName); + filters.ShouldNotContain(typeof(AbpUowActionFilter).FullName); + filters.ShouldNotContain(typeof(AbpExceptionFilter).FullName); + } + +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/AbpInterceptionTestBase.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/AbpInterceptionTestBase.cs index e244237598..4cce6a0c78 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/AbpInterceptionTestBase.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/AbpInterceptionTestBase.cs @@ -15,22 +15,34 @@ public abstract class AbpInterceptionTestBase : AbpAsyncIntegrat services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.OnRegistered(registration => { if (typeof(SimpleInterceptionTargetClass) == registration.ImplementationType) { registration.Interceptors.Add(); registration.Interceptors.Add(); + registration.Interceptors.Add(); } if (typeof(CachedTestObject) == registration.ImplementationType) { registration.Interceptors.Add(); } + + if (typeof(DisableInterceptionTargetClass) == registration.ImplementationType) + { + registration.Interceptors.Add(); + registration.Interceptors.Add(); + registration.Interceptors.Add(); + registration.Interceptors.Add(); + } }); return Task.CompletedTask; @@ -96,4 +108,23 @@ public abstract class AbpInterceptionTestBase : AbpAsyncIntegrat (await target.GetValueAsync(43)).ShouldBe(42); //First run, cached previous value (await target.GetValueAsync(44)).ShouldBe(42); //First run, cached previous value } + + [Fact] + public async Task Should_Disable_Interceptors() + { + //Arrange + + var target = ServiceProvider.GetService(); + + //Act + + await target.DoItAsync(); + + //Assert + + target.Logs.Count.ShouldBe(3); + target.Logs[0].ShouldBe("EnterDoItAsync"); + target.Logs[1].ShouldBe("MiddleDoItAsync"); + target.Logs[2].ShouldBe("ExitDoItAsync"); + } } diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/AlwaysExceptionAsyncInterceptor.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/AlwaysExceptionAsyncInterceptor.cs new file mode 100644 index 0000000000..2b9845a6ea --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/AlwaysExceptionAsyncInterceptor.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.DynamicProxy; + +public class AlwaysExceptionAsyncInterceptor : AbpInterceptor +{ + public override Task InterceptAsync(IAbpMethodInvocation invocation) + { + throw new AbpException("This interceptor should not be executed!"); + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/DisableInterceptionTargetClass.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/DisableInterceptionTargetClass.cs new file mode 100644 index 0000000000..caf17b5b9d --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/DisableInterceptionTargetClass.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.TestBase.Logging; + +namespace Volo.Abp.DynamicProxy; + +[DisableAbpFeatures] +public class DisableInterceptionTargetClass : ICanLogOnObject +{ + public List Logs { get; } = new List(); + + public virtual void DoIt() + { + Logs.Add("ExecutingDoIt"); + } + + public virtual int GetValue() + { + Logs.Add("ExecutingGetValue"); + return 42; + } + + public virtual async Task GetValueAsync() + { + Logs.Add("EnterGetValueAsync"); + await Task.Delay(5); + Logs.Add("MiddleGetValueAsync"); + await Task.Delay(5); + Logs.Add("ExitGetValueAsync"); + return 42; + } + + public virtual async Task DoItAsync() + { + Logs.Add("EnterDoItAsync"); + await Task.Delay(5); + Logs.Add("MiddleDoItAsync"); + await Task.Delay(5); + Logs.Add("ExitDoItAsync"); + } +} From 3cca9a13cfcf3b2c087b64989c88e7efda9ebb05 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 4 Jan 2024 13:41:07 +0800 Subject: [PATCH 08/58] Use Deepl to translate localization files Resovle #18665 --- .../2024-01-04-CLI-Online-Translate/Post.md | 72 ++++++++++++++++++ .../2024-01-04-CLI-Online-Translate/deepl.jpg | Bin 0 -> 466794 bytes 2 files changed, 72 insertions(+) create mode 100644 docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/Post.md create mode 100644 docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/deepl.jpg diff --git a/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/Post.md b/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/Post.md new file mode 100644 index 0000000000..abddfd43fd --- /dev/null +++ b/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/Post.md @@ -0,0 +1,72 @@ +# Use Deepl to translate localization files + +Translating localized text during the development ABP modules is a boring work. For this reason we have added the `translate` command to the CLI tool to translate the localization files, but it still requires manual translate texts by the developer. + +Now, We introduce a new way to translate the target language, which is to use the [Deepl](https://www.deepl.com/translator) translation service to translate the target language. + +You can use the `translate --online` command to in your module directory to translate the target language. + +For example, You have added all `en` localization texts to your module, and you want to translate them to `zh-Hans`, you can run the following command: + +``` +abp translate -r en -c zh-Hans --online --deepl-auth-key your_auth_key +``` + +* `-r` parameter is used to specify the source language. It is usually a localized file that you have created. +* `-c` parameter is used to specify the target language. It is usually a language that you want to translate. +* `--online` parameter is used to indicate that the translation is performed from the Deepl service. +* `--deepl-auth-key` parameter is the API key of your Deepl account. You can get it from [here](https://support.deepl.com/hc/en-us/articles/360020695820-Authentication-Key). + + +The output of the above command is as follows: + +``` +ABP CLI 8.0.0 +Abp translate online... +Target culture: zh-Hans +Reference culture: en +Create translation: Settings => 设置 +Create translation: SuccessfullySaved => 成功保存 +Create translation: Permission:SettingManagement => 设置管理 +Create translation: Permission:Emailing => 发送电子邮件 +Create translation: Permission:EmailingTest => 电子邮件测试 +Create translation: Permission:TimeZone => 时区 +Create translation: SendTestEmail => 发送测试电子邮件 +Create translation: SenderEmailAddress => 发件人电子邮件地址 +Create translation: TargetEmailAddress => 目标电子邮件地址 +Create translation: Subject => 主题 +Create translation: Body => 正文 +Create translation: TestEmailSubject => 测试电子邮件 {0} +Create translation: TestEmailBody => 在此测试电子邮件正文信息 +Create translation: SuccessfullySent => 成功发送 +Create translation: Send => 发送 +Create translation: Menu:Emailing => 发送电子邮件 +Create translation: Menu:TimeZone => 时区 +Create translation: DisplayName:Timezone => 时区 +Create translation: TimezoneHelpText => 此设置用于应用程序范围或基于租户的设置。 +Create translation: SmtpHost => 主机 +Create translation: SmtpPort => 端口 +Create translation: SmtpUserName => 用户名 +Create translation: SmtpPassword => 密码 +Create translation: SmtpDomain => 域名 +Create translation: SmtpEnableSsl => 启用 ssl +Create translation: SmtpUseDefaultCredentials => 使用默认凭据 +Create translation: DefaultFromAddress => 默认地址 +Create translation: DefaultFromDisplayName => 显示名称的默认值 +Create translation: Feature:SettingManagementGroup => 设置管理 +Create translation: Feature:SettingManagementEnable => 启用设置管理 +Create translation: Feature:SettingManagementEnableDescription => 在应用程序中启用设置管理系统。 +Create translation: Feature:AllowChangingEmailSettings => 允许更改电子邮件设置。 +Create translation: Feature:AllowChangingEmailSettingsDescription => 允许更改电子邮件设置。 +Write translation json to setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/zh-Hans.json. +``` + +The generated `zh-Hans.json` as follow: + +![zh-Hans.json](deepl.jpg) + +In this example, It only translates one `en.json` to `zh-Hans.json`, but if there are multiple `en.json` files in the module, it will translate all `en.json` files to `zh-Hans.json`. + +Of course, the translation is not always correct, you can update the translation in the generated `zh-Hans.json` files. + +Enjoy it! diff --git a/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/deepl.jpg b/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/deepl.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c54b9840f0df9a789e2058c1ba44f5b7d8448dee GIT binary patch literal 466794 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]Sx)$7a1cvinRZE#nl#|}%0UCcHc>Ee#Em_Ybw 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

bGI?k0;>0S>do&()f~AaxK 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

_*xSRiN(3feiuqpmgQ)j=f)eJw&X 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 WKbZ4#_Wv|z00K`}KbLh*2~7YxrIX+Q literal 0 HcmV?d00001 From 6bcfd844caa1174ebc12548f86b6e386925b01e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Thu, 4 Jan 2024 15:37:06 +0300 Subject: [PATCH 09/58] initial commit (for saving) --- .../lib/strategies/auth-code-flow-strategy.ts | 6 ++++ .../strategies/auth-password-flow-strategy.ts | 9 ++---- .../oauth/src/lib/utils/cookie-utils.ts | 29 +++++++++++++++++++ 3 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 npm/ng-packs/packages/oauth/src/lib/utils/cookie-utils.ts diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts index c9708d699e..c3443427d2 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts @@ -2,11 +2,17 @@ import { noop } from '@abp/ng.core'; import { Params } from '@angular/router'; import { from, of } from 'rxjs'; import { AuthFlowStrategy } from './auth-flow-strategy'; +import { deleteAllCookies } from '../utils/cookie-utils'; export class AuthCodeFlowStrategy extends AuthFlowStrategy { readonly isInternalAuth = false; + private rememberMeKey = 'remember_me' async init() { + console.log('code flow'); + const accessToken = this.oAuthService.getAccessToken(); + let parsedToken = JSON.parse(atob(accessToken.split(".")[1]));; + return super .init() .then(() => this.oAuthService.tryLogin().catch(noop)) diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts index 1958865e23..74ffc3bd30 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts @@ -7,11 +7,7 @@ import { AuthFlowStrategy } from './auth-flow-strategy'; import { pipeToLogin, removeRememberMe } from '../utils/auth-utils'; import { LoginParams } from '@abp/ng.core'; import { clearOAuthStorage } from '../utils/clear-o-auth-storage'; - -function getCookieValueByName(name: string) { - const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)')); - return match ? match[2] : ''; -} +import { getCookieValueByName } from '../utils/cookie-utils'; export class AuthPasswordFlowStrategy extends AuthFlowStrategy { readonly isInternalAuth = true; @@ -40,7 +36,8 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { } async init() { - if (!getCookieValueByName(this.cookieKey) && localStorage.getItem(this.storageKey)) { + if (!(getCookieValueByName(this.cookieKey) === 'true') && localStorage.getItem(this.storageKey)) { + removeRememberMe(this.localStorageService); this.oAuthService.logOut(); } diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/cookie-utils.ts b/npm/ng-packs/packages/oauth/src/lib/utils/cookie-utils.ts new file mode 100644 index 0000000000..e31d4944ff --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/utils/cookie-utils.ts @@ -0,0 +1,29 @@ +export function getCookieValueByName(name: string) { + const cookiesArray = document.cookie.split(';'); + + for (let i = 0; i < cookiesArray.length; i++) { + let cookie = cookiesArray[i].trim(); + + if (cookie.startsWith(name + '=')) { + return cookie.substring(name.length + 1); + } + } + return null; +} + +export function deleteAllCookies() { + var cookies = document.cookie.split("; "); + for (var c = 0; c < cookies.length; c++) { + var d = window.location.hostname.split("."); + while (d.length > 0) { + var cookieBase = encodeURIComponent(cookies[c].split(";")[0].split("=")[0]) + '=; expires=Thu, 01-Jan-1970 00:00:01 GMT; domain=' + d.join('.') + ' ;path='; + var p = location.pathname.split('/'); + document.cookie = cookieBase + '/'; + while (p.length > 0) { + document.cookie = cookieBase + p.join('/'); + p.pop(); + }; + d.shift(); + } + } +} \ No newline at end of file From c5eb3f34b58af1586ec2837435819918613a1412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Fri, 5 Jan 2024 17:19:23 +0300 Subject: [PATCH 10/58] add latest updates, will be checked again --- .../dev-app/src/environments/environment.ts | 2 +- .../lib/strategies/auth-code-flow-strategy.ts | 66 ++++++++++++++++--- .../src/lib/strategies/auth-flow-strategy.ts | 13 ++-- .../strategies/auth-password-flow-strategy.ts | 30 ++++++--- .../oauth/src/lib/utils/auth-utils.ts | 16 +++-- .../oauth/src/lib/utils/cookie-utils.ts | 29 -------- 6 files changed, 93 insertions(+), 63 deletions(-) delete mode 100644 npm/ng-packs/packages/oauth/src/lib/utils/cookie-utils.ts diff --git a/npm/ng-packs/apps/dev-app/src/environments/environment.ts b/npm/ng-packs/apps/dev-app/src/environments/environment.ts index 1e014dcaa7..45b31e8ef0 100644 --- a/npm/ng-packs/apps/dev-app/src/environments/environment.ts +++ b/npm/ng-packs/apps/dev-app/src/environments/environment.ts @@ -14,7 +14,7 @@ export const environment = { issuer: 'https://localhost:44305/', clientId: 'MyProjectName_App', scope: 'offline_access MyProjectName', - responseType: 'code', + // responseType: 'code', redirectUri: baseUrl, }, apis: { diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts index c3443427d2..9825fa953e 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts @@ -1,22 +1,71 @@ import { noop } from '@abp/ng.core'; import { Params } from '@angular/router'; -import { from, of } from 'rxjs'; +import { filter, from, of } from 'rxjs'; import { AuthFlowStrategy } from './auth-flow-strategy'; -import { deleteAllCookies } from '../utils/cookie-utils'; +import { getRememberMe, removeRememberMe, setRememberMe } from '../utils'; -export class AuthCodeFlowStrategy extends AuthFlowStrategy { +export class AuthCodeFlowStrategy extends AuthFlowStrategy{ readonly isInternalAuth = false; - private rememberMeKey = 'remember_me' + private remember_me = 'remember_me' async init() { - console.log('code flow'); - const accessToken = this.oAuthService.getAccessToken(); - let parsedToken = JSON.parse(atob(accessToken.split(".")[1]));; + this.checkRememberMeOption(); return super .init() .then(() => this.oAuthService.tryLogin().catch(noop)) - .then(() => this.oAuthService.setupAutomaticSilentRefresh({}, 'access_token')); + .then(() => this.oAuthService.setupAutomaticSilentRefresh()) + // .then(() => this.listenToTokenExpiration()); + } + + // private listenToTokenExpiration() { + // this.oAuthService.events + // .pipe( + // filter( + // event => { + // return event instanceof OAuthInfoEvent && + // event.type === 'token_expires' && + // event.info === 'access_token' + // } + // ), + // ) + // .subscribe(() => { + // if (this.oAuthService.getRefreshToken()) { + // console.log('refresh token'); + // this.refreshToken(); + // } else { + // this.oAuthService.logOut(); + // removeRememberMe(this.localStorageService); + // this.configState.refreshAppState().subscribe(); + // } + // }); + // } + + private checkRememberMeOption() { + const accessToken = this.oAuthService.getAccessToken(); + const expireDate = this.oAuthService.getAccessTokenExpiration(); + const currentDate = new Date().getTime(); + let rememberMe = getRememberMe(this.localStorageService); + + if (accessToken && rememberMe === null) { + let parsedToken = JSON.parse(atob(accessToken.split(".")[1])); + + if (parsedToken[this.remember_me]) { + setRememberMe(true, this.localStorageService); + } else { + setRememberMe(false, this.localStorageService) + } + + } + rememberMe = getRememberMe(this.localStorageService); + + if (accessToken && expireDate < currentDate && rememberMe === 'false') { + removeRememberMe(this.localStorageService); + this.oAuthService.logOut(); + }else{ + console.log('try login'); + this.oAuthService.tryLogin().catch(noop) + } } navigateToLogin(queryParams?: Params) { @@ -35,6 +84,7 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { } logout(queryParams?: Params) { + removeRememberMe(this.localStorageService); return from(this.oAuthService.revokeTokenAndLogout(this.getCultureParams(queryParams))); } diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts index e5189966bd..4184cf2c8d 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts @@ -70,23 +70,20 @@ export abstract class AuthFlowStrategy { const shouldClear = shouldStorageClear(this.oAuthConfig.clientId, oAuthStorage); if (shouldClear) clearOAuthStorage(oAuthStorage); } - this.oAuthService.configure(this.oAuthConfig); - this.oAuthService.events .pipe(filter(event => event.type === 'token_refresh_error')) .subscribe(() => this.navigateToLogin()); - this.navigateToPreviousUrl(); - return this.oAuthService .loadDiscoveryDocument() .then(() => { - if (this.oAuthService.hasValidAccessToken() || !this.oAuthService.getRefreshToken()) { - return Promise.resolve(); + const expireDate = this.oAuthService.getAccessTokenExpiration(); + const currentDate = new Date().getTime(); + if (expireDate > currentDate || this.oAuthService.getRefreshToken()) { + return this.refreshToken(); } - - return this.refreshToken(); + return Promise.resolve(); }) .catch(this.catchError); } diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts index 74ffc3bd30..8936ebd0a5 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts @@ -1,13 +1,12 @@ import { filter, switchMap, tap } from 'rxjs/operators'; import { OAuthInfoEvent } from 'angular-oauth2-oidc'; import { Params, Router } from '@angular/router'; -import { from, Observable, pipe } from 'rxjs'; +import { from, Observable } from 'rxjs'; import { HttpHeaders } from '@angular/common/http'; import { AuthFlowStrategy } from './auth-flow-strategy'; -import { pipeToLogin, removeRememberMe } from '../utils/auth-utils'; -import { LoginParams } from '@abp/ng.core'; +import { getRememberMe, pipeToLogin, removeRememberMe } from '../utils/auth-utils'; +import { AbpLocalStorageService, LoginParams } from '@abp/ng.core'; import { clearOAuthStorage } from '../utils/clear-o-auth-storage'; -import { getCookieValueByName } from '../utils/cookie-utils'; export class AuthPasswordFlowStrategy extends AuthFlowStrategy { readonly isInternalAuth = true; @@ -18,10 +17,11 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { this.oAuthService.events .pipe( filter( - event => - event instanceof OAuthInfoEvent && + event => { + return event instanceof OAuthInfoEvent && event.type === 'token_expires' && - event.info === 'access_token', + event.info === 'access_token' + } ), ) .subscribe(() => { @@ -36,12 +36,21 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { } async init() { - if (!(getCookieValueByName(this.cookieKey) === 'true') && localStorage.getItem(this.storageKey)) { + this.checkRememberMeOption(this.localStorageService); + + return super.init().then(() => this.listenToTokenExpiration()); + } + + private checkRememberMeOption(localStorageService: AbpLocalStorageService) { + const accessToken = this.oAuthService.getAccessToken(); + const expireDate = this.oAuthService.getAccessTokenExpiration(); + const currentDate = new Date().getTime(); + const rememberMe = getRememberMe(localStorageService) === 'true'; + + if (accessToken && expireDate < currentDate && !rememberMe) { removeRememberMe(this.localStorageService); this.oAuthService.logOut(); } - - return super.init().then(() => this.listenToTokenExpiration()); } navigateToLogin(queryParams?: Params) { @@ -77,6 +86,7 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { } protected refreshToken() { + console.log('token refreshed'); return this.oAuthService.refreshToken().catch(() => { clearOAuthStorage(); removeRememberMe(this.localStorageService); diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts index bd50e97ee7..9bc14d7e31 100644 --- a/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts +++ b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts @@ -11,6 +11,7 @@ import { const cookieKey = 'rememberMe'; const storageKey = 'passwordFlow'; +const remember_me = 'remember_me'; export const pipeToLogin: PipeToLoginFn = function ( params: Pick, @@ -32,14 +33,15 @@ export function setRememberMe( remember: boolean | undefined, localStorageService: AbpLocalStorageService, ) { - removeRememberMe(localStorageService); - localStorageService.setItem(storageKey, 'true'); - document.cookie = `${cookieKey}=true; path=/${ - remember ? ' ;expires=Fri, 31 Dec 9999 23:59:59 GMT' : '' - }`; + console.log('set Remember Me'); + localStorageService.setItem(remember_me, JSON.stringify(remember)); } export function removeRememberMe(localStorageService: AbpLocalStorageService) { - localStorageService.removeItem(storageKey); - document.cookie = cookieKey + '= ; path=/; expires = Thu, 01 Jan 1970 00:00:00 GMT'; + console.log('remove remember Me'); + localStorageService.removeItem(remember_me); +} + +export function getRememberMe(localStorageService: AbpLocalStorageService){ + return localStorageService.getItem(remember_me); } diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/cookie-utils.ts b/npm/ng-packs/packages/oauth/src/lib/utils/cookie-utils.ts deleted file mode 100644 index e31d4944ff..0000000000 --- a/npm/ng-packs/packages/oauth/src/lib/utils/cookie-utils.ts +++ /dev/null @@ -1,29 +0,0 @@ -export function getCookieValueByName(name: string) { - const cookiesArray = document.cookie.split(';'); - - for (let i = 0; i < cookiesArray.length; i++) { - let cookie = cookiesArray[i].trim(); - - if (cookie.startsWith(name + '=')) { - return cookie.substring(name.length + 1); - } - } - return null; -} - -export function deleteAllCookies() { - var cookies = document.cookie.split("; "); - for (var c = 0; c < cookies.length; c++) { - var d = window.location.hostname.split("."); - while (d.length > 0) { - var cookieBase = encodeURIComponent(cookies[c].split(";")[0].split("=")[0]) + '=; expires=Thu, 01-Jan-1970 00:00:01 GMT; domain=' + d.join('.') + ' ;path='; - var p = location.pathname.split('/'); - document.cookie = cookieBase + '/'; - while (p.length > 0) { - document.cookie = cookieBase + p.join('/'); - p.pop(); - }; - d.shift(); - } - } -} \ No newline at end of file From 669721384b6fceca5dfd9225e106beffdd6148aa Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 9 Jan 2024 14:13:29 +0800 Subject: [PATCH 11/58] Update Multi-Tenancy.md --- docs/en/Multi-Tenancy.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/en/Multi-Tenancy.md b/docs/en/Multi-Tenancy.md index 661d99da16..392bea6809 100644 --- a/docs/en/Multi-Tenancy.md +++ b/docs/en/Multi-Tenancy.md @@ -394,6 +394,8 @@ app.UseMultiTenancy(); `ITenantStore` is used to get the tenant configuration from a data source. +> Tenant names are not case-sensitive. `ITenantStore` will use the `NormalizedName` parameter to get tenants, You need to use `ITenantNormalizer to normalize tenant names. + #### Tenant Management Module The [tenant management module](Modules/Tenant-Management) is **included in the startup templates** and implements the `ITenantStore` interface to get the tenants and their configuration from a database. It also provides the necessary functionality and UI to manage the tenants and their connection strings. @@ -408,11 +410,13 @@ The [tenant management module](Modules/Tenant-Management) is **included in the s "Tenants": [ { "Id": "446a5211-3d72-4339-9adc-845151f8ada0", - "Name": "tenant1" + "Name": "tenant1", + "NormalizedName": "TENANT1" }, { "Id": "25388015-ef1c-4355-9c18-f6b6ddbaf89d", "Name": "tenant2", + "NormalizedName": "TENANT2", "ConnectionStrings": { "Default": "...tenant2's db connection string here..." } From 1d659c5cbecf6a8bd0ea9ff910c64a189dd82af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Tue, 16 Jan 2024 11:01:30 +0300 Subject: [PATCH 12/58] existing code tested and reviewed by me --- .../dev-app/src/environments/environment.ts | 2 +- .../lib/strategies/auth-code-flow-strategy.ts | 39 +++---------------- .../strategies/auth-password-flow-strategy.ts | 6 +-- .../oauth/src/lib/utils/auth-utils.ts | 8 +--- 4 files changed, 12 insertions(+), 43 deletions(-) diff --git a/npm/ng-packs/apps/dev-app/src/environments/environment.ts b/npm/ng-packs/apps/dev-app/src/environments/environment.ts index 45b31e8ef0..1e014dcaa7 100644 --- a/npm/ng-packs/apps/dev-app/src/environments/environment.ts +++ b/npm/ng-packs/apps/dev-app/src/environments/environment.ts @@ -14,7 +14,7 @@ export const environment = { issuer: 'https://localhost:44305/', clientId: 'MyProjectName_App', scope: 'offline_access MyProjectName', - // responseType: 'code', + responseType: 'code', redirectUri: baseUrl, }, apis: { diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts index 9825fa953e..77ceb94dbf 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts @@ -1,10 +1,10 @@ import { noop } from '@abp/ng.core'; import { Params } from '@angular/router'; -import { filter, from, of } from 'rxjs'; +import { from, of } from 'rxjs'; import { AuthFlowStrategy } from './auth-flow-strategy'; import { getRememberMe, removeRememberMe, setRememberMe } from '../utils'; -export class AuthCodeFlowStrategy extends AuthFlowStrategy{ +export class AuthCodeFlowStrategy extends AuthFlowStrategy { readonly isInternalAuth = false; private remember_me = 'remember_me' @@ -15,32 +15,8 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy{ .init() .then(() => this.oAuthService.tryLogin().catch(noop)) .then(() => this.oAuthService.setupAutomaticSilentRefresh()) - // .then(() => this.listenToTokenExpiration()); } - // private listenToTokenExpiration() { - // this.oAuthService.events - // .pipe( - // filter( - // event => { - // return event instanceof OAuthInfoEvent && - // event.type === 'token_expires' && - // event.info === 'access_token' - // } - // ), - // ) - // .subscribe(() => { - // if (this.oAuthService.getRefreshToken()) { - // console.log('refresh token'); - // this.refreshToken(); - // } else { - // this.oAuthService.logOut(); - // removeRememberMe(this.localStorageService); - // this.configState.refreshAppState().subscribe(); - // } - // }); - // } - private checkRememberMeOption() { const accessToken = this.oAuthService.getAccessToken(); const expireDate = this.oAuthService.getAccessTokenExpiration(); @@ -49,22 +25,19 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy{ if (accessToken && rememberMe === null) { let parsedToken = JSON.parse(atob(accessToken.split(".")[1])); + let rememberMeValue = parsedToken[this.remember_me]; - if (parsedToken[this.remember_me]) { + if (rememberMeValue && (rememberMeValue === 'True' || rememberMeValue === 'true')) { setRememberMe(true, this.localStorageService); } else { setRememberMe(false, this.localStorageService) } - } - rememberMe = getRememberMe(this.localStorageService); - if (accessToken && expireDate < currentDate && rememberMe === 'false') { + rememberMe = getRememberMe(this.localStorageService); + if (accessToken && expireDate < currentDate && rememberMe !== 'true') { removeRememberMe(this.localStorageService); this.oAuthService.logOut(); - }else{ - console.log('try login'); - this.oAuthService.tryLogin().catch(noop) } } diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts index 8936ebd0a5..f8e585d170 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts @@ -45,9 +45,9 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { const accessToken = this.oAuthService.getAccessToken(); const expireDate = this.oAuthService.getAccessTokenExpiration(); const currentDate = new Date().getTime(); - const rememberMe = getRememberMe(localStorageService) === 'true'; + const rememberMe = getRememberMe(localStorageService); - if (accessToken && expireDate < currentDate && !rememberMe) { + if (accessToken && expireDate < currentDate && rememberMe !== 'true') { removeRememberMe(this.localStorageService); this.oAuthService.logOut(); } @@ -73,6 +73,7 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { ), ).pipe(pipeToLogin(params, this.injector)); } + logout() { const router = this.injector.get(Router); const noRedirectToLogoutUrl = true; @@ -86,7 +87,6 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { } protected refreshToken() { - console.log('token refreshed'); return this.oAuthService.refreshToken().catch(() => { clearOAuthStorage(); removeRememberMe(this.localStorageService); diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts index 9bc14d7e31..0d8fb28fe3 100644 --- a/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts +++ b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts @@ -9,8 +9,6 @@ import { AbpLocalStorageService, } from '@abp/ng.core'; -const cookieKey = 'rememberMe'; -const storageKey = 'passwordFlow'; const remember_me = 'remember_me'; export const pipeToLogin: PipeToLoginFn = function ( @@ -30,18 +28,16 @@ export const pipeToLogin: PipeToLoginFn = function ( }; export function setRememberMe( - remember: boolean | undefined, + remember: boolean, localStorageService: AbpLocalStorageService, ) { - console.log('set Remember Me'); localStorageService.setItem(remember_me, JSON.stringify(remember)); } export function removeRememberMe(localStorageService: AbpLocalStorageService) { - console.log('remove remember Me'); localStorageService.removeItem(remember_me); } export function getRememberMe(localStorageService: AbpLocalStorageService){ return localStorageService.getItem(remember_me); -} +} \ No newline at end of file From ed4a0e4359cb5618d0351fe97a9dbc6dab08b1b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Tue, 16 Jan 2024 11:16:47 +0300 Subject: [PATCH 13/58] remove changes in auth-flow-strategy.ts --- .../oauth/src/lib/strategies/auth-flow-strategy.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts index 4184cf2c8d..594e6e5c89 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts @@ -78,12 +78,11 @@ export abstract class AuthFlowStrategy { return this.oAuthService .loadDiscoveryDocument() .then(() => { - const expireDate = this.oAuthService.getAccessTokenExpiration(); - const currentDate = new Date().getTime(); - if (expireDate > currentDate || this.oAuthService.getRefreshToken()) { - return this.refreshToken(); + if (this.oAuthService.hasValidAccessToken() || !this.oAuthService.getRefreshToken()) { + return Promise.resolve(); } - return Promise.resolve(); + + return this.refreshToken(); }) .catch(this.catchError); } From 5857c5551bb2412458808ee48e18f48176ad9438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Tue, 16 Jan 2024 21:52:02 +0300 Subject: [PATCH 14/58] fix reviews --- .../lib/strategies/auth-code-flow-strategy.ts | 28 ++++++------- .../src/lib/strategies/auth-flow-strategy.ts | 10 +++-- .../strategies/auth-password-flow-strategy.ts | 29 ++++++------- .../oauth/src/lib/utils/auth-utils.ts | 41 +++++++++++-------- 4 files changed, 57 insertions(+), 51 deletions(-) diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts index 77ceb94dbf..d160a14d33 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts @@ -2,11 +2,12 @@ import { noop } from '@abp/ng.core'; import { Params } from '@angular/router'; import { from, of } from 'rxjs'; import { AuthFlowStrategy } from './auth-flow-strategy'; -import { getRememberMe, removeRememberMe, setRememberMe } from '../utils'; +import { RememberMeService, isTokenExpired } from '../utils'; export class AuthCodeFlowStrategy extends AuthFlowStrategy { readonly isInternalAuth = false; - private remember_me = 'remember_me' + private rememberMe = 'remember_me' + rememberMeService = new RememberMeService(this.injector); async init() { this.checkRememberMeOption(); @@ -19,24 +20,23 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { private checkRememberMeOption() { const accessToken = this.oAuthService.getAccessToken(); - const expireDate = this.oAuthService.getAccessTokenExpiration(); - const currentDate = new Date().getTime(); - let rememberMe = getRememberMe(this.localStorageService); + const isTokenExpire = isTokenExpired(this.oAuthService); + let rememberMe = Boolean(JSON.parse(this.rememberMeService.getRememberMe())); - if (accessToken && rememberMe === null) { + if (accessToken && !rememberMe) { let parsedToken = JSON.parse(atob(accessToken.split(".")[1])); - let rememberMeValue = parsedToken[this.remember_me]; + const rememberMeValue = Boolean(parsedToken[this.rememberMe]); - if (rememberMeValue && (rememberMeValue === 'True' || rememberMeValue === 'true')) { - setRememberMe(true, this.localStorageService); + if (rememberMeValue) { + this.rememberMeService.setRememberMe(true); } else { - setRememberMe(false, this.localStorageService) + this.rememberMeService.setRememberMe(false) } } - rememberMe = getRememberMe(this.localStorageService); - if (accessToken && expireDate < currentDate && rememberMe !== 'true') { - removeRememberMe(this.localStorageService); + rememberMe = Boolean(JSON.parse(this.rememberMeService.getRememberMe())); + if (accessToken && isTokenExpire && !rememberMe) { + this.rememberMeService.removeRememberMe(); this.oAuthService.logOut(); } } @@ -57,7 +57,7 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { } logout(queryParams?: Params) { - removeRememberMe(this.localStorageService); + this.rememberMeService.removeRememberMe(); return from(this.oAuthService.revokeTokenAndLogout(this.getCultureParams(queryParams))); } diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts index 594e6e5c89..8bafb4a70a 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts @@ -24,6 +24,7 @@ import { import { clearOAuthStorage } from '../utils/clear-o-auth-storage'; import { oAuthStorage } from '../utils/oauth-storage'; import { OAuthErrorFilterService } from '../services'; +import { isTokenExpired } from '../utils'; export abstract class AuthFlowStrategy { abstract readonly isInternalAuth: boolean; @@ -78,11 +79,12 @@ export abstract class AuthFlowStrategy { return this.oAuthService .loadDiscoveryDocument() .then(() => { - if (this.oAuthService.hasValidAccessToken() || !this.oAuthService.getRefreshToken()) { - return Promise.resolve(); + const isTokenExpire = isTokenExpired(this.oAuthService); + if (!isTokenExpire || this.oAuthService.getRefreshToken()) { + return this.refreshToken(); } - - return this.refreshToken(); + + return Promise.resolve(); }) .catch(this.catchError); } diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts index f8e585d170..7a7ee98c65 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts @@ -4,24 +4,21 @@ import { Params, Router } from '@angular/router'; import { from, Observable } from 'rxjs'; import { HttpHeaders } from '@angular/common/http'; import { AuthFlowStrategy } from './auth-flow-strategy'; -import { getRememberMe, pipeToLogin, removeRememberMe } from '../utils/auth-utils'; +import { RememberMeService, isTokenExpired, pipeToLogin } from '../utils/auth-utils'; import { AbpLocalStorageService, LoginParams } from '@abp/ng.core'; import { clearOAuthStorage } from '../utils/clear-o-auth-storage'; export class AuthPasswordFlowStrategy extends AuthFlowStrategy { readonly isInternalAuth = true; - private cookieKey = 'rememberMe'; - private storageKey = 'passwordFlow'; + rememberMeService = new RememberMeService(this.injector); private listenToTokenExpiration() { this.oAuthService.events .pipe( filter( - event => { - return event instanceof OAuthInfoEvent && + event => event instanceof OAuthInfoEvent && event.type === 'token_expires' && event.info === 'access_token' - } ), ) .subscribe(() => { @@ -29,26 +26,24 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { this.refreshToken(); } else { this.oAuthService.logOut(); - removeRememberMe(this.localStorageService); + this.rememberMeService.removeRememberMe(); this.configState.refreshAppState().subscribe(); } }); } async init() { - this.checkRememberMeOption(this.localStorageService); + this.checkRememberMeOption(this.localStorageService); return super.init().then(() => this.listenToTokenExpiration()); } private checkRememberMeOption(localStorageService: AbpLocalStorageService) { const accessToken = this.oAuthService.getAccessToken(); - const expireDate = this.oAuthService.getAccessTokenExpiration(); - const currentDate = new Date().getTime(); - const rememberMe = getRememberMe(localStorageService); - - if (accessToken && expireDate < currentDate && rememberMe !== 'true') { - removeRememberMe(this.localStorageService); + const isTokenExpire = isTokenExpired(this.oAuthService); + const rememberMe = Boolean(JSON.parse(this.rememberMeService.getRememberMe())) + if (accessToken && isTokenExpire && !rememberMe) { + this.rememberMeService.removeRememberMe(); this.oAuthService.logOut(); } } @@ -73,7 +68,7 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { ), ).pipe(pipeToLogin(params, this.injector)); } - + logout() { const router = this.injector.get(Router); const noRedirectToLogoutUrl = true; @@ -81,7 +76,7 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { switchMap(() => this.configState.refreshAppState()), tap(() => { router.navigateByUrl('/'); - removeRememberMe(this.localStorageService); + this.rememberMeService.removeRememberMe(); }), ); } @@ -89,7 +84,7 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { protected refreshToken() { return this.oAuthService.refreshToken().catch(() => { clearOAuthStorage(); - removeRememberMe(this.localStorageService); + this.rememberMeService.removeRememberMe(); }); } } diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts index 0d8fb28fe3..7c163a40c7 100644 --- a/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts +++ b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts @@ -8,8 +8,26 @@ import { PipeToLoginFn, AbpLocalStorageService, } from '@abp/ng.core'; +import { OAuthService } from 'angular-oauth2-oidc'; -const remember_me = 'remember_me'; +const rememberMe = 'remember_me'; + +export class RememberMeService { + constructor(private injector: Injector) { } + localStorageService = this.injector.get(AbpLocalStorageService); + + setRememberMe(remember: boolean) { + this.localStorageService.setItem(rememberMe, JSON.stringify(remember)); + } + + removeRememberMe() { + this.localStorageService.removeItem(rememberMe); + } + + getRememberMe() { + return this.localStorageService.getItem(rememberMe); + } +} export const pipeToLogin: PipeToLoginFn = function ( params: Pick, @@ -17,27 +35,18 @@ export const pipeToLogin: PipeToLoginFn = function ( ) { const configState = injector.get(ConfigStateService); const router = injector.get(Router); - const localStorage = injector.get(AbpLocalStorageService); + const rememberMeService = new RememberMeService(injector); return pipe( switchMap(() => configState.refreshAppState()), tap(() => { - setRememberMe(params.rememberMe, localStorage); + rememberMeService.setRememberMe(params.rememberMe); if (params.redirectUrl) router.navigate([params.redirectUrl]); }), ); }; -export function setRememberMe( - remember: boolean, - localStorageService: AbpLocalStorageService, -) { - localStorageService.setItem(remember_me, JSON.stringify(remember)); -} - -export function removeRememberMe(localStorageService: AbpLocalStorageService) { - localStorageService.removeItem(remember_me); +export function isTokenExpired(oAuthService: OAuthService): boolean { + const expireDate = oAuthService.getAccessTokenExpiration(); + const currentDate = new Date().getTime(); + return expireDate < currentDate; } - -export function getRememberMe(localStorageService: AbpLocalStorageService){ - return localStorageService.getItem(remember_me); -} \ No newline at end of file From 4049971cfff42809444e291da05c20328841eed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Wed, 17 Jan 2024 15:54:09 +0300 Subject: [PATCH 15/58] fix reviews --- .../src/lib/services/remember-me.service.ts | 24 ++++++++++++++++++ .../lib/strategies/auth-code-flow-strategy.ts | 19 +++++++------- .../src/lib/strategies/auth-flow-strategy.ts | 3 +++ .../strategies/auth-password-flow-strategy.ts | 13 +++++----- .../oauth/src/lib/utils/auth-utils.ts | 25 +++---------------- 5 files changed, 45 insertions(+), 39 deletions(-) create mode 100644 npm/ng-packs/packages/oauth/src/lib/services/remember-me.service.ts diff --git a/npm/ng-packs/packages/oauth/src/lib/services/remember-me.service.ts b/npm/ng-packs/packages/oauth/src/lib/services/remember-me.service.ts new file mode 100644 index 0000000000..cc1c78af8a --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/services/remember-me.service.ts @@ -0,0 +1,24 @@ +import { AbpLocalStorageService } from "@abp/ng.core"; +import { Injectable, Injector } from "@angular/core"; + +const rememberMe = 'remember_me'; + +@Injectable({ + providedIn: 'root' +}) +export class RememberMeService { + constructor(private injector: Injector) { } + localStorageService = this.injector.get(AbpLocalStorageService); + + set(remember: boolean) { + this.localStorageService.setItem(rememberMe, JSON.stringify(remember)); + } + + remove() { + this.localStorageService.removeItem(rememberMe); + } + + get() { + return Boolean(JSON.parse(this.localStorageService.getItem(rememberMe))); + } +} \ No newline at end of file diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts index d160a14d33..a616d60770 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts @@ -2,12 +2,11 @@ import { noop } from '@abp/ng.core'; import { Params } from '@angular/router'; import { from, of } from 'rxjs'; import { AuthFlowStrategy } from './auth-flow-strategy'; -import { RememberMeService, isTokenExpired } from '../utils'; +import { isTokenExpired } from '../utils'; export class AuthCodeFlowStrategy extends AuthFlowStrategy { readonly isInternalAuth = false; - private rememberMe = 'remember_me' - rememberMeService = new RememberMeService(this.injector); + readonly #rememberMe = 'remember_me' async init() { this.checkRememberMeOption(); @@ -21,22 +20,22 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { private checkRememberMeOption() { const accessToken = this.oAuthService.getAccessToken(); const isTokenExpire = isTokenExpired(this.oAuthService); - let rememberMe = Boolean(JSON.parse(this.rememberMeService.getRememberMe())); + let rememberMe = this.rememberMeService.get(); if (accessToken && !rememberMe) { let parsedToken = JSON.parse(atob(accessToken.split(".")[1])); - const rememberMeValue = Boolean(parsedToken[this.rememberMe]); + const rememberMeValue = Boolean(parsedToken[this.#rememberMe]); if (rememberMeValue) { - this.rememberMeService.setRememberMe(true); + this.rememberMeService.set(true); } else { - this.rememberMeService.setRememberMe(false) + this.rememberMeService.set(false) } } - rememberMe = Boolean(JSON.parse(this.rememberMeService.getRememberMe())); + rememberMe = this.rememberMeService.get(); if (accessToken && isTokenExpire && !rememberMe) { - this.rememberMeService.removeRememberMe(); + this.rememberMeService.remove(); this.oAuthService.logOut(); } } @@ -57,7 +56,7 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { } logout(queryParams?: Params) { - this.rememberMeService.removeRememberMe(); + this.rememberMeService.remove(); return from(this.oAuthService.revokeTokenAndLogout(this.getCultureParams(queryParams))); } diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts index 8bafb4a70a..80b63ec77c 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts @@ -25,6 +25,7 @@ import { clearOAuthStorage } from '../utils/clear-o-auth-storage'; import { oAuthStorage } from '../utils/oauth-storage'; import { OAuthErrorFilterService } from '../services'; import { isTokenExpired } from '../utils'; +import { RememberMeService } from '../services/remember-me.service'; export abstract class AuthFlowStrategy { abstract readonly isInternalAuth: boolean; @@ -36,6 +37,7 @@ export abstract class AuthFlowStrategy { protected oAuthConfig!: AuthConfig; protected sessionState: SessionStateService; protected localStorageService: AbpLocalStorageService; + protected rememberMeService: RememberMeService; protected tenantKey: string; protected router: Router; @@ -62,6 +64,7 @@ export abstract class AuthFlowStrategy { this.tenantKey = injector.get(TENANT_KEY); this.router = injector.get(Router); this.oAuthErrorFilterService = injector.get(OAuthErrorFilterService); + this.rememberMeService = injector.get(RememberMeService); this.listenToOauthErrors(); } diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts index 7a7ee98c65..65198536a8 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts @@ -4,13 +4,12 @@ import { Params, Router } from '@angular/router'; import { from, Observable } from 'rxjs'; import { HttpHeaders } from '@angular/common/http'; import { AuthFlowStrategy } from './auth-flow-strategy'; -import { RememberMeService, isTokenExpired, pipeToLogin } from '../utils/auth-utils'; +import { isTokenExpired, pipeToLogin } from '../utils/auth-utils'; import { AbpLocalStorageService, LoginParams } from '@abp/ng.core'; import { clearOAuthStorage } from '../utils/clear-o-auth-storage'; export class AuthPasswordFlowStrategy extends AuthFlowStrategy { readonly isInternalAuth = true; - rememberMeService = new RememberMeService(this.injector); private listenToTokenExpiration() { this.oAuthService.events @@ -26,7 +25,7 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { this.refreshToken(); } else { this.oAuthService.logOut(); - this.rememberMeService.removeRememberMe(); + this.rememberMeService.remove(); this.configState.refreshAppState().subscribe(); } }); @@ -41,9 +40,9 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { private checkRememberMeOption(localStorageService: AbpLocalStorageService) { const accessToken = this.oAuthService.getAccessToken(); const isTokenExpire = isTokenExpired(this.oAuthService); - const rememberMe = Boolean(JSON.parse(this.rememberMeService.getRememberMe())) + const rememberMe = this.rememberMeService.get(); if (accessToken && isTokenExpire && !rememberMe) { - this.rememberMeService.removeRememberMe(); + this.rememberMeService.remove(); this.oAuthService.logOut(); } } @@ -76,7 +75,7 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { switchMap(() => this.configState.refreshAppState()), tap(() => { router.navigateByUrl('/'); - this.rememberMeService.removeRememberMe(); + this.rememberMeService.remove(); }), ); } @@ -84,7 +83,7 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { protected refreshToken() { return this.oAuthService.refreshToken().catch(() => { clearOAuthStorage(); - this.rememberMeService.removeRememberMe(); + this.rememberMeService.remove(); }); } } diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts index 7c163a40c7..64f867df7e 100644 --- a/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts +++ b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts @@ -6,28 +6,9 @@ import { ConfigStateService, LoginParams, PipeToLoginFn, - AbpLocalStorageService, } from '@abp/ng.core'; import { OAuthService } from 'angular-oauth2-oidc'; - -const rememberMe = 'remember_me'; - -export class RememberMeService { - constructor(private injector: Injector) { } - localStorageService = this.injector.get(AbpLocalStorageService); - - setRememberMe(remember: boolean) { - this.localStorageService.setItem(rememberMe, JSON.stringify(remember)); - } - - removeRememberMe() { - this.localStorageService.removeItem(rememberMe); - } - - getRememberMe() { - return this.localStorageService.getItem(rememberMe); - } -} +import { RememberMeService } from '../services/remember-me.service'; export const pipeToLogin: PipeToLoginFn = function ( params: Pick, @@ -35,11 +16,11 @@ export const pipeToLogin: PipeToLoginFn = function ( ) { const configState = injector.get(ConfigStateService); const router = injector.get(Router); - const rememberMeService = new RememberMeService(injector); + const rememberMeService = injector.get(RememberMeService); return pipe( switchMap(() => configState.refreshAppState()), tap(() => { - rememberMeService.setRememberMe(params.rememberMe); + rememberMeService.set(params.rememberMe); if (params.redirectUrl) router.navigate([params.redirectUrl]); }), ); From 95a4ccc9c7eb46d6a73f5f7795566ee2dfb3863d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Wed, 17 Jan 2024 17:13:28 +0300 Subject: [PATCH 16/58] fix reviews --- .../src/lib/services/remember-me.service.ts | 19 +++++++++++-------- .../lib/strategies/auth-code-flow-strategy.ts | 6 ++---- .../src/lib/strategies/auth-flow-strategy.ts | 4 ++-- .../strategies/auth-password-flow-strategy.ts | 8 ++++---- .../oauth/src/lib/utils/auth-utils.ts | 4 +--- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/npm/ng-packs/packages/oauth/src/lib/services/remember-me.service.ts b/npm/ng-packs/packages/oauth/src/lib/services/remember-me.service.ts index cc1c78af8a..7c099c5166 100644 --- a/npm/ng-packs/packages/oauth/src/lib/services/remember-me.service.ts +++ b/npm/ng-packs/packages/oauth/src/lib/services/remember-me.service.ts @@ -1,24 +1,27 @@ import { AbpLocalStorageService } from "@abp/ng.core"; -import { Injectable, Injector } from "@angular/core"; - -const rememberMe = 'remember_me'; +import { Injectable, inject } from "@angular/core"; @Injectable({ providedIn: 'root' }) export class RememberMeService { - constructor(private injector: Injector) { } - localStorageService = this.injector.get(AbpLocalStorageService); + readonly #rememberMe = 'remember_me' + protected readonly localStorageService = inject(AbpLocalStorageService); set(remember: boolean) { - this.localStorageService.setItem(rememberMe, JSON.stringify(remember)); + this.localStorageService.setItem(this.#rememberMe, JSON.stringify(remember)); } remove() { - this.localStorageService.removeItem(rememberMe); + this.localStorageService.removeItem(this.#rememberMe); } get() { - return Boolean(JSON.parse(this.localStorageService.getItem(rememberMe))); + return Boolean(JSON.parse(this.localStorageService.getItem(this.#rememberMe))); + } + + getFromToken(accessToken: string) { + let parsedToken = JSON.parse(atob(accessToken.split(".")[1])); + return Boolean(parsedToken[this.#rememberMe]); } } \ No newline at end of file diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts index a616d60770..5a1b2c3d05 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts @@ -6,7 +6,6 @@ import { isTokenExpired } from '../utils'; export class AuthCodeFlowStrategy extends AuthFlowStrategy { readonly isInternalAuth = false; - readonly #rememberMe = 'remember_me' async init() { this.checkRememberMeOption(); @@ -19,12 +18,11 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { private checkRememberMeOption() { const accessToken = this.oAuthService.getAccessToken(); - const isTokenExpire = isTokenExpired(this.oAuthService); + const isTokenExpire = isTokenExpired(this.oAuthService.getAccessTokenExpiration()); let rememberMe = this.rememberMeService.get(); if (accessToken && !rememberMe) { - let parsedToken = JSON.parse(atob(accessToken.split(".")[1])); - const rememberMeValue = Boolean(parsedToken[this.#rememberMe]); + const rememberMeValue = this.rememberMeService.getFromToken(accessToken); if (rememberMeValue) { this.rememberMeService.set(true); diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts index 80b63ec77c..8a75a23b8b 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts @@ -82,11 +82,11 @@ export abstract class AuthFlowStrategy { return this.oAuthService .loadDiscoveryDocument() .then(() => { - const isTokenExpire = isTokenExpired(this.oAuthService); + const isTokenExpire = isTokenExpired(this.oAuthService.getAccessTokenExpiration()); if (!isTokenExpire || this.oAuthService.getRefreshToken()) { return this.refreshToken(); } - + return Promise.resolve(); }) .catch(this.catchError); diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts index 65198536a8..eddf38a03e 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts @@ -5,7 +5,7 @@ import { from, Observable } from 'rxjs'; import { HttpHeaders } from '@angular/common/http'; import { AuthFlowStrategy } from './auth-flow-strategy'; import { isTokenExpired, pipeToLogin } from '../utils/auth-utils'; -import { AbpLocalStorageService, LoginParams } from '@abp/ng.core'; +import { LoginParams } from '@abp/ng.core'; import { clearOAuthStorage } from '../utils/clear-o-auth-storage'; export class AuthPasswordFlowStrategy extends AuthFlowStrategy { @@ -32,14 +32,14 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { } async init() { - this.checkRememberMeOption(this.localStorageService); + this.checkRememberMeOption(); return super.init().then(() => this.listenToTokenExpiration()); } - private checkRememberMeOption(localStorageService: AbpLocalStorageService) { + private checkRememberMeOption() { const accessToken = this.oAuthService.getAccessToken(); - const isTokenExpire = isTokenExpired(this.oAuthService); + const isTokenExpire = isTokenExpired(this.oAuthService.getAccessTokenExpiration()); const rememberMe = this.rememberMeService.get(); if (accessToken && isTokenExpire && !rememberMe) { this.rememberMeService.remove(); diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts index 64f867df7e..8742136b1f 100644 --- a/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts +++ b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts @@ -7,7 +7,6 @@ import { LoginParams, PipeToLoginFn, } from '@abp/ng.core'; -import { OAuthService } from 'angular-oauth2-oidc'; import { RememberMeService } from '../services/remember-me.service'; export const pipeToLogin: PipeToLoginFn = function ( @@ -26,8 +25,7 @@ export const pipeToLogin: PipeToLoginFn = function ( ); }; -export function isTokenExpired(oAuthService: OAuthService): boolean { - const expireDate = oAuthService.getAccessTokenExpiration(); +export function isTokenExpired(expireDate: number): boolean { const currentDate = new Date().getTime(); return expireDate < currentDate; } From 3214c802fb087fee11b16acadee61ad5b550730d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Fri, 19 Jan 2024 11:16:52 +0300 Subject: [PATCH 17/58] remove remember_me from localstorage before routing and use double exclamation --- .../oauth/src/lib/strategies/auth-code-flow-strategy.ts | 4 ++-- .../oauth/src/lib/strategies/auth-password-flow-strategy.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts index 5a1b2c3d05..ced281253d 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts @@ -25,9 +25,9 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { const rememberMeValue = this.rememberMeService.getFromToken(accessToken); if (rememberMeValue) { - this.rememberMeService.set(true); + this.rememberMeService.set(!!rememberMeValue); } else { - this.rememberMeService.set(false) + this.rememberMeService.set(!!rememberMeValue) } } diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts index eddf38a03e..9c38c64e27 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts @@ -74,8 +74,8 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { return from(this.oAuthService.revokeTokenAndLogout(noRedirectToLogoutUrl)).pipe( switchMap(() => this.configState.refreshAppState()), tap(() => { - router.navigateByUrl('/'); this.rememberMeService.remove(); + router.navigateByUrl('/'); }), ); } From 254ff8c52e3291a65ab90747448f71a4466856d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Fri, 19 Jan 2024 11:52:06 +0300 Subject: [PATCH 18/58] remove unnecesarry if block --- .../oauth/src/lib/strategies/auth-code-flow-strategy.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts index ced281253d..f648be47c6 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts @@ -24,11 +24,7 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { if (accessToken && !rememberMe) { const rememberMeValue = this.rememberMeService.getFromToken(accessToken); - if (rememberMeValue) { - this.rememberMeService.set(!!rememberMeValue); - } else { - this.rememberMeService.set(!!rememberMeValue) - } + this.rememberMeService.set(!!rememberMeValue); } rememberMe = this.rememberMeService.get(); From 037c013427cf0b4518f8f012e0dd3909bd9024cf Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 22 Jan 2024 11:25:34 +0800 Subject: [PATCH 19/58] Return `NotFoundFileInfo` or `NotFoundDirectoryContents` when `subpach` is `null`. --- .../VirtualFileSystem/WebContentFileProvider.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs index ba9240d48b..fffc35792a 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Options; @@ -34,7 +33,10 @@ public class WebContentFileProvider : IWebContentFileProvider, ISingletonDepende public virtual IFileInfo GetFileInfo(string subpath) { - Check.NotNullOrEmpty(subpath, nameof(subpath)); + if (string.IsNullOrEmpty(subpath)) + { + return new NotFoundFileInfo(subpath); + } if (PathUtils.PathNavigatesAboveRoot(subpath)) { @@ -53,11 +55,9 @@ public class WebContentFileProvider : IWebContentFileProvider, ISingletonDepende return _fileProvider.GetFileInfo(_rootPath + subpath); } - public virtual IDirectoryContents GetDirectoryContents([NotNull] string subpath) + public virtual IDirectoryContents GetDirectoryContents(string subpath) { - Check.NotNullOrEmpty(subpath, nameof(subpath)); - - if (PathUtils.PathNavigatesAboveRoot(subpath)) + if (subpath == null || PathUtils.PathNavigatesAboveRoot(subpath)) { return NotFoundDirectoryContents.Singleton; } From b34c01616418a8012ab7307ac87844d770885c10 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 22 Jan 2024 17:02:04 +0800 Subject: [PATCH 20/58] Throw exception if provder was not found --- .../Volo/Abp/SettingManagement/SettingManager.cs | 2 +- .../SettingManagement/SettingManager_Basic_Tests.cs | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManager.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManager.cs index 5439c1213a..68d66ee4b0 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManager.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManager.cs @@ -125,7 +125,7 @@ public class SettingManager : ISettingManager, ISingletonDependency if (!providers.Any()) { - return; + throw new AbpException($"Could not find a setting provider named '{providerName}'."); } if (setting.IsEncrypted) diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingManager_Basic_Tests.cs b/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingManager_Basic_Tests.cs index 44655c8cb0..00dc337c0f 100644 --- a/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingManager_Basic_Tests.cs +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingManager_Basic_Tests.cs @@ -63,4 +63,15 @@ public class SettingManager_Basic_Tests : SettingsTestBase (await _settingManager.GetOrNullGlobalAsync("MySetting1")).ShouldBe("43"); (await _settingProvider.GetOrNullAsync("MySetting1")).ShouldBe("43"); } + + [Fact] + public async Task Should_Throw_Exception_If_Provider_Not_Found() + { + var exception = await Assert.ThrowsAsync(async () => + { + await _settingManager.SetAsync("MySetting1", "43", "UndefinedProvider", "UndefinedProviderKey"); + }); + + exception.Message.ShouldBe("Could not find a setting provider named 'UndefinedProvider'."); + } } \ No newline at end of file From dc33781ed7addfcde378ebc2b3370921b4e5d6f3 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 22 Jan 2024 17:39:09 +0800 Subject: [PATCH 21/58] SettingValueProvider with duplicate names is not allowed --- .../Settings/SettingValueProviderManager.cs | 16 ++++- .../SettingValueProviderManager_Tests.cs | 64 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingValueProviderManager_Tests.cs diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValueProviderManager.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValueProviderManager.cs index d0300357dc..c13f884e98 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValueProviderManager.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValueProviderManager.cs @@ -9,7 +9,8 @@ namespace Volo.Abp.Settings; public class SettingValueProviderManager : ISettingValueProviderManager, ISingletonDependency { - public List Providers => _lazyProviders.Value; + public List Providers => GetProviders(); + protected AbpSettingOptions Options { get; } private readonly Lazy> _lazyProviders; @@ -28,4 +29,17 @@ public class SettingValueProviderManager : ISettingValueProviderManager, ISingle true ); } + + protected virtual List GetProviders() + { + var providers = _lazyProviders.Value; + + var multipleProviders = providers.GroupBy(p => p.Name).FirstOrDefault(x => x.Count() > 1); + if(multipleProviders != null) + { + throw new AbpException($"Duplicate setting value provider name detected: {multipleProviders.Key}. Providers:{Environment.NewLine}{multipleProviders.Select(p => p.GetType().FullName!).JoinAsString(Environment.NewLine)}"); + } + + return providers; + } } diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingValueProviderManager_Tests.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingValueProviderManager_Tests.cs new file mode 100644 index 0000000000..93bf26431a --- /dev/null +++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingValueProviderManager_Tests.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using NSubstitute.Extensions; +using Shouldly; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Testing; +using Xunit; + +namespace Volo.Abp.Settings; + +public class SettingValueProviderManager_Tests: AbpIntegratedTest +{ + private readonly ISettingValueProviderManager _settingValueProviderManager; + + public SettingValueProviderManager_Tests() + { + _settingValueProviderManager = GetRequiredService(); + } + + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + options.Services.Configure(settingOptions => + { + settingOptions.ValueProviders.Add(); + }); + } + + [Fact] + public void Should_Throw_Exception_If_Duplicate_Provider_Name_Detected() + { + var exception = Assert.Throws(() => + { + var providers = _settingValueProviderManager.Providers; + }); + + exception.Message.ShouldBe($"Duplicate setting value provider name detected: Test. Providers:{Environment.NewLine}Volo.Abp.Settings.Test2SettingValueProvider{Environment.NewLine}Volo.Abp.Settings.TestSettingValueProvider"); + } +} + +public class Test2SettingValueProvider : ISettingValueProvider, ITransientDependency +{ + public const string ProviderName = "Test"; + + + public string Name => ProviderName; + + public Test2SettingValueProvider() + { + } + + public Task GetOrNullAsync(SettingDefinition setting) + { + throw new NotImplementedException(); + } + + public Task> GetAllAsync(SettingDefinition[] settings) + { + throw new NotImplementedException(); + } +} \ No newline at end of file From 165885e5813e03d4ac21ae99272218dcc1c68674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Tue, 23 Jan 2024 14:14:58 +0300 Subject: [PATCH 22/58] prettify --- .../src/lib/services/remember-me.service.ts | 38 +++++++++---------- .../lib/strategies/auth-code-flow-strategy.ts | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/npm/ng-packs/packages/oauth/src/lib/services/remember-me.service.ts b/npm/ng-packs/packages/oauth/src/lib/services/remember-me.service.ts index 7c099c5166..84d40d982a 100644 --- a/npm/ng-packs/packages/oauth/src/lib/services/remember-me.service.ts +++ b/npm/ng-packs/packages/oauth/src/lib/services/remember-me.service.ts @@ -1,27 +1,27 @@ -import { AbpLocalStorageService } from "@abp/ng.core"; -import { Injectable, inject } from "@angular/core"; +import { AbpLocalStorageService } from '@abp/ng.core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ - providedIn: 'root' + providedIn: 'root', }) export class RememberMeService { - readonly #rememberMe = 'remember_me' - protected readonly localStorageService = inject(AbpLocalStorageService); + readonly #rememberMe = 'remember_me'; + protected readonly localStorageService = inject(AbpLocalStorageService); - set(remember: boolean) { - this.localStorageService.setItem(this.#rememberMe, JSON.stringify(remember)); - } + set(remember: boolean) { + this.localStorageService.setItem(this.#rememberMe, JSON.stringify(remember)); + } - remove() { - this.localStorageService.removeItem(this.#rememberMe); - } + remove() { + this.localStorageService.removeItem(this.#rememberMe); + } - get() { - return Boolean(JSON.parse(this.localStorageService.getItem(this.#rememberMe))); - } + get() { + return Boolean(JSON.parse(this.localStorageService.getItem(this.#rememberMe))); + } - getFromToken(accessToken: string) { - let parsedToken = JSON.parse(atob(accessToken.split(".")[1])); - return Boolean(parsedToken[this.#rememberMe]); - } -} \ No newline at end of file + getFromToken(accessToken: string) { + const parsedToken = JSON.parse(atob(accessToken.split('.')[1])); + return Boolean(parsedToken[this.#rememberMe]); + } +} diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts index f648be47c6..7b1e0c108a 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts @@ -13,7 +13,7 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { return super .init() .then(() => this.oAuthService.tryLogin().catch(noop)) - .then(() => this.oAuthService.setupAutomaticSilentRefresh()) + .then(() => this.oAuthService.setupAutomaticSilentRefresh()); } private checkRememberMeOption() { From 39eeba55e588a8594e53c6db4c587f50cbf0bd45 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Tue, 23 Jan 2024 15:26:55 +0300 Subject: [PATCH 23/58] Use outline variation for Cancel in Modals --- .../TagHelpers/Modal/AbpModalFooterTagHelperService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalFooterTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalFooterTagHelperService.cs index 671b00e094..8b46f6e78c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalFooterTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalFooterTagHelperService.cs @@ -90,13 +90,13 @@ public class AbpModalFooterTagHelperService : AbpTagHelperService Date: Tue, 23 Jan 2024 16:00:12 +0300 Subject: [PATCH 24/58] use outline variation for sweetalert modals --- .../sweetalert2/abp-sweetalert2.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js index 51c7db5cd9..44ef812995 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js @@ -103,6 +103,13 @@ var abp = abp || {}; abp.libs.sweetAlert.config.default.confirmButtonText = l('Ok'); abp.libs.sweetAlert.config.default.denyButtonText = l('No'); abp.libs.sweetAlert.config.default.cancelButtonText = l('Cancel'); + abp.libs.sweetAlert.config.default.buttonsStyling = false; + abp.libs.sweetAlert.config.default.customClass = { + confirmButton: "btn btn-primary", + cancelButton: "btn btn-outline-primary me-1", + denyButton: "btn btn-outline-primary me-1" + }; + abp.libs.sweetAlert.config.confirm.title = l('AreYouSure'); abp.libs.sweetAlert.config.confirm.confirmButtonText = l('Yes'); abp.libs.sweetAlert.config.confirm.showCancelButton = true; From a240717e4c1f74bb0ed7f66ec73b09068b678514 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Tue, 23 Jan 2024 16:10:51 +0300 Subject: [PATCH 25/58] Update Default.cshtml --- .../Components/EmailSettingGroup/Default.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Components/EmailSettingGroup/Default.cshtml b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Components/EmailSettingGroup/Default.cshtml index f653ec54a0..61d4dbe996 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Components/EmailSettingGroup/Default.cshtml +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Components/EmailSettingGroup/Default.cshtml @@ -31,7 +31,7 @@ @if (await PermissionChecker.IsGrantedAsync(SettingManagementPermissions.EmailingTest)) { - + @L["SendTestEmail"] } From c95dbaac17bbf6e8b6a7daed85f8ead66b09e922 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Tue, 23 Jan 2024 16:30:49 +0300 Subject: [PATCH 26/58] Update abp-sweetalert2.js --- .../sweetalert2/abp-sweetalert2.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js index 44ef812995..4a11feeda2 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js @@ -106,8 +106,8 @@ var abp = abp || {}; abp.libs.sweetAlert.config.default.buttonsStyling = false; abp.libs.sweetAlert.config.default.customClass = { confirmButton: "btn btn-primary", - cancelButton: "btn btn-outline-primary me-1", - denyButton: "btn btn-outline-primary me-1" + cancelButton: "btn btn-outline-primary mx-2", + denyButton: "btn btn-outline-primary mx-2" }; abp.libs.sweetAlert.config.confirm.title = l('AreYouSure'); From 45e9a0da2df2a0bbf5dc7564fc08fa02782d0175 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 24 Jan 2024 11:20:45 +0800 Subject: [PATCH 27/58] FeatureValueProvider and PermissionValueProvider with duplicate names is not allowed --- .../PermissionValueProviderManager.cs | 15 ++++- .../Volo/Abp/Features/FeatureChecker.cs | 20 ++----- .../Features/FeatureValueProviderManager.cs | 44 ++++++++++++++ .../Features/IFeatureValueProviderManager.cs | 8 +++ .../PermissionValueProviderManager_Tests.cs | 59 +++++++++++++++++++ .../FeatureValueProviderManager_Tests.cs | 54 +++++++++++++++++ .../SettingValueProviderManager_Tests.cs | 10 ++-- 7 files changed, 189 insertions(+), 21 deletions(-) create mode 100644 framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureValueProviderManager.cs create mode 100644 framework/src/Volo.Abp.Features/Volo/Abp/Features/IFeatureValueProviderManager.cs create mode 100644 framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionValueProviderManager_Tests.cs create mode 100644 framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/FeatureValueProviderManager_Tests.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs index 84d0ad0b2c..09b2da2acb 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.Authorization.Permissions; public class PermissionValueProviderManager : IPermissionValueProviderManager, ISingletonDependency { - public IReadOnlyList ValueProviders => _lazyProviders.Value; + public IReadOnlyList ValueProviders => GetProviders(); private readonly Lazy> _lazyProviders; protected AbpPermissionOptions Options { get; } @@ -28,4 +28,17 @@ public class PermissionValueProviderManager : IPermissionValueProviderManager, I true ); } + + protected virtual List GetProviders() + { + var providers = _lazyProviders.Value; + + var multipleProviders = providers.GroupBy(p => p.Name).FirstOrDefault(x => x.Count() > 1); + if(multipleProviders != null) + { + throw new AbpException($"Duplicate permission value provider name detected: {multipleProviders.Key}. Providers:{Environment.NewLine}{multipleProviders.Select(p => p.GetType().FullName!).JoinAsString(Environment.NewLine)}"); + } + + return providers; + } } diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureChecker.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureChecker.cs index c2a4a71ab3..66e145563d 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureChecker.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureChecker.cs @@ -12,34 +12,26 @@ public class FeatureChecker : FeatureCheckerBase protected AbpFeatureOptions Options { get; } protected IServiceProvider ServiceProvider { get; } protected IFeatureDefinitionManager FeatureDefinitionManager { get; } - protected List Providers => _providers.Value; - - private readonly Lazy> _providers; + protected IFeatureValueProviderManager FeatureValueProviderManager { get; } public FeatureChecker( IOptions options, IServiceProvider serviceProvider, - IFeatureDefinitionManager featureDefinitionManager) + IFeatureDefinitionManager featureDefinitionManager, + IFeatureValueProviderManager featureValueProviderManager) { ServiceProvider = serviceProvider; FeatureDefinitionManager = featureDefinitionManager; + FeatureValueProviderManager = featureValueProviderManager; Options = options.Value; - - _providers = new Lazy>( - () => Options - .ValueProviders - .Select(type => (ServiceProvider.GetRequiredService(type) as IFeatureValueProvider)!) - .ToList(), - true - ); } public override async Task GetOrNullAsync(string name) { var featureDefinition = await FeatureDefinitionManager.GetAsync(name); - var providers = Enumerable - .Reverse(Providers); + var providers = FeatureValueProviderManager.ValueProviders + .Reverse(); if (featureDefinition.AllowedProviders.Any()) { diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureValueProviderManager.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureValueProviderManager.cs new file mode 100644 index 0000000000..98d73dd4e4 --- /dev/null +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureValueProviderManager.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Features; + +public class FeatureValueProviderManager : IFeatureValueProviderManager, ISingletonDependency +{ + public IReadOnlyList ValueProviders => GetProviders(); + private readonly Lazy> _lazyProviders; + + protected AbpFeatureOptions Options { get; } + + public FeatureValueProviderManager( + IServiceProvider serviceProvider, + IOptions options) + { + Options = options.Value; + + _lazyProviders = new Lazy>( + () => Options + .ValueProviders + .Select(c => serviceProvider.GetRequiredService(c) as IFeatureValueProvider) + .ToList()!, + true + ); + } + + protected virtual List GetProviders() + { + var providers = _lazyProviders.Value; + + var multipleProviders = providers.GroupBy(p => p.Name).FirstOrDefault(x => x.Count() > 1); + if(multipleProviders != null) + { + throw new AbpException($"Duplicate feature value provider name detected: {multipleProviders.Key}. Providers:{Environment.NewLine}{multipleProviders.Select(p => p.GetType().FullName!).JoinAsString(Environment.NewLine)}"); + } + + return providers; + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/IFeatureValueProviderManager.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/IFeatureValueProviderManager.cs new file mode 100644 index 0000000000..56de662a99 --- /dev/null +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/IFeatureValueProviderManager.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Features; + +public interface IFeatureValueProviderManager +{ + IReadOnlyList ValueProviders { get; } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionValueProviderManager_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionValueProviderManager_Tests.cs new file mode 100644 index 0000000000..d4af25ad3a --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionValueProviderManager_Tests.cs @@ -0,0 +1,59 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Authorization; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.TestServices; +using Xunit; + +namespace Volo.Abp; + +public class PermissionValueProviderManager_Tests: AuthorizationTestBase +{ + private readonly IPermissionValueProviderManager _permissionValueProviderManager; + + public PermissionValueProviderManager_Tests() + { + _permissionValueProviderManager = GetRequiredService(); + } + + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.Services.Configure(permissionOptions => + { + permissionOptions.ValueProviders.Add(); + }); + } + + [Fact] + public void Should_Throw_Exception_If_Duplicate_Provider_Name_Detected() + { + var exception = Assert.Throws(() => + { + var providers = _permissionValueProviderManager.ValueProviders; + }); + + exception.Message.ShouldBe($"Duplicate permission value provider name detected: TestPermissionValueProvider1. Providers:{Environment.NewLine}{typeof(TestDuplicatePermissionValueProvider).FullName}{Environment.NewLine}{typeof(TestPermissionValueProvider1).FullName}"); + } +} + +public class TestDuplicatePermissionValueProvider : PermissionValueProvider +{ + public TestDuplicatePermissionValueProvider(IPermissionStore permissionStore) : base(permissionStore) + { + } + + public override string Name => "TestPermissionValueProvider1"; + + public override Task CheckAsync(PermissionValueCheckContext context) + { + throw new NotImplementedException(); + } + + public override Task CheckAsync(PermissionValuesCheckContext context) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/FeatureValueProviderManager_Tests.cs b/framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/FeatureValueProviderManager_Tests.cs new file mode 100644 index 0000000000..7e73ef65fc --- /dev/null +++ b/framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/FeatureValueProviderManager_Tests.cs @@ -0,0 +1,54 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Xunit; + +namespace Volo.Abp.Features; + +public class FeatureValueProviderManager_Tests : FeatureTestBase +{ + private readonly IFeatureValueProviderManager _featureValueProviderManager; + + public FeatureValueProviderManager_Tests() + { + _featureValueProviderManager = GetRequiredService(); + } + + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.Services.Configure(permissionOptions => + { + permissionOptions.ValueProviders.Add(); + }); + } + + [Fact] + public void Should_Throw_Exception_If_Duplicate_Provider_Name_Detected() + { + var exception = Assert.Throws(() => + { + var providers = _featureValueProviderManager.ValueProviders; + }); + + exception.Message.ShouldBe($"Duplicate feature value provider name detected: {TestDuplicateFeatureValueProvider.ProviderName}. Providers:{Environment.NewLine}{typeof(TestDuplicateFeatureValueProvider).FullName}{Environment.NewLine}{typeof(DefaultValueFeatureValueProvider).FullName}"); + } +} + +public class TestDuplicateFeatureValueProvider : FeatureValueProvider +{ + public const string ProviderName = "D"; + + public override string Name => ProviderName; + + public TestDuplicateFeatureValueProvider(IFeatureStore settingStore) + : base(settingStore) + { + + } + + public override Task GetOrNullAsync(FeatureDefinition setting) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingValueProviderManager_Tests.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingValueProviderManager_Tests.cs index 93bf26431a..f85e465d8e 100644 --- a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingValueProviderManager_Tests.cs +++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingValueProviderManager_Tests.cs @@ -1,9 +1,7 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; -using NSubstitute.Extensions; using Shouldly; using Volo.Abp.DependencyInjection; using Volo.Abp.Testing; @@ -25,7 +23,7 @@ public class SettingValueProviderManager_Tests: AbpIntegratedTest(settingOptions => { - settingOptions.ValueProviders.Add(); + settingOptions.ValueProviders.Add(); }); } @@ -37,18 +35,18 @@ public class SettingValueProviderManager_Tests: AbpIntegratedTest ProviderName; - public Test2SettingValueProvider() + public TestDuplicateSettingValueProvider() { } From 46f3338e8fac2a4a1e3f933065fbad748e4ec738 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Wed, 24 Jan 2024 10:55:11 +0300 Subject: [PATCH 28/58] Use Outline button variation for blazor alert --- .../src/Volo.Abp.BlazoriseUI/Components/UiMessageAlert.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/UiMessageAlert.razor b/framework/src/Volo.Abp.BlazoriseUI/Components/UiMessageAlert.razor index 82fc576b7e..9951e616e2 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/Components/UiMessageAlert.razor +++ b/framework/src/Volo.Abp.BlazoriseUI/Components/UiMessageAlert.razor @@ -22,7 +22,7 @@ @if ( IsConfirmation ) { - + @@ -119,7 +119,7 @@ - + From 44d51d06bd7642594828f6c7bd6f898816d48231 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Wed, 24 Jan 2024 15:19:55 +0300 Subject: [PATCH 31/58] Update FeatureManagementModal buttons --- .../Components/FeatureManagementModal.razor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Components/FeatureManagementModal.razor b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Components/FeatureManagementModal.razor index 719cea562a..6b5a16fbb0 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Components/FeatureManagementModal.razor +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Components/FeatureManagementModal.razor @@ -95,8 +95,8 @@ - - + + } From 46fcdb21e5f32d1680abee23c0307d93d96e5e5e Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Wed, 24 Jan 2024 15:28:03 +0300 Subject: [PATCH 32/58] Use outline variation of buttons for Identity module on blazor --- .../Pages/Identity/RoleManagement.razor | 4 ++-- .../Pages/Identity/UserManagement.razor | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor index b5b8b15d47..d65325abae 100644 --- a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor @@ -63,7 +63,7 @@ - + @@ -101,7 +101,7 @@ - + diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor index 57ab80dc5e..349da3d9da 100644 --- a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor @@ -154,7 +154,7 @@ - + @@ -275,7 +275,7 @@ - + From 4384eb683e18690ea23ab888bff5f2df4efbb424 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Wed, 24 Jan 2024 16:52:09 +0300 Subject: [PATCH 33/58] Update PermissionManagementModal.razor --- .../Components/PermissionManagementModal.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor index 8c1f5871db..88d023a906 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor @@ -81,7 +81,7 @@ } - + From 4df046dae234e6c6a64f2b22824567a8f6fcc3eb Mon Sep 17 00:00:00 2001 From: denizdemirkan Date: Wed, 24 Jan 2024 19:29:10 +0300 Subject: [PATCH 34/58] MarkdownSupported Localization for Community --- .../AbpIoLocalization/Community/Localization/Resources/ar.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/cs.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/de.json | 3 ++- .../Community/Localization/Resources/en-GB.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/en.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/es.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/fi.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/fr.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/hi.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/hr.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/hu.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/is.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/it.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/nl.json | 3 ++- .../Community/Localization/Resources/pl-PL.json | 3 ++- .../Community/Localization/Resources/pt-BR.json | 3 ++- .../Community/Localization/Resources/ro-RO.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/ru.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/sk.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/sl.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/tr.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/vi.json | 3 ++- .../Community/Localization/Resources/zh-Hans.json | 3 ++- .../Community/Localization/Resources/zh-Hant.json | 3 ++- 24 files changed, 48 insertions(+), 24 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json index 963546d9a3..df39dea75d 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json @@ -255,6 +255,7 @@ "LatestArticles": "أحدث المقالات", "RaffleHeader": "مرحبًا عضو مجتمع برنامج الجسر الأكاديمي!", "RafflesInfo": "
هذه هي صفحة السحب المخصصة لإظهار تقديرنا لك لكونك عضوًا نشطًا في المجتمع. نحن نقوم بإجراء
محادثات مجتمعية لبرنامج ABP ، ومؤتمر ABP .NET ، ونحضر أو نرعى الأحداث المتعلقة بـ .NET والتي نقدم فيها بعض الهدايا.

يمكنك متابعة هذه الصفحة لرؤية السحوبات القادمة أو حضورها أو الاطلاع على السحوبات السابقة التي قمنا بسحبها بما في ذلك الفائزين.

شكرا لكونك عضوا نشطا! نراكم في السحوبات القادمة.", - "RafflesInfoTitle": "سحوبات مجتمع ABP" + "RafflesInfoTitle": "سحوبات مجتمع ABP", + "MarkdownSupported": "Markdown أيد." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json index 418cf5aef1..4c6a229861 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json @@ -255,6 +255,7 @@ "LatestArticles": "poslední články", "RaffleHeader": "Dobrý den, člen komunity ABP!", "RafflesInfo": "
Toto je stránka s losováním věnovaná tomu, abychom vám ukázali naše uznání za to, že jste aktivním členem komunity. Pořádáme ABP Community Talks , ABP .NET Conference , účastníme se nebo sponzorujeme akce související s .NET, ve kterých rozdáváme nějaké dárky.

Na této stránce můžete sledovat nadcházející tomboly, zúčastnit se jich nebo si prohlédnout předchozí tomboly, které losujeme, včetně výherců.

Děkujeme, že jste aktivním členem! Uvidíme se v nadcházejícím slosování.", - "RafflesInfoTitle": "Komunitní tomboly ABP" + "RafflesInfoTitle": "Komunitní tomboly ABP", + "MarkdownSupported": "Markdown podporováno." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json index 021c19b3ff..146985eb49 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json @@ -255,6 +255,7 @@ "LatestArticles": "Neueste Artikel", "RaffleHeader": "Hallo ABP-Community-Mitglied!", "RafflesInfo": "
Auf dieser Verlosungsseite möchten wir Ihnen unsere Wertschätzung dafür zeigen, dass Sie ein aktives Community-Mitglied sind. Wir veranstalten ABP Community Talks und ABP .NET Conferences , nehmen an .NET-bezogenen Veranstaltungen teil oder sponsern diese, bei denen wir einige Geschenke verschenken.

Sie können dieser Seite folgen, um die bevorstehenden Verlosungen zu sehen, daran teilzunehmen oder frühere Verlosungen, die wir verlosen, einschließlich der Gewinner, anzusehen.

Vielen Dank, dass Sie ein aktives Mitglied sind! Wir sehen uns bei den kommenden Gewinnspielen.", - "RafflesInfoTitle": "ABP-Community- Verlosungen" + "RafflesInfoTitle": "ABP-Community- Verlosungen", + "MarkdownSupported": "Markdown unterstützt." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json index 0283b963bc..fc21345c05 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json @@ -103,6 +103,7 @@ "Language": "Language", "CreatePostLanguageInfo": "Language of the post", "SeeMore": "See More", - "MemberNotPublishedPostYet": "This member hasn't published any posts yet." + "MemberNotPublishedPostYet": "This member hasn't published any posts yet.", + "MarkdownSupported": "Markdown supported." } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json index fa10d9c408..4bcd1bd525 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json @@ -256,6 +256,7 @@ "RaffleHeader": "Hello ABP Community Member!", "RafflesInfo": "
This is the raffle page dedicated to show our appreciation towards you for being an active Community Member. We do ABP Community Talks ,ABP .NET Conference, attend or sponsor to the .NET-related events in which we give away some gifts.

You can follow this page to see the upcoming raffles, attend them, or see previous raffles we draw including the winners.

Thank you for being an active member! See you in the upcoming raffles.", "RafflesInfoTitle": "ABP Community Raffles", - "ToLuckyWinner": "to 1 lucky winner" + "ToLuckyWinner": "to 1 lucky winner", + "MarkdownSupported": "Markdown supported." } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json index c4e178bbd9..f24cb1d511 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json @@ -255,6 +255,7 @@ "LatestArticles": "últimos artículos", "RaffleHeader": "¡Hola miembro de la comunidad ABP!", "RafflesInfo": "
Esta es la página del sorteo dedicada a mostrarle nuestro agradecimiento por ser un miembro activo de la comunidad. Realizamos charlas comunitarias de ABP , conferencias ABP .NET , asistimos o patrocinamos eventos relacionados con .NET en los que regalamos algunos obsequios.

Puedes seguir esta página para ver los próximos sorteos, asistir a ellos o ver sorteos anteriores que sorteamos incluyendo a los ganadores.

¡Gracias por ser un miembro activo! Nos vemos en los próximos sorteos.", - "RafflesInfoTitle": "Rifas de la Comunidad ABP" + "RafflesInfoTitle": "Rifas de la Comunidad ABP", + "MarkdownSupported": "Markdown soportado." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json index ac509875d6..a42a7d693f 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json @@ -255,6 +255,7 @@ "LatestArticles": "Viimeisimmät artikkelit", "RaffleHeader": "Hei ABP-yhteisön jäsen!", "RafflesInfo": "
Tämä on arvontasivu, joka on omistettu osoittamaan kiitollisuuttamme sinua kohtaan, että olet aktiivinen yhteisön jäsen. Teemme ABP Community Talksia , ABP .NET -konferenssia , osallistumme tai sponsoroimme .NET-tapahtumia, joissa annamme lahjoja.

Voit seurata tätä sivua nähdäksesi tulevat arvonnat, osallistua niihin tai nähdäksesi aiemmat arvonnamme, mukaan lukien voittajat.

Kiitos aktiivisesta jäsenyydestäsi! Nähdään tulevissa arvonnassa.", - "RafflesInfoTitle": "ABP-yhteisön arpajaiset" + "RafflesInfoTitle": "ABP-yhteisön arpajaiset", + "MarkdownSupported": "Markdown tuettu." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json index c98a48d93e..2ed85aaa95 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json @@ -255,6 +255,7 @@ "LatestArticles": "Derniers articles", "RaffleHeader": "Bonjour membre de la communauté ABP !", "RafflesInfo": "
Ceci est la page de tirage au sort dédiée à vous montrer notre gratitude pour votre participation active à la communauté. Nous organisons des discussions communautaires ABP , des conférences ABP .NET , assistons ou sponsorisons des événements liés à .NET au cours desquels nous offrons des cadeaux.

Vous pouvez suivre cette page pour voir les tirages au sort à venir, y assister ou voir les tirages au sort précédents que nous tirons, y compris les gagnants.

Merci d'être un membre actif ! Rendez-vous lors des prochains tirages au sort.", - "RafflesInfoTitle": "Tirages au sort communautaires ABP" + "RafflesInfoTitle": "Tirages au sort communautaires ABP", + "MarkdownSupported": "Markdown prise en charge." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json index f3d300e8a2..6a969b99f3 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json @@ -255,6 +255,7 @@ "LatestArticles": "नवीनतम लेख", "RaffleHeader": "नमस्ते एबीपी समुदाय सदस्य!", "RafflesInfo": "
यह रैफ़ल पेज है जो एक सक्रिय समुदाय सदस्य होने के लिए आपके प्रति हमारी सराहना दिखाने के लिए समर्पित है। हम एबीपी सामुदायिक वार्ता , एबीपी .NET सम्मेलन करते हैं, .NET से संबंधित कार्यक्रमों में भाग लेते हैं या प्रायोजित करते हैं जिसमें हम कुछ उपहार देते हैं।

आप आगामी रैफ़ल देखने, उनमें भाग लेने, या विजेताओं सहित हमारे द्वारा निकाले गए पिछले रैफ़ल देखने के लिए इस पृष्ठ का अनुसरण कर सकते हैं।

सक्रिय सदस्य बनने के लिए धन्यवाद! आगामी रैफ़ल में मिलते हैं।", - "RafflesInfoTitle": "एबीपी कम्युनिटी रैफल्स" + "RafflesInfoTitle": "एबीपी कम्युनिटी रैफल्स", + "MarkdownSupported": "Markdown का समर्थन किया।" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json index 5b3546a78b..4e213a9c66 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json @@ -255,6 +255,7 @@ "LatestArticles": "Najnoviji članci", "RaffleHeader": "Pozdrav članu ABP zajednice!", "RafflesInfo": "
Ovo je stranica za nagradnu igru namijenjena da vam pokažemo našu zahvalnost što ste aktivni član zajednice. Vodimo razgovore o ABP zajednici , ABP .NET konferenciji , prisustvujemo ili sponzoriramo događaje vezane uz .NET na kojima dijelimo neke darove.

Možete pratiti ovu stranicu kako biste vidjeli nadolazeće nagradne igre, prisustvovali im ili vidjeli prethodne nagradne igre koje izvlačimo uključujući dobitnike.

Hvala vam što ste aktivan član! Vidimo se u nadolazećim nagradnim igrama.", - "RafflesInfoTitle": "Izvlačenje nagradne igre zajednice ABP" + "RafflesInfoTitle": "Izvlačenje nagradne igre zajednice ABP", + "MarkdownSupported": "Markdown podržan." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json index 1f74f9e7a9..f489cdc571 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json @@ -255,6 +255,7 @@ "LatestArticles": "Legfrissebb cikkek", "RaffleHeader": "Kedves ABP közösségi tag!", "RafflesInfo": "
Ez az a sorsolási oldal, amelynek célja, hogy kifejezzük hálánkat feléd, amiért aktív közösségi tag vagy. Az ABP Community Talks-okat , az ABP .NET konferenciákat szervezzük, részt veszünk vagy szponzorálunk olyan .NET-hez kapcsolódó eseményeket, amelyeken ajándékokat adunk.

Ezt az oldalt követheti, hogy megtekinthesse a közelgő sorsolásokat, részt vegyen azokon, vagy megtekinthesse korábbi sorsolásainkat, beleértve a nyerteseket is.

Köszönjük, hogy aktív tag vagy! Találkozunk a sorsoláson.", - "RafflesInfoTitle": "ABP közösségi tombola" + "RafflesInfoTitle": "ABP közösségi tombola", + "MarkdownSupported": "Markdown támogatott." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json index a991c387d4..32284f5f37 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json @@ -255,6 +255,7 @@ "LatestArticles": "Nýjustu greinar", "RaffleHeader": "Halló ABP samfélagsmeðlimur!", "RafflesInfo": "
Þetta er happdrættisíðan sem er tileinkuð þér að þakka þér fyrir að vera virkur samfélagsmeðlimur. Við gerum ABP Community Talks , ABP .NET ráðstefnu , sækjum eða styrkjum .NET tengda viðburði þar sem við gefum nokkrar gjafir.

Þú getur fylgst með þessari síðu til að sjá komandi happdrætti, mæta á þær eða sjá fyrri happdrætti sem við drögum út, þar á meðal vinningshafa.

Þakka þér fyrir að vera virkur meðlimur! Sjáumst í komandi happdrætti.", - "RafflesInfoTitle": "ABP samfélagshappdrætti" + "RafflesInfoTitle": "ABP samfélagshappdrætti", + "MarkdownSupported": "Markdown stutt." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json index 901c356c9a..301c1e84e7 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json @@ -255,6 +255,7 @@ "LatestArticles": "Articoli Recenti", "RaffleHeader": "Ciao membro della comunità ABP!", "RafflesInfo": "
Questa è la pagina della lotteria dedicata a mostrare il nostro apprezzamento nei tuoi confronti per essere un membro attivo della comunità. Organizziamo ABP Community Talks , ABP .NET Conference , partecipiamo o sponsorizziamo eventi relativi a .NET in cui regaliamo alcuni regali.

Puoi seguire questa pagina per vedere le prossime lotterie, parteciparvi o vedere le lotterie precedenti che estraiamo, compresi i vincitori.

Grazie per essere un membro attivo! Ci vediamo alle prossime lotterie.", - "RafflesInfoTitle": "Lotterie comunitarie ABP" + "RafflesInfoTitle": "Lotterie comunitarie ABP", + "MarkdownSupported": "Markdown supportato." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json index 4ee8e44a09..8beba46650 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json @@ -255,6 +255,7 @@ "LatestArticles": "Laatste artikels", "RaffleHeader": "Hallo ABP Community-lid!", "RafflesInfo": "
Dit is de loterijpagina die bedoeld is om onze waardering voor u te tonen omdat u een actief lid van de community bent. We houden ABP Community Talks , ABP .NET Conference , wonen of sponsoren de .NET-gerelateerde evenementen bij waarin we een aantal geschenken weggeven.

U kunt deze pagina volgen om de komende loterijen te zien, deze bij te wonen of eerdere loterijen te zien die we trekken, inclusief de winnaars.

Bedankt dat u een actief lid bent! Tot ziens bij de komende loterijen.", - "RafflesInfoTitle": "ABP- gemeenschaploterijen" + "RafflesInfoTitle": "ABP- gemeenschaploterijen", + "MarkdownSupported": "Markdown ondersteund." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json index 2df6780f03..e47be75ccc 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json @@ -255,6 +255,7 @@ "LatestArticles": "ostatnie artykuły", "RaffleHeader": "Witaj, członku społeczności ABP!", "RafflesInfo": "
To jest strona loterii, której celem jest wyrażenie naszego uznania dla Ciebie za bycie aktywnym członkiem społeczności. Prowadzimy rozmowy społecznościowe ABP , konferencje ABP .NET , uczestniczymy lub sponsorujemy wydarzenia związane z .NET, podczas których rozdajemy prezenty.

Możesz śledzić tę stronę, aby zobaczyć nadchodzące loterie, wziąć w nich udział lub zobaczyć poprzednie loterie, które losowaliśmy, w tym zwycięzców.

Dziękujemy za bycie aktywnym członkiem! Do zobaczenia w nadchodzących loteriach.", - "RafflesInfoTitle": "Loterie społecznościowe ABP" + "RafflesInfoTitle": "Loterie społecznościowe ABP", + "MarkdownSupported": "Markdown utrzymany." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json index 9f2ce433d9..d987c03211 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json @@ -255,6 +255,7 @@ "LatestArticles": "Artigos Mais Recentes", "RaffleHeader": "Olá, membro da comunidade ABP!", "RafflesInfo": "
Esta é a página do sorteio dedicada a mostrar nosso agradecimento por você ser um membro ativo da comunidade. Fazemos ABP Community Talks , ABP .NET Conference , participamos ou patrocinamos eventos relacionados ao .NET nos quais distribuímos alguns presentes.

Você pode seguir esta página para ver os próximos sorteios, participar deles ou ver os sorteios anteriores que sorteamos, incluindo os vencedores.

Obrigado por ser um membro ativo! Nos vemos nos próximos sorteios.", - "RafflesInfoTitle": "Sorteios da Comunidade ABP" + "RafflesInfoTitle": "Sorteios da Comunidade ABP", + "MarkdownSupported": "Markdown suportado." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json index c2862d1fd7..06ecc4dea8 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json @@ -255,6 +255,7 @@ "LatestArticles": "ultimele articole", "RaffleHeader": "Bună ziua, membru al comunității ABP!", "RafflesInfo": "
Aceasta este pagina de tombolă dedicată pentru a arăta aprecierea noastră față de dvs. pentru că sunteți un membru activ al comunității. Facem ABP Community Talks , ABP .NET Conference , participăm sau sponsorizăm evenimentele legate de .NET în care oferim câteva cadouri.

Puteți urmări această pagină pentru a vedea tombolele viitoare, a participa la ele sau pentru a vedea tombolele anterioare pe care le extragem, inclusiv câștigătorii.

Vă mulțumim că sunteți un membru activ! Ne vedem la tombolele viitoare.", - "RafflesInfoTitle": "Tombole comunitare ABP" + "RafflesInfoTitle": "Tombole comunitare ABP", + "MarkdownSupported": "Markdown sprijinit." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json index 27f2b1203a..07d6a87fe9 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json @@ -258,6 +258,7 @@ "LatestArticles": "Последние статьи", "RaffleHeader": "Привет, участник сообщества ABP!", "RafflesInfo": "
Эта страница розыгрыша посвящена тому, чтобы выразить нашу признательность вам за то, что вы являетесь активным членом сообщества. Обсуждения сообщества ABP ,Конференция ABP .NET, посещать или спонсировать мероприятия, связанные с .NET, на которых мы раздаем подарки.

Вы можете подписаться на эту страницу, чтобы увидеть предстоящие розыгрыши, посетить их или просмотреть предыдущие розыгрыши, которые мы проводим, включая победителей.

Спасибо за активное участие! ", - "RafflesInfoTitle": "Сообщество АБП Розыгрыши" + "RafflesInfoTitle": "Сообщество АБП Розыгрыши", + "MarkdownSupported": "Markdown поддерживается." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json index 6ab3c9d074..fa9826b421 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json @@ -255,6 +255,7 @@ "LatestArticles": "Najnovšie články", "RaffleHeader": "Dobrý deň, člen komunity ABP!", "RafflesInfo": "
Toto je stránka žrebovania venovaná na vyjadrenie nášho uznania vám za to, že ste aktívnym členom komunity. Robíme ABP Community Talks , ABP .NET konferenciu , zúčastňujeme sa alebo sponzorujeme podujatia súvisiace s .NET, na ktorých rozdávame nejaké darčeky.

Na tejto stránke si môžete pozrieť pripravované tomboly, zúčastniť sa ich alebo si pozrieť predchádzajúce žrebovanie, ktoré vyžrebujeme vrátane výhercov.

Ďakujeme, že ste aktívnym členom! Vidíme sa v najbližšom žrebovaní.", - "RafflesInfoTitle": "Komunitné tomboly ABP" + "RafflesInfoTitle": "Komunitné tomboly ABP", + "MarkdownSupported": "Markdown podporované." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json index 23763c6f78..81e103cd17 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json @@ -255,6 +255,7 @@ "LatestArticles": "Najnovejši članki", "RaffleHeader": "Pozdravljeni član skupnosti ABP!", "RafflesInfo": "
To je stran za nagradno igro, namenjena izkazovanju naše hvaležnosti do vas, ker ste aktivni član skupnosti. Izvajamo ABP Community Talks , ABP .NET Conference , se udeležujemo ali sponzoriramo dogodke, povezane z .NET, na katerih podarimo nekaj daril.

To stran lahko spremljate in si ogledate prihajajoče nagradne igre, se jih udeležite ali si ogledate prejšnje nagradne igre, ki smo jih izžrebali, vključno z zmagovalci.

Hvala, ker ste aktivni član! Se vidimo na prihajajočih nagradnih igrah.", - "RafflesInfoTitle": "Žrebanje skupnosti ABP" + "RafflesInfoTitle": "Žrebanje skupnosti ABP", + "MarkdownSupported": "Markdown podprt." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json index 2d52d01ed2..d184bb63d1 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json @@ -189,6 +189,7 @@ "Layout_MetaDescription": "ABP Topluluğu, insanların ABP çerçevesi hakkında paylaşımlarda bulunabileceği ve projeleri takip edebileceği bir ortamdır.", "Index_Page_CommunityIntroduction": "Burası ABP Çerçevesi, .NET ve yazılım geliştirme için bir merkezdir. Makaleleri okuyabilir, eğitim videolarını izleyebilir, ABP'nin gelişim süreci ve ABP ile ilgili etkinlikler hakkında bilgi alabilir, diğer geliştiricilere yardımcı olabilir ve uzmanlığınızı ABP topluluğu ile paylaşabilirsiniz.", "IConsentToMedium": "Bu yazının https://medium.com/volosoft adresinde yayınlanmasına izin veriyorum.", - "DiscordPageTitle": "ABP Discord Topluluğu" + "DiscordPageTitle": "ABP Discord Topluluğu", + "MarkdownSupported": "Markdown destekleniyor." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json index a36ec9b0e8..d7febbb014 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json @@ -255,6 +255,7 @@ "LatestArticles": "Bài viết mới nhất", "RaffleHeader": "Xin chào Thành viên Cộng đồng ABP!", "RafflesInfo": "
Đây là trang xổ số dành riêng để thể hiện sự đánh giá cao của chúng tôi đối với bạn vì đã trở thành Thành viên cộng đồng tích cực. Chúng tôi tổ chức các buổi nói chuyện cộng đồng ABP , Hội nghị ABP .NET , tham dự hoặc tài trợ cho các sự kiện liên quan đến .NET mà trong đó chúng tôi tặng một số quà tặng.

Bạn có thể theo dõi trang này để xem các cuộc xổ số sắp tới, tham dự hoặc xem các cuộc xổ số trước đây mà chúng tôi rút ra bao gồm cả những người chiến thắng.

Cảm ơn bạn đã là thành viên tích cực! Hẹn gặp lại các bạn trong đợt xổ số sắp tới.", - "RafflesInfoTitle": "Xổ số cộng đồng ABP" + "RafflesInfoTitle": "Xổ số cộng đồng ABP", + "MarkdownSupported": "Markdown được hỗ trợ." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json index e899a94872..c0aaf2678b 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json @@ -255,6 +255,7 @@ "LatestArticles": "最新文章", "RaffleHeader": "你好,ABP 社区成员!", "RafflesInfo": "
这是一个抽奖页面,旨在感谢您成为活跃的社区成员。我们举办 ABP 社区讲座 、ABP .NET 会议,参加或赞助与 .NET 相关的活动,并在活动中赠送一些礼品。

您可以关注此页面,查看即将举行的抽奖活动、参加这些活动或查看我们以前举行的抽奖活动(包括获奖者)。

感谢您成为我们的活跃成员!在即将举行的抽奖活动中再见。", - "RafflesInfoTitle": "ABP 社区来抽奖来抽奖Markdown 支持的。" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json index ebec42dd8a..7f8e58f7df 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json @@ -255,6 +255,7 @@ "LatestArticles": "最新的文章", "RaffleHeader": "ABP 社群成員您好!", "RafflesInfo": "
這是抽獎頁面,旨在表達我們對您作為活躍社區成員的感謝。我們舉辦ABP 社群講座、ABP .NET 會議、參加或贊助 .NET 相關活動,並在活動中贈送一些禮物。

您可以關注此頁面查看即將舉行的抽獎活動、參加抽獎活動或查看我們之前抽獎的抽獎活動(包括獲獎者)。

感謝您成為活躍會員!在即將到來的抽獎活動中再見。", - "RafflesInfoTitle": "ABP 社區萊佛士" + "RafflesInfoTitle": "ABP 社區萊佛士", + "MarkdownSupported": "Markdown 支持的。" } } \ No newline at end of file From 368eb9c565543934ab4d23b706b59a1f7e8556c1 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 25 Jan 2024 13:53:30 +0800 Subject: [PATCH 35/58] Migration notes for NormalizedName property of Tenant. Resolve #18857 --- docs/en/Migration-Guides/Abp-8_1.md | 86 +++++++++++++++++++++++++++++ docs/en/Multi-Tenancy.md | 2 +- 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 docs/en/Migration-Guides/Abp-8_1.md diff --git a/docs/en/Migration-Guides/Abp-8_1.md b/docs/en/Migration-Guides/Abp-8_1.md new file mode 100644 index 0000000000..d5ec87a3ca --- /dev/null +++ b/docs/en/Migration-Guides/Abp-8_1.md @@ -0,0 +1,86 @@ +# ABP Version 8.1 Migration Guide + +This document is a guide for upgrading ABP v8.0 solutions to ABP v8.1. There are some changes in this version that may affect your applications, please read it carefully and apply the necessary changes to your application. + +## Added `NormalizedName` property to `Tenant` + +The `Tenant` entity has a new property called `NormalizedName`. It is used to find/cache a tenant by its name in a case-insensitive way. +This property is automatically set when a tenant is created or updated. It gets the normalized name of the tenant name by `UpperInvariantTenantNormalizer(ITenantNormalizer)` service. You can implement this service to change the normalization logic. + +### `ITenantStore` + +The `ITenantStore` will use the `NormalizedName` parameter to get tenants, Please use the `ITenantNormalizer` to normalize the tenant name before calling the `ITenantStore` methods. + +### Update `NormalizedName` in `appsettings.json` + +If your tenants defined in the `appsettings.json` file, you should add the `NormalizedName` property to your tenants. + +````json +"Tenants": [ + { + "Id": "446a5211-3d72-4339-9adc-845151f8ada0", + "Name": "tenant1", + "NormalizedName": "TENANT1" // <-- Add this property + }, + { + "Id": "25388015-ef1c-4355-9c18-f6b6ddbaf89d", + "Name": "tenant2", + "NormalizedName": "TENANT2", // <-- Add this property + "ConnectionStrings": { + "Default": "...tenant2's db connection string here..." + } + } + ] +```` + +### Update `NormalizedName` in the database + +Please add a sql script to your migration to set the `NormalizedName` property of the existing tenants. You can use the following script: + +> This script is for the SQL Server database. You can change it for your database. + +> The table name `SaasTenants` is used for ABP commercial Saas module. `AbpTenants` is for the ABP open-source Tenant Management module. + +```sql +UPDATE SaasTenants SET NormalizedName = UPPER(Name) WHERE NormalizedName IS NULL OR NormalizedName = '' +``` + +```csharp +/// +public partial class Add_NormalizedName : Migration +{ + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "NormalizedName", + table: "SaasTenants", + type: "citext", + maxLength: 64, + nullable: false, + defaultValue: ""); + + migrationBuilder.Sql("UPDATE SaasTenants SET NormalizedName = UPPER(Name) WHERE NormalizedName IS NULL OR NormalizedName = ''"); + + migrationBuilder.CreateIndex( + name: "IX_SaasTenants_NormalizedName", + table: "SaasTenants", + column: "NormalizedName"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_SaasTenants_NormalizedName", + table: "SaasTenants"); + + migrationBuilder.DropColumn( + name: "NormalizedName", + table: "SaasTenants"); + } +} +``` + +See https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/managing?tabs=dotnet-core-cli#adding-raw-sql to learn how to add raw SQL to migrations. + diff --git a/docs/en/Multi-Tenancy.md b/docs/en/Multi-Tenancy.md index 392bea6809..698879bdf1 100644 --- a/docs/en/Multi-Tenancy.md +++ b/docs/en/Multi-Tenancy.md @@ -394,7 +394,7 @@ app.UseMultiTenancy(); `ITenantStore` is used to get the tenant configuration from a data source. -> Tenant names are not case-sensitive. `ITenantStore` will use the `NormalizedName` parameter to get tenants, You need to use `ITenantNormalizer to normalize tenant names. +> Tenant names are not case-sensitive. `ITenantStore` will use the `NormalizedName` parameter to get tenants, You need to use `ITenantNormalizer`` to normalize tenant names. #### Tenant Management Module From 1fe4a25b9cf73921b84305f8d258126f9db09436 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 25 Jan 2024 13:55:42 +0800 Subject: [PATCH 36/58] Update Multi-Tenancy.md --- docs/en/Multi-Tenancy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Multi-Tenancy.md b/docs/en/Multi-Tenancy.md index 698879bdf1..922976767d 100644 --- a/docs/en/Multi-Tenancy.md +++ b/docs/en/Multi-Tenancy.md @@ -394,7 +394,7 @@ app.UseMultiTenancy(); `ITenantStore` is used to get the tenant configuration from a data source. -> Tenant names are not case-sensitive. `ITenantStore` will use the `NormalizedName` parameter to get tenants, You need to use `ITenantNormalizer`` to normalize tenant names. +> Tenant names are not case-sensitive. `ITenantStore` will use the `NormalizedName` parameter to get tenants, You need to use `ITenantNormalizer` to normalize tenant names. #### Tenant Management Module From 1bffcc7220b99eb9346fc4f88ca70722168e970d Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 25 Jan 2024 14:05:36 +0800 Subject: [PATCH 37/58] Update Abp-8_1.md --- docs/en/Migration-Guides/Abp-8_1.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/en/Migration-Guides/Abp-8_1.md b/docs/en/Migration-Guides/Abp-8_1.md index d5ec87a3ca..6f4c316d3f 100644 --- a/docs/en/Migration-Guides/Abp-8_1.md +++ b/docs/en/Migration-Guides/Abp-8_1.md @@ -55,8 +55,7 @@ public partial class Add_NormalizedName : Migration migrationBuilder.AddColumn( name: "NormalizedName", table: "SaasTenants", - type: "citext", - maxLength: 64, + type: "nvarchar(64)", nullable: false, defaultValue: ""); From 9438b57bbe4a3fca3cf2b995307459b2fe6591f9 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 25 Jan 2024 14:17:32 +0800 Subject: [PATCH 38/58] Add index for `NormalizedName` peroperty. --- .../AbpTenantManagementDbContextModelCreatingExtensions.cs | 1 + ...nitial.Designer.cs => 20240125061235_Initial.Designer.cs} | 4 +++- .../{20240110051639_Initial.cs => 20240125061235_Initial.cs} | 5 +++++ .../Migrations/MyProjectNameDbContextModelSnapshot.cs | 2 ++ ...nitial.Designer.cs => 20240125061501_Initial.Designer.cs} | 4 +++- .../Server/Migrations/20240125061501_Initial.cs} | 5 +++++ .../Server/Migrations/MyProjectNameDbContextModelSnapshot.cs | 2 ++ ...nitial.Designer.cs => 20240125061101_Initial.Designer.cs} | 4 +++- .../{20240110051553_Initial.cs => 20240125061101_Initial.cs} | 5 +++++ .../Migrations/MyProjectNameDbContextModelSnapshot.cs | 2 ++ ...nitial.Designer.cs => 20240125061143_Initial.Designer.cs} | 4 +++- .../{20240110051615_Initial.cs => 20240125061143_Initial.cs} | 5 +++++ .../Migrations/MyProjectNameDbContextModelSnapshot.cs | 2 ++ ...nitial.Designer.cs => 20240125061248_Initial.Designer.cs} | 4 +++- .../{20240110051649_Initial.cs => 20240125061248_Initial.cs} | 5 +++++ .../Migrations/MyProjectNameDbContextModelSnapshot.cs | 2 ++ ...nitial.Designer.cs => 20240125061344_Initial.Designer.cs} | 4 +++- .../Migrations/20240125061344_Initial.cs} | 5 +++++ .../Migrations/AuthServerDbContextModelSnapshot.cs | 2 ++ ...nitial.Designer.cs => 20240125061321_Initial.Designer.cs} | 4 +++- .../{20240110051713_Initial.cs => 20240125061321_Initial.cs} | 5 +++++ .../Migrations/UnifiedDbContextModelSnapshot.cs | 2 ++ ...nitial.Designer.cs => 20240125061400_Initial.Designer.cs} | 2 +- .../{20240110051748_Initial.cs => 20240125061400_Initial.cs} | 0 ...nitial.Designer.cs => 20240125061424_Initial.Designer.cs} | 4 +++- .../{20240110051810_Initial.cs => 20240125061424_Initial.cs} | 5 +++++ .../Migrations/UnifiedDbContextModelSnapshot.cs | 2 ++ 27 files changed, 82 insertions(+), 9 deletions(-) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/{20240110051639_Initial.Designer.cs => 20240125061235_Initial.Designer.cs} (99%) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/{20240110051639_Initial.cs => 20240125061235_Initial.cs} (99%) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/{20240110051838_Initial.Designer.cs => 20240125061501_Initial.Designer.cs} (99%) rename templates/{module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240110051734_Initial.cs => app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.cs} (99%) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/{20240110051553_Initial.Designer.cs => 20240125061101_Initial.Designer.cs} (99%) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/{20240110051553_Initial.cs => 20240125061101_Initial.cs} (99%) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/{20240110051615_Initial.Designer.cs => 20240125061143_Initial.Designer.cs} (99%) rename templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/{20240110051615_Initial.cs => 20240125061143_Initial.cs} (99%) rename templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/{20240110051649_Initial.Designer.cs => 20240125061248_Initial.Designer.cs} (99%) rename templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/{20240110051649_Initial.cs => 20240125061248_Initial.cs} (99%) rename templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/{20240110051734_Initial.Designer.cs => 20240125061344_Initial.Designer.cs} (99%) rename templates/{app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240110051838_Initial.cs => module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.cs} (99%) rename templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/{20240110051713_Initial.Designer.cs => 20240125061321_Initial.Designer.cs} (99%) rename templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/{20240110051713_Initial.cs => 20240125061321_Initial.cs} (99%) rename templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/{20240110051748_Initial.Designer.cs => 20240125061400_Initial.Designer.cs} (96%) rename templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/{20240110051748_Initial.cs => 20240125061400_Initial.cs} (100%) rename templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/{20240110051810_Initial.Designer.cs => 20240125061424_Initial.Designer.cs} (99%) rename templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/{20240110051810_Initial.cs => 20240125061424_Initial.cs} (99%) diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs index bb189e72a1..a91cf066e5 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs @@ -28,6 +28,7 @@ public static class AbpTenantManagementDbContextModelCreatingExtensions b.HasMany(u => u.ConnectionStrings).WithOne().HasForeignKey(uc => uc.TenantId).IsRequired(); b.HasIndex(u => u.Name); + b.HasIndex(u => u.NormalizedName); b.ApplyObjectExtensionMappings(); }); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240110051639_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.Designer.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240110051639_Initial.Designer.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.Designer.cs index 720730ac29..2f3a437364 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240110051639_Initial.Designer.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20240110051639_Initial")] + [Migration("20240125061235_Initial")] partial class Initial { /// @@ -1696,6 +1696,8 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240110051639_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240110051639_Initial.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.cs index f55e1bd71a..dd96c605e7 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240110051639_Initial.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.cs @@ -914,6 +914,11 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations table: "AbpTenants", column: "Name"); + migrationBuilder.CreateIndex( + name: "IX_AbpTenants_NormalizedName", + table: "AbpTenants", + column: "NormalizedName"); + migrationBuilder.CreateIndex( name: "IX_AbpUserClaims_UserId", table: "AbpUserClaims", diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs index 94403eda52..652e7b674d 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -1693,6 +1693,8 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240110051838_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.Designer.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240110051838_Initial.Designer.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.Designer.cs index d8f8a2f32c..f25d60e99b 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240110051838_Initial.Designer.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20240110051838_Initial")] + [Migration("20240125061501_Initial")] partial class Initial { /// @@ -1696,6 +1696,8 @@ namespace MyCompanyName.MyProjectName.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240110051734_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.cs similarity index 99% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240110051734_Initial.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.cs index 42da66e3e2..b0cb9b0e6f 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240110051734_Initial.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.cs @@ -914,6 +914,11 @@ namespace MyCompanyName.MyProjectName.Migrations table: "AbpTenants", column: "Name"); + migrationBuilder.CreateIndex( + name: "IX_AbpTenants_NormalizedName", + table: "AbpTenants", + column: "NormalizedName"); + migrationBuilder.CreateIndex( name: "IX_AbpUserClaims_UserId", table: "AbpUserClaims", diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs index 2085b9d8cd..72f44ed239 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -1693,6 +1693,8 @@ namespace MyCompanyName.MyProjectName.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240110051553_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.Designer.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240110051553_Initial.Designer.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.Designer.cs index a17b97362f..364eaa6b57 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240110051553_Initial.Designer.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Host.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20240110051553_Initial")] + [Migration("20240125061101_Initial")] partial class Initial { /// @@ -1696,6 +1696,8 @@ namespace MyCompanyName.MyProjectName.Host.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240110051553_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240110051553_Initial.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.cs index 0b4123ab8d..bfb34fcaad 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240110051553_Initial.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.cs @@ -914,6 +914,11 @@ namespace MyCompanyName.MyProjectName.Host.Migrations table: "AbpTenants", column: "Name"); + migrationBuilder.CreateIndex( + name: "IX_AbpTenants_NormalizedName", + table: "AbpTenants", + column: "NormalizedName"); + migrationBuilder.CreateIndex( name: "IX_AbpUserClaims_UserId", table: "AbpUserClaims", diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs index 6035862d19..f2b46a651f 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -1693,6 +1693,8 @@ namespace MyCompanyName.MyProjectName.Host.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240110051615_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.Designer.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240110051615_Initial.Designer.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.Designer.cs index e2a3ff5a34..54929eb8e9 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240110051615_Initial.Designer.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Mvc.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20240110051615_Initial")] + [Migration("20240125061143_Initial")] partial class Initial { /// @@ -1696,6 +1696,8 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240110051615_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240110051615_Initial.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.cs index 6fd77905c4..44eddb6abb 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240110051615_Initial.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.cs @@ -914,6 +914,11 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations table: "AbpTenants", column: "Name"); + migrationBuilder.CreateIndex( + name: "IX_AbpTenants_NormalizedName", + table: "AbpTenants", + column: "NormalizedName"); + migrationBuilder.CreateIndex( name: "IX_AbpUserClaims_UserId", table: "AbpUserClaims", diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs index 7f594fe2e5..8041069541 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -1693,6 +1693,8 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240110051649_Initial.Designer.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.Designer.cs similarity index 99% rename from templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240110051649_Initial.Designer.cs rename to templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.Designer.cs index 5749fe8a39..e211d7e755 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240110051649_Initial.Designer.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20240110051649_Initial")] + [Migration("20240125061248_Initial")] partial class Initial { /// @@ -1748,6 +1748,8 @@ namespace MyCompanyName.MyProjectName.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240110051649_Initial.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.cs similarity index 99% rename from templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240110051649_Initial.cs rename to templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.cs index 2fe3338034..9fc3a5a0b9 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240110051649_Initial.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.cs @@ -940,6 +940,11 @@ namespace MyCompanyName.MyProjectName.Migrations table: "AbpTenants", column: "Name"); + migrationBuilder.CreateIndex( + name: "IX_AbpTenants_NormalizedName", + table: "AbpTenants", + column: "NormalizedName"); + migrationBuilder.CreateIndex( name: "IX_AbpUserClaims_UserId", table: "AbpUserClaims", diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs index 1b7c95358e..877bff36e8 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -1745,6 +1745,8 @@ namespace MyCompanyName.MyProjectName.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240110051734_Initial.Designer.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.Designer.cs similarity index 99% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240110051734_Initial.Designer.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.Designer.cs index d732cf68bb..b6dd932e2f 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240110051734_Initial.Designer.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(AuthServerDbContext))] - [Migration("20240110051734_Initial")] + [Migration("20240125061344_Initial")] partial class Initial { /// @@ -1696,6 +1696,8 @@ namespace MyCompanyName.MyProjectName.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240110051838_Initial.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.cs similarity index 99% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240110051838_Initial.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.cs index 42da66e3e2..b0cb9b0e6f 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240110051838_Initial.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.cs @@ -914,6 +914,11 @@ namespace MyCompanyName.MyProjectName.Migrations table: "AbpTenants", column: "Name"); + migrationBuilder.CreateIndex( + name: "IX_AbpTenants_NormalizedName", + table: "AbpTenants", + column: "NormalizedName"); + migrationBuilder.CreateIndex( name: "IX_AbpUserClaims_UserId", table: "AbpUserClaims", diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/AuthServerDbContextModelSnapshot.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/AuthServerDbContextModelSnapshot.cs index 95ab069a86..c3fb7f9ff0 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/AuthServerDbContextModelSnapshot.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/AuthServerDbContextModelSnapshot.cs @@ -1693,6 +1693,8 @@ namespace MyCompanyName.MyProjectName.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240110051713_Initial.Designer.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240125061321_Initial.Designer.cs similarity index 99% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240110051713_Initial.Designer.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240125061321_Initial.Designer.cs index fa01be30fc..3c17670e22 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240110051713_Initial.Designer.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240125061321_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations { [DbContext(typeof(UnifiedDbContext))] - [Migration("20240110051713_Initial")] + [Migration("20240125061321_Initial")] partial class Initial { /// @@ -1337,6 +1337,8 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240110051713_Initial.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240125061321_Initial.cs similarity index 99% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240110051713_Initial.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240125061321_Initial.cs index a27989973a..1a8774f577 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240110051713_Initial.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240125061321_Initial.cs @@ -778,6 +778,11 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations table: "AbpTenants", column: "Name"); + migrationBuilder.CreateIndex( + name: "IX_AbpTenants_NormalizedName", + table: "AbpTenants", + column: "NormalizedName"); + migrationBuilder.CreateIndex( name: "IX_AbpUserClaims_UserId", table: "AbpUserClaims", diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/UnifiedDbContextModelSnapshot.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/UnifiedDbContextModelSnapshot.cs index 9835c59cd3..4acfb0c562 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/UnifiedDbContextModelSnapshot.cs @@ -1334,6 +1334,8 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240110051748_Initial.Designer.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240125061400_Initial.Designer.cs similarity index 96% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240110051748_Initial.Designer.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240125061400_Initial.Designer.cs index 2eb38813a6..c58552ea60 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240110051748_Initial.Designer.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240125061400_Initial.Designer.cs @@ -12,7 +12,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(MyProjectNameHttpApiHostMigrationsDbContext))] - [Migration("20240110051748_Initial")] + [Migration("20240125061400_Initial")] partial class Initial { /// diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240110051748_Initial.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240125061400_Initial.cs similarity index 100% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240110051748_Initial.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240125061400_Initial.cs diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240110051810_Initial.Designer.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240125061424_Initial.Designer.cs similarity index 99% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240110051810_Initial.Designer.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240125061424_Initial.Designer.cs index f7363bd08d..04cad1c308 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240110051810_Initial.Designer.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240125061424_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(UnifiedDbContext))] - [Migration("20240110051810_Initial")] + [Migration("20240125061424_Initial")] partial class Initial { /// @@ -1337,6 +1337,8 @@ namespace MyCompanyName.MyProjectName.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240110051810_Initial.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240125061424_Initial.cs similarity index 99% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240110051810_Initial.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240125061424_Initial.cs index 014376034b..469e6eac08 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240110051810_Initial.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240125061424_Initial.cs @@ -778,6 +778,11 @@ namespace MyCompanyName.MyProjectName.Migrations table: "AbpTenants", column: "Name"); + migrationBuilder.CreateIndex( + name: "IX_AbpTenants_NormalizedName", + table: "AbpTenants", + column: "NormalizedName"); + migrationBuilder.CreateIndex( name: "IX_AbpUserClaims_UserId", table: "AbpUserClaims", diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs index 7a50a01df4..b6fd7b9e97 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs @@ -1334,6 +1334,8 @@ namespace MyCompanyName.MyProjectName.Migrations b.HasIndex("Name"); + b.HasIndex("NormalizedName"); + b.ToTable("AbpTenants", (string)null); }); From 5f5085a48554953df5befa0ddfb59f0e45f962ef Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 25 Jan 2024 14:34:55 +0800 Subject: [PATCH 39/58] Remove `Nito.AsyncEx.Coordination` package from `Volo.Abp.Core`. --- framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj b/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj index 042cbd270c..8804c8868f 100644 --- a/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj +++ b/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj @@ -31,7 +31,6 @@ - From 771e93ecfc65edd7d48a7b9809a1cf82c448b102 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 25 Jan 2024 14:35:20 +0800 Subject: [PATCH 40/58] Update Directory.Packages.props --- Directory.Packages.props | 1 - 1 file changed, 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index b9c94c0106..f5cf8871de 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -107,7 +107,6 @@ - From bf3b665de17487a5ccb262d743aa9afcc70b53bb Mon Sep 17 00:00:00 2001 From: Salih Date: Thu, 25 Jan 2024 09:48:27 +0300 Subject: [PATCH 41/58] Update en.json --- .../AbpIoLocalization/Admin/Localization/Resources/en.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index aa16e3931c..ee660f72e4 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -592,6 +592,8 @@ "OrganizationId": "Organization Id", "RemoveAllWinnersConfirmationMessage": "Are you sure you want to remove all winners?", "AutoRenewals": "Auto Renewals", - "OrganizationHasCreditCard": "Organization has credit card. Please remove credit card first!" + "OrganizationHasCreditCard": "Organization has credit card. Please remove credit card first!", + "DisplayName:DontSendEmailForLicenseExpire": "Don't Send Email For License Expire", + "DontSendEmailForLicenseExpire": "Don't Send Email For License Expire" } } From 46afb5e3f9f96356457ee1b7e2c1dc5aafc32cee Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Thu, 25 Jan 2024 10:30:01 +0300 Subject: [PATCH 42/58] Update EmailSettingGroupViewComponent.razor --- .../EmailSettingGroup/EmailSettingGroupViewComponent.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/EmailSettingGroup/EmailSettingGroupViewComponent.razor b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/EmailSettingGroup/EmailSettingGroupViewComponent.razor index e80115cfde..177f1d75fa 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/EmailSettingGroup/EmailSettingGroupViewComponent.razor +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/EmailSettingGroup/EmailSettingGroupViewComponent.razor @@ -95,7 +95,7 @@ @if (HasSendTestEmailPermission) { - + } From 5d8d15917a94c3eb8a868f4d5dd1d1cf59dcd421 Mon Sep 17 00:00:00 2001 From: Salih Date: Thu, 25 Jan 2024 11:17:17 +0300 Subject: [PATCH 43/58] Update en.json --- .../AbpIoLocalization/Commercial/Localization/Resources/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index e5d8c15ac2..dcf3423484 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -1129,7 +1129,7 @@ "NameOnCard": "Name on Card", "BillingDetails": "Billing Details", "ThereIsNoDeveloper": "There is no developer.", - "CardDetails": "Card Details", + "CardDetails": "Debit/Credit Card Details", "NoActiveLicence": "You are not eligible for this action! You have no active license." } } From aa832dbfaadc218dc98ea6f997060c22a9f9b1e0 Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Thu, 25 Jan 2024 13:39:30 +0300 Subject: [PATCH 44/58] Update Post.md --- .../2024-01-04-CLI-Online-Translate/Post.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/Post.md b/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/Post.md index abddfd43fd..285d7d5dc9 100644 --- a/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/Post.md +++ b/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/Post.md @@ -1,12 +1,12 @@ # Use Deepl to translate localization files -Translating localized text during the development ABP modules is a boring work. For this reason we have added the `translate` command to the CLI tool to translate the localization files, but it still requires manual translate texts by the developer. +Translating localized text during the development of ABP modules is a boring job. For this reason, we have added the `translate` command to the CLI tool to translate the localization files, but it still requires manual translation of texts by the developer. -Now, We introduce a new way to translate the target language, which is to use the [Deepl](https://www.deepl.com/translator) translation service to translate the target language. +Now, we introduce a new way to translate the target language, which is to use the [Deepl](https://www.deepl.com/translator) translation service to translate the target language. -You can use the `translate --online` command to in your module directory to translate the target language. +You can use the `translate --online` command in your module directory to translate the target language. -For example, You have added all `en` localization texts to your module, and you want to translate them to `zh-Hans`, you can run the following command: +For example, if you have added all `en` localization texts to your module, and you want to translate them to `zh-Hans`, you can run the following command: ``` abp translate -r en -c zh-Hans --online --deepl-auth-key your_auth_key From 2282441869e7b821dce4684f377ee1822eedac22 Mon Sep 17 00:00:00 2001 From: Salih Date: Thu, 25 Jan 2024 15:42:50 +0300 Subject: [PATCH 45/58] Fix: Selects on docs shrinks to unusable sizes on mobile --- .../Pages/Documents/Project/Index.cshtml | 55 ++++++++++++------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index 85d402c11d..d285ae5338 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -332,28 +332,45 @@ - @foreach (var parameter in Model.DocumentPreferences.Parameters) - { -

-
- @(parameter.DisplayName) - + @foreach (var value in parameter.Values.OrderBy(p => p.Value)) { - + @if (value.Key == (Model.UserPreferences.ContainsKey(parameter.Name) ? Model.UserPreferences[parameter.Name] : null)) + { + + } + else + { + + } } - } - + +
- + } } From 6784765b793ffef95b808c8abc5e3243481f97e3 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Thu, 25 Jan 2024 15:47:25 +0300 Subject: [PATCH 46/58] Update FeatureManagementModal.cshtml --- .../Pages/FeatureManagement/FeatureManagementModal.cshtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml index ca38284046..a3a00a89c1 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml @@ -123,8 +123,8 @@ - @L["ResetToDefault"] - @L["Cancel"] + @L["Cancel"] + @L["ResetToDefault"] @L["Save"] } From 66cf8377cfe50b86d0789fa1f9cf3f729ee7cc9d Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Thu, 25 Jan 2024 15:50:43 +0300 Subject: [PATCH 47/58] Update Create.cshtml --- .../Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml index 190df58ecb..5c855e9ffe 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml @@ -132,7 +132,7 @@ - + @if ((await AuthorizationService.AuthorizeAsync(CmsKitAdminPermissions.BlogPosts.Publish)).Succeeded) { From 893b038efc72edb3fb0b7ae351d3180bb0c311da Mon Sep 17 00:00:00 2001 From: Salih Date: Thu, 25 Jan 2024 15:57:53 +0300 Subject: [PATCH 48/58] Update Index.cshtml --- .../src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index d285ae5338..83f4c7a775 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -337,12 +337,13 @@ var count = Model.DocumentPreferences.Parameters.Count; var rowCount = count / maxCellCount + (count % maxCellCount > 0 ? 1 : 0); var cellSize = 12 / (count > maxCellCount ? maxCellCount : count); + var latestCellSize = 12 / count - (rowCount - 1) * maxCellCount; string BuildParameterDivClass(int index) { var row = index / maxCellCount; var isLastRow = row == rowCount - 1; - var currentCellSize = isLastRow ? 12 / (count % maxCellCount) : cellSize; + var currentCellSize = isLastRow ? latestCellSize : cellSize; return $"col-12 col-lg-{currentCellSize} mb-lg-{(isLastRow ? "0" : "2")} {(index == count - 1 ? "" : "mb-2")}"; } From 50e952bd6263b1bd95de377be4a3c291b6e20dce Mon Sep 17 00:00:00 2001 From: Salih Date: Thu, 25 Jan 2024 16:19:12 +0300 Subject: [PATCH 49/58] Add new localizations --- .../AbpIoLocalization/Www/Localization/Resources/en.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json index d1bc23b308..ec2d301a29 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json @@ -353,6 +353,8 @@ "BuildSolutionsWithAbp": "Build maintainable .NET solutions by following software development best practices using ABP.", "BuyOnAmazon": "Buy on Amazon", "BuyOnPackt": "Buy on Packt", + "BuyOnDangDang": "Buy on DangDang", + "BuyOnJD": "Buy on JD", "Discounted": "Discounted", "MasteringAbpFramework_Book_KeyFeatures": "Key Features", "MasteringAbpFramework_Book_Key_Features_Description_1": "Build robust, maintainable, modular, and scalable software solutions using ABP Framework.", From 0fe8b8ab6f29561319979723ca60b2e574bacec5 Mon Sep 17 00:00:00 2001 From: Salih Date: Thu, 25 Jan 2024 16:42:24 +0300 Subject: [PATCH 50/58] Update zh-Hant.json --- .../AbpIoLocalization/Www/Localization/Resources/zh-Hant.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json index 81664b5f8d..dc396ce8b9 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json @@ -353,6 +353,8 @@ "BuildSolutionsWithAbp": "使用 ABP 遵循軟體開發最佳實務來建立可維護的 .NET 解決方案。", "BuyOnAmazon": "在亞馬遜上購買", "BuyOnPackt": "在 Packt 上購買", + "BuyOnDangDang": "在當當上購買", + "BuyOnJD": "在京東上購買", "Discounted": "折扣", "MasteringAbpFramework_Book_KeyFeatures": "主要特徵", "MasteringAbpFramework_Book_Key_Features_Description_1": "使用 ABP 框架建構健壯、可維護、模組化和可擴展的軟體解決方案。", From 8f6f075944a6f177c1632683ecbe18c49e65cb50 Mon Sep 17 00:00:00 2001 From: Salih Date: Thu, 25 Jan 2024 16:42:26 +0300 Subject: [PATCH 51/58] Update zh-Hans.json --- .../AbpIoLocalization/Www/Localization/Resources/zh-Hans.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json index 9fb6a08b32..88d56a6303 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json @@ -353,6 +353,8 @@ "BuildSolutionsWithAbp": "使用 ABP,遵循软件开发最佳实践,构建可维护的 .NET 解决方案。", "BuyOnAmazon": "在亚马逊上购买", "BuyOnPackt": "在 Packt 购买", + "BuyOnDangDang": "在当当网购买", + "BuyOnJD": "在京东上购买", "Discounted": "折扣", "MasteringAbpFramework_Book_KeyFeatures": "主要功能", "MasteringAbpFramework_Book_Key_Features_Description_1": "使用 ABP 框架构建稳健、可维护、模块化和可扩展的软件解决方案。", From 446de0b438eff6b465b678369824b24208f37b83 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Thu, 25 Jan 2024 16:49:39 +0300 Subject: [PATCH 52/58] Reorder buttons in email setting group component --- .../Components/EmailSettingGroup/Default.cshtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Components/EmailSettingGroup/Default.cshtml b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Components/EmailSettingGroup/Default.cshtml index 61d4dbe996..ee8db3e38f 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Components/EmailSettingGroup/Default.cshtml +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Components/EmailSettingGroup/Default.cshtml @@ -26,15 +26,15 @@
- - @L["Save"] - @if (await PermissionChecker.IsGrantedAsync(SettingManagementPermissions.EmailingTest)) { @L["SendTestEmail"] } + + @L["Save"] +
From 707b99f35a0d905b5d77037d8fea9f8fe1e9a7f5 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Thu, 25 Jan 2024 16:52:02 +0300 Subject: [PATCH 53/58] Refactor email setting group view component --- .../EmailSettingGroup/EmailSettingGroupViewComponent.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/EmailSettingGroup/EmailSettingGroupViewComponent.razor b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/EmailSettingGroup/EmailSettingGroupViewComponent.razor index 177f1d75fa..19f95ca52a 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/EmailSettingGroup/EmailSettingGroupViewComponent.razor +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/EmailSettingGroup/EmailSettingGroupViewComponent.razor @@ -92,11 +92,11 @@ - @if (HasSendTestEmailPermission) { } + From d3058a9a3ecd2d22717dfcb257416b9b76e7ac04 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Fri, 26 Jan 2024 10:01:29 +0800 Subject: [PATCH 54/58] Throw exception if provder was not found --- .../Volo/Abp/FeatureManagement/FeatureManager.cs | 2 +- .../Abp/FeatureManagement/FeatureManager_Tests.cs | 11 +++++++++++ .../PermissionManager_Tests.cs | 15 +++++++++++++++ .../Volo/Abp/SettingManagement/SettingManager.cs | 2 +- .../SettingManager_Basic_Tests.cs | 7 ++++--- 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs index 1a5356a1be..9805f03752 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs @@ -144,7 +144,7 @@ public class FeatureManager : IFeatureManager, ISingletonDependency if (!providers.Any()) { - return; + throw new AbpException($"Unknown feature value provider: {providerName}"); } if (providers.Count > 1 && !forceToSet && value != null) diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Domain.Tests/Volo/Abp/FeatureManagement/FeatureManager_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Domain.Tests/Volo/Abp/FeatureManagement/FeatureManager_Tests.cs index 831d021e38..fd4ea324ea 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.Domain.Tests/Volo/Abp/FeatureManagement/FeatureManager_Tests.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Domain.Tests/Volo/Abp/FeatureManagement/FeatureManager_Tests.cs @@ -209,4 +209,15 @@ public class FeatureManager_Tests : FeatureManagementDomainTestBase (await _featureManager.GetOrNullAsync(TestFeatureDefinitionProvider.BackupCount, TenantFeatureValueProvider.ProviderName, TestEditionIds.TenantId.ToString())).ShouldBe("0"); } + + [Fact] + public async Task Set_Should_Throw_Exception_If_Provider_Not_Found() + { + var exception = await Assert.ThrowsAsync(async () => + { + await _featureManager.SetAsync(TestFeatureDefinitionProvider.EmailSupport, "true", "UndefinedProvider", "Test"); + }); + + exception.Message.ShouldBe("Unknown feature value provider: UndefinedProvider"); + } } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionManager_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionManager_Tests.cs index 1f771bdb3b..3f2e9c7565 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionManager_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionManager_Tests.cs @@ -134,6 +134,21 @@ public class PermissionManager_Tests : PermissionTestBase "Test", true); } + + [Fact] + public async Task Set_Should_Throw_Exception_If_Provider_Not_Found() + { + var exception = await Assert.ThrowsAsync(async () => + { + await _permissionManager.SetAsync( + "MyPermission1", + "UndefinedProvider", + "Test", + true); + }); + + exception.Message.ShouldBe("Unknown permission management provider: UndefinedProvider"); + } [Fact] public async Task UpdateProviderKey() diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManager.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManager.cs index 68d66ee4b0..ddf451154d 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManager.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManager.cs @@ -125,7 +125,7 @@ public class SettingManager : ISettingManager, ISingletonDependency if (!providers.Any()) { - throw new AbpException($"Could not find a setting provider named '{providerName}'."); + throw new AbpException($"Unknown setting value provider: {providerName}"); } if (setting.IsEncrypted) diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingManager_Basic_Tests.cs b/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingManager_Basic_Tests.cs index 00dc337c0f..ca9db64c70 100644 --- a/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingManager_Basic_Tests.cs +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingManager_Basic_Tests.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using Shouldly; using Volo.Abp.Settings; @@ -65,13 +66,13 @@ public class SettingManager_Basic_Tests : SettingsTestBase } [Fact] - public async Task Should_Throw_Exception_If_Provider_Not_Found() + public async Task Set_Should_Throw_Exception_If_Provider_Not_Found() { var exception = await Assert.ThrowsAsync(async () => { - await _settingManager.SetAsync("MySetting1", "43", "UndefinedProvider", "UndefinedProviderKey"); + await _settingManager.SetAsync("MySetting1", "43", "UndefinedProvider", "Test"); }); - exception.Message.ShouldBe("Could not find a setting provider named 'UndefinedProvider'."); + exception.Message.ShouldBe("Unknown setting value provider: UndefinedProvider"); } } \ No newline at end of file From 88e6fc7aa81b615c5c6d68194ca3024b4a518745 Mon Sep 17 00:00:00 2001 From: denizdemirkan Date: Fri, 26 Jan 2024 13:21:03 +0300 Subject: [PATCH 55/58] Preview word added --- .../AbpIoLocalization/Community/Localization/Resources/ar.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/cs.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/de.json | 3 ++- .../Community/Localization/Resources/en-GB.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/en.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/es.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/fi.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/fr.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/hi.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/hr.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/hu.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/is.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/it.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/nl.json | 3 ++- .../Community/Localization/Resources/pl-PL.json | 3 ++- .../Community/Localization/Resources/pt-BR.json | 3 ++- .../Community/Localization/Resources/ro-RO.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/ru.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/sk.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/sl.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/tr.json | 3 ++- .../AbpIoLocalization/Community/Localization/Resources/vi.json | 3 ++- .../Community/Localization/Resources/zh-Hans.json | 3 ++- .../Community/Localization/Resources/zh-Hant.json | 3 ++- 24 files changed, 48 insertions(+), 24 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json index df39dea75d..7151345ea9 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json @@ -256,6 +256,7 @@ "RaffleHeader": "مرحبًا عضو مجتمع برنامج الجسر الأكاديمي!", "RafflesInfo": "
هذه هي صفحة السحب المخصصة لإظهار تقديرنا لك لكونك عضوًا نشطًا في المجتمع. نحن نقوم بإجراء محادثات مجتمعية لبرنامج ABP ، ومؤتمر ABP .NET ، ونحضر أو نرعى الأحداث المتعلقة بـ .NET والتي نقدم فيها بعض الهدايا.

يمكنك متابعة هذه الصفحة لرؤية السحوبات القادمة أو حضورها أو الاطلاع على السحوبات السابقة التي قمنا بسحبها بما في ذلك الفائزين.

شكرا لكونك عضوا نشطا! نراكم في السحوبات القادمة.", "RafflesInfoTitle": "سحوبات مجتمع ABP", - "MarkdownSupported": "Markdown أيد." + "MarkdownSupported": "Markdown أيد.", + "Preview": "معاينة" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json index 4c6a229861..252b0dcb2b 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json @@ -256,6 +256,7 @@ "RaffleHeader": "Dobrý den, člen komunity ABP!", "RafflesInfo": "
Toto je stránka s losováním věnovaná tomu, abychom vám ukázali naše uznání za to, že jste aktivním členem komunity. Pořádáme ABP Community Talks , ABP .NET Conference , účastníme se nebo sponzorujeme akce související s .NET, ve kterých rozdáváme nějaké dárky.

Na této stránce můžete sledovat nadcházející tomboly, zúčastnit se jich nebo si prohlédnout předchozí tomboly, které losujeme, včetně výherců.

Děkujeme, že jste aktivním členem! Uvidíme se v nadcházejícím slosování.", "RafflesInfoTitle": "Komunitní tomboly ABP", - "MarkdownSupported": "Markdown podporováno." + "MarkdownSupported": "Markdown podporováno.", + "Preview": "Náhled" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json index 146985eb49..4326ff88ef 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json @@ -256,6 +256,7 @@ "RaffleHeader": "Hallo ABP-Community-Mitglied!", "RafflesInfo": "
Auf dieser Verlosungsseite möchten wir Ihnen unsere Wertschätzung dafür zeigen, dass Sie ein aktives Community-Mitglied sind. Wir veranstalten ABP Community Talks und ABP .NET Conferences , nehmen an .NET-bezogenen Veranstaltungen teil oder sponsern diese, bei denen wir einige Geschenke verschenken.

Sie können dieser Seite folgen, um die bevorstehenden Verlosungen zu sehen, daran teilzunehmen oder frühere Verlosungen, die wir verlosen, einschließlich der Gewinner, anzusehen.

Vielen Dank, dass Sie ein aktives Mitglied sind! Wir sehen uns bei den kommenden Gewinnspielen.", "RafflesInfoTitle": "ABP-Community- Verlosungen", - "MarkdownSupported": "Markdown unterstützt." + "MarkdownSupported": "Markdown unterstützt.", + "Preview": "Vorschau" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json index fc21345c05..347b18ce4b 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json @@ -104,6 +104,7 @@ "CreatePostLanguageInfo": "Language of the post", "SeeMore": "See More", "MemberNotPublishedPostYet": "This member hasn't published any posts yet.", - "MarkdownSupported": "Markdown supported." + "MarkdownSupported": "Markdown supported.", + "Preview": "Preview" } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json index 4bcd1bd525..b22fc19de8 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json @@ -257,6 +257,7 @@ "RafflesInfo": "
This is the raffle page dedicated to show our appreciation towards you for being an active Community Member. We do ABP Community Talks ,ABP .NET Conference, attend or sponsor to the .NET-related events in which we give away some gifts.

You can follow this page to see the upcoming raffles, attend them, or see previous raffles we draw including the winners.

Thank you for being an active member! See you in the upcoming raffles.", "RafflesInfoTitle": "ABP Community Raffles", "ToLuckyWinner": "to 1 lucky winner", - "MarkdownSupported": "Markdown supported." + "MarkdownSupported": "Markdown supported.", + "Preview": "Preview" } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json index f24cb1d511..c53b45ab81 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json @@ -256,6 +256,7 @@ "RaffleHeader": "¡Hola miembro de la comunidad ABP!", "RafflesInfo": "
Esta es la página del sorteo dedicada a mostrarle nuestro agradecimiento por ser un miembro activo de la comunidad. Realizamos charlas comunitarias de ABP , conferencias ABP .NET , asistimos o patrocinamos eventos relacionados con .NET en los que regalamos algunos obsequios.

Puedes seguir esta página para ver los próximos sorteos, asistir a ellos o ver sorteos anteriores que sorteamos incluyendo a los ganadores.

¡Gracias por ser un miembro activo! Nos vemos en los próximos sorteos.", "RafflesInfoTitle": "Rifas de la Comunidad ABP", - "MarkdownSupported": "Markdown soportado." + "MarkdownSupported": "Markdown soportado.", + "Preview": "Avance" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json index a42a7d693f..abd8cdd21f 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json @@ -256,6 +256,7 @@ "RaffleHeader": "Hei ABP-yhteisön jäsen!", "RafflesInfo": "
Tämä on arvontasivu, joka on omistettu osoittamaan kiitollisuuttamme sinua kohtaan, että olet aktiivinen yhteisön jäsen. Teemme ABP Community Talksia , ABP .NET -konferenssia , osallistumme tai sponsoroimme .NET-tapahtumia, joissa annamme lahjoja.

Voit seurata tätä sivua nähdäksesi tulevat arvonnat, osallistua niihin tai nähdäksesi aiemmat arvonnamme, mukaan lukien voittajat.

Kiitos aktiivisesta jäsenyydestäsi! Nähdään tulevissa arvonnassa.", "RafflesInfoTitle": "ABP-yhteisön arpajaiset", - "MarkdownSupported": "Markdown tuettu." + "MarkdownSupported": "Markdown tuettu.", + "Preview": "Esikatselu" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json index 2ed85aaa95..1f259aac6d 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json @@ -256,6 +256,7 @@ "RaffleHeader": "Bonjour membre de la communauté ABP !", "RafflesInfo": "
Ceci est la page de tirage au sort dédiée à vous montrer notre gratitude pour votre participation active à la communauté. Nous organisons des discussions communautaires ABP , des conférences ABP .NET , assistons ou sponsorisons des événements liés à .NET au cours desquels nous offrons des cadeaux.

Vous pouvez suivre cette page pour voir les tirages au sort à venir, y assister ou voir les tirages au sort précédents que nous tirons, y compris les gagnants.

Merci d'être un membre actif ! Rendez-vous lors des prochains tirages au sort.", "RafflesInfoTitle": "Tirages au sort communautaires ABP", - "MarkdownSupported": "Markdown prise en charge." + "MarkdownSupported": "Markdown prise en charge.", + "Preview": "Aperçu" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json index 6a969b99f3..b868260ae6 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json @@ -256,6 +256,7 @@ "RaffleHeader": "नमस्ते एबीपी समुदाय सदस्य!", "RafflesInfo": "
यह रैफ़ल पेज है जो एक सक्रिय समुदाय सदस्य होने के लिए आपके प्रति हमारी सराहना दिखाने के लिए समर्पित है। हम एबीपी सामुदायिक वार्ता , एबीपी .NET सम्मेलन करते हैं, .NET से संबंधित कार्यक्रमों में भाग लेते हैं या प्रायोजित करते हैं जिसमें हम कुछ उपहार देते हैं।

आप आगामी रैफ़ल देखने, उनमें भाग लेने, या विजेताओं सहित हमारे द्वारा निकाले गए पिछले रैफ़ल देखने के लिए इस पृष्ठ का अनुसरण कर सकते हैं।

सक्रिय सदस्य बनने के लिए धन्यवाद! आगामी रैफ़ल में मिलते हैं।", "RafflesInfoTitle": "एबीपी कम्युनिटी रैफल्स", - "MarkdownSupported": "Markdown का समर्थन किया।" + "MarkdownSupported": "Markdown का समर्थन किया।", + "Preview": "पूर्व दर्शन" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json index 4e213a9c66..eb3b66d9c8 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json @@ -256,6 +256,7 @@ "RaffleHeader": "Pozdrav članu ABP zajednice!", "RafflesInfo": "
Ovo je stranica za nagradnu igru namijenjena da vam pokažemo našu zahvalnost što ste aktivni član zajednice. Vodimo razgovore o ABP zajednici , ABP .NET konferenciji , prisustvujemo ili sponzoriramo događaje vezane uz .NET na kojima dijelimo neke darove.

Možete pratiti ovu stranicu kako biste vidjeli nadolazeće nagradne igre, prisustvovali im ili vidjeli prethodne nagradne igre koje izvlačimo uključujući dobitnike.

Hvala vam što ste aktivan član! Vidimo se u nadolazećim nagradnim igrama.", "RafflesInfoTitle": "Izvlačenje nagradne igre zajednice ABP", - "MarkdownSupported": "Markdown podržan." + "MarkdownSupported": "Markdown podržan.", + "Preview": "Pregled" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json index f489cdc571..08917573ff 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json @@ -256,6 +256,7 @@ "RaffleHeader": "Kedves ABP közösségi tag!", "RafflesInfo": "
Ez az a sorsolási oldal, amelynek célja, hogy kifejezzük hálánkat feléd, amiért aktív közösségi tag vagy. Az ABP Community Talks-okat , az ABP .NET konferenciákat szervezzük, részt veszünk vagy szponzorálunk olyan .NET-hez kapcsolódó eseményeket, amelyeken ajándékokat adunk.

Ezt az oldalt követheti, hogy megtekinthesse a közelgő sorsolásokat, részt vegyen azokon, vagy megtekinthesse korábbi sorsolásainkat, beleértve a nyerteseket is.

Köszönjük, hogy aktív tag vagy! Találkozunk a sorsoláson.", "RafflesInfoTitle": "ABP közösségi tombola", - "MarkdownSupported": "Markdown támogatott." + "MarkdownSupported": "Markdown támogatott.", + "Preview": "Előnézet" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json index 32284f5f37..0d8eb6cb48 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json @@ -256,6 +256,7 @@ "RaffleHeader": "Halló ABP samfélagsmeðlimur!", "RafflesInfo": "
Þetta er happdrættisíðan sem er tileinkuð þér að þakka þér fyrir að vera virkur samfélagsmeðlimur. Við gerum ABP Community Talks , ABP .NET ráðstefnu , sækjum eða styrkjum .NET tengda viðburði þar sem við gefum nokkrar gjafir.

Þú getur fylgst með þessari síðu til að sjá komandi happdrætti, mæta á þær eða sjá fyrri happdrætti sem við drögum út, þar á meðal vinningshafa.

Þakka þér fyrir að vera virkur meðlimur! Sjáumst í komandi happdrætti.", "RafflesInfoTitle": "ABP samfélagshappdrætti", - "MarkdownSupported": "Markdown stutt." + "MarkdownSupported": "Markdown stutt.", + "Preview": "Forskoðun" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json index 301c1e84e7..a301a7f482 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json @@ -256,6 +256,7 @@ "RaffleHeader": "Ciao membro della comunità ABP!", "RafflesInfo": "
Questa è la pagina della lotteria dedicata a mostrare il nostro apprezzamento nei tuoi confronti per essere un membro attivo della comunità. Organizziamo ABP Community Talks , ABP .NET Conference , partecipiamo o sponsorizziamo eventi relativi a .NET in cui regaliamo alcuni regali.

Puoi seguire questa pagina per vedere le prossime lotterie, parteciparvi o vedere le lotterie precedenti che estraiamo, compresi i vincitori.

Grazie per essere un membro attivo! Ci vediamo alle prossime lotterie.", "RafflesInfoTitle": "Lotterie comunitarie ABP", - "MarkdownSupported": "Markdown supportato." + "MarkdownSupported": "Markdown supportato.", + "Preview": "Anteprima" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json index 8beba46650..45b3024c96 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json @@ -256,6 +256,7 @@ "RaffleHeader": "Hallo ABP Community-lid!", "RafflesInfo": "
Dit is de loterijpagina die bedoeld is om onze waardering voor u te tonen omdat u een actief lid van de community bent. We houden ABP Community Talks , ABP .NET Conference , wonen of sponsoren de .NET-gerelateerde evenementen bij waarin we een aantal geschenken weggeven.

U kunt deze pagina volgen om de komende loterijen te zien, deze bij te wonen of eerdere loterijen te zien die we trekken, inclusief de winnaars.

Bedankt dat u een actief lid bent! Tot ziens bij de komende loterijen.", "RafflesInfoTitle": "ABP- gemeenschaploterijen", - "MarkdownSupported": "Markdown ondersteund." + "MarkdownSupported": "Markdown ondersteund.", + "Preview": "Voorbeeld" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json index e47be75ccc..124f910ac0 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json @@ -256,6 +256,7 @@ "RaffleHeader": "Witaj, członku społeczności ABP!", "RafflesInfo": "
To jest strona loterii, której celem jest wyrażenie naszego uznania dla Ciebie za bycie aktywnym członkiem społeczności. Prowadzimy rozmowy społecznościowe ABP , konferencje ABP .NET , uczestniczymy lub sponsorujemy wydarzenia związane z .NET, podczas których rozdajemy prezenty.

Możesz śledzić tę stronę, aby zobaczyć nadchodzące loterie, wziąć w nich udział lub zobaczyć poprzednie loterie, które losowaliśmy, w tym zwycięzców.

Dziękujemy za bycie aktywnym członkiem! Do zobaczenia w nadchodzących loteriach.", "RafflesInfoTitle": "Loterie społecznościowe ABP", - "MarkdownSupported": "Markdown utrzymany." + "MarkdownSupported": "Markdown utrzymany.", + "Preview": "Zapowiedź" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json index d987c03211..419ef77140 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json @@ -256,6 +256,7 @@ "RaffleHeader": "Olá, membro da comunidade ABP!", "RafflesInfo": "
Esta é a página do sorteio dedicada a mostrar nosso agradecimento por você ser um membro ativo da comunidade. Fazemos ABP Community Talks , ABP .NET Conference , participamos ou patrocinamos eventos relacionados ao .NET nos quais distribuímos alguns presentes.

Você pode seguir esta página para ver os próximos sorteios, participar deles ou ver os sorteios anteriores que sorteamos, incluindo os vencedores.

Obrigado por ser um membro ativo! Nos vemos nos próximos sorteios.", "RafflesInfoTitle": "Sorteios da Comunidade ABP", - "MarkdownSupported": "Markdown suportado." + "MarkdownSupported": "Markdown suportado.", + "Preview": "Visualização" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json index 06ecc4dea8..47e513f125 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json @@ -256,6 +256,7 @@ "RaffleHeader": "Bună ziua, membru al comunității ABP!", "RafflesInfo": "
Aceasta este pagina de tombolă dedicată pentru a arăta aprecierea noastră față de dvs. pentru că sunteți un membru activ al comunității. Facem ABP Community Talks , ABP .NET Conference , participăm sau sponsorizăm evenimentele legate de .NET în care oferim câteva cadouri.

Puteți urmări această pagină pentru a vedea tombolele viitoare, a participa la ele sau pentru a vedea tombolele anterioare pe care le extragem, inclusiv câștigătorii.

Vă mulțumim că sunteți un membru activ! Ne vedem la tombolele viitoare.", "RafflesInfoTitle": "Tombole comunitare ABP", - "MarkdownSupported": "Markdown sprijinit." + "MarkdownSupported": "Markdown sprijinit.", + "Preview": "previzualizare" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json index 07d6a87fe9..b91893ce94 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json @@ -259,6 +259,7 @@ "RaffleHeader": "Привет, участник сообщества ABP!", "RafflesInfo": "
Эта страница розыгрыша посвящена тому, чтобы выразить нашу признательность вам за то, что вы являетесь активным членом сообщества. Обсуждения сообщества ABP ,Конференция ABP .NET, посещать или спонсировать мероприятия, связанные с .NET, на которых мы раздаем подарки.

Вы можете подписаться на эту страницу, чтобы увидеть предстоящие розыгрыши, посетить их или просмотреть предыдущие розыгрыши, которые мы проводим, включая победителей.

Спасибо за активное участие! ", "RafflesInfoTitle": "Сообщество АБП Розыгрыши", - "MarkdownSupported": "Markdown поддерживается." + "MarkdownSupported": "Markdown поддерживается.", + "Preview": "Предварительный просмотр" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json index fa9826b421..25a73a6bd7 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json @@ -256,6 +256,7 @@ "RaffleHeader": "Dobrý deň, člen komunity ABP!", "RafflesInfo": "
Toto je stránka žrebovania venovaná na vyjadrenie nášho uznania vám za to, že ste aktívnym členom komunity. Robíme ABP Community Talks , ABP .NET konferenciu , zúčastňujeme sa alebo sponzorujeme podujatia súvisiace s .NET, na ktorých rozdávame nejaké darčeky.

Na tejto stránke si môžete pozrieť pripravované tomboly, zúčastniť sa ich alebo si pozrieť predchádzajúce žrebovanie, ktoré vyžrebujeme vrátane výhercov.

Ďakujeme, že ste aktívnym členom! Vidíme sa v najbližšom žrebovaní.", "RafflesInfoTitle": "Komunitné tomboly ABP", - "MarkdownSupported": "Markdown podporované." + "MarkdownSupported": "Markdown podporované.", + "Preview": "Náhľad" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json index 81e103cd17..b6192142c6 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json @@ -256,6 +256,7 @@ "RaffleHeader": "Pozdravljeni član skupnosti ABP!", "RafflesInfo": "
To je stran za nagradno igro, namenjena izkazovanju naše hvaležnosti do vas, ker ste aktivni član skupnosti. Izvajamo ABP Community Talks , ABP .NET Conference , se udeležujemo ali sponzoriramo dogodke, povezane z .NET, na katerih podarimo nekaj daril.

To stran lahko spremljate in si ogledate prihajajoče nagradne igre, se jih udeležite ali si ogledate prejšnje nagradne igre, ki smo jih izžrebali, vključno z zmagovalci.

Hvala, ker ste aktivni član! Se vidimo na prihajajočih nagradnih igrah.", "RafflesInfoTitle": "Žrebanje skupnosti ABP", - "MarkdownSupported": "Markdown podprt." + "MarkdownSupported": "Markdown podprt.", + "Preview": "Predogled" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json index d184bb63d1..88c88208e8 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json @@ -190,6 +190,7 @@ "Index_Page_CommunityIntroduction": "Burası ABP Çerçevesi, .NET ve yazılım geliştirme için bir merkezdir. Makaleleri okuyabilir, eğitim videolarını izleyebilir, ABP'nin gelişim süreci ve ABP ile ilgili etkinlikler hakkında bilgi alabilir, diğer geliştiricilere yardımcı olabilir ve uzmanlığınızı ABP topluluğu ile paylaşabilirsiniz.", "IConsentToMedium": "Bu yazının https://medium.com/volosoft adresinde yayınlanmasına izin veriyorum.", "DiscordPageTitle": "ABP Discord Topluluğu", - "MarkdownSupported": "Markdown destekleniyor." + "MarkdownSupported": "Markdown destekleniyor.", + "Preview": "Ön izleme" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json index d7febbb014..e195a80fa5 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json @@ -256,6 +256,7 @@ "RaffleHeader": "Xin chào Thành viên Cộng đồng ABP!", "RafflesInfo": "
Đây là trang xổ số dành riêng để thể hiện sự đánh giá cao của chúng tôi đối với bạn vì đã trở thành Thành viên cộng đồng tích cực. Chúng tôi tổ chức các buổi nói chuyện cộng đồng ABP , Hội nghị ABP .NET , tham dự hoặc tài trợ cho các sự kiện liên quan đến .NET mà trong đó chúng tôi tặng một số quà tặng.

Bạn có thể theo dõi trang này để xem các cuộc xổ số sắp tới, tham dự hoặc xem các cuộc xổ số trước đây mà chúng tôi rút ra bao gồm cả những người chiến thắng.

Cảm ơn bạn đã là thành viên tích cực! Hẹn gặp lại các bạn trong đợt xổ số sắp tới.", "RafflesInfoTitle": "Xổ số cộng đồng ABP", - "MarkdownSupported": "Markdown được hỗ trợ." + "MarkdownSupported": "Markdown được hỗ trợ.", + "Preview": "Xem trước" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json index c0aaf2678b..fd1130b894 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json @@ -256,6 +256,7 @@ "RaffleHeader": "你好,ABP 社区成员!", "RafflesInfo": "
这是一个抽奖页面,旨在感谢您成为活跃的社区成员。我们举办 ABP 社区讲座 、ABP .NET 会议,参加或赞助与 .NET 相关的活动,并在活动中赠送一些礼品。

您可以关注此页面,查看即将举行的抽奖活动、参加这些活动或查看我们以前举行的抽奖活动(包括获奖者)。

感谢您成为我们的活跃成员!在即将举行的抽奖活动中再见。", "RafflesInfoTitle": "ABP 社区来抽奖Markdown 支持的。" + "MarkdownSupported": "Markdown 支持的。", + "Preview": "预览" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json index 7f8e58f7df..e5725ce996 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json @@ -256,6 +256,7 @@ "RaffleHeader": "ABP 社群成員您好!", "RafflesInfo": "
這是抽獎頁面,旨在表達我們對您作為活躍社區成員的感謝。我們舉辦ABP 社群講座、ABP .NET 會議、參加或贊助 .NET 相關活動,並在活動中贈送一些禮物。

您可以關注此頁面查看即將舉行的抽獎活動、參加抽獎活動或查看我們之前抽獎的抽獎活動(包括獲獎者)。

感謝您成為活躍會員!在即將到來的抽獎活動中再見。", "RafflesInfoTitle": "ABP 社區萊佛士", - "MarkdownSupported": "Markdown 支持的。" + "MarkdownSupported": "Markdown 支持的。", + "Preview": "预览" } } \ No newline at end of file From ed266b79bf9317bb6e7527256e811a9a17fcc65e Mon Sep 17 00:00:00 2001 From: Salih Date: Fri, 26 Jan 2024 18:33:33 +0300 Subject: [PATCH 56/58] Fix: tooltip seems broken --- modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js index f23100d34a..fef573f413 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js @@ -283,7 +283,7 @@ initDocumentNodeBreadcrumb(); Element.prototype.querySelector = function (selector) { - var result = $(decodeURI(selector)); + var result = $(this).find(decodeURI(selector)); if(result.length > 0){ return result[0]; } From dc803c72fb3c256844b09d44c7fba046d597c5b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Fri, 26 Jan 2024 18:44:20 +0300 Subject: [PATCH 57/58] datatable filtering issue --- npm/ng-packs/packages/core/src/lib/services/list.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/list.service.ts b/npm/ng-packs/packages/core/src/lib/services/list.service.ts index 76dac87b5a..48996bade1 100644 --- a/npm/ng-packs/packages/core/src/lib/services/list.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/list.service.ts @@ -52,7 +52,7 @@ export class ListService implements return this._page; } - private _totalCount = 0 + private _totalCount = 0; set totalCount(value: number) { if (value === this._totalCount) return; @@ -150,7 +150,7 @@ export class ListService implements this._query$.next({ filter: this._filter || undefined, maxResultCount: this._maxResultCount, - skipCount: this._page * this._maxResultCount, + skipCount: this._filter ? 0 : this._page * this._maxResultCount, sorting: this._sortOrder ? `${this._sortKey} ${this._sortOrder}` : undefined, } as any as QueryParamsType); } From 8d9e3e09f8046ab71114103a67e7d9669e4bc717 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 29 Jan 2024 09:37:42 +0800 Subject: [PATCH 58/58] Improve --- .../PermissionValueProviderManager.cs | 17 ++++++++--------- .../Abp/Features/FeatureValueProviderManager.cs | 17 ++++++++--------- .../Abp/Settings/SettingValueProviderManager.cs | 17 ++++++++--------- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs index 09b2da2acb..aebd14f36e 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs @@ -9,29 +9,28 @@ namespace Volo.Abp.Authorization.Permissions; public class PermissionValueProviderManager : IPermissionValueProviderManager, ISingletonDependency { - public IReadOnlyList ValueProviders => GetProviders(); + public IReadOnlyList ValueProviders => _lazyProviders.Value; private readonly Lazy> _lazyProviders; protected AbpPermissionOptions Options { get; } + protected IServiceProvider ServiceProvider { get; } public PermissionValueProviderManager( IServiceProvider serviceProvider, IOptions options) { Options = options.Value; + ServiceProvider = serviceProvider; - _lazyProviders = new Lazy>( - () => Options - .ValueProviders - .Select(c => serviceProvider.GetRequiredService(c) as IPermissionValueProvider) - .ToList()!, - true - ); + _lazyProviders = new Lazy>(GetProviders, true); } protected virtual List GetProviders() { - var providers = _lazyProviders.Value; + var providers = Options + .ValueProviders + .Select(type => (ServiceProvider.GetRequiredService(type) as IPermissionValueProvider)!) + .ToList(); var multipleProviders = providers.GroupBy(p => p.Name).FirstOrDefault(x => x.Count() > 1); if(multipleProviders != null) diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureValueProviderManager.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureValueProviderManager.cs index 98d73dd4e4..c793ee8ce5 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureValueProviderManager.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureValueProviderManager.cs @@ -9,29 +9,28 @@ namespace Volo.Abp.Features; public class FeatureValueProviderManager : IFeatureValueProviderManager, ISingletonDependency { - public IReadOnlyList ValueProviders => GetProviders(); + public IReadOnlyList ValueProviders => _lazyProviders.Value; private readonly Lazy> _lazyProviders; protected AbpFeatureOptions Options { get; } + protected IServiceProvider ServiceProvider { get; } public FeatureValueProviderManager( IServiceProvider serviceProvider, IOptions options) { Options = options.Value; + ServiceProvider = serviceProvider; - _lazyProviders = new Lazy>( - () => Options - .ValueProviders - .Select(c => serviceProvider.GetRequiredService(c) as IFeatureValueProvider) - .ToList()!, - true - ); + _lazyProviders = new Lazy>(GetProviders, true); } protected virtual List GetProviders() { - var providers = _lazyProviders.Value; + var providers = Options + .ValueProviders + .Select(type => (ServiceProvider.GetRequiredService(type) as IFeatureValueProvider)!) + .ToList(); var multipleProviders = providers.GroupBy(p => p.Name).FirstOrDefault(x => x.Count() > 1); if(multipleProviders != null) diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValueProviderManager.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValueProviderManager.cs index c13f884e98..116fae5643 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValueProviderManager.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValueProviderManager.cs @@ -9,9 +9,10 @@ namespace Volo.Abp.Settings; public class SettingValueProviderManager : ISettingValueProviderManager, ISingletonDependency { - public List Providers => GetProviders(); + public List Providers => _lazyProviders.Value; protected AbpSettingOptions Options { get; } + protected IServiceProvider ServiceProvider { get; } private readonly Lazy> _lazyProviders; public SettingValueProviderManager( @@ -20,19 +21,17 @@ public class SettingValueProviderManager : ISettingValueProviderManager, ISingle { Options = options.Value; + ServiceProvider = serviceProvider; - _lazyProviders = new Lazy>( - () => Options - .ValueProviders - .Select(type => serviceProvider.GetRequiredService(type) as ISettingValueProvider) - .ToList()!, - true - ); + _lazyProviders = new Lazy>(GetProviders, true); } protected virtual List GetProviders() { - var providers = _lazyProviders.Value; + var providers = Options + .ValueProviders + .Select(type => (ServiceProvider.GetRequiredService(type) as ISettingValueProvider)!) + .ToList(); var multipleProviders = providers.GroupBy(p => p.Name).FirstOrDefault(x => x.Count() > 1); if(multipleProviders != null)