diff --git a/.github/workflows/auto-pr.yml b/.github/workflows/auto-pr.yml
index 1a7b797ef8..083ccc554c 100644
--- a/.github/workflows/auto-pr.yml
+++ b/.github/workflows/auto-pr.yml
@@ -1,4 +1,4 @@
-name: Merge branch dev with rel-7.0
+name: Merge branch rel-7.1 with rel-7.0
on:
push:
branches:
@@ -7,7 +7,7 @@ permissions:
contents: read
jobs:
- merge-dev-with-rel-6-0:
+ merge-rel-7-1-with-rel-7-0:
permissions:
contents: write # for peter-evans/create-pull-request to create branch
pull-requests: write # for peter-evans/create-pull-request to create a PR
@@ -15,7 +15,7 @@ jobs:
steps:
- uses: actions/checkout@v2
with:
- ref: dev
+ ref: rel-7.1
- name: Reset promotion branch
run: |
git fetch origin rel-7.0:rel-7.0
@@ -24,7 +24,7 @@ jobs:
uses: peter-evans/create-pull-request@v3
with:
branch: auto-merge/rel-7-0/${{github.run_number}}
- title: Merge branch dev with rel-7.0
- body: This PR generated automatically to merge dev with rel-7.0. Please review the changed files before merging to prevent any errors that may occur.
+ title: Merge branch rel-7.1 with rel-7.0
+ body: This PR generated automatically to merge rel-7.1 with rel-7.0. Please review the changed files before merging to prevent any errors that may occur.
reviewers: ${{github.actor}}
token: ${{ github.token }}
diff --git a/docs/en/Themes/LeptonXLite/Angular.md b/docs/en/Themes/LeptonXLite/Angular.md
index 7ebb649aca..56b003e606 100644
--- a/docs/en/Themes/LeptonXLite/Angular.md
+++ b/docs/en/Themes/LeptonXLite/Angular.md
@@ -14,11 +14,15 @@ To add `LeptonX-lite` into your project,
- Install `@abp/ng.theme.lepton-x`
-`yarn add @abp/ng.theme.lepton-x@preview`
+```bash
+yarn add @abp/ng.theme.lepton-x
+```
- Install `bootstrap-icons`
-`yarn add bootstrap-icons`
+```bash
+yarn add bootstrap-icons
+```
- Then, we need to edit the styles array in `angular.json` to replace the existing style with the new one in the following link :
diff --git a/docs/en/Tutorials/Todo/Single-Layer/Index.md b/docs/en/Tutorials/Todo/Single-Layer/Index.md
index bc7fbb9a05..6b772f7f6a 100644
--- a/docs/en/Tutorials/Todo/Single-Layer/Index.md
+++ b/docs/en/Tutorials/Todo/Single-Layer/Index.md
@@ -14,6 +14,33 @@ This is a single-part quick-start tutorial to build a simple todo application wi
You can find the source code of the completed application [here](https://github.com/abpframework/abp-samples/tree/master/TodoApp-SingleLayer).
+This documentation has a video tutorial on **YouTube**!! You can watch it here:
+{{if UI=="MVC" && DB =="EF"}}
+
+
+
+{{else if UI=="BlazorServer" && DB=="EF"}}
+
+
+
+{{else if UI=="NG" && DB=="EF"}}
+
+
+
+{{else if UI=="MVC" && DB=="Mongo"}}
+
+
+
+{{else if UI=="BlazorServer" && DB=="Mongo"}}
+
+
+
+{{else if UI=="NG" && DB=="Mongo"}}
+
+
+
+{{end}}
+
## Pre-Requirements
* An IDE (e.g. [Visual Studio](https://visualstudio.microsoft.com/vs/)) that supports [.NET 7.0+](https://dotnet.microsoft.com/download/dotnet) development.
diff --git a/docs/en/UI/Angular/HTTP-Requests.md b/docs/en/UI/Angular/HTTP-Requests.md
index 57a058ef36..a0e53df9c9 100644
--- a/docs/en/UI/Angular/HTTP-Requests.md
+++ b/docs/en/UI/Angular/HTTP-Requests.md
@@ -298,3 +298,15 @@ export function handleHttpErrors(injector: Injector, httpError: HttpErrorRespons
return throwError(httpError)
}
```
+
+
+### How to Skip HTTP interceptors and ABP headers
+
+The ABP Framework adds several HTTP headers to the HttpClient, such as the "Auth token" or "tenant Id".
+The ABP Server must possess the information but the ABP user may not want to send this informations to an external server.
+ExternalHttpClient and IS EXTERNAL REQUEST HttpContext Token were added in V6.0.4.
+The ABP Http interceptors check the value of the `IS_EXTERNAL_REQUEST` token. If the token is True then ABP-specific headers won't be added to Http Request.
+The `ExternalHttpClient` extends from `HTTPClient` and sets the `IS_EXTERNAL_REQUEST` context token to true.
+When you are using `ExternalHttpClient` as HttpClient in your components, it does not add ABP-specific headers.
+
+Note: With `IS_EXTERNAL_REQUEST` or without it, ABP loading service works.
diff --git a/docs/en/UI/Angular/Modal.md b/docs/en/UI/Angular/Modal.md
index 144f38e842..903e98f1fd 100644
--- a/docs/en/UI/Angular/Modal.md
+++ b/docs/en/UI/Angular/Modal.md
@@ -57,7 +57,7 @@ You can add the `abp-modal` to your component very quickly. See an example:
@Component(/* component metadata */)
export class SampleComponent {
- isModelOpen = false
+ isModalOpen = false
}
```
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/ApplicationConfigurationChangedService.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/ApplicationConfigurationChangedService.cs
new file mode 100644
index 0000000000..9803a7991d
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/ApplicationConfigurationChangedService.cs
@@ -0,0 +1,15 @@
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.AspNetCore.Components.Web.Security;
+
+public delegate void ApplicationConfigurationChangedHandler();
+
+public class ApplicationConfigurationChangedService : IScopedDependency
+{
+ public event ApplicationConfigurationChangedHandler Changed;
+
+ public void NotifyChanged()
+ {
+ Changed?.Invoke();
+ }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs
index c3ba260a88..79a2dacd9a 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs
@@ -1,4 +1,6 @@
using System.Threading.Tasks;
+using Microsoft.AspNetCore.Components.Authorization;
+using Volo.Abp.AspNetCore.Components.Web.Security;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClientProxies;
using Volo.Abp.AspNetCore.Mvc.Client;
@@ -10,23 +12,31 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly;
public class WebAssemblyCachedApplicationConfigurationClient : ICachedApplicationConfigurationClient, ITransientDependency
{
protected AbpApplicationConfigurationClientProxy ApplicationConfigurationClientProxy { get; }
-
+
protected AbpApplicationLocalizationClientProxy ApplicationLocalizationClientProxy { get; }
protected ApplicationConfigurationCache Cache { get; }
protected ICurrentTenantAccessor CurrentTenantAccessor { get; }
+ protected ApplicationConfigurationChangedService ApplicationConfigurationChangedService { get; }
+
+ protected AuthenticationStateProvider AuthenticationStateProvider { get; }
+
public WebAssemblyCachedApplicationConfigurationClient(
AbpApplicationConfigurationClientProxy applicationConfigurationClientProxy,
ApplicationConfigurationCache cache,
- ICurrentTenantAccessor currentTenantAccessor,
- AbpApplicationLocalizationClientProxy applicationLocalizationClientProxy)
+ ICurrentTenantAccessor currentTenantAccessor,
+ AbpApplicationLocalizationClientProxy applicationLocalizationClientProxy,
+ ApplicationConfigurationChangedService applicationConfigurationChangedService,
+ AuthenticationStateProvider authenticationStateProvider)
{
ApplicationConfigurationClientProxy = applicationConfigurationClientProxy;
Cache = cache;
CurrentTenantAccessor = currentTenantAccessor;
ApplicationLocalizationClientProxy = applicationLocalizationClientProxy;
+ ApplicationConfigurationChangedService = applicationConfigurationChangedService;
+ AuthenticationStateProvider = authenticationStateProvider;
}
public virtual async Task InitializeAsync()
@@ -45,9 +55,11 @@ public class WebAssemblyCachedApplicationConfigurationClient : ICachedApplicatio
);
configurationDto.Localization.Resources = localizationDto.Resources;
-
+
Cache.Set(configurationDto);
+ ApplicationConfigurationChangedService.NotifyChanged();
+
CurrentTenantAccessor.Current = new BasicTenantInfo(
configurationDto.CurrentTenant.Id,
configurationDto.CurrentTenant.Name
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs
index 9777265abd..4fc5a04859 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs
@@ -20,6 +20,8 @@ public static class MvcCoreBuilderExtensions
options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory());
options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter());
+ options.JsonSerializerOptions.Converters.Add(new AbpStringToGuidConverter());
+ options.JsonSerializerOptions.Converters.Add(new AbpNullableStringToGuidConverter());
options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter());
options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(serviceProvider
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs
index c8d3aeb75b..4adffb6745 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs
@@ -267,11 +267,19 @@ public class AngularSourceCodeAdder : ITransientDependency
var fileContent = File.ReadAllText(filePath);
- fileContent = "import { "+moduleName.Split(".").Last()+"Module } from '@"+moduleName.Split(".").Last().ToKebabCase()+"/config';" + Environment.NewLine + fileContent;
+ var moduleNameAsConfigPath = moduleName.ToKebabCase();
+
+ if (moduleName.Contains("."))
+ {
+ var moduleNameSplited = moduleName.Split(".");
+ moduleNameAsConfigPath = moduleNameSplited.Take(moduleNameSplited.Length-1).JoinAsString(".").ToKebabCase() + "/" + moduleNameSplited.Last().ToKebabCase();
+ }
+
+ fileContent = "import { "+moduleName.Split(".").Last()+"ConfigModule } from '@"+moduleNameAsConfigPath+"/config';" + Environment.NewLine + fileContent;
fileContent = Regex.Replace(fileContent, "imports\\s*:\\s*\\[",
"imports: ["+ Environment.NewLine +
- " " + moduleName.Split(".").Last() + "Module.forRoot(),");
+ " " + moduleName.Split(".").Last() + "ConfigModule.forRoot(),");
File.WriteAllText(filePath, fileContent);
}
diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Domain/Entities/EntityNotFoundException.cs b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Domain/Entities/EntityNotFoundException.cs
index d5a143d736..1feb8c4cbb 100644
--- a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Domain/Entities/EntityNotFoundException.cs
+++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Domain/Entities/EntityNotFoundException.cs
@@ -3,7 +3,7 @@
namespace Volo.Abp.Domain.Entities;
///
-/// This exception is thrown if an entity excepted to be found but not found.
+/// This exception is thrown if an entity is expected to be found but not found.
///
public class EntityNotFoundException : AbpException
{
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs
index 50dd47d9e2..f6ef46a4e7 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs
@@ -22,6 +22,8 @@ public class AbpJsonSystemTextJsonModule : AbpModule
options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory());
options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter());
+ options.JsonSerializerOptions.Converters.Add(new AbpStringToGuidConverter());
+ options.JsonSerializerOptions.Converters.Add(new AbpNullableStringToGuidConverter());
options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter());
options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(serviceProvider
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableStringToGuidConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableStringToGuidConverter.cs
new file mode 100644
index 0000000000..c80e5aa9a5
--- /dev/null
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableStringToGuidConverter.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Volo.Abp.Json.SystemTextJson.JsonConverters;
+
+public class AbpNullableStringToGuidConverter : JsonConverter
+{
+ private JsonSerializerOptions _writeJsonSerializerOptions;
+
+ public override Guid? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ if (reader.TokenType == JsonTokenType.String)
+ {
+ var guidString = reader.GetString();
+ string[] formats = { "N", "D", "B", "P", "X" };
+ foreach (var format in formats)
+ {
+ if (Guid.TryParseExact(guidString, format, out var guid))
+ {
+ return guid;
+ }
+ }
+ }
+
+ if (reader.TryGetGuid(out var guid2))
+ {
+ return guid2;
+ }
+
+ return null;
+ }
+
+ public override void Write(Utf8JsonWriter writer, Guid? value, JsonSerializerOptions options)
+ {
+ _writeJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this);
+ var entityConverter = (JsonConverter)_writeJsonSerializerOptions.GetConverter(typeof(Guid?));
+
+ entityConverter.Write(writer, value, _writeJsonSerializerOptions);
+ }
+}
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToGuidConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToGuidConverter.cs
new file mode 100644
index 0000000000..586e4462cf
--- /dev/null
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToGuidConverter.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Volo.Abp.Json.SystemTextJson.JsonConverters;
+
+public class AbpStringToGuidConverter : JsonConverter
+{
+ private JsonSerializerOptions _writeJsonSerializerOptions;
+
+ public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ if (reader.TokenType == JsonTokenType.String)
+ {
+ var guidString = reader.GetString();
+ string[] formats = { "N", "D", "B", "P", "X" };
+ foreach (var format in formats)
+ {
+ if (Guid.TryParseExact(guidString, format, out var guid))
+ {
+ return guid;
+ }
+ }
+ }
+
+ return reader.GetGuid();
+ }
+
+ public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options)
+ {
+ _writeJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this);
+ var entityConverter = (JsonConverter)_writeJsonSerializerOptions.GetConverter(typeof(Guid));
+
+ entityConverter.Write(writer, value, _writeJsonSerializerOptions);
+ }
+}
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs
index e667f7880d..2de527866b 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs
@@ -11,7 +11,7 @@ public static class ExtensibleObjectMapper
///
/// Copies extra properties from the object
/// to the object.
- ///
+ ///
/// Checks property definitions (over the )
/// based on the preference.
///
@@ -34,14 +34,29 @@ public static class ExtensibleObjectMapper
Check.NotNull(source, nameof(source));
Check.NotNull(destination, nameof(destination));
- ExtensibleObjectMapper.MapExtraPropertiesTo(
- typeof(TSource),
- typeof(TDestination),
- source.ExtraProperties,
- destination.ExtraProperties,
- definitionChecks,
- ignoredProperties
- );
+ var sourceType = typeof(TSource);
+ var destinationType = typeof(TDestination);
+
+ Check.AssignableTo(sourceType, nameof(sourceType));
+ Check.AssignableTo(destinationType, nameof(destinationType));
+ Check.NotNull(source.ExtraProperties, nameof(source.ExtraProperties));
+ Check.NotNull(destination.ExtraProperties, nameof(destination.ExtraProperties));
+
+ var sourceObjectExtension = ObjectExtensionManager.Instance.GetOrNull(sourceType);
+ var destinationObjectExtension = ObjectExtensionManager.Instance.GetOrNull(destinationType);
+
+ foreach (var keyValue in source.ExtraProperties)
+ {
+ if (CanMapProperty(
+ keyValue.Key,
+ sourceObjectExtension,
+ destinationObjectExtension,
+ definitionChecks,
+ ignoredProperties))
+ {
+ destination.SetProperty(keyValue.Key, keyValue.Value);
+ }
+ }
}
///
@@ -80,7 +95,7 @@ public static class ExtensibleObjectMapper
///
/// Copies extra properties from the object
/// to the object.
- ///
+ ///
/// Checks property definitions (over the )
/// based on the preference.
///
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController.cs
index 471d33261a..6dfe3a7281 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController.cs
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController.cs
@@ -49,6 +49,12 @@ public class ModelBindingController : AbpController
input.Time3.Value.Kind.ToString().ToLower() + "_" +
input.InnerModel.Time4.Kind.ToString().ToLower();
}
+
+ [HttpPost("Guid_Json_Test")]
+ public GuidJsonModel Guid_Json_Test([FromBody] GuidJsonModel input)
+ {
+ return input;
+ }
}
public class GetDateTimeKindModel
@@ -68,3 +74,20 @@ public class GetDateTimeKindModel
public DateTime Time4 { get; set; }
}
}
+
+public class GuidJsonModel
+{
+ public Guid UserId { get; set; }
+
+ public Guid UserId2 { get; set; }
+
+ public Guid UserId3 { get; set; }
+
+ public Guid UserId4 { get; set; }
+
+ public Guid UserId5 { get; set; }
+
+ public Guid? TenantId { get; set; }
+
+ public Guid? TenantId2 { get; set; }
+}
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs
index befbd169fa..53bfff8b68 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs
@@ -106,6 +106,18 @@ public abstract class ModelBindingController_Tests : AspNetCoreMvcTestBase
var resultAsString = await response.Content.ReadAsStringAsync();
resultAsString.ShouldBe($"local_{Kind.ToString().ToLower()}_{Kind.ToString().ToLower()}_local");
}
+
+ [Fact]
+ public async Task Guid_Json_Test()
+ {
+ var guid = Guid.NewGuid();
+ var json = $"{{\"UserId\":\"{guid:B}\",\"UserId2\":\"{guid:N}\",\"UserId3\":\"{guid:D}\",\"UserId4\":\"{guid:P}\",\"UserId5\":\"{guid:x}\",\"TenantId\":null,\"TenantId2\":\"\"}}";
+ var response = await Client.PostAsync("/api/model-Binding-test/Guid_Json_Test", new StringContent(json, Encoding.UTF8, MimeTypes.Application.Json));
+
+ response.StatusCode.ShouldBe(HttpStatusCode.OK);
+ var resultAsString = await response.Content.ReadAsStringAsync();
+ resultAsString.ShouldBe($"{{\"userId\":\"{guid:D}\",\"userId2\":\"{guid:D}\",\"userId3\":\"{guid:D}\",\"userId4\":\"{guid:D}\",\"userId5\":\"{guid:D}\",\"tenantId\":null,\"tenantId2\":null}}");
+ }
}
public class ModelBindingController_Utc_Tests : ModelBindingController_Tests
diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpStringToGuid_Tests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpStringToGuid_Tests.cs
new file mode 100644
index 0000000000..93918b48c1
--- /dev/null
+++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpStringToGuid_Tests.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Text.Json;
+using Shouldly;
+using Volo.Abp.Json.SystemTextJson.JsonConverters;
+using Xunit;
+
+namespace Volo.Abp.Json;
+
+public class AbpStringToGuid_Tests
+{
+ [Fact]
+ public void Test_Read()
+ {
+ var options = new JsonSerializerOptions()
+ {
+ Converters =
+ {
+ new AbpStringToGuidConverter(),
+ new AbpNullableStringToGuidConverter()
+ }
+ };
+
+ var guid = Guid.Parse("762DDB84-5225-4853-A566-FF0B3AF57585");
+ var testClass = JsonSerializer.Deserialize("{" +
+ $"\"Id\": \"{guid:N}\", " +
+ $"\"NullableId\": \"{guid:D}\", " +
+ $"\"NullableId2\": \"{guid:B}\", " +
+ $"\"NullableId3\": \"{guid:P}\", " +
+ $"\"NullableId4\": \"{guid:X}\", " +
+ "\"NullableId5\": \"\", " +
+ "\"NullableId6\": null}", options);
+ testClass.ShouldNotBeNull();
+ testClass.Id.ShouldBe(guid);
+ testClass.NullableId.ShouldBe(guid);
+ testClass.NullableId2.ShouldBe(guid);
+ testClass.NullableId3.ShouldBe(guid);
+ testClass.NullableId4.ShouldBe(guid);
+ testClass.NullableId5.ShouldBeNull();
+ testClass.NullableId6.ShouldBeNull();
+ }
+
+ [Fact]
+ public void Test_Write()
+ {
+ var options = new JsonSerializerOptions()
+ {
+ Converters =
+ {
+ new AbpStringToGuidConverter(),
+ new AbpNullableStringToGuidConverter()
+ }
+ };
+
+ var guid = Guid.Parse("762DDB84-5225-4853-A566-FF0B3AF57585");
+ var json = JsonSerializer.Serialize(new TestClass()
+ {
+ Id = guid,
+ NullableId = null,
+ NullableId2 = guid,
+ NullableId3 = null,
+ NullableId4 = guid,
+ NullableId5 = null,
+ NullableId6 = guid
+ }, options);
+
+ json.ShouldBe($"{{\"Id\":\"{guid:D}\",\"NullableId\":null,\"NullableId2\":\"{guid:D}\",\"NullableId3\":null,\"NullableId4\":\"{guid:D}\",\"NullableId5\":null,\"NullableId6\":\"{guid:D}\"}}");
+ }
+
+ class TestClass
+ {
+ public Guid Id { get; set; }
+
+ public Guid? NullableId { get; set; }
+
+ public Guid? NullableId2 { get; set; }
+
+ public Guid? NullableId3 { get; set; }
+
+ public Guid? NullableId4 { get; set; }
+
+ public Guid? NullableId5 { get; set; }
+
+ public Guid? NullableId6 { get; set; }
+ }
+}
diff --git a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs
index 5bf34515ef..bc31c60ac5 100644
--- a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs
+++ b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs
@@ -1,6 +1,10 @@
-using Shouldly;
+using System.ComponentModel.DataAnnotations;
+using System.Globalization;
+using Shouldly;
using Volo.Abp.Data;
+using Volo.Abp.Localization;
using Volo.Abp.ObjectExtending.TestObjects;
+using Volo.Abp.Validation;
using Xunit;
namespace Volo.Abp.ObjectExtending;
@@ -90,4 +94,29 @@ public class HasExtraPropertiesObjectExtendingExtensions_Tests : AbpObjectExtend
_personDto.GetProperty("Sex").ShouldBe("male");
_personDto.GetProperty("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values
}
+
+ [Fact]
+ public void MapExtraPropertiesTo_Should_Validate_Properties()
+ {
+ using (CultureHelper.Use(CultureInfo.InvariantCulture))
+ {
+ ObjectExtensionManager.Instance
+ .AddOrUpdateProperty(
+ "Name",
+ options =>
+ {
+ options.Attributes.Add(new StringLengthAttribute(4));
+ });
+
+ var person = new ExtensibleTestPerson().SetProperty("Name", "John");
+ var personDto = new ExtensibleTestPersonDto();
+
+ person.MapExtraPropertiesTo(personDto);
+
+ person.SetProperty("Name", "John Bush");
+ Assert.Throws(() => person.MapExtraPropertiesTo(personDto)).ValidationErrors.ShouldContain(x => x.ErrorMessage == "The field Name must be a string with a maximum length of 4.");
+ }
+
+ }
+
}
diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/EntityChange.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/EntityChange.cs
index 05de8f7181..dd12102e4a 100644
--- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/EntityChange.cs
+++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/EntityChange.cs
@@ -46,6 +46,7 @@ public class EntityChange : Entity, IMultiTenant, IHasExtraProperties
TenantId = tenantId;
ChangeTime = entityChangeInfo.ChangeTime;
ChangeType = entityChangeInfo.ChangeType;
+ EntityTenantId = entityChangeInfo.EntityTenantId;
EntityId = entityChangeInfo.EntityId.Truncate(EntityChangeConsts.MaxEntityTypeFullNameLength);
EntityTypeFullName = entityChangeInfo.EntityTypeFullName.TruncateFromBeginning(EntityChangeConsts.MaxEntityTypeFullNameLength);
diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo/Abp/AuditLogging/MultiTenantAuditLog_Tests.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo/Abp/AuditLogging/MultiTenantAuditLog_Tests.cs
index 990b3d75a5..a97969d41c 100644
--- a/modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo/Abp/AuditLogging/MultiTenantAuditLog_Tests.cs
+++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo/Abp/AuditLogging/MultiTenantAuditLog_Tests.cs
@@ -71,5 +71,6 @@ public class MultiTenantAuditLog_Tests : AuditLogsTestBase
auditLog.EntityChanges.Count.ShouldBe(2);
auditLog.EntityChanges.ShouldContain(e => e.EntityId == entityId1.ToString());
auditLog.EntityChanges.ShouldContain(e => e.EntityId == entityId2.ToString());
+ auditLog.EntityChanges.ShouldContain(e => e.EntityTenantId == tenantId);
}
}
diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NavMenu.razor.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NavMenu.razor.cs
index fb117369eb..5b9c07ad44 100644
--- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NavMenu.razor.cs
+++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NavMenu.razor.cs
@@ -1,7 +1,9 @@
using System;
+using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
+using Volo.Abp.AspNetCore.Components.Web.Security;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic;
@@ -12,24 +14,24 @@ public partial class NavMenu : IDisposable
protected IMenuManager MenuManager { get; set; }
[Inject]
- protected AuthenticationStateProvider AuthenticationStateProvider { get; set; }
+ protected ApplicationConfigurationChangedService ApplicationConfigurationChangedService { get; set; }
protected ApplicationMenu Menu { get; set; }
- protected override async Task OnInitializedAsync()
+ protected async override Task OnInitializedAsync()
{
Menu = await MenuManager.GetMainMenuAsync();
- AuthenticationStateProvider.AuthenticationStateChanged += AuthenticationStateProviderOnAuthenticationStateChanged;
+ ApplicationConfigurationChangedService.Changed += ApplicationConfigurationChanged;
}
- public void Dispose()
+ private async void ApplicationConfigurationChanged()
{
- AuthenticationStateProvider.AuthenticationStateChanged -= AuthenticationStateProviderOnAuthenticationStateChanged;
+ Menu = await MenuManager.GetMainMenuAsync();
+ await InvokeAsync(StateHasChanged);
}
- private async void AuthenticationStateProviderOnAuthenticationStateChanged(Task task)
+ public void Dispose()
{
- Menu = await MenuManager.GetMainMenuAsync();
- await InvokeAsync(StateHasChanged);
+ ApplicationConfigurationChangedService.Changed -= ApplicationConfigurationChanged;
}
}
diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NavToolbar.razor.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NavToolbar.razor.cs
index 8e1040ae89..9a0d76afa2 100644
--- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NavToolbar.razor.cs
+++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NavToolbar.razor.cs
@@ -4,6 +4,7 @@ using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
+using Volo.Abp.AspNetCore.Components.Web.Security;
using Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars;
namespace Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic;
@@ -14,14 +15,14 @@ public partial class NavToolbar : IDisposable
private IToolbarManager ToolbarManager { get; set; }
[Inject]
- private AuthenticationStateProvider AuthenticationStateProvider { get; set; }
+ protected ApplicationConfigurationChangedService ApplicationConfigurationChangedService { get; set; }
private List ToolbarItemRenders { get; set; } = new List();
- protected override async Task OnInitializedAsync()
+ protected async override Task OnInitializedAsync()
{
await GetToolbarItemRendersAsync();
- AuthenticationStateProvider.AuthenticationStateChanged += AuthenticationStateProviderOnAuthenticationStateChanged;
+ ApplicationConfigurationChangedService.Changed += ApplicationConfigurationChanged;
}
private async Task GetToolbarItemRendersAsync()
@@ -41,7 +42,7 @@ public partial class NavToolbar : IDisposable
}
}
- private async void AuthenticationStateProviderOnAuthenticationStateChanged(Task task)
+ private async void ApplicationConfigurationChanged()
{
await GetToolbarItemRendersAsync();
await InvokeAsync(StateHasChanged);
@@ -49,6 +50,6 @@ public partial class NavToolbar : IDisposable
public void Dispose()
{
- AuthenticationStateProvider.AuthenticationStateChanged -= AuthenticationStateProviderOnAuthenticationStateChanged;
+ ApplicationConfigurationChangedService.Changed -= ApplicationConfigurationChanged;
}
}
diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Pages/Authentication.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Pages/Authentication.razor
index e237cea555..1b9fe309a2 100644
--- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Pages/Authentication.razor
+++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Pages/Authentication.razor
@@ -1,7 +1,18 @@
@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
-
-
+@using Volo.Abp.AspNetCore.Components.Web.Security
+
+@inject WebAssemblyCachedApplicationConfigurationClient WebAssemblyCachedApplicationConfigurationClient
@code{
[Parameter] public string Action { get; set; }
+
+ private async Task OnLogInSucceeded(RemoteAuthenticationState state)
+ {
+ await WebAssemblyCachedApplicationConfigurationClient.InitializeAsync();
+ }
+
+ private async Task OnLogOutSucceeded(RemoteAuthenticationState state)
+ {
+ await WebAssemblyCachedApplicationConfigurationClient.InitializeAsync();
+ }
}
diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs
index 92577ff937..4312369b2b 100644
--- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs
+++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs
@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.JSInterop;
+using Volo.Abp.AspNetCore.Components.Web.Security;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic;
@@ -16,18 +17,17 @@ public partial class LoginDisplay : IDisposable
protected IMenuManager MenuManager { get; set; }
[Inject]
- public AuthenticationStateProvider AuthenticationStateProvider { get; set; }
+ protected ApplicationConfigurationChangedService ApplicationConfigurationChangedService { get; set; }
protected ApplicationMenu Menu { get; set; }
- protected override async Task OnInitializedAsync()
+ protected async override Task OnInitializedAsync()
{
Menu = await MenuManager.GetAsync(StandardMenus.User);
Navigation.LocationChanged += OnLocationChanged;
- AuthenticationStateProvider.AuthenticationStateChanged +=
- AuthenticationStateProviderOnAuthenticationStateChanged;
+ ApplicationConfigurationChangedService.Changed += ApplicationConfigurationChanged;
}
protected virtual void OnLocationChanged(object sender, LocationChangedEventArgs e)
@@ -35,7 +35,7 @@ public partial class LoginDisplay : IDisposable
InvokeAsync(StateHasChanged);
}
- private async void AuthenticationStateProviderOnAuthenticationStateChanged(Task task)
+ private async void ApplicationConfigurationChanged()
{
Menu = await MenuManager.GetAsync(StandardMenus.User);
await InvokeAsync(StateHasChanged);
@@ -44,8 +44,7 @@ public partial class LoginDisplay : IDisposable
public void Dispose()
{
Navigation.LocationChanged -= OnLocationChanged;
- AuthenticationStateProvider.AuthenticationStateChanged -=
- AuthenticationStateProviderOnAuthenticationStateChanged;
+ ApplicationConfigurationChangedService.Changed -= ApplicationConfigurationChanged;
}
private async Task NavigateToAsync(string uri, string target = null)
diff --git a/npm/ng-packs/apps/dev-app/src/app/app.module.ts b/npm/ng-packs/apps/dev-app/src/app/app.module.ts
index c3a0cd68c5..52ebd38362 100644
--- a/npm/ng-packs/apps/dev-app/src/app/app.module.ts
+++ b/npm/ng-packs/apps/dev-app/src/app/app.module.ts
@@ -14,7 +14,7 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { APP_ROUTE_PROVIDER } from './route.provider';
import { FeatureManagementModule } from '@abp/ng.feature-management';
-// import { AbpOAuthModule } from '@abp/ng.oauth';
+import { AbpOAuthModule } from '@abp/ng.oauth';
@NgModule({
imports: [
@@ -27,7 +27,7 @@ import { FeatureManagementModule } from '@abp/ng.feature-management';
sendNullsAsQueryParam: false,
skipGetAppConfiguration: false,
}),
- // AbpOAuthModule.forRoot(),
+ AbpOAuthModule.forRoot(),
ThemeSharedModule.forRoot(),
AccountConfigModule.forRoot(),
IdentityConfigModule.forRoot(),
diff --git a/npm/ng-packs/packages/core/src/lib/clients/http.client.ts b/npm/ng-packs/packages/core/src/lib/clients/http.client.ts
new file mode 100644
index 0000000000..c6e9017be7
--- /dev/null
+++ b/npm/ng-packs/packages/core/src/lib/clients/http.client.ts
@@ -0,0 +1,30 @@
+import { HttpClient, HttpContext, HttpRequest } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { Observable } from 'rxjs';
+import { IS_EXTERNAL_REQUEST } from '../tokens/http-context.token';
+
+// source : https://github.com/armanozak/demo-angular-server-specific-interceptors
+@Injectable({
+ providedIn: 'root',
+})
+export class ExternalHttpClient extends HttpClient {
+ override request(
+ first: string | HttpRequest,
+ url?: string,
+ options: RequestOptions = {},
+ ): Observable {
+ if (typeof first === 'string') {
+ this.#setPlaceholderContext(options);
+ return super.request(first, url, options);
+ }
+
+ this.#setPlaceholderContext(first);
+ return super.request(first);
+ }
+ #setPlaceholderContext(optionsOrRequest: { context?: HttpContext }) {
+ optionsOrRequest.context ??= new HttpContext();
+ optionsOrRequest.context.set(IS_EXTERNAL_REQUEST, true);
+ }
+}
+
+type RequestOptions = Parameters[2];
diff --git a/npm/ng-packs/packages/core/src/lib/clients/index.ts b/npm/ng-packs/packages/core/src/lib/clients/index.ts
new file mode 100644
index 0000000000..c9aba4d030
--- /dev/null
+++ b/npm/ng-packs/packages/core/src/lib/clients/index.ts
@@ -0,0 +1 @@
+export * from './http.client';
diff --git a/npm/ng-packs/packages/core/src/lib/models/auth.ts b/npm/ng-packs/packages/core/src/lib/models/auth.ts
index 9c0250d316..dcaf6e7f11 100644
--- a/npm/ng-packs/packages/core/src/lib/models/auth.ts
+++ b/npm/ng-packs/packages/core/src/lib/models/auth.ts
@@ -12,6 +12,8 @@ export type PipeToLoginFn = (
params: Pick,
injector: Injector,
) => UnaryFunction;
-
-export type SetTokenResponseToStorageFn = (injector: Injector, tokenRes: T) => void;
+/**
+ * @deprecated The interface should not be used anymore.
+ */
+export type SetTokenResponseToStorageFn = (tokenRes: T) => void;
export type CheckAuthenticationStateFn = (injector: Injector) => void;
diff --git a/npm/ng-packs/packages/core/src/lib/providers/include-localization-resources.provider.ts b/npm/ng-packs/packages/core/src/lib/providers/include-localization-resources.provider.ts
index f530f72cb1..344dced803 100644
--- a/npm/ng-packs/packages/core/src/lib/providers/include-localization-resources.provider.ts
+++ b/npm/ng-packs/packages/core/src/lib/providers/include-localization-resources.provider.ts
@@ -1,8 +1,7 @@
- import { Provider } from "@angular/core";
- import { INCUDE_LOCALIZATION_RESOURCES_TOKEN } from "../tokens/include-localization-resources.token";
+import { Provider } from '@angular/core';
+import { INCUDE_LOCALIZATION_RESOURCES_TOKEN } from '../tokens/include-localization-resources.token';
export const IncludeLocalizationResourcesProvider: Provider = {
- provide: INCUDE_LOCALIZATION_RESOURCES_TOKEN,
- useValue: false,
- };
-
\ No newline at end of file
+ provide: INCUDE_LOCALIZATION_RESOURCES_TOKEN,
+ useValue: false,
+};
diff --git a/npm/ng-packs/packages/core/src/lib/providers/index.ts b/npm/ng-packs/packages/core/src/lib/providers/index.ts
index 8a9f61bda5..4ae2d22a1a 100644
--- a/npm/ng-packs/packages/core/src/lib/providers/index.ts
+++ b/npm/ng-packs/packages/core/src/lib/providers/index.ts
@@ -1,3 +1,3 @@
export * from './cookie-language.provider';
export * from './locale.provider';
-export * from './include-localization-resources.provider';
\ No newline at end of file
+export * from './include-localization-resources.provider';
diff --git a/npm/ng-packs/packages/core/src/lib/tests/application-localization.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/application-localization.service.spec.ts
new file mode 100644
index 0000000000..4e81b39f59
--- /dev/null
+++ b/npm/ng-packs/packages/core/src/lib/tests/application-localization.service.spec.ts
@@ -0,0 +1,17 @@
+export const APPLICATION_LOCALIZATION_DATA = {
+ resources: {
+ Default: { texts: {}, baseResources: [] },
+ MyProjectName: {
+ texts: {
+ "'{0}' and '{1}' do not match.": "'{0}' and '{1}' do not match.",
+ },
+ baseResources: [],
+ },
+ AbpIdentity: {
+ texts: {
+ Identity: 'identity',
+ },
+ baseResources: [],
+ },
+ },
+};
diff --git a/npm/ng-packs/packages/core/src/lib/tests/config-state.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/config-state.service.spec.ts
index 3dc1b45732..58040e8652 100644
--- a/npm/ng-packs/packages/core/src/lib/tests/config-state.service.spec.ts
+++ b/npm/ng-packs/packages/core/src/lib/tests/config-state.service.spec.ts
@@ -8,6 +8,9 @@ import {
} from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/models';
import { ConfigStateService } from '../services';
import { CORE_OPTIONS } from '../tokens';
+import { IncludeLocalizationResourcesProvider } from '../providers';
+import { APPLICATION_LOCALIZATION_DATA } from './application-localization.service.spec';
+import { AbpApplicationLocalizationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service';
export const CONFIG_STATE_DATA = {
environment: {
@@ -34,14 +37,7 @@ export const CONFIG_STATE_DATA = {
layouts: [null, null, null],
},
localization: {
- values: {
- MyProjectName: {
- "'{0}' and '{1}' do not match.": "'{0}' and '{1}' do not match.",
- },
- AbpIdentity: {
- Identity: 'identity',
- },
- },
+ values: {},
languages: [
{
cultureName: 'cs',
@@ -115,6 +111,11 @@ describe('ConfigStateService', () => {
provide: AbpApplicationConfigurationService,
useValue: { get: () => of(CONFIG_STATE_DATA) },
},
+ {
+ provide: AbpApplicationLocalizationService,
+ useValue: { get: () => APPLICATION_LOCALIZATION_DATA },
+ },
+ IncludeLocalizationResourcesProvider,
],
});
diff --git a/npm/ng-packs/packages/core/src/lib/tests/date-utils.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/date-utils.spec.ts
index 20ef2e4a48..33f02dfb4f 100644
--- a/npm/ng-packs/packages/core/src/lib/tests/date-utils.spec.ts
+++ b/npm/ng-packs/packages/core/src/lib/tests/date-utils.spec.ts
@@ -15,7 +15,7 @@ describe('Date Utils', () => {
let config: ConfigStateService;
beforeEach(() => {
- config = new ConfigStateService(null);
+ config = new ConfigStateService(null, null, null);
});
describe('#getShortDateFormat', () => {
diff --git a/npm/ng-packs/packages/core/src/lib/tests/localization-utils.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/localization-utils.spec.ts
index c12b7b61ce..4af0755d6c 100644
--- a/npm/ng-packs/packages/core/src/lib/tests/localization-utils.spec.ts
+++ b/npm/ng-packs/packages/core/src/lib/tests/localization-utils.spec.ts
@@ -57,6 +57,7 @@ describe('Localization Utils', () => {
languages: [],
languageFilesMap: null,
languagesMap: null,
+ resources: {},
});
test.each`
@@ -100,6 +101,7 @@ describe('Localization Utils', () => {
languages: [],
languageFilesMap: null,
languagesMap: null,
+ resources: {},
});
test.each`
@@ -148,6 +150,7 @@ describe('Localization Utils', () => {
languages: [],
languageFilesMap: null,
languagesMap: null,
+ resources: {},
});
test.each`
diff --git a/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts
index 5aedd28f6e..d2eb653a85 100644
--- a/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts
+++ b/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts
@@ -8,8 +8,12 @@ import { SessionStateService } from '../services/session-state.service';
import { LocalizationService } from '../services/localization.service';
import { CORE_OPTIONS } from '../tokens/options.token';
import { CONFIG_STATE_DATA } from './config-state.service.spec';
+import { AbpApplicationLocalizationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service';
+import { APPLICATION_LOCALIZATION_DATA } from './application-localization.service.spec';
+import { IncludeLocalizationResourcesProvider } from '../providers';
const appConfigData$ = new BehaviorSubject(CONFIG_STATE_DATA);
+const appLocalizationData$ = new BehaviorSubject(APPLICATION_LOCALIZATION_DATA);
describe('LocalizationService', () => {
let spectator: SpectatorService;
@@ -22,6 +26,7 @@ describe('LocalizationService', () => {
entryComponents: [],
mocks: [Router],
providers: [
+ IncludeLocalizationResourcesProvider,
{
provide: CORE_OPTIONS,
useValue: { registerLocaleFn: () => Promise.resolve(), cultureNameLocaleFileMap: {} },
@@ -30,6 +35,10 @@ describe('LocalizationService', () => {
provide: AbpApplicationConfigurationService,
useValue: { get: () => appConfigData$ },
},
+ {
+ provide: AbpApplicationLocalizationService,
+ useValue: { get: () => appLocalizationData$ },
+ },
],
});
diff --git a/npm/ng-packs/packages/core/src/lib/tests/permission.guard.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/permission.guard.spec.ts
index 4369b8434f..372f3434f3 100644
--- a/npm/ng-packs/packages/core/src/lib/tests/permission.guard.spec.ts
+++ b/npm/ng-packs/packages/core/src/lib/tests/permission.guard.spec.ts
@@ -9,6 +9,7 @@ import { HttpErrorReporterService } from '../services/http-error-reporter.servic
import { PermissionService } from '../services/permission.service';
import { RoutesService } from '../services/routes.service';
import { CORE_OPTIONS } from '../tokens/options.token';
+import { IncludeLocalizationResourcesProvider } from '../providers';
describe('PermissionGuard', () => {
let spectator: SpectatorService;
@@ -36,7 +37,7 @@ describe('PermissionGuard', () => {
},
},
],
- { relativeLinkResolution: 'legacy' },
+ {},
),
],
providers: [
@@ -45,6 +46,7 @@ describe('PermissionGuard', () => {
useValue: '/',
},
{ provide: CORE_OPTIONS, useValue: { skipGetAppConfiguration: true } },
+ IncludeLocalizationResourcesProvider,
],
});
diff --git a/npm/ng-packs/packages/core/src/lib/tokens/http-context.token.ts b/npm/ng-packs/packages/core/src/lib/tokens/http-context.token.ts
new file mode 100644
index 0000000000..e935232b08
--- /dev/null
+++ b/npm/ng-packs/packages/core/src/lib/tokens/http-context.token.ts
@@ -0,0 +1,3 @@
+import { HttpContextToken } from '@angular/common/http';
+
+export const IS_EXTERNAL_REQUEST = new HttpContextToken(() => false);
diff --git a/npm/ng-packs/packages/core/src/lib/tokens/include-localization-resources.token.ts b/npm/ng-packs/packages/core/src/lib/tokens/include-localization-resources.token.ts
index ac805a8ee8..4c5495ad12 100644
--- a/npm/ng-packs/packages/core/src/lib/tokens/include-localization-resources.token.ts
+++ b/npm/ng-packs/packages/core/src/lib/tokens/include-localization-resources.token.ts
@@ -1,3 +1,5 @@
-import { InjectionToken } from "@angular/core";
+import { InjectionToken } from '@angular/core';
-export const INCUDE_LOCALIZATION_RESOURCES_TOKEN = new InjectionToken('INCUDE_LOCALIZATION_RESOURCES_TOKEN');
+export const INCUDE_LOCALIZATION_RESOURCES_TOKEN = new InjectionToken(
+ 'INCUDE_LOCALIZATION_RESOURCES_TOKEN',
+);
diff --git a/npm/ng-packs/packages/core/src/lib/tokens/index.ts b/npm/ng-packs/packages/core/src/lib/tokens/index.ts
index b9d724f9f6..f0e724259a 100644
--- a/npm/ng-packs/packages/core/src/lib/tokens/index.ts
+++ b/npm/ng-packs/packages/core/src/lib/tokens/index.ts
@@ -11,3 +11,4 @@ export * from './include-localization-resources.token';
export * from './pipe-to-login.token';
export * from './set-token-response-to-storage.token';
export * from './check-authentication-state';
+export * from './http-context.token';
diff --git a/npm/ng-packs/packages/core/src/lib/tokens/set-token-response-to-storage.token.ts b/npm/ng-packs/packages/core/src/lib/tokens/set-token-response-to-storage.token.ts
index 0436195654..0cd26708bf 100644
--- a/npm/ng-packs/packages/core/src/lib/tokens/set-token-response-to-storage.token.ts
+++ b/npm/ng-packs/packages/core/src/lib/tokens/set-token-response-to-storage.token.ts
@@ -1,6 +1,9 @@
import { InjectionToken } from '@angular/core';
import { SetTokenResponseToStorageFn } from '../models';
+/**
+ * @deprecated The token should not be used anymore.
+ */
export const SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY = new InjectionToken(
'SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY',
);
diff --git a/npm/ng-packs/packages/core/src/public-api.ts b/npm/ng-packs/packages/core/src/public-api.ts
index da5fccd8c0..c7b56ac41c 100644
--- a/npm/ng-packs/packages/core/src/public-api.ts
+++ b/npm/ng-packs/packages/core/src/public-api.ts
@@ -23,3 +23,4 @@ export * from './lib/tokens';
export * from './lib/utils';
export * from './lib/validators';
export * from './lib/interceptors';
+export * from './lib/clients';
diff --git a/npm/ng-packs/packages/feature-management/proxy/src/lib/proxy/feature-management/features.service.ts b/npm/ng-packs/packages/feature-management/proxy/src/lib/proxy/feature-management/features.service.ts
index 490089fbbd..189076428d 100644
--- a/npm/ng-packs/packages/feature-management/proxy/src/lib/proxy/feature-management/features.service.ts
+++ b/npm/ng-packs/packages/feature-management/proxy/src/lib/proxy/feature-management/features.service.ts
@@ -7,34 +7,37 @@ import { Injectable } from '@angular/core';
})
export class FeaturesService {
apiName = 'AbpFeatureManagement';
-
delete = (providerName: string, providerKey: string) =>
- this.restService.request({
- method: 'DELETE',
- url: '/api/feature-management/features',
- params: { providerName, providerKey },
- },
- { apiName: this.apiName });
-
+ this.restService.request(
+ {
+ method: 'DELETE',
+ url: '/api/feature-management/features',
+ params: { providerName, providerKey },
+ },
+ { apiName: this.apiName },
+ );
get = (providerName: string, providerKey: string) =>
- this.restService.request({
- method: 'GET',
- url: '/api/feature-management/features',
- params: { providerName, providerKey },
- },
- { apiName: this.apiName });
-
+ this.restService.request(
+ {
+ method: 'GET',
+ url: '/api/feature-management/features',
+ params: { providerName, providerKey },
+ },
+ { apiName: this.apiName },
+ );
update = (providerName: string, providerKey: string, input: UpdateFeaturesDto) =>
- this.restService.request({
- method: 'PUT',
- url: '/api/feature-management/features',
- params: { providerName, providerKey },
- body: input,
- },
- { apiName: this.apiName });
+ this.restService.request(
+ {
+ method: 'PUT',
+ url: '/api/feature-management/features',
+ params: { providerName, providerKey },
+ body: input,
+ },
+ { apiName: this.apiName },
+ );
constructor(private restService: RestService) {}
}
diff --git a/npm/ng-packs/packages/oauth/src/lib/interceptors/api.interceptor.ts b/npm/ng-packs/packages/oauth/src/lib/interceptors/api.interceptor.ts
index e807133c0d..f36f966559 100644
--- a/npm/ng-packs/packages/oauth/src/lib/interceptors/api.interceptor.ts
+++ b/npm/ng-packs/packages/oauth/src/lib/interceptors/api.interceptor.ts
@@ -2,7 +2,13 @@ import { HttpHandler, HttpHeaders, HttpRequest } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
import { finalize } from 'rxjs/operators';
-import { SessionStateService, HttpWaitService, TENANT_KEY, IApiInterceptor } from '@abp/ng.core';
+import {
+ SessionStateService,
+ HttpWaitService,
+ TENANT_KEY,
+ IApiInterceptor,
+ IS_EXTERNAL_REQUEST,
+} from '@abp/ng.core';
@Injectable({
providedIn: 'root',
@@ -17,12 +23,15 @@ export class OAuthApiInterceptor implements IApiInterceptor {
intercept(request: HttpRequest, next: HttpHandler) {
this.httpWaitService.addRequest(request);
- return next
- .handle(
- request.clone({
+ const isExternalRequest = request.context?.get(IS_EXTERNAL_REQUEST);
+ const newRequest = isExternalRequest
+ ? request
+ : request.clone({
setHeaders: this.getAdditionalHeaders(request.headers),
- }),
- )
+ });
+
+ return next
+ .handle(newRequest)
.pipe(finalize(() => this.httpWaitService.deleteRequest(request)));
}
diff --git a/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts b/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts
index 753ad815e3..7c8c2af99c 100644
--- a/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts
+++ b/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts
@@ -1,4 +1,4 @@
-import { APP_INITIALIZER, Injector, ModuleWithProviders, NgModule } from '@angular/core';
+import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { OAuthModule, OAuthStorage } from 'angular-oauth2-oidc';
import {
@@ -7,8 +7,7 @@ import {
AuthService,
CHECK_AUTHENTICATION_STATE_FN_KEY,
noop,
- PIPE_TO_LOGIN_FN_KEY,
- SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY,
+ PIPE_TO_LOGIN_FN_KEY
} from '@abp/ng.core';
import { storageFactory } from './utils/storage.factory';
import { AbpOAuthService } from './services';
@@ -17,7 +16,7 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { OAuthApiInterceptor } from './interceptors/api.interceptor';
import { AbpOAuthGuard } from './guards/oauth.guard';
import { NavigateToManageProfileProvider } from './providers';
-import { checkAccessToken, pipeToLogin, setTokenResponseToStorage } from './utils';
+import { checkAccessToken, pipeToLogin } from './utils';
@NgModule({
imports: [CommonModule, OAuthModule],
@@ -43,10 +42,6 @@ export class AbpOAuthModule {
provide: PIPE_TO_LOGIN_FN_KEY,
useValue: pipeToLogin,
},
- {
- provide: SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY,
- useValue: setTokenResponseToStorage,
- },
{
provide: CHECK_AUTHENTICATION_STATE_FN_KEY,
useValue: checkAccessToken,
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 74df5ce79b..64dcd76576 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
@@ -1,4 +1,4 @@
-import { Injector } from '@angular/core';
+import { inject, Injector } from '@angular/core';
import { Router } from '@angular/router';
import { OAuthStorage, TokenResponse } from 'angular-oauth2-oidc';
import { pipe } from 'rxjs';
@@ -29,29 +29,6 @@ export const pipeToLogin: PipeToLoginFn = function (
);
};
-export const setTokenResponseToStorage: SetTokenResponseToStorageFn = function (
- injector: Injector,
- tokenRes: TokenResponse,
-) {
- const { access_token, refresh_token, scope: grantedScopes, expires_in } = tokenRes;
- const storage = injector.get(OAuthStorage);
-
- storage.setItem('access_token', access_token);
- storage.setItem('refresh_token', refresh_token);
- storage.setItem('access_token_stored_at', '' + Date.now());
-
- if (grantedScopes) {
- storage.setItem('granted_scopes', JSON.stringify(grantedScopes.split(' ')));
- }
-
- if (expires_in) {
- const expiresInMilliSeconds = expires_in * 1000;
- const now = new Date();
- const expiresAt = now.getTime() + expiresInMilliSeconds;
- storage.setItem('expires_at', '' + expiresAt);
- }
-};
-
export function setRememberMe(remember: boolean) {
removeRememberMe();
localStorage.setItem(storageKey, 'true');
diff --git a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts
index 35380fe47c..44cc372f32 100644
--- a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts
+++ b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts
@@ -1,13 +1,13 @@
-import { ConfigStateService, CurrentUserDto } from "@abp/ng.core";
+import { ConfigStateService, CurrentUserDto } from '@abp/ng.core';
import {
GetPermissionListResultDto,
PermissionGrantInfoDto,
PermissionGroupDto,
PermissionsService,
ProviderInfoDto,
- UpdatePermissionDto
-} from "@abp/ng.permission-management/proxy";
-import { LocaleDirection } from "@abp/ng.theme.shared";
+ UpdatePermissionDto,
+} from '@abp/ng.permission-management/proxy';
+import { LocaleDirection } from '@abp/ng.theme.shared';
import {
Component,
ElementRef,
@@ -16,11 +16,11 @@ import {
Output,
QueryList,
TrackByFunction,
- ViewChildren
-} from "@angular/core";
-import { concat, of } from "rxjs";
-import { finalize, switchMap, take, tap } from "rxjs/operators";
-import { PermissionManagement } from "../models/permission-management";
+ ViewChildren,
+} from '@angular/core';
+import { concat, of } from 'rxjs';
+import { finalize, switchMap, take, tap } from 'rxjs/operators';
+import { PermissionManagement } from '../models/permission-management';
type PermissionWithStyle = PermissionGrantInfoDto & {
style: string;
diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/index.ts b/npm/ng-packs/packages/schematics/src/commands/create-lib/index.ts
index 2b92336c0e..4b5408311b 100644
--- a/npm/ng-packs/packages/schematics/src/commands/create-lib/index.ts
+++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/index.ts
@@ -246,4 +246,3 @@ export function addRoutingToAppRoutingModule(workspace: WorkspaceDefinition, pac
return;
};
}
-
diff --git a/npm/ng-packs/packages/schematics/src/models/model.ts b/npm/ng-packs/packages/schematics/src/models/model.ts
index 048c08a1b0..142d4da75c 100644
--- a/npm/ng-packs/packages/schematics/src/models/model.ts
+++ b/npm/ng-packs/packages/schematics/src/models/model.ts
@@ -45,9 +45,13 @@ abstract class TypeRef {
get default() {
return this._default;
}
- set default(value: string) {
+ set default(value: any) {
if (!value) return;
- this._default = ` = ${value}`;
+ if (typeof value === 'string') {
+ this._default = ` = "${value}"`;
+ } else {
+ this._default = ` = ${value}`;
+ }
}
constructor(options: TypeRefOptions) {
diff --git a/npm/ng-packs/packages/schematics/src/utils/angular/generate-from-files.ts b/npm/ng-packs/packages/schematics/src/utils/angular/generate-from-files.ts
index eaf8febb54..169c6c389a 100644
--- a/npm/ng-packs/packages/schematics/src/utils/angular/generate-from-files.ts
+++ b/npm/ng-packs/packages/schematics/src/utils/angular/generate-from-files.ts
@@ -48,7 +48,7 @@ export function generateFromFiles(
validateClassName(strings.classify(options.name));
const templateSource = apply(url('./files'), [
- options.skipTests ? filter((path) => !path.endsWith('.spec.ts.template')) : noop(),
+ options.skipTests ? filter(path => !path.endsWith('.spec.ts.template')) : noop(),
applyTemplates({
...strings,
...options,
diff --git a/npm/ng-packs/packages/theme-basic/src/lib/theme-basic.module.ts b/npm/ng-packs/packages/theme-basic/src/lib/theme-basic.module.ts
index d73fa50f4e..e04ed6dde1 100644
--- a/npm/ng-packs/packages/theme-basic/src/lib/theme-basic.module.ts
+++ b/npm/ng-packs/packages/theme-basic/src/lib/theme-basic.module.ts
@@ -78,7 +78,7 @@ export class ThemeBasicModule {
},
{
provide: VALIDATION_TARGET_SELECTOR,
- useValue: '*:has(> .form-control)',
+ useValue: '.form-group',
},
{
provide: VALIDATION_INVALID_CLASSES,
diff --git a/templates/app-nolayers/angular/package.json b/templates/app-nolayers/angular/package.json
index 6a1077b772..8db88c765c 100644
--- a/templates/app-nolayers/angular/package.json
+++ b/templates/app-nolayers/angular/package.json
@@ -20,7 +20,7 @@
"@abp/ng.setting-management": "~7.0.1",
"@abp/ng.tenant-management": "~7.0.1",
"@abp/ng.theme.shared": "~7.0.1",
- "@abp/ng.theme.lepton-x": "~2.0.0-rc.4",
+ "@abp/ng.theme.lepton-x": "~2.0.2",
"@angular/animations": "^15.0.1",
"@angular/common": "^15.0.1",
"@angular/compiler": "^15.0.1",
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyCompanyName.MyProjectName.Blazor.Server.Mongo.csproj b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyCompanyName.MyProjectName.Blazor.Server.Mongo.csproj
index 0983f7740c..60d0fd9252 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyCompanyName.MyProjectName.Blazor.Server.Mongo.csproj
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyCompanyName.MyProjectName.Blazor.Server.Mongo.csproj
@@ -21,8 +21,8 @@
-
-
+
+
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj
index 50d90dcc3e..67b96e0b72 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj
@@ -21,8 +21,8 @@
-
-
+
+
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host.Mongo/MyCompanyName.MyProjectName.Host.Mongo.csproj b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host.Mongo/MyCompanyName.MyProjectName.Host.Mongo.csproj
index 60712105a2..1d24418c23 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host.Mongo/MyCompanyName.MyProjectName.Host.Mongo.csproj
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host.Mongo/MyCompanyName.MyProjectName.Host.Mongo.csproj
@@ -69,7 +69,7 @@
-
+
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/MyCompanyName.MyProjectName.Host.csproj b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/MyCompanyName.MyProjectName.Host.csproj
index 24eb4368de..693c73691b 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/MyCompanyName.MyProjectName.Host.csproj
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/MyCompanyName.MyProjectName.Host.csproj
@@ -70,7 +70,7 @@
-
+
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.Mongo/MyCompanyName.MyProjectName.Mvc.Mongo.csproj b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.Mongo/MyCompanyName.MyProjectName.Mvc.Mongo.csproj
index 5f99ac74ae..98f822e53b 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.Mongo/MyCompanyName.MyProjectName.Mvc.Mongo.csproj
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.Mongo/MyCompanyName.MyProjectName.Mvc.Mongo.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/MyCompanyName.MyProjectName.Mvc.csproj b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/MyCompanyName.MyProjectName.Mvc.csproj
index 06cec0688c..996e05eca2 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/MyCompanyName.MyProjectName.Mvc.csproj
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/MyCompanyName.MyProjectName.Mvc.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/templates/app/angular/package.json b/templates/app/angular/package.json
index 4872476d1e..3dbb2c7424 100644
--- a/templates/app/angular/package.json
+++ b/templates/app/angular/package.json
@@ -20,7 +20,7 @@
"@abp/ng.setting-management": "~7.0.1",
"@abp/ng.tenant-management": "~7.0.1",
"@abp/ng.theme.shared": "~7.0.1",
- "@abp/ng.theme.lepton-x": "~2.0.0-rc.4",
+ "@abp/ng.theme.lepton-x": "~2.0.2",
"@angular/animations": "^15.0.1",
"@angular/common": "^15.0.1",
"@angular/compiler": "^15.0.1",
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.AuthServer/MyCompanyName.MyProjectName.AuthServer.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.AuthServer/MyCompanyName.MyProjectName.AuthServer.csproj
index 21fb37e73e..f033af0cde 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.AuthServer/MyCompanyName.MyProjectName.AuthServer.csproj
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.AuthServer/MyCompanyName.MyProjectName.AuthServer.csproj
@@ -43,7 +43,7 @@
-
+
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj
index 832bd8d7ba..0ba0a2718b 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj
@@ -29,8 +29,8 @@
-
-
+
+
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj
index eb34741aa4..a7d61d429e 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj
@@ -27,8 +27,8 @@
-
-
+
+
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj
index 53338ee686..1c205cfec0 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj
index 6e72b6879f..612eb08f9c 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj
@@ -25,7 +25,7 @@
-
+
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj
index fe7c773451..100ba3ffa5 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj
@@ -27,7 +27,7 @@
-
+
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj
index 560ba570dd..809fecad53 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj
@@ -41,7 +41,7 @@
-
+