diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
index 89f7648368..0b097d53a8 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
@@ -27,6 +27,7 @@
"Volo.AbpIo.Domain:030010": "To purchase the trial license, you first need to activate your trial license!",
"Volo.AbpIo.Domain:030011": "You cannot delete a trial license when it is purchased!",
"Volo.AbpIo.Domain:030012": "A user is entitled to have only 1 free trial period. You already used your trial license.",
+ "Volo.AbpIo.Domain:030013": "A user with an active license cannot start a trial license.",
"Volo.AbpIo.Domain:070000": "The organization name can only contain latin letters, numbers, dots and hyphens!",
"Volo.AbpIo.Domain:070001": "The company name can only contain latin letters, numbers, dots, space and hyphens!",
"WantToLearn?": "Want to learn?",
@@ -205,6 +206,8 @@
"Icons": "Icons",
"Url": "Url",
"Icon": "Icon",
- "RecentActivities": "Recent Activities"
+ "RecentActivities": "Recent Activities",
+ "SpringCampaign": "Welcome Spring Sale!",
+ "SpringCampaign2": "Limited Time Offer!"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
index 6e5e69f079..8ba77e32a9 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
@@ -196,7 +196,7 @@
"ChangingDevelopers": "Can I change the registered developers of my organization in the future?",
"ChangingDevelopersExplanation": "In addition to adding new developers to your license, you can also change the existing developers (you can remove a developer and add a new one to the same seat) without any additional cost.",
"WhatHappensWhenLicenseEnds": "What happens when my license period ends?",
- "WhatHappensWhenLicenseEndsExplanation1": "The ABP Commercial license is a perpetual license. After your license expires, you can continue developing your project. And you are not obliged to renew your license. Your license comes with a one-year update and support plan out of the box. In order to continue to get new features, performance enhancements, bug fixes, support and continue using ABP Suite, you need to renew your license. When your license expires, you will not get the following benefits:",
+ "WhatHappensWhenLicenseEndsExplanation1": "The ABP Commercial license is a perpetual license. After your license expires, you can continue developing your project. And you are not obliged to renew your license. Your license comes with a one-year update and support plan out of the box. In order to continue to get new features, performance enhancements, bug fixes, support and continue using ABP Suite, you need to renew your license. When your license expires;",
"WhatHappensWhenLicenseEndsExplanation2": "You can not create new solutions using the ABP Commercial, but you can continue developing your existing applications forever.",
"WhatHappensWhenLicenseEndsExplanation3": "You will be able to get updates for the modules and themes within your MINOR version (except RC or Preview versions). For example: if you are using v3.2.0 of a module, you can still get updates for v3.2.x (v3.2.1, v3.2.5... etc.) of that module. But you cannot get updates for the next major or minor version (like v3.3.0, v3.3.3, 4.x.x.. etc.). For example, when your license expired, the latest release was v4.4.3, and later, it published both 4.4.4 version and 4.5.0 version, you would be able to access the v4.4.X but you wouldn't be access the v4.5.X.",
"WhatHappensWhenLicenseEndsExplanation4": "You can not install new modules and themes added to the ABP Commercial platform after your license ends.",
@@ -818,6 +818,7 @@
"DeletingMemberWarningMessage": "\"{0}\" will be removed from the developer list. If you want, you can assign this empty seat to another developer later.",
"AdditionalInfo": "If the developer seats are above your requirements, you can reduce them. You can email at info@abp.io to remove some of your developer seats. Clearing unused developer seats will reduce the license renewal cost. If you want, you can re-purchase additional developer seats within your active license period. Note that, since there are {0} developers in this license package, you cannot reduce this number.",
"LinkExpiredErrorMessage": "The link you are trying to access is expired.",
- "ExpirationDate": "Expiration Date"
+ "ExpirationDate": "Expiration Date",
+ "SpringCampaignDiscount": "Spring Campaign Discount"
}
}
diff --git a/docs/en/Background-Jobs.md b/docs/en/Background-Jobs.md
index 84e746f73d..c6e19fb48a 100644
--- a/docs/en/Background-Jobs.md
+++ b/docs/en/Background-Jobs.md
@@ -75,6 +75,42 @@ This job simply uses `IEmailSender` to send emails (see [email sending document]
A background job should not hide exceptions. If it throws an exception, the background job is automatically re-tried after a calculated waiting time. Hide exceptions only if you don't want to re-run the background job for the current argument.
+#### Cancelling Background Jobs
+
+If your background task is cancellable, then you can use the standard [Cancellation Token](Cancellation-Token-Provider.md) system to obtain a `CancellationToken` to cancel your job when requested. See the following example that uses the `ICancellationTokenProvider` to obtain the cancellation token:
+
+```csharp
+using System;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Threading;
+
+namespace MyProject
+{
+ public class LongRunningJob : AsyncBackgroundJob, ITransientDependency
+ {
+ private readonly ICancellationTokenProvider _cancellationTokenProvider;
+
+ public LongRunningJob(ICancellationTokenProvider cancellationTokenProvider)
+ {
+ _cancellationTokenProvider = cancellationTokenProvider;
+ }
+
+ public override async Task ExecuteAsync(LongRunningJobArgs args)
+ {
+ foreach (var id in args.Ids)
+ {
+ _cancellationTokenProvider.Token.ThrowIfCancellationRequested();
+ await ProcessAsync(id); // code omitted for brevity
+ }
+ }
+ }
+}
+```
+
+> A cancellation operation might be needed if the application is shutting down and we don't want to block the application in the background job. This example throws an exception if the cancellation is requested. So, the job will be retried the next time the application starts. If you don't want that, just return from the `ExecuteAsync` method without throwing any exception (you can simply check the `_cancellationTokenProvider.Token.IsCancellationRequested` property).
+
#### Job Name
Each background job has a name. Job names are used in several places. For example, RabbitMQ provider uses job names to determine the RabbitMQ Queue names.
diff --git a/docs/en/Community-Articles/2023-02-22-Streamline-Localization-In-Your-ABP-Project/POST.md b/docs/en/Community-Articles/2023-02-22-Streamline-Localization-In-Your-ABP-Project/POST.md
new file mode 100644
index 0000000000..63936521c6
--- /dev/null
+++ b/docs/en/Community-Articles/2023-02-22-Streamline-Localization-In-Your-ABP-Project/POST.md
@@ -0,0 +1,44 @@
+## Streamline Localization in Your ABP Project
+
+Making localization changes to an ABP project can be a daunting task, especially if you're dealing with multiple languages and translations. During development, it's easy to overlook some changes and that leads to inconsistencies across different languages. Fortunately, I have developed a tool that can help streamline the localization process and ensure consistency across different languages.
+
+The tool is a console application that uses JSON files to manage localization keys and their translations. It addresses three common scenarios that can arise during localization:
+
+
+1. When the argument count of a key changes, it can be difficult to update the translations for all languages. My tool solves this problem by scanning all JSON files in the project folder and identifying any keys that have mismatched argument counts. It then offers two options to the user: delete the mismatched translations or export them as a JSON file for manual editing.
+
+2. When a new key is added to the project, forgetting to add its translations to all the other languages is easy. My tool helps to avoid this issue by scanning the default language's JSON file and identifying any keys that don't have translations in other languages. It then exports these keys as a JSON file that can be used to add missing translations.
+
+3. When a key's name is changed, it's important to update its translations in all the other languages. My tool makes this task simple by scanning all the JSON files in the project folder and updating any translations of the old key name with the new one.
+
+The tool also includes an export feature that allows users to modify translations outside of the application and import them back into the JSON files.
+
+## How it Helps
+
+With my Localization Key Synchronizer tool, you can perform complex localization changes more quickly and easily than by manually sifting through files and making changes one-by-one. This can save you significant time and effort, especially if you're working with a large number of languages or translations.
+
+## How it Works
+
+When you run the Localization Key Synchronizer tool, it presents you with three options:
+
+1. Find Asynchronous Keys
+2. Apply Changes in the Exported File
+3. Replace Keys
+
+If you select "Find Asynchronous Keys," the tool prompts you to enter the default language path. Once you've entered the path, the tool displays all of the JSON files in the same folder as a multi-select list. After selecting one or more files, you are asked whether you want to find keys that do not match the number of arguments, missing keys, or both. If you select "Missing Keys," the tool prompts you to enter the absolute path to export the missing keys. After you've entered the path, the export process starts, and the tool closes.
+
+
+
+If you select "Apply Changes in the Exported File" at the main menu, the tool prompts you to enter the path to the exported file. After you've entered the path, the import process starts, and the tool closes.
+
+
+
+If you select "Replace Keys," the tool prompts you to enter the localization folder path, the old key, the new key, and the JSON files to apply the changes to. Once you've entered all the required information and made your selections, the tool performs the replacements and closes.
+
+
+
+## Conclusion
+
+If you're struggling to manage localization changes in an ABP project, give my Localization Key Synchronizer tool a try. It can help streamline your workflow and make the process much more manageable. You can find the tool on [GitHub](https://github.com/abpframework/abp/tree/dev/tools/localization-key-synchronizer).
+
+To use the tool, simply run the console application and follow the prompts. It's a user-friendly solution that helps to ensure localization consistency in your ABP project. Give it a try and let me know what you think!
diff --git a/docs/en/Community-Articles/2023-02-22-Streamline-Localization-In-Your-ABP-Project/images/Part1.gif b/docs/en/Community-Articles/2023-02-22-Streamline-Localization-In-Your-ABP-Project/images/Part1.gif
new file mode 100644
index 0000000000..f2e6b66e64
Binary files /dev/null and b/docs/en/Community-Articles/2023-02-22-Streamline-Localization-In-Your-ABP-Project/images/Part1.gif differ
diff --git a/docs/en/Community-Articles/2023-02-22-Streamline-Localization-In-Your-ABP-Project/images/Part2.gif b/docs/en/Community-Articles/2023-02-22-Streamline-Localization-In-Your-ABP-Project/images/Part2.gif
new file mode 100644
index 0000000000..9bc70d361d
Binary files /dev/null and b/docs/en/Community-Articles/2023-02-22-Streamline-Localization-In-Your-ABP-Project/images/Part2.gif differ
diff --git a/docs/en/Community-Articles/2023-02-22-Streamline-Localization-In-Your-ABP-Project/images/Part3.gif b/docs/en/Community-Articles/2023-02-22-Streamline-Localization-In-Your-ABP-Project/images/Part3.gif
new file mode 100644
index 0000000000..8a8ae32d25
Binary files /dev/null and b/docs/en/Community-Articles/2023-02-22-Streamline-Localization-In-Your-ABP-Project/images/Part3.gif differ
diff --git a/docs/en/Distributed-Event-Bus.md b/docs/en/Distributed-Event-Bus.md
index 8a2bb60a18..f1b8464d59 100644
--- a/docs/en/Distributed-Event-Bus.md
+++ b/docs/en/Distributed-Event-Bus.md
@@ -306,7 +306,7 @@ Assume that there is a `Product` entity (probably an aggregate root entity) in a
The first step to establish the synchronization is to define an ETO (Event Transfer Object) class in the Catalog microservice that is used to transfer the event data. Assuming the `Product` entity has a `Guid` key, your ETO can be as shown below:
-````
+````csharp
[EventName("product")]
public class ProductEto : EntityEto
{
diff --git a/docs/en/Migration-Guides/IdentityServer4-Step-by-Step.md b/docs/en/Migration-Guides/IdentityServer4-Step-by-Step.md
new file mode 100644
index 0000000000..aff389ccf8
--- /dev/null
+++ b/docs/en/Migration-Guides/IdentityServer4-Step-by-Step.md
@@ -0,0 +1,230 @@
+# Migrating from OpenIddict to IdentityServer4 Step by Step Guide
+
+ABP startup templates use `OpenIddict` OpenID provider from v6.0.0 by default and `IdentityServer` projects are renamed to `AuthServer` in tiered/separated solutions. Since OpenIddict is the default OpenID provider library for ABP templates since v6.0, you may want to keep using [IdentityServer4](https://github.com/IdentityServer/IdentityServer4) library, even it is **archived and no longer maintained by the owners**. ABP doesn't provide support for newer versions of IdentityServer. This guide provides layer-by-layer guidance for migrating your existing [OpenIddict](https://github.com/openiddict/openiddict-core) application to IdentityServer4.
+
+## IdentityServer4 Migration Steps
+
+Use the `abp update` command to update your existing application. See [Upgrading docs](../Upgrading.md) for more info. Apply required migrations by following the [Migration Guides](Index.md) based on your application version.
+
+### Domain.Shared Layer
+
+- In **MyApplication.Domain.Shared.csproj** replace **project reference**:
+
+```csharp
+
+```
+
+ with
+
+```csharp
+
+```
+
+- In **MyApplicationDomainSharedModule.cs** replace usings and **module dependencies:**
+
+```csharp
+using Volo.Abp.OpenIddict;
+...
+typeof(AbpOpenIddictDomainSharedModule)
+```
+
+ with
+
+```csharp
+using Volo.Abp.IdentityServer;
+...
+typeof(AbpIdentityServerDomainSharedModule)
+```
+
+### Domain Layer
+
+- In **MyApplication.Domain.csproj** replace **project references**:
+
+```csharp
+
+
+```
+
+ with
+
+```csharp
+
+
+```
+
+- In **MyApplicationDomainModule.cs** replace usings and **module dependencies**:
+
+```csharp
+using Volo.Abp.OpenIddict;
+using Volo.Abp.PermissionManagement.OpenIddict;
+...
+typeof(AbpOpenIddictDomainModule),
+typeof(AbpPermissionManagementDomainOpenIddictModule),
+```
+
+ with
+
+```csharp
+using Volo.Abp.IdentityServer;
+using Volo.Abp.PermissionManagement.IdentityServer;
+...
+typeof(AbpIdentityServerDomainModule),
+typeof(AbpPermissionManagementDomainIdentityServerModule),
+```
+
+#### OpenIddictDataSeedContributor
+
+DataSeeder is the most important part for starting the application since it seeds the initial data for both OpenID providers.
+
+- Create a folder named *IdentityServer* under the Domain project and copy the [IdentityServerDataSeedContributor.cs](https://github.com/abpframework/abp-samples/blob/master/Ids2OpenId/src/Ids2OpenId.Domain/IdentityServer/IdentityServerDataSeedContributor.cs) under this folder. **Rename** all the `OpenId2Ids` with your project name.
+- Delete *OpenIddict* folder that contains `OpenIddictDataSeedContributor.cs` which is no longer needed.
+
+### EntityFrameworkCore Layer
+
+If you are using MongoDB, skip this step and check the *MongoDB* layer section.
+
+- In **MyApplication.EntityFrameworkCore.csproj** replace **project reference**:
+
+ ```csharp
+
+ ```
+
+ with
+
+ ```csharp
+
+ ```
+
+- In **MyApplicationEntityFrameworkCoreModule.cs** replace usings and **module dependencies**:
+
+```csharp
+using Volo.Abp.OpenIddict.EntityFrameworkCore;
+...
+typeof(AbpOpenIddictEntityFrameworkCoreModule),
+```
+
+ with
+
+```csharp
+using Volo.Abp.IdentityServer.EntityFrameworkCore;
+...
+typeof(AbpIdentityServerEntityFrameworkCoreModule),
+```
+
+- In **MyApplicationDbContext.cs** replace usings and **fluent api configurations**:
+
+ ```csharp
+ using Volo.Abp.OpenIddict.EntityFrameworkCore;
+ ...
+ protected override void OnModelCreating(ModelBuilder builder)
+ {
+ base.OnModelCreating(builder);
+
+ /* Include modules to your migration db context */
+
+ ...
+ builder.ConfigureOpenIddict();
+ ```
+
+ with
+
+ ```csharp
+ using Volo.Abp.IdentityServer.EntityFrameworkCore;
+ ...
+ using Volo.Abp.OpenIddict.EntityFrameworkCore;
+ ...
+ protected override void OnModelCreating(ModelBuilder builder)
+ {
+ base.OnModelCreating(builder);
+
+ /* Include modules to your migration db context */
+
+ ...
+ builder.ConfigureIdentityServer();
+ ```
+
+> Not: You need to create new migration after updating the fluent api. Navigate to *EntityFrameworkCore* folder and add a new migration. Ex, `dotnet ef migrations add Updated_To_IdentityServer `
+
+### MongoDB Layer
+
+If you are using EntityFrameworkCore, skip this step and check the *EntityFrameworkCore* layer section.
+
+- In **MyApplication.MongoDB.csproj** replace **project reference**:
+
+ ```csharp
+
+ ```
+
+ with
+
+ ```csharp
+
+ ```
+
+- In **MyApplicationMongoDbModule.cs** replace usings and **module dependencies**:
+
+```csharp
+using Volo.Abp.OpenIddict.MongoDB;
+...
+typeof(AbpOpenIddictMongoDbModule),
+```
+
+ with
+
+```csharp
+using Volo.Abp.IdentityServer.MongoDB;
+...
+typeof(AbpIdentityServerMongoDbModule),
+```
+
+### DbMigrator Project
+
+- In `appsettings.json` **replace OpenIddict section with IdentityServer** since IdentityServerDataSeeder will be using these information for initial data seeding:
+
+ ```json
+ "IdentityServer": { // Rename OpenIddict to IdentityServer
+ "Clients ": { // Rename Applications to Clients
+ ...
+ }
+ }
+ ```
+
+
+### Test Project
+
+- In **MyApplicationTestBaseModule.cs** **add** the IdentityServer related using and PreConfigurations:
+
+ ```csharp
+ using Volo.Abp.IdentityServer;
+ ```
+
+ and
+
+ ```csharp
+ PreConfigure(options =>
+ {
+ options.AddDeveloperSigningCredential = false;
+ });
+
+ PreConfigure(identityServerBuilder =>
+ {
+ identityServerBuilder.AddDeveloperSigningCredential(false, System.Guid.NewGuid().ToString());
+ });
+ ```
+
+ to `PreConfigureServices` to run authentication related unit tests.
+
+### UI Layer
+
+You can follow the migrations guides from IdentityServer to OpenIddict in **reverse order** to update your UIs. You can also check the source-code for [Index.cshtml.cs](https://github.com/abpframework/abp-samples/blob/master/OpenId2Ids/src/OpenId2Ids.AuthServer/Pages/Index.cshtml) and [Index.cshtml](https://github.com/abpframework/abp-samples/blob/master/OpenId2Ids/src/OpenId2Ids.AuthServer/Pages/Index.cshtml.cs) files for **AuthServer** project.
+
+- [Angular UI Migration](OpenIddict-Angular.md)
+- [MVC/Razor UI Migration](OpenIddict-Mvc.md)
+- [Blazor-Server UI Migration](OpenIddict-Blazor-Server.md)
+- [Blazor-Wasm UI Migration](OpenIddict-Blazor.md)
+
+## Source code of samples and module
+
+* [Open source tiered & separate auth server application migrate OpenIddict to Identity Server](https://github.com/abpframework/abp-samples/tree/master/OpenId2Ids)
+* [IdentityServer module document](https://docs.abp.io/en/abp/6.0/Modules/IdentityServer)
+* [IdentityServer module source code](https://github.com/abpframework/abp/tree/rel-6.0/modules/identityserver)
diff --git a/docs/en/Modules/Database-Tables.md b/docs/en/Modules/Database-Tables.md
index 8d0290b311..0f00055d13 100644
--- a/docs/en/Modules/Database-Tables.md
+++ b/docs/en/Modules/Database-Tables.md
@@ -32,7 +32,7 @@ This table stores information about entity changes in the application, which are
This table stores information about property changes to entities in the application, which are logged for auditing purposes.
-## Uses
+#### Foreign Keys
| Table | Column | Description |
| --- | --- | --- |
@@ -54,7 +54,7 @@ This table stores information about the tenants. Each record represents a tenant
This table stores information about the tenant database connection strings. When you define a connection string for a tenant, a new record will be added to this table. You can query this database to get connection strings by tenants.
-## Uses
+#### Foreign Keys
| Table | Column | Description |
| --- | --- | --- |
diff --git a/docs/en/Modules/IdentityServer.md b/docs/en/Modules/IdentityServer.md
index f754a29687..90c08f6c6b 100644
--- a/docs/en/Modules/IdentityServer.md
+++ b/docs/en/Modules/IdentityServer.md
@@ -1,10 +1,12 @@
# IdentityServer Module
-IdentityServer module provides a full integration with the [IdentityServer](https://github.com/IdentityServer/IdentityServer4) (IDS) framework, which provides advanced authentication features like single sign-on and API access control. This module persists clients, resources and other IDS-related objects to database.
+IdentityServer module provides a full integration with the [IdentityServer4](https://github.com/IdentityServer/IdentityServer4) (IDS) framework, which provides advanced authentication features like single sign-on and API access control. This module persists clients, resources and other IDS-related objects to database. **This module is replaced by** [OpenIddict module](https://docs.abp.io/en/abp/latest/Modules/OpenIddict) after ABP v6.0 in the startup templates.
+
+> Note: You can not use IdentityServer and OpenIddict modules together. They are separate OpenID provider libraries for the same job.
## How to Install
-This module comes as pre-installed (as NuGet/NPM packages). You can continue to use it as package and get updates easily, or you can include its source code into your solution (see `get-source` [CLI](../CLI.md) command) to develop your custom module.
+You don't need this module when you are using OpenIddict module. However, if you want to keep using IdentityServer4 for your applications, you can install this module and remove the OpenIddict module. You can continue to use it as package and get updates easily, or you can include its source code into your solution (see `get-source` [CLI](../CLI.md) command) to develop your custom module.
### The Source Code
diff --git a/docs/en/UI/Angular/Quick-Start.md b/docs/en/UI/Angular/Quick-Start.md
index 768b3b7b67..dd26dd3efe 100644
--- a/docs/en/UI/Angular/Quick-Start.md
+++ b/docs/en/UI/Angular/Quick-Start.md
@@ -179,7 +179,7 @@ This command will download and start a simple static server, a browser window at
Of course, you need your application to run on an optimized web server and become available to everyone. This is quite straight-forward:
-1. Create a new static web server instance. You can use a service like [Azure App Service](https://azure.microsoft.com/tr-tr/services/app-service/web/), [Firebase](https://firebase.google.com/docs/hosting), [Netlify](https://www.netlify.com/), [Vercel](https://vercel.com/), or even [GitHub Pages](https://angular.io/guide/deployment#deploy-to-github-pages). Another option is maintaining own web server with [NGINX](https://www.nginx.com/), [IIS](https://www.iis.net/), [Apache HTTP Server](https://httpd.apache.org/), or equivalent.
+1. Create a new static web server instance. You can use a service like [Azure App Service](https://azure.microsoft.com/en-us/services/app-service/web/), [Firebase](https://firebase.google.com/docs/hosting), [Netlify](https://www.netlify.com/), [Vercel](https://vercel.com/), or even [GitHub Pages](https://angular.io/guide/deployment#deploy-to-github-pages). Another option is maintaining own web server with [NGINX](https://www.nginx.com/), [IIS](https://www.iis.net/), [Apache HTTP Server](https://httpd.apache.org/), or equivalent.
2. Copy the files from `dist/MyProjectName` [1](#f-dist-folder-name) to a publicly served destination on the server via CLI of the service provider, SSH, or FTP (whichever is available). This step would be defined as a job if you have a CI/CD flow.
3. [Configure the server](https://angular.io/guide/deployment#server-configuration) to redirect all requests to the _index.html_ file. Some services do that automatically. Others require you [to add a file to the bundle via assets](https://angular.io/guide/workspace-config#assets-configuration) which describes the server how to do the redirections. Occasionally, you may need to do manual configuration.
diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Form-elements.md b/docs/en/UI/AspNetCore/Tag-Helpers/Form-elements.md
index 8f664a80a5..15a8b0819c 100644
--- a/docs/en/UI/AspNetCore/Tag-Helpers/Form-elements.md
+++ b/docs/en/UI/AspNetCore/Tag-Helpers/Form-elements.md
@@ -10,7 +10,7 @@ See the [form elements demo page](https://bootstrap-taghelpers.abp.io/Components
## abp-input
-`abp-input` tag creates a Bootstrap form input for a given c# property. It uses [Asp.Net Core Input Tag Helper](https://docs.microsoft.com/tr-tr/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-3.1#the-input-tag-helper) in background, so every data annotation attribute of `input` tag helper of Asp.Net Core is also valid for `abp-input`.
+`abp-input` tag creates a Bootstrap form input for a given c# property. It uses [Asp.Net Core Input Tag Helper](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-7.0#the-input-tag-helper) in background, so every data annotation attribute of `input` tag helper of Asp.Net Core is also valid for `abp-input`.
Usage:
@@ -88,7 +88,7 @@ You can set some of the attributes on your c# property, or directly on html tag.
* `label`: Sets the label for input.
* `display-required-symbol`: Adds the required symbol (*) to label if input is required. Default `True`.
-`asp-format`, `name` and `value` attributes of [Asp.Net Core Input Tag Helper](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-3.1#the-input-tag-helper) are also valid for `abp-input` tag helper.
+`asp-format`, `name` and `value` attributes of [Asp.Net Core Input Tag Helper](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-7.0#the-input-tag-helper) are also valid for `abp-input` tag helper.
### Label & Localization
@@ -100,7 +100,7 @@ You can set label of your input in different ways:
## abp-select
-`abp-select` tag creates a Bootstrap form select for a given c# property. It uses [Asp.Net Core Select Tag Helper](https://docs.microsoft.com/tr-tr/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-3.1#the-select-tag-helper) in background, so every data annotation attribute of `select` tag helper of Asp.Net Core is also valid for `abp-select`.
+`abp-select` tag creates a Bootstrap form select for a given c# property. It uses [Asp.Net Core Select Tag Helper](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-7.0#the-select-tag-helper) in background, so every data annotation attribute of `select` tag helper of Asp.Net Core is also valid for `abp-select`.
`abp-select` tag needs a list of `Microsoft.AspNetCore.Mvc.Rendering.SelectListItem ` to work. It can be provided by `asp-items` attriube on the tag or `[SelectItems()]` attribute on c# property. (if you are using [abp-dynamic-form](Dynamic-forms.md), c# attribute is the only way.)
diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json
index 351bfde88f..2ce69e69a9 100644
--- a/docs/en/docs-nav.json
+++ b/docs/en/docs-nav.json
@@ -1370,16 +1370,22 @@
},
{
"text": "IdentityServer",
- "path": "Modules/IdentityServer.md"
+ "path": "Modules/IdentityServer.md",
+ "items": [
+ {
+ "text": "IdentityServer Migration Guide",
+ "path": "Migration-Guides/IdentityServer4-Step-by-Step.md"
+ }
+ ]
},
{
"text": "OpenIddict",
- "items": [
- {
- "text": "OpenIddict Migration Guide",
- "path": "Migration-Guides/OpenIddict-Step-by-Step.md"
- }
- ],
+ "items": [
+ {
+ "text": "OpenIddict Migration Guide",
+ "path": "Migration-Guides/OpenIddict-Step-by-Step.md"
+ }
+ ],
"path": "Modules/OpenIddict.md"
},
{
diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs
index 4e4411756d..447861a788 100644
--- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs
+++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs
@@ -1,6 +1,7 @@
using System;
using System.Globalization;
using System.Net;
+using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
@@ -42,8 +43,8 @@ public class AbpAspNetCoreMultiTenancyOptions
var message = exception.Message;
var details = exception is BusinessException businessException ? businessException.Details : string.Empty;
- await context.Response.WriteAsync($"\r\n");
- await context.Response.WriteAsync($"