diff --git a/.github/workflows/auto-pr.yml b/.github/workflows/auto-pr.yml
index f353a21e37..526cfc144b 100644
--- a/.github/workflows/auto-pr.yml
+++ b/.github/workflows/auto-pr.yml
@@ -1,13 +1,13 @@
-name: Merge branch rel-8.3 with rel-8.2
+name: Merge branch dev with rel-8.3
on:
push:
branches:
- - rel-8.2
+ - rel-8.3
permissions:
contents: read
jobs:
- merge-rel-8-3-with-rel-8-2:
+ merge-dev-with-rel-8-3:
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,22 +15,22 @@ jobs:
steps:
- uses: actions/checkout@v2
with:
- ref: rel-8.3
+ ref: dev
- name: Reset promotion branch
run: |
- git fetch origin rel-8.2:rel-8.2
- git reset --hard rel-8.2
+ git fetch origin rel-8.3:rel-8.3
+ git reset --hard rel-8.3
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
- branch: auto-merge/rel-8-2/${{github.run_number}}
- title: Merge branch rel-8.3 with rel-8.2
- body: This PR generated automatically to merge rel-8.3 with rel-8.2. Please review the changed files before merging to prevent any errors that may occur.
+ branch: auto-merge/rel-8-3/${{github.run_number}}
+ title: Merge branch dev with rel-8.3
+ body: This PR generated automatically to merge dev with rel-8.3. Please review the changed files before merging to prevent any errors that may occur.
reviewers: maliming
token: ${{ github.token }}
- name: Merge Pull Request
env:
GH_TOKEN: ${{ secrets.BOT_SECRET }}
run: |
- gh pr review auto-merge/rel-8-2/${{github.run_number}} --approve
- gh pr merge auto-merge/rel-8-2/${{github.run_number}} --merge --auto --delete-branch
+ gh pr review auto-merge/rel-8-3/${{github.run_number}} --approve
+ gh pr merge auto-merge/rel-8-3/${{github.run_number}} --merge --auto --delete-branch
\ No newline at end of file
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 472fb034a5..854123b215 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -48,8 +48,8 @@
-
-
+
+
@@ -61,7 +61,6 @@
-
@@ -164,7 +163,7 @@
-
+
diff --git a/LICENSE.md b/LICENSE.md
index 65c5ca88a6..5da3c16f4c 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,165 +1,89 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
+Copyright (C) 2007 Free Software Foundation, Inc.
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public.
+The license is supplemented by the additional permissions listed below.
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
- 0. Additional Definitions.
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
+ **0. Additional Definitions.**
+
+As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License.
+
+"The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below.
+
+An "Application" is any work that makes use of an interface provided by the Library but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library.
+
+A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version".
+
+The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application and not on the Linked Version.
+
+The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work.
+
+
+
+ **1. Exception to Section 3 of the GNU GPL.**
+
+You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL.
+
+
+
+ **2. Conveying Modified Versions.**
+
+If you modify a copy of the Library and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version:
+
+ **a)** under this License, provided that you make a good-faith effort to ensure that, in the event an Application does not supply the
+ function or data, the facility still operates and performs whatever part of its purpose remains meaningful, or
+
+ **b)** under the GNU GPL, with none of the additional permissions of this License is applicable to that copy.
+
+
+
+ **3. Object Code Incorporating Material from Library Header Files.**
+
+The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such an object code under terms of your choice, provided that if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following:
+
+ **a)** Give prominent notice with each copy of the object code that the Library is used in it, and the Library and its use are covered by this License.
+
+ **b)** Accompany the object code with a copy of the GNU GPL and this license document.
+
+
+
+ **4. Combined Works.**
+
+You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following:
+
+ **a)** Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License.
+
+ **b)** Accompany the Combined Work with a copy of the GNU GPL and this license document.
+
+ **c)** For a Combined Work that displays copyright notices during execution, including the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document.
+
+ **d)** Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this License and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.
+ 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version.
+
+ **e)** Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying the Corresponding Source.)
+
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
5. Combined Libraries.
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
+You may place library facilities that are work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License and convey such a combined library under the terms of your choice if you do both of the following:
+
+ **a)** Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License.
+
+ **b)** Give prominent notice with the combined library that part of it is a work based on the Library and explains where to find the accompanying uncombined form of the same work.
+
+
+
+ **6. Revised Versions of the GNU Lesser General Public License.**
+
+The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received, it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.
diff --git a/README.md b/README.md
index ccc31da4b5..dd953a6431 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,18 @@
# ABP Framework
-
-[](https://codecov.io/gh/abpframework/abp)
-[](https://www.nuget.org/packages/Volo.Abp.Core)
-[](https://www.nuget.org/packages/Volo.Abp.Core)
-[](https://docs.abp.io/en/abp/latest/Nightly-Builds)
-[](https://www.nuget.org/packages/Volo.Abp.Core)
-[](https://github.com/abpframework/abp/blob/dev/CODE_OF_CONDUCT.md)
-[](https://cla-assistant.io/abpframework/abp)
-[](https://discord.gg/abp)
-
-ABP Framework is a complete **infrastructure** based on **ASP.NET Core** to create **modern web applications** and **APIs** by following the software development **best practices** and the **latest technologies**. Check out https://abp.io
+ 🔹 [](https://codecov.io/gh/abpframework/abp) 🔹 [](https://www.nuget.org/packages/Volo.Abp.Core) 🔹 [](https://www.nuget.org/packages/Volo.Abp.Core) 🔹 [](https://docs.abp.io/en/abp/latest/Nightly-Builds) 🔹
+[](https://www.nuget.org/packages/Volo.Abp.Core) 🔹 [](https://github.com/abpframework/abp/blob/dev/CODE_OF_CONDUCT.md) 🔹 [](https://cla-assistant.io/abpframework/abp) 🔹 [](https://discord.gg/abp)
+
+ABP Framework is a complete **infrastructure** based on **ASP.NET Core** that creates **modern web applications** and **APIs** by following the software development **best practices** and the **latest technologies**.
+
+[](https://abp.io)
+
## Getting Started
-- [Quick Start](https://docs.abp.io/en/abp/latest/Tutorials/Todo/Index) is a single-part, quick-start tutorial to build a simple application with the ABP Framework. Start with this tutorial if you want to quickly understand how ABP works.
-- [Getting Started guide](https://docs.abp.io/en/abp/latest/Getting-Started) can be used to create and run ABP based solutions with different options and details.
-- [Web Application Development Tutorial](https://docs.abp.io/en/abp/latest/Tutorials/Part-1) is a complete tutorial to develop a full stack web application with all aspects of a real-life solution.
+- [Quick Start](https://docs.abp.io/en/abp/latest/Tutorials/Todo/Index) is a single-part, quick-start tutorial to build a simple application with the ABP Framework. Start with this tutorial if you want to understand how ABP works quickly.
+- [Getting Started guide](https://docs.abp.io/en/abp/latest/Getting-Started) can be used to create and run ABP-based solutions with different options and details.
+- [Web Application Development Tutorial](https://docs.abp.io/en/abp/latest/Tutorials/Part-1) is a complete tutorial on developing a full-stack web application with all aspects of a real-life solution.
### Quick Start
@@ -34,28 +30,26 @@ Create a new solution:
> See the [CLI documentation](https://docs.abp.io/en/abp/latest/CLI) for all available options.
+
+
### UI Framework Options
+
+
### Database Provider Options
-## The Book: Mastering ABP Framework
-Written by the creator of ABP Framework, this book will help you to gain a complete understanding of the ABP Framework and modern web application development techniques.
-
-* [Buy on Amazon](https://www.amazon.com/gp/product/B097Z2DM8Q)
-* [Buy on Packt Publishing](https://www.packtpub.com/product/mastering-abp-framework/9781801079242)
-* [More details about the book](https://abp.io/books/mastering-abp-framework)
-
-
## What ABP Provides?
ABP provides a **full stack developer experience**.
+
+
### Architecture
@@ -64,30 +58,48 @@ ABP offers a complete, **modular** and **layered** software architecture based o
ABP Framework is suitable for **[microservice solutions](https://docs.abp.io/en/abp/latest/Microservice-Architecture)** as well as monolithic applications.
+
+
### Infrastructure
-There are a lot of features provided by the ABP Framework to achieve real world scenarios easier, like [Event Bus](https://docs.abp.io/en/abp/latest/Event-Bus), [Background Job System](https://docs.abp.io/en/abp/latest/Background-Jobs), [Audit Logging](https://docs.abp.io/en/abp/latest/Audit-Logging), [BLOB Storing](https://docs.abp.io/en/abp/latest/Blob-Storing), [Data Seeding](https://docs.abp.io/en/abp/latest/Data-Seeding), [Data Filtering](https://docs.abp.io/en/abp/latest/Data-Filtering), etc.
+There are a lot of features provided by the ABP Framework to achieve real-world scenarios easier, like [Event Bus](https://docs.abp.io/en/abp/latest/Event-Bus), [Background Job System](https://docs.abp.io/en/abp/latest/Background-Jobs), [Audit Logging](https://docs.abp.io/en/abp/latest/Audit-Logging), [BLOB Storing](https://docs.abp.io/en/abp/latest/Blob-Storing), [Data Seeding](https://docs.abp.io/en/abp/latest/Data-Seeding), [Data Filtering](https://docs.abp.io/en/abp/latest/Data-Filtering), etc.
+
+
+
+### Cross-Cutting Concerns
+
+ABP also simplifies (and even automates wherever possible) cross-cutting concerns and common non-functional requirements like [Exception Handling](https://docs.abp.io/en/abp/latest/Exception-Handling), [Validation](https://docs.abp.io/en/abp/latest/Validation), [Authorization](https://docs.abp.io/en/abp/latest/Authorization), [Localization](https://docs.abp.io/en/abp/latest/Localization), [Caching](https://docs.abp.io/en/abp/latest/Caching), [Dependency Injection](https://docs.abp.io/en/abp/latest/Dependency-Injection), [Setting Management](https://docs.abp.io/en/abp/latest/Settings), etc.
-### Cross Cutting Concerns
-ABP also simplifies (and even automates wherever possible) cross cutting concerns and common non-functional requirements like [Exception Handling](https://docs.abp.io/en/abp/latest/Exception-Handling), [Validation](https://docs.abp.io/en/abp/latest/Validation), [Authorization](https://docs.abp.io/en/abp/latest/Authorization), [Localization](https://docs.abp.io/en/abp/latest/Localization), [Caching](https://docs.abp.io/en/abp/latest/Caching), [Dependency Injection](https://docs.abp.io/en/abp/latest/Dependency-Injection), [Setting Management](https://docs.abp.io/en/abp/latest/Settings), etc.
### Application Modules
ABP is a modular framework and the Application Modules provide **pre-built application functionalities**;
- [**Account**](https://docs.abp.io/en/abp/latest/Modules/Account): Provides UI for the account management and allows user to login/register to the application.
-- **[Identity](https://docs.abp.io/en/abp/latest/Modules/Identity)**: Manages organization units, roles, users and their permissions, based on the Microsoft Identity library.
+- **[Identity](https://docs.abp.io/en/abp/latest/Modules/Identity)**: Manages organization units, roles, users and their permissions based on the Microsoft Identity library.
- [**OpenIddict**](https://docs.abp.io/en/abp/latest/Modules/OpenIddict): Integrates to OpenIddict.
- [**Tenant Management**](https://docs.abp.io/en/abp/latest/Modules/Tenant-Management): Manages tenants for a [multi-tenant](https://docs.abp.io/en/abp/latest/Multi-Tenancy) (SaaS) application.
See the [Application Modules](https://docs.abp.io/en/abp/latest/Modules/Index) document for all pre-built modules.
+
+
### Startup Templates
The [Startup templates](https://docs.abp.io/en/abp/latest/Startup-Templates/Index) are pre-built Visual Studio solution templates. You can create your own solution based on these templates to **immediately start your development**.
-## ABP Community
+
+
+## Mastering ABP Framework Book
+
+This book will help you to gain a complete understanding of the ABP Framework and modern web application development techniques. It is written by the creator and team lead of the ABP Framework. You can buy from [Amazon](https://www.amazon.com/gp/product/B097Z2DM8Q) or [Packt Publishing](https://www.packtpub.com/product/mastering-abp-framework/9781801079242). Find further info about the book at [abp.io/books/mastering-abp-framework](https://abp.io/books/mastering-abp-framework).
+
+
+
+
+
+## The Community
### ABP Community Web Site
@@ -103,28 +115,31 @@ See the [sample projects](https://docs.abp.io/en/abp/latest/Samples/Index) built
### Want to Contribute?
-ABP is a community-driven open source project. See [the contribution guide](https://docs.abp.io/en/abp/latest/Contribution/Index) if you want to be a part of this project.
+ABP is a community-driven open-source project. See [the contribution guide](https://docs.abp.io/en/abp/latest/Contribution/Index) if you want to participate in this project.
+
+
## Official Links
-* Main Web Site
- * Get Started
- * Features
-* Documentation
-* Samples
-* Blog
-* Community
-* Stack overflow
-* Twitter
+* [Home Website](https://abp.io)
+ * [Get Started](https://abp.io/get-started)
+ * [Features](https://abp.io/features)
+* [Documents](https://docs.abp.io/)
+* [Samples](https://docs.abp.io/en/abp/latest/Samples/Index)
+* [Blog](https://blog.abp.io/)
+* [Community](https://community.abp.io/)
+* [Stackoverflow](https://stackoverflow.com/questions/tagged/abp)
+* [Twitter](https://twitter.com/abpframework)
+
+
+
+## Support ABP
-## Support the ABP Framework
+GitHub repository stars are an important indicator of popularity and the size of the community. If you like ABP Framework, support us by clicking the star :star: on the repository.
-Love ABP Framework? **Please give a star** to this repository :star:
-## Discord Channel
-You can use this link to join the ABP Community Discord Server: https://discord.gg/abp
+## Discord Server
-## ABP Commercial
+We have a Discord server where you can chat with other ABP users. Share your ideas, report technical issues, showcase your creations, share the tips that worked for you and catch up with the latest news and announcements about ABP Framework. Join 👉 https://discord.gg/abp.
-See also [ABP Commercial](https://commercial.abp.io/) if you are looking for pre-built application modules, professional themes, code generation tooling and premium support for the ABP Framework.
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/en.json
index 8470709c99..44ab5b3e31 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/en.json
@@ -12,6 +12,7 @@
"CommunityWebSite": "ABP community website",
"ManageAccount": "My Account | ABP.IO",
"ManageYourProfile": "Manage your profile",
- "ReturnToApplication": "Return to application"
+ "ReturnToApplication": "Return to application",
+ "IdentityUserNotAvailable:Deleted": "This email address is not available. Reason: Already deleted."
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json
index f95a0117b6..6ab986076e 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json
@@ -816,6 +816,7 @@
"ErrorExceptionMessage": "حدث خطأ أثناء معالجة طلبك",
"WatchTakeCodeGeneration": "شاهد فيديو \"استكشاف إمكانات إنشاء الأكواد البرمجية: ABP Suite\"!",
"ExtendNow": "تمديد / تجديد",
- "RegisterDemo": "يسجل"
+ "RegisterDemo": "يسجل",
+ "AbpStudio_ComingSoon": "إذا كنت ترغب في اختبار ABP Studio قبل أي شخص آخر، يمكنك أن تصبح أحد مختبري النسخة التجريبية"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/cs.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/cs.json
index 3571ae469e..a92366fa07 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/cs.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/cs.json
@@ -431,6 +431,7 @@
"ErrorExceptionMessage": "Při zpracování vašeho požadavku nastala chyba",
"WatchTakeCodeGeneration": "Podívejte se na video „Prozkoumejte potenciál generování kódu: ABP Suite“!",
"ExtendNow": "Prodloužit / Obnovit",
- "RegisterDemo": "Registrovat"
+ "RegisterDemo": "Registrovat",
+ "AbpStudio_ComingSoon": "Pokud chcete ABP Studio otestovat dříve než kdokoli jiný, staňte se BETA testerem"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/de.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/de.json
index f6e56588f7..dcea7faa20 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/de.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/de.json
@@ -411,6 +411,7 @@
"SendUsEmail": "Senden Sie uns eine E-Mail",
"ErrorExceptionMessage": "Während Ihrer Anfrage ist ein Fehler aufgetreten",
"WatchTakeCodeGeneration": "Sehen Sie sich das Video „Entdecken Sie das Potenzial der Codegenerierung: ABP Suite“ an!",
- "ExtendNow": "Verlängern / Erneuern"
+ "ExtendNow": "Verlängern / Erneuern",
+ "AbpStudio_ComingSoon": "Wenn Sie ABP Studio vor allen anderen testen möchten, werden Sie BETA-Tester"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
index 7a02bf8a39..ae040e7fd2 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
@@ -916,7 +916,7 @@
"AbpStudio_Description": "ABP Studio is still under development. You can fill out the form below to be one of the first users.",
"AbpStudio_Description1": "ABP Studio is a cross-platform desktop application for ABP developers.",
"AbpStudio_Description2": "It is well integrated to the ABP Framework and aims to provide a comfortable development environment for you by automating things, providing insights about your solution, making develop, run and deploy your solutions much easier.",
- "AbpStudio_ComingSoon": "Coming Soon Planned beta release date: Q4 of 2023.",
+ "AbpStudio_ComingSoon": "If you want to test ABP Studio before anyone else, become a BETA tester",
"AbpStudio_PlannedPreviewDate": "Planned preview release date: Q4 of 2023.",
"BetaRequest": "Beta Request",
"CreateNewSolutions": "Create New Solutions",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/es.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/es.json
index 03b6e8ebde..a8389d694d 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/es.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/es.json
@@ -411,6 +411,7 @@
"SendUsEmail": "Envíanos un correo electrónico",
"ErrorExceptionMessage": "Se produjo un error al procesar su solicitud.",
"WatchTakeCodeGeneration": "¡Mire el vídeo \"Explore el potencial de la generación de código: ABP Suite\"!",
- "ExtendNow": "Ampliar / Renovar"
+ "ExtendNow": "Ampliar / Renovar",
+ "AbpStudio_ComingSoon": "Si quieres probar ABP Studio antes que nadie, conviértete en tester BETA"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
index e963dc7032..4c87baefb3 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
@@ -852,6 +852,7 @@
"ErrorExceptionMessage": "Virhe pyynnön käsittelyn yhteydessä",
"WatchTakeCodeGeneration": "Katso \"Tutki koodin luomisen potentiaalia: ABP Suite\" -video!",
"ExtendNow": "Laajenna / Uusi",
- "RegisterDemo": "Rekisteröidy"
+ "RegisterDemo": "Rekisteröidy",
+ "AbpStudio_ComingSoon": "Jos haluat testata ABP Studiota ennen muita, ryhdy BETA-testaajaksi"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json
index 248b575753..a78b492d07 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json
@@ -431,6 +431,7 @@
"ErrorExceptionMessage": "Une erreur s'est produite lors du traitement de votre demande",
"WatchTakeCodeGeneration": "Regardez la vidéo « Explorez le potentiel de la génération de code : ABP Suite » !",
"ExtendNow": "Prolonger / Renouveler",
- "RegisterDemo": "Registre"
+ "RegisterDemo": "Registre",
+ "AbpStudio_ComingSoon": "Si vous souhaitez tester ABP Studio avant tout le monde, devenez BETA testeur"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json
index e48e4494a7..68fab24fc2 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json
@@ -430,6 +430,7 @@
"ErrorExceptionMessage": "आपका अनुरोध संसाधित करते समय एक त्रुटि पाई गई",
"WatchTakeCodeGeneration": "\"कोड जनरेशन की क्षमता का अन्वेषण करें: एबीपी सुइट\" वीडियो देखें!",
"ExtendNow": "विस्तार/नवीनीकरण",
- "RegisterDemo": "पंजीकरण करवाना"
+ "RegisterDemo": "पंजीकरण करवाना",
+ "AbpStudio_ComingSoon": "यदि आप किसी और से पहले एबीपी स्टूडियो का परीक्षण करना चाहते हैं, तो बीटा परीक्षक बनें"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hr.json
index fe67373478..07974134a2 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hr.json
@@ -915,7 +915,6 @@
"AbpStudio_Description": "ABP Studio je još uvijek u razvoju. Možete ispuniti obrazac ispod i biti jedan od prvih korisnika.",
"AbpStudio_Description1": "ABP Studio je stolna aplikacija za više platformi za ABP programere.",
"AbpStudio_Description2": "Dobro je integriran u ABP Framework i ima za cilj pružiti vam ugodno razvojno okruženje automatiziranjem stvari, pružanjem uvida u vaše rješenje, čineći razvoj, pokretanje i implementaciju vaših rješenja puno lakšim.",
- "AbpStudio_ComingSoon": "Uskoro. Planirani datum izdavanja beta verzije: 4. tromjesečje 2023.",
"AbpStudio_PlannedPreviewDate": "Planirani datum izdavanja pregleda: 4. kvartal 2023.",
"BetaRequest": "Zahtjev za beta verziju",
"CreateNewSolutions": "Stvorite nova rješenja",
@@ -1107,6 +1106,7 @@
"SendUsEmail": "Pošaljite nam e-mail",
"ErrorExceptionMessage": "Pojavila se greška prilikom obrade Vašeg zahtjeva",
"WatchTakeCodeGeneration": "Pogledajte video \"Istražite potencijal generiranja koda: ABP Suite\"!",
- "ExtendNow": "Produži / obnovi"
+ "ExtendNow": "Produži / obnovi",
+ "AbpStudio_ComingSoon": "Ako želite testirati ABP Studio prije svih ostalih, postanite BETA tester"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json
index 4b4b099c49..4fbdb2a8d4 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json
@@ -777,6 +777,7 @@
"SendUsEmail": "Küldjön nekünk e-mailt",
"ErrorExceptionMessage": "Hiba történt a kérése feldolgozása során",
"WatchTakeCodeGeneration": "Nézze meg a \"Fedezze fel a kódgenerálás lehetőségét: ABP Suite\" videót!",
- "ExtendNow": "Bővítés / Megújítás"
+ "ExtendNow": "Bővítés / Megújítás",
+ "AbpStudio_ComingSoon": "Ha bárki más előtt szeretné tesztelni az ABP Studio-t, legyen BÉTA tesztelő"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/is.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/is.json
index 6b5a58480e..be9337e842 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/is.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/is.json
@@ -408,6 +408,7 @@
"SendUsEmail": "Sendu okkur tölvupóst",
"ErrorExceptionMessage": "Villa kom upp við úrvinnslu beiðni þinnar",
"WatchTakeCodeGeneration": "Horfðu á \"Kannaðu möguleika kóðaframleiðslu: ABP Suite\" myndbandið!",
- "ExtendNow": "Framlengja / endurnýja"
+ "ExtendNow": "Framlengja / endurnýja",
+ "AbpStudio_ComingSoon": "Ef þú vilt prófa ABP Studio á undan öllum öðrum skaltu gerast BETA prófari"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json
index 633c41f66e..edc80b48e1 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json
@@ -430,6 +430,7 @@
"ErrorExceptionMessage": "Si è verificato un errore durante l'elaborazione della richiesta",
"WatchTakeCodeGeneration": "Guarda il video \"Esplora il potenziale della generazione di codice: ABP Suite\"!",
"ExtendNow": "Estendi/Rinnova",
- "RegisterDemo": "Registrati"
+ "RegisterDemo": "Registrati",
+ "AbpStudio_ComingSoon": "Se vuoi provare ABP Studio prima di chiunque altro, diventa un BETA tester"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/nl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/nl.json
index c26bdb8993..da7037c8f2 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/nl.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/nl.json
@@ -408,6 +408,7 @@
"SendUsEmail": "Stuur ons een e-mail",
"ErrorExceptionMessage": "Er is een fout opgetreden bij het verwerken van uw verzoek",
"WatchTakeCodeGeneration": "Bekijk de video 'Ontdek het potentieel van codegeneratie: ABP Suite'!",
- "ExtendNow": "Verlengen / Verlengen"
+ "ExtendNow": "Verlengen / Verlengen",
+ "AbpStudio_ComingSoon": "Als u ABP Studio als eerste wilt testen, wordt dan BETA-tester"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pl-PL.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pl-PL.json
index c5b0849545..8c37e62706 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pl-PL.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pl-PL.json
@@ -409,6 +409,7 @@
"ErrorExceptionMessage": "Podczas przetwarzania żądania wystąpił błąd",
"WatchTakeCodeGeneration": "Obejrzyj film „Odkryj potencjał generowania kodu: pakiet ABP”!",
"ExtendNow": "Przedłuż/Odnów",
- "RegisterDemo": "Rejestr"
+ "RegisterDemo": "Rejestr",
+ "AbpStudio_ComingSoon": "Jeśli chcesz przetestować ABP Studio zanim ktokolwiek inny, zostań testerem BETA"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pt-BR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pt-BR.json
index fd92099059..43d80af012 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pt-BR.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pt-BR.json
@@ -431,6 +431,7 @@
"SendUsEmail": "Envie-nos um e-mail",
"ErrorExceptionMessage": "Um erro ocorreu durante o processamento do seu pedido",
"WatchTakeCodeGeneration": "Assista ao vídeo \"Explore o potencial de geração de código: ABP Suite\"!",
- "ExtendNow": "Estender/Renovar"
+ "ExtendNow": "Estender/Renovar",
+ "AbpStudio_ComingSoon": "Se você quiser testar o ABP Studio antes de todo mundo, torne-se um testador BETA"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
index b2693311a2..b04650b958 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
@@ -408,6 +408,7 @@
"SendUsEmail": "Trimite-ne e-mail",
"ErrorExceptionMessage": "A apărut o eroare în timpul procesării cererii dumneavoastră",
"WatchTakeCodeGeneration": "Urmărește videoclipul „Explorați potențialul generării codului: ABP Suite”!",
- "ExtendNow": "Extinde/Reînnoiește"
+ "ExtendNow": "Extinde/Reînnoiește",
+ "AbpStudio_ComingSoon": "Dacă doriți să testați ABP Studio înaintea oricui, deveniți un tester BETA"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json
index f06bc507c7..48f4a3c304 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json
@@ -427,6 +427,7 @@
"SendUsEmail": "Pošlite nám e-mail",
"ErrorExceptionMessage": "Nastala chyba pri spracovaní vašej žiadosti",
"WatchTakeCodeGeneration": "Pozrite si video „Preskúmajte potenciál generovania kódu: ABP Suite“!",
- "ExtendNow": "Predĺžiť / obnoviť"
+ "ExtendNow": "Predĺžiť / obnoviť",
+ "AbpStudio_ComingSoon": "Ak chcete otestovať ABP Studio skôr ako ktokoľvek iný, staňte sa BETA testerom"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sl.json
index b7a5724528..870268c576 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sl.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sl.json
@@ -409,6 +409,7 @@
"ErrorExceptionMessage": "Pri obdelavi vaše zahteve je prišlo do napake",
"WatchTakeCodeGeneration": "Oglejte si video »Raziščite potencial generiranja kode: zbirka ABP«!",
"ExtendNow": "Podaljšaj / obnovi",
- "RegisterDemo": "Registrirajte se"
+ "RegisterDemo": "Registrirajte se",
+ "AbpStudio_ComingSoon": "Če želite preizkusiti ABP Studio pred vsemi drugimi, postanite BETA tester"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
index 4366f26e8f..64bf89dc48 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
@@ -1058,7 +1058,6 @@
"AbpStudio_Description": "ABP Studio hala geliştirme aşamasında. İlk kullanıcılardan biri olmak için aşağıdaki formu doldurabilirsiniz.",
"AbpStudio_Description1": "ABP Studio, ABP geliştiricileri için çok platformlu masaüstü uygulamasıdır.",
"AbpStudio_Description2": "ABP Studio, ABP Framework'e iyi entegre edilmiştir ve sizin için işleri otomatikleştirerek, projeniz hakkında bilgi sağlayarak, projelerinizi geliştirmeyi, çalıştırmayı ve dağıtımını çok daha kolay hale getirmeyi amaçlamaktadır.",
- "AbpStudio_ComingSoon": "Yakında Planlanan beta sürüm tarihi: 2023'ün 4. çeyreği.",
"AbpStudio_PlannedPreviewDate": "Planlanan beta sürüm tarihi: 2023'ün 4. çeyreği.",
"BetaRequest": "Beta Talebi",
"CreateNewSolutions": "Yeni Projeler Oluştur",
@@ -1140,6 +1139,7 @@
"RemoveBasket": "Sepetten kaldır",
"TrainingPack": "Eğitim paketi",
"TrainingPackDiscount": "Eğitim paketi indirimi",
- "LinkExpiredMessage": "Ödeme bağlantısının süresi doldu! Bağlantıyı güncellemek için sales@volosoft.com adresinden bizimle iletişime geçin veya iletişim sayfasına gitmek için buraya tıklayın."
+ "LinkExpiredMessage": "Ödeme bağlantısının süresi doldu! Bağlantıyı güncellemek için sales@volosoft.com adresinden bizimle iletişime geçin veya iletişim sayfasına gitmek için buraya tıklayın.",
+ "AbpStudio_ComingSoon": "ABP Studio'yu herkesten önce test etmek istiyorsanız BETA test kullanıcısı olun"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/vi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/vi.json
index ee588cba8f..231687fc9b 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/vi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/vi.json
@@ -408,6 +408,7 @@
"SendUsEmail": "Gửi email cho chúng tôi",
"ErrorExceptionMessage": "Đã xảy ra lỗi trong khi xử lý yêu cầu của bạn",
"WatchTakeCodeGeneration": "Xem video \"Khám phá tiềm năng tạo mã: ABP Suite\"!",
- "ExtendNow": "Gia hạn/Gia hạn"
+ "ExtendNow": "Gia hạn/Gia hạn",
+ "AbpStudio_ComingSoon": "Nếu bạn muốn thử nghiệm ABP Studio trước bất kỳ ai khác, hãy trở thành người thử nghiệm BETA"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
index afb9a428e9..5f8141bf2a 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
@@ -915,7 +915,6 @@
"AbpStudio_Description": "ABP Studio 仍在开发中。您可以填写下面的表单,成为首批用户之一。",
"AbpStudio_Description1": "ABP Studio 是专为 ABP 开发人员设计的跨平台桌面应用程序。",
"AbpStudio_Description2": "它与 ABP 框架集成得很好,旨在通过自动化、提供有关解决方案的见解,为您提供舒适的开发环境,使开发、运行和部署解决方案变得更加容易。",
- "AbpStudio_ComingSoon": "即将发布 计划测试版发布日期:计划测试版发布日期:2023年第四季度。",
"AbpStudio_PlannedPreviewDate": "计划预览版发布日期:2023 年第四季度。",
"BetaRequest": "测试版请求",
"CreateNewSolutions": "创建新的解决方案",
@@ -1110,6 +1109,7 @@
"ErrorExceptionMessage": "处理您的请求时发生错误",
"WatchTakeCodeGeneration": "观看“探索代码生成的潜力:ABP Suite”视频!",
"PreBuiltApplicationModulesTitle": "预构建应用程序 模块",
- "RegisterDemo": "登记"
+ "RegisterDemo": "登记",
+ "AbpStudio_ComingSoon": "如果您想先于其他人测试 ABP Studio,请成为 BETA 测试员"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
index 1d57000aee..302007af79 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
@@ -897,7 +897,6 @@
"AbpStudio_Description": "ABP Studio 仍在開發中。您可以填寫下面的表单,成為第一批使用者之一。",
"AbpStudio_Description1": "ABP Studio 是一款針對 ABP 開發人員的跨平台桌面應用程式。",
"AbpStudio_Description2": "它與 ABP 框架很好地集成,旨在透過自動化為您提供一個舒適的開發環境,提供有關您的解決方案的見解,使開發、運行和部署您的解決方案變得更加容易。",
- "AbpStudio_ComingSoon": "即將推出計劃測試版發布日期:2023 年第四季。",
"AbpStudio_PlannedPreviewDate": "計畫預覽版發布日期:2023 年第四季。",
"BetaRequest": "測試版請求",
"CreateNewSolutions": "建立新的解決方案",
@@ -1100,6 +1099,7 @@
"WatchTakeCodeGeneration": "观看“探索代码生成的潜力:ABP Suite”视频!",
"ExtendNow": "延长 / 续订",
"PreBuiltApplicationModulesTitle": "预构建应用程序 模块",
- "RegisterDemo": "登记"
+ "RegisterDemo": "登记",
+ "AbpStudio_ComingSoon": "如果您想先于其他人测试 ABP Studio,请成为 BETA 测试员"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json
index 2b6f5db40c..fef40ce7c1 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json
@@ -259,6 +259,9 @@
"MarkdownSupported": "Markdown أيد.",
"Preview": "معاينة",
"VisitVideoCourseDescription": "إذا كنت ترغب في تعلم أساسيات إطار عمل برنامج ABP، فاطلع على دورات الفيديو الخاصة ببرنامج ABP Essentials.",
- "VisitPage": "زر الصفحة"
+ "VisitPage": "زر الصفحة",
+ "ConfirmEmailForPost": "لتتمكن من النشر، تحتاج إلى تأكيد بريدك الإلكتروني. انتقل إلى account.abp.io/Account/Manage وتحقق من بريدك الإلكتروني في علامة التبويب \"المعلومات الشخصية\".",
+ "DailyPostCreateLimitation": "لقد وصلت إلى الحد الأقصى اليومي لإنشاء المنشورات. يمكنك إنشاء مشاركة جديدة في {0}.",
+ "YourAccountDisabled": "تم تعطيل حساب المستخدم الخاص بك!"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json
index 35119a1408..86910d5557 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown podporováno.",
"Preview": "Náhled",
"VisitPage": "Navštivte stránku",
- "VisitVideoCourseDescription": "Pokud se chcete naučit základy rámce ABP, podívejte se na videokurzy ABP Essentials."
+ "VisitVideoCourseDescription": "Pokud se chcete naučit základy rámce ABP, podívejte se na videokurzy ABP Essentials.",
+ "ConfirmEmailForPost": "Abyste mohli přidávat příspěvky, musíte potvrdit svůj e-mail. Přejděte na stránku account.abp.io/Account/Manage a ověřte svůj e-mail na kartě Osobní údaje.",
+ "DailyPostCreateLimitation": "Dosáhli jste denního limitu pro vytváření příspěvků. Nový příspěvek můžete vytvořit v {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json
index d26c081de5..99c60d5199 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown unterstützt.",
"Preview": "Vorschau",
"VisitPage": "Seite besuchen",
- "VisitVideoCourseDescription": "Wenn Sie die Grundlagen des ABP Framework erlernen möchten, schauen Sie sich die ABP Essentials-Videokurse an."
+ "VisitVideoCourseDescription": "Wenn Sie die Grundlagen des ABP Framework erlernen möchten, schauen Sie sich die ABP Essentials-Videokurse an.",
+ "ConfirmEmailForPost": "Um Beiträge verfassen zu können, müssen Sie Ihre E-Mail-Adresse bestätigen. Gehen Sie zu account.abp.io/Account/Manage und bestätigen Sie Ihre E-Mail-Adresse auf der Registerkarte „Persönliche Daten“.",
+ "DailyPostCreateLimitation": "Sie haben das tägliche Limit für die Erstellung von Beiträgen erreicht. Sie können in {0} einen neuen Beitrag erstellen."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json
index 347b18ce4b..dc59234777 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json
@@ -59,7 +59,7 @@
"MilestoneErrorMessage": "Couldn't get the current milestone details from Github.",
"QuestionItemErrorMessage": "Couldn't get the latest question details from Stackoverflow.",
"Oops": "Oops!",
- "CreatePostSuccessMessage": "The Post has been successfully submitted. It will be published once it has been reviewed by the site admin.",
+ "CreatePostSuccessMessage": "Your post has been successfully submitted. It will be published after review by the site administrator.",
"ChooseCoverImage": "Choose a cover image...",
"CoverImage": "Cover Image",
"ShareYourExperiencesWithTheABPFramework": "Share your experiences with the ABP Framework!",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
index 80fbc8539b..78231bb1af 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
@@ -16,7 +16,7 @@
"Title": "Title",
"CreationTime": "Creation time",
"Save": "Save",
- "SameUrlAlreadyExist": "Same url already exists if you want to add this post, you should change the url!",
+ "SameUrlAlreadyExist": "Same URL already exists! You must change the URL!",
"UrlIsNotValid": "Url is not valid.",
"UrlNotFound": "Url not found.",
"UrlContentNotFound": "Url content not found.",
@@ -33,7 +33,7 @@
"FeatureRequest": "Feature Request",
"CreatePostTitleInfo": "Title of the post to be shown on the post list.",
"CreatePostSummaryInfo": "A short summary of the post to be shown on the post list. Maximum length: {0}",
- "CreatePostCoverInfo": "For creating an effective post, add a cover photo. Upload 16:9 aspect ratio pictures for the best view. Maximum file size: 1MB.",
+ "CreatePostCoverInfo": "To create an effective post, add a cover photo. Upload 16:9 aspect ratio pictures for the best view. Maximum file size is 1MB.",
"ThisExtensionIsNotAllowed": "This extension is not allowed.",
"TheFileIsTooLarge": "The file is too large.",
"GoToThePost": "Go to the Post",
@@ -56,7 +56,7 @@
"MilestoneErrorMessage": "Could not get the current milestone details from Github.",
"QuestionItemErrorMessage": "Could not get the latest question details from Stackoverflow.",
"Oops": "Oops!",
- "CreatePostSuccessMessage": "The Post has been successfully submitted. It will be published after a review from the site admin.",
+ "CreatePostSuccessMessage": "Your post has been successfully submitted. It will be published after review by the site administrator.",
"Browse": "Browse",
"CoverImage": "Cover Image",
"ShareYourExperiencesWithTheABPFramework": "Share your experiences with the ABP Framework!",
@@ -125,7 +125,7 @@
"YoutubeVideoSubmitStepTwo": "2. Submit the video URL using the form.",
"YoutubeVideoSubmitStepThree": "3. Visitors will be able to watch your video content directly on this website.",
"ExternalContent": "External Content",
- "ExternalContentSubmitStepOne": "1. Create a content on any public platform (Medium, your own blog or anywhere you like).",
+ "ExternalContentSubmitStepOne": "1. Create content on any public platform (Medium, your own blog or anywhere you like).",
"ExternalContentSubmitStepTwo": "2. Submit your content URL using the form.",
"ExternalContentSubmitStepThree": "3. Visitors are redirected to the content on the original website.",
"ChooseYourContentType": "Please choose the way you want to add your content.",
@@ -135,12 +135,12 @@
"GitHubUserNameValidationMessage": "Your Github username can not include whitespace, please make sure your Github username is correct.",
"PersonalSiteUrlValidationMessage": "Your personal site URL can not include whitespace, please make sure your personal site URL is correct.",
"TwitterUserNameValidationMessage": "Your Twitter username can not include whitespace, please make sure your Twitter username is correct.",
- "LinkedinUrlValidationMessage": "Your Linkedin URL can not include whitespace, please make sure your Linkedin URL is correct.",
+ "LinkedinUrlValidationMessage": "Your LinkedIn URL can not include whitespace, please make sure your LinkedIn URL is correct.",
"NoPostsFound": "No posts found!",
"SearchInPosts": "Search in posts...",
"MinimumSearchContent": "You must enter at least 3 characters!",
"Volo.AbpIo.Domain:060001": "Source URL(\"{PostUrl}\") is not Github URL",
- "Volo.AbpIo.Domain:060002": "Post Content is not available from Github(\"{PostUrl}\") resource.",
+ "Volo.AbpIo.Domain:060002": "Post Content is not available from GitHub(\"{PostUrl}\") resource.",
"Volo.AbpIo.Domain:060003": "No post content found!",
"SeeMore": "See More",
"JoinTheABPCommunity": "Join the ABP Community",
@@ -171,14 +171,14 @@
"Discord_Page_Announce": "We are happy to announce ABP Community Discord Server!",
"Discord_Page_Description_1": "ABP Community has been growing since day one. We wanted to take it to the next step by creating an official ABP Discord server so the ABP Community can interact with each other using the wonders of instant messaging.",
"Discord_Page_Description_2": "ABP Community Discord Server is the place where you can showcase your creations using ABP Framework, share the tips that worked for you, catch up with the latest news and announcements about ABP Framework, just chat with community members to exchange ideas, and have fun!",
- "Discord_Page_Description_3": "This ABP Community Discord Server is the official one with the ABP Core Team is present on the server to monitor.",
+ "Discord_Page_Description_3": "This ABP Community Discord Server is the official one with the ABP Core Team present on the server to monitor.",
"Discord_Page_JoinToServer": "Join ABP Discord Server",
"Events_Page_MetaTitle": "ABP Community Events",
"Events_Page_MetaDescription": "The live shows, hosted by the ABP Team, are casual sessions full of community content, demos, Q&A, and discussions around what's happening in ABP.",
"Events_Page_Title": "ABP Community Talks",
"Members_Page_WritingFromUser": "Read writing from {0} on ABP Community.",
"Post_Create_Page_MetaTitle": "New Post",
- "Post_Create_Page_MetaDescription": "Create your post for sharing your experiences about ABP framework and contributing the ABP Community.",
+ "Post_Create_Page_MetaDescription": "Create your post for sharing your experiences about the ABP framework and contributing to the ABP Community.",
"Post_Create_Page_CreateNewPost": "Create New Post",
"Post_Index_Page_MetaDescription": "ABP Community's purpose is to create a contribution environment for developers who use the ABP framework.",
"Layout_Title": "{0} | ABP Community",
@@ -193,7 +193,7 @@
"AbpCommunityTitleContent": "ABP Community - Open Source ABP Framework",
"CommunitySlogan": "A unique community platform for ABP Lovers",
"RaffleIsNotActive": "Raffle is not active",
- "YouAreAlreadyJoinedToThisRaffle": "You already joined to this raffle!",
+ "YouAreAlreadyJoinedToThisRaffle": "You already joined this raffle!",
"InvalidSubscriptionCode": "Invalid subscription code",
"Raffle:{0}": "Raffle: {0}",
"Join": "Join",
@@ -261,6 +261,9 @@
"Preview": "Preview",
"VisitPage": "Visit Page",
"VisitVideoCourseDescription": "If you want to learn the basics of the ABP Framework, check out the ABP Essentials Video courses.",
- "EditProfile": "Edit Profile"
+ "EditProfile": "Edit Profile",
+ "ConfirmEmailForPost": "To be able to post, you need to confirm your email. Go to account.abp.io/Account/Manage and verify your email in the Personal Info tab.",
+ "DailyPostCreateLimitation": "You have reached the daily post creation limit. You can create a new post in {0}.",
+ "YourAccountDisabled": "Your user account is disabled!"
}
-}
\ No newline at end of file
+}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json
index bf045dea81..2403cb7681 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown soportado.",
"Preview": "Avance",
"VisitPage": "Visita la página",
- "VisitVideoCourseDescription": "Si desea aprender los conceptos básicos del marco ABP, consulte los cursos en vídeo de ABP Essentials."
+ "VisitVideoCourseDescription": "Si desea aprender los conceptos básicos del marco ABP, consulte los cursos en vídeo de ABP Essentials.",
+ "ConfirmEmailForPost": "Para poder publicar, debe confirmar su correo electrónico. Vaya a account.abp.io/Account/Manage y verifique su correo electrónico en la pestaña Información personal.",
+ "DailyPostCreateLimitation": "Has alcanzado el límite diario de creación de publicaciones. Puedes crear una nueva publicación en {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json
index acf70381ff..3f420b1822 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown tuettu.",
"Preview": "Esikatselu",
"VisitPage": "Vieraile sivulla",
- "VisitVideoCourseDescription": "Jos haluat oppia ABP Frameworkin perusteet, katso ABP Essentials Video -kurssit."
+ "VisitVideoCourseDescription": "Jos haluat oppia ABP Frameworkin perusteet, katso ABP Essentials Video -kurssit.",
+ "ConfirmEmailForPost": "Jotta voit lähettää viestejä, sinun on vahvistettava sähköpostiosoitteesi. Siirry osoitteeseen account.abp.io/Account/Manage ja vahvista sähköpostiosoitteesi Henkilökohtaiset tiedot -välilehdessä.",
+ "DailyPostCreateLimitation": "Olet saavuttanut päivittäisen viestien luomisrajan. Voit luoda uuden viestin kohteessa {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json
index 963bde3048..a7821015b4 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown prise en charge.",
"Preview": "Aperçu",
"VisitPage": "Page de visite",
- "VisitVideoCourseDescription": "Si vous souhaitez apprendre les bases du framework ABP, consultez les cours vidéo ABP Essentials."
+ "VisitVideoCourseDescription": "Si vous souhaitez apprendre les bases du framework ABP, consultez les cours vidéo ABP Essentials.",
+ "ConfirmEmailForPost": "Pour pouvoir publier, vous devez confirmer votre e-mail. Accédez à account.abp.io/Account/Manage et vérifiez votre e-mail dans l'onglet Informations personnelles.",
+ "DailyPostCreateLimitation": "Vous avez atteint la limite quotidienne de création de publications. Vous pouvez créer une nouvelle publication dans {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json
index 940d92573f..87919eef8b 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown का समर्थन किया।",
"Preview": "पूर्व दर्शन",
"VisitPage": "यात्रा पेज",
- "VisitVideoCourseDescription": "यदि आप एबीपी फ्रेमवर्क की मूल बातें सीखना चाहते हैं, तो एबीपी एसेंशियल वीडियो पाठ्यक्रम देखें।"
+ "VisitVideoCourseDescription": "यदि आप एबीपी फ्रेमवर्क की मूल बातें सीखना चाहते हैं, तो एबीपी एसेंशियल वीडियो पाठ्यक्रम देखें।",
+ "ConfirmEmailForPost": "पोस्ट करने में सक्षम होने के लिए, आपको अपने ईमेल की पुष्टि करनी होगी। account.abp.io/Account/Manage पर जाएं और व्यक्तिगत जानकारी टैब में अपना ईमेल सत्यापित करें।",
+ "DailyPostCreateLimitation": "आप दैनिक पोस्ट निर्माण सीमा तक पहुंच गए हैं। आप {0} में एक नई पोस्ट बना सकते हैं।"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json
index f0b3a5941c..5cb7ff44a0 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown podržan.",
"Preview": "Pregled",
"VisitPage": "Posjetite stranicu",
- "VisitVideoCourseDescription": "Ako želite naučiti osnove ABP okvira, pogledajte video tečajeve ABP Essentials."
+ "VisitVideoCourseDescription": "Ako želite naučiti osnove ABP okvira, pogledajte video tečajeve ABP Essentials.",
+ "ConfirmEmailForPost": "Da biste mogli objavljivati, morate potvrditi svoju e-poštu. Idite na account.abp.io/Account/Manage i potvrdite svoju e-poštu na kartici Osobni podaci.",
+ "DailyPostCreateLimitation": "Dosegli ste dnevno ograničenje za izradu postova. Možete stvoriti novi post u {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json
index 84117ededd..95433c6d92 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown támogatott.",
"Preview": "Előnézet",
"VisitPage": "Látogassa meg az oldalt",
- "VisitVideoCourseDescription": "Ha meg szeretné tanulni az ABP Framework alapjait, nézze meg az ABP Essentials Video tanfolyamokat."
+ "VisitVideoCourseDescription": "Ha meg szeretné tanulni az ABP Framework alapjait, nézze meg az ABP Essentials Video tanfolyamokat.",
+ "ConfirmEmailForPost": "A bejegyzések közzétételéhez meg kell erősítenie e-mail-címét. Nyissa meg az account.abp.io/Account/Manage oldalt, és ellenőrizze e-mail-címét a Személyes adatok lapon.",
+ "DailyPostCreateLimitation": "Elérte a napi bejegyzéslétrehozási korlátot. Új bejegyzést itt hozhat létre: {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json
index 953186b239..8f2a733a2d 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown stutt.",
"Preview": "Forskoðun",
"VisitPage": "Heimsæktu síðu",
- "VisitVideoCourseDescription": "Ef þú vilt læra grunnatriði ABP Framework skaltu skoða ABP Essentials Video námskeiðin."
+ "VisitVideoCourseDescription": "Ef þú vilt læra grunnatriði ABP Framework skaltu skoða ABP Essentials Video námskeiðin.",
+ "ConfirmEmailForPost": "Til að geta sent færslur þarftu að staðfesta netfangið þitt. Farðu á account.abp.io/Account/Manage og staðfestu tölvupóstinn þinn á Persónulegum upplýsingum flipanum.",
+ "DailyPostCreateLimitation": "Þú hefur náð daglegu takmörkunum fyrir færslu færslu. Þú getur búið til nýja færslu í {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json
index 88bf43fc0e..45021c315d 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown supportato.",
"Preview": "Anteprima",
"VisitPage": "Visita la pagina",
- "VisitVideoCourseDescription": "Se vuoi apprendere le nozioni di base del Framework ABP, dai un'occhiata ai corsi video ABP Essentials."
+ "VisitVideoCourseDescription": "Se vuoi apprendere le nozioni di base del Framework ABP, dai un'occhiata ai corsi video ABP Essentials.",
+ "ConfirmEmailForPost": "Per poter pubblicare, devi confermare la tua email. Vai su account.abp.io/Account/Manage e verifica la tua email nella scheda Informazioni personali.",
+ "DailyPostCreateLimitation": "Hai raggiunto il limite giornaliero di creazione di post. Puoi creare un nuovo post in {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json
index 5d18bde830..958c68263d 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown ondersteund.",
"Preview": "Voorbeeld",
"VisitPage": "Bezoek pagina",
- "VisitVideoCourseDescription": "Als je de basis van het ABP Framework wilt leren, bekijk dan de ABP Essentials Videocursussen."
+ "VisitVideoCourseDescription": "Als je de basis van het ABP Framework wilt leren, bekijk dan de ABP Essentials Videocursussen.",
+ "ConfirmEmailForPost": "Om te kunnen posten, moet u uw e-mailadres bevestigen. Ga naar account.abp.io/Account/Manage en verifieer uw e-mailadres op het tabblad Persoonlijke informatie.",
+ "DailyPostCreateLimitation": "Je hebt de dagelijkse limiet voor het maken van berichten bereikt. Je kunt een nieuw bericht maken in {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json
index a86b93515c..16af07e6e4 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown utrzymany.",
"Preview": "Zapowiedź",
"VisitPage": "Odwiedź stronę",
- "VisitVideoCourseDescription": "Jeśli chcesz poznać podstawy ABP Framework, sprawdź kursy wideo ABP Essentials."
+ "VisitVideoCourseDescription": "Jeśli chcesz poznać podstawy ABP Framework, sprawdź kursy wideo ABP Essentials.",
+ "ConfirmEmailForPost": "Aby móc publikować, musisz potwierdzić swój adres e-mail. Przejdź do account.abp.io/Account/Manage i zweryfikuj swój adres e-mail w zakładce Dane osobowe.",
+ "DailyPostCreateLimitation": "Osiągnąłeś dzienny limit tworzenia postów. Możesz utworzyć nowy post w {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json
index af28a46228..249e758a53 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown suportado.",
"Preview": "Visualização",
"VisitPage": "Visite a página",
- "VisitVideoCourseDescription": "Se você quiser aprender o básico do ABP Framework, confira os cursos em vídeo ABP Essentials."
+ "VisitVideoCourseDescription": "Se você quiser aprender o básico do ABP Framework, confira os cursos em vídeo ABP Essentials.",
+ "ConfirmEmailForPost": "Para poder postar, você precisa confirmar seu e-mail. Acesse account.abp.io/Account/Manage e verifique seu e-mail na guia Informações pessoais.",
+ "DailyPostCreateLimitation": "Você atingiu o limite diário de criação de postagens. Você pode criar uma nova postagem em {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json
index e9d89b398b..7d33ecdb90 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown sprijinit.",
"Preview": "previzualizare",
"VisitPage": "Vizitați pagina",
- "VisitVideoCourseDescription": "Dacă doriți să aflați elementele de bază ale cadrului ABP, consultați cursurile video ABP Essentials."
+ "VisitVideoCourseDescription": "Dacă doriți să aflați elementele de bază ale cadrului ABP, consultați cursurile video ABP Essentials.",
+ "ConfirmEmailForPost": "Pentru a putea posta, trebuie să vă confirmați adresa de e-mail. Accesați account.abp.io/Account/Manage și verificați e-mailul în fila Informații personale.",
+ "DailyPostCreateLimitation": "Ați atins limita zilnică de creare a postărilor. Puteți crea o postare nouă în {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json
index dcfbc84bf9..6c842ef388 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown podporované.",
"Preview": "Náhľad",
"VisitPage": "Navštívte stránku",
- "VisitVideoCourseDescription": "Ak sa chcete naučiť základy rámca ABP, pozrite si video kurzy ABP Essentials."
+ "VisitVideoCourseDescription": "Ak sa chcete naučiť základy rámca ABP, pozrite si video kurzy ABP Essentials.",
+ "ConfirmEmailForPost": "Aby ste mohli uverejňovať príspevky, musíte potvrdiť svoj e-mail. Prejdite na stránku account.abp.io/Account/Manage a overte svoj e-mail na karte Osobné informácie.",
+ "DailyPostCreateLimitation": "Dosiahli ste denný limit na vytváranie príspevkov. Nový príspevok môžete vytvoriť v {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json
index 8ed4d53271..eb6a616017 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown podprt.",
"Preview": "Predogled",
"VisitPage": "Obiščite stran",
- "VisitVideoCourseDescription": "Če se želite naučiti osnov ogrodja ABP, si oglejte video tečaje ABP Essentials."
+ "VisitVideoCourseDescription": "Če se želite naučiti osnov ogrodja ABP, si oglejte video tečaje ABP Essentials.",
+ "ConfirmEmailForPost": "Če želite objavljati, morate potrditi svoj e-poštni naslov. Pojdite na account.abp.io/Account/Manage in potrdite svoj e-poštni naslov na zavihku Osebni podatki.",
+ "DailyPostCreateLimitation": "Dosegli ste dnevno omejitev za ustvarjanje objav. Novo objavo lahko ustvarite v {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json
index 711d068087..8d42d61eb0 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json
@@ -244,6 +244,9 @@
"BuyTicket": "Bilet al",
"SeeEvent": "Etkinliği Gör",
"Cancel": "Vazgeç",
- "Continue": "Devam"
+ "Continue": "Devam",
+ "ConfirmEmailForPost": "Gönderi paylaşabilmek için e-posta adresinizi onaylamanız gerekir. account.abp.io/Account/Manage adresine gidin ve Kişisel Bilgiler sekmesinden e-posta adresinizi doğrulayın.",
+ "DailyPostCreateLimitation": "Günlük gönderi paylaşma sınırına ulaştınız. {0}'da yeni bir gönderi paylaşabilirsiniz.",
+ "YourAccountDisabled": "Kullanıcı hesabınız devre dışı bırakıldı!"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json
index bd6baa67bb..4ca0c8ca49 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown được hỗ trợ.",
"Preview": "Xem trước",
"VisitPage": "Ghé thăm trang",
- "VisitVideoCourseDescription": "Nếu bạn muốn tìm hiểu những kiến thức cơ bản về Khung ABP, hãy xem các khóa học Video Cơ bản về ABP."
+ "VisitVideoCourseDescription": "Nếu bạn muốn tìm hiểu những kiến thức cơ bản về Khung ABP, hãy xem các khóa học Video Cơ bản về ABP.",
+ "ConfirmEmailForPost": "Để có thể đăng bài, bạn cần xác nhận email của mình. Hãy truy cập account.abp.io/Account/Quản lý và xác minh email của bạn trong tab Thông tin cá nhân.",
+ "DailyPostCreateLimitation": "Bạn đã đạt đến giới hạn tạo bài đăng hàng ngày. Bạn có thể tạo bài đăng mới trong {0}."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
index 2bf0e9fb50..c6ef5a2c3d 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown 支持的。",
"Preview": "预览",
"VisitPage": "访问页面",
- "VisitVideoCourseDescription": "如果您想学习 ABP 框架的基础知识,请查看 ABP Essentials 视频课程。"
+ "VisitVideoCourseDescription": "如果您想学习 ABP 框架的基础知识,请查看 ABP Essentials 视频课程。",
+ "ConfirmEmailForPost": "为了能够发帖,您需要确认您的电子邮件。转到 account.abp.io/Account/Manage 并在“个人信息”选项卡中验证您的电子邮件。",
+ "DailyPostCreateLimitation": "您已达到每日帖子创建限制。您可以在 {0} 中创建新帖子。"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json
index 61bb0aa8a0..b72c927296 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json
@@ -259,6 +259,8 @@
"MarkdownSupported": "Markdown 支持的。",
"Preview": "预览",
"VisitPage": "访问页面",
- "VisitVideoCourseDescription": "如果您想学习 ABP 框架的基础知识,请查看 ABP Essentials 视频课程。"
+ "VisitVideoCourseDescription": "如果您想学习 ABP 框架的基础知识,请查看 ABP Essentials 视频课程。",
+ "ConfirmEmailForPost": "为了能够发帖,您需要确认您的电子邮件。转到 account.abp.io/Account/Manage 并在“个人信息”选项卡中验证您的电子邮件。",
+ "DailyPostCreateLimitation": "您已达到每日帖子创建限制。您可以在 {0} 中创建新帖子。"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
index 7f440cf205..984a3d28a7 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
@@ -158,7 +158,7 @@
"IndexPageHeroSection": "open sourceWeb Application Frameworkfor asp.net core",
"UiFramework": "UI框架",
"EmailAddress": "电子邮件地址",
- "Mobile": "移动电话",
+ "Mobile": "选择移动应用程序框架",
"ReactNative": "React Native",
"Strong": "强大",
"Complete": "完整",
@@ -476,4 +476,4 @@
"ABPVideoCoursesPageDescription": "通过ABP团队创建的视频课程学习ABP框架的基础知识。在本视频系列中,您将学习ABP框架的基本主题。每个视频上的数字都是根据学习流程编写的。",
"ABPVideoCoursesTitle": "ABP 基本视频"
}
-}
\ No newline at end of file
+}
diff --git a/common.props b/common.props
index 26b2c2f91a..d01368396b 100644
--- a/common.props
+++ b/common.props
@@ -1,8 +1,8 @@
latest
- 8.2.3
- 3.2.3
+ 8.3.1
+ 3.3.1$(NoWarn);CS1591;CS0436https://abp.io/assets/abp_nupkg.pnghttps://abp.io/
diff --git a/docs/en/Blog-Posts/2024-05 ABP Unification/post.md b/docs/en/Blog-Posts/2024-05 ABP Unification/post.md
index fd7c1198a9..c09f9cc8e2 100644
--- a/docs/en/Blog-Posts/2024-05 ABP Unification/post.md
+++ b/docs/en/Blog-Posts/2024-05 ABP Unification/post.md
@@ -51,7 +51,7 @@ You can easily download and install ABP Studio, login with your abp.io account a
### The New Pricing Page
-Since the [ABP Commercial website](https://commercial.abp.io/) has merged with the main website, you will see the *Pricing* page located on the main menu of the abp.io website. We have completely revised the design and content of this page to better reflect which features are open source and free, and what is included in the commercial licenses.
+Since the [ABP Commercial website](https://commercial.abp.io/) has merged with the main website, you will see the *Pricing* page located on the main menu of the abp.io website. We have completely revised the design and content of this page to better reflect which features are open source and free, and what is included in the paid licenses.

@@ -68,7 +68,7 @@ Based on our and customers' experiences, there are some problems with that appro
* Getting started, development tutorials, release notes, road map and some other documents are duplicated (or very similar) among ABP Framework and ABP Commercial documents.
* For ABP Commercial users, it is not clear if they also need to read the ABP Framework (open source) documentation or not. Also, when they read the framework document, some parts are different for ABP Commercial users, and it is also not clear in some cases.
-We are currently working to completely merge the ABP Framework (open source) and ABP Commercial documentation, remove duplications and revisit the contents. We will clearly indicate if a part of a document requires a commercial license.
+We are currently working to completely merge the ABP Framework (open source) and ABP Commercial documentation, remove duplications and revisit the contents. We will clearly indicate if a part of a document requires a paid license.
The left navigation panel tree is also completely revisited and simplified:
diff --git a/docs/en/cli/index.md b/docs/en/cli/index.md
index 8e3649e386..ba3e6aabf8 100644
--- a/docs/en/cli/index.md
+++ b/docs/en/cli/index.md
@@ -105,6 +105,8 @@ abp cli update
abp cli update --preview
abp cli update --version 1.0.0
abp cli remove
+abp cli check-version
+abp cli clear-cache
````
### new
@@ -138,10 +140,10 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md
* `--tiered`: Creates a tiered solution where Web and Http API layers are physically separated. If not specified, it creates a layered solution which is less complex and suitable for most scenarios. (*Available for* ***Team*** *or higher licenses*)
* `angular`: Angular UI. There are some additional options for this template:
* `--tiered`: The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side. (*Available for* ***Team*** *or higher licenses*)
- * `--pwa`: Specifies the project as Progressive Web Application.
+ * `--progressive-web-app` or `-pwa`: Specifies the project as Progressive Web Application.
* `blazor`: Blazor UI. There are some additional options for this template:
* `--tiered`The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side. (*Available for* ***Team*** *or higher licenses*)
- * `--pwa`: Specifies the project as Progressive Web Application.
+ * `--progressive-web-app` or `-pwa`: Specifies the project as Progressive Web Application.
* `blazor-server`: Blazor Server UI. There are some additional options for this template:
* `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project. (*Available for* ***Team*** *or higher licenses*)
* `maui-blazor`: Blazor Maui UI (*Available for* ***Team*** *or higher licenses*). There are some additional options for this template:
@@ -156,8 +158,12 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
* `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](../framework/data/entity-framework-core/other-dbms.md) (after creating the solution).
+ * `--skip-migrations` or `-sm`: Skips the creating initial database migration step.
+ * `--skip-migrator` or `-smr`: Skips the run database migrator step.
* `--public-website`: Public Website is a front-facing website for describing your project, listing your products and doing SEO for marketing purposes. Users can login and register on your website with this website. This option is only included in PRO templates.
+ * `--without-cms-kit`: When you add a public website to your solution, it automatically includes the [CmsKit](./../modules/cms-kit-pro/index.md) module. If you don't want to include *CmsKit*, you can use this parameter.
* `--separate-tenant-schema`: Creates a different DbContext for tenant schema. If not specified, the tenant schema is shared with the host schema. This option is only included in PRO templates.
+ * `--sample-crud-page` or `-scp`: It adds the [BookStore](./../tutorials/book-store/index.md) sample to your solution.
* `--theme` or `-th`: Specifes the theme. Default theme is `leptonx`. Available themes:
* `leptonx`: LeptonX Theme. (*Available for* ***Team*** *or higher licenses*)
* `leptonx-lite`: LeptonX-Lite Theme.
@@ -174,6 +180,9 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
* `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](../framework/data/entity-framework-core/other-dbms.md) (after creating the solution).
+ * `--skip-migrations` or `-sm`: Skips the creating initial database migration step.
+ * `--skip-migrator` or `-smr`: Skips the run database migrator step.
+ * `--sample-crud-page` or `-scp`: It adds the [BookStore](./../tutorials/book-store/index.md) sample to your solution.
* `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
* `leptonx`: LeptonX Theme. (*Available for* ***Team*** *or higher licenses*)
* `leptonx-lite`: LeptonX-Lite Theme.
@@ -211,6 +220,7 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md
* `--dont-run-install-libs`: Skip installing client side packages.
* `--dont-run-bundling`: Skip bundling for Blazor packages.
* `--no-kubernetes-configuration` or `-nkc`: Skips the Kubernetes configuration files.
+* `--no-social-logins` or `-nsl`: Skipts the social login configuration.
* *Module Options*: You can skip some modules if you don't want to add them to your solution (*Available for* ***Team*** *or higher licenses*). Available commands:
* `-no-saas`: Skips the Saas module.
* `-no-gdpr`: Skips the GDPR module.
diff --git a/docs/en/framework/architecture/multi-tenancy/index.md b/docs/en/framework/architecture/multi-tenancy/index.md
index 1431e12aa4..7a8f23c53e 100644
--- a/docs/en/framework/architecture/multi-tenancy/index.md
+++ b/docs/en/framework/architecture/multi-tenancy/index.md
@@ -10,8 +10,8 @@ Wikipedia [defines](https://en.wikipedia.org/wiki/Multitenancy) the multi-tenanc
There are two main side of a typical SaaS / Multi-tenant application:
-* A **Tenant** is a customer of the SaaS application that pays money to use the service.
-* **Host** is the company that owns the SaaS application and manages the system.
+- A **Tenant** is a customer of the SaaS application that pays money to use the service.
+- **Host** is the company that owns the SaaS application and manages the system.
The Host and the Tenant terms will be used for that purpose in the rest of the document.
@@ -36,9 +36,9 @@ Configure(options =>
ABP supports all the following approaches to store the tenant data in the database;
-* **Single Database**: All tenants are stored in a single database.
-* **Database per Tenant**: Every tenant has a separate, dedicated database to store the data related to that tenant.
-* **Hybrid**: Some tenants share a single databases while some tenants may have their own databases.
+- **Single Database**: All tenants are stored in a single database.
+- **Database per Tenant**: Every tenant has a separate, dedicated database to store the data related to that tenant.
+- **Hybrid**: Some tenants share a single database while some tenants may have their own databases.
[Tenant management module](../../../modules/tenant-management.md) (which comes pre-installed with the startup projects) allows you to set a connection string for any tenant (as optional), so you can achieve any of the approaches.
@@ -50,9 +50,9 @@ Multi-tenancy system is designed to **work seamlessly** and make your applicatio
You should implement the `IMultiTenant` interface for your [entities](../domain-driven-design/entities.md) to make them **multi-tenancy ready**.
-**Example: A multi-tenant *Product* entity**
+**Example: A multi-tenant _Product_ entity**
-````csharp
+```csharp
using System;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
@@ -68,7 +68,7 @@ namespace MultiTenancyDemo.Products
public float Price { get; set; }
}
}
-````
+```
`IMultiTenant` interface just defines a `TenantId` property. When you implement this interface, ABP **automatically** [filters](../../infrastructure/data-filtering.md) entities for the current tenant when you query from database. So, you don't need to manually add `TenantId` condition while performing queries. A tenant can not access to data of another tenant by default.
@@ -96,9 +96,9 @@ If you set the `TenantId` value for a specific entity object, it will override t
`ICurrentTenant` defines the following properties;
-* `Id` (`Guid`): Id of the current tenant. Can be `null` if the current user is a host user or the tenant could not be determined from the request.
-* `Name` (`string`): Name of the current tenant. Can be `null` if the current user is a host user or the tenant could not be determined from the request.
-* `IsAvailable` (`bool`): Returns `true` if the `Id` is not `null`.
+- `Id` (`Guid`): Id of the current tenant. Can be `null` if the current user is a host user or the tenant could not be determined from the request.
+- `Name` (`string`): Name of the current tenant. Can be `null` if the current user is a host user or the tenant could not be determined from the request.
+- `IsAvailable` (`bool`): Returns `true` if the `Id` is not `null`.
#### Change the Current Tenant
@@ -108,7 +108,7 @@ ABP automatically filters the resources (database, cache...) based on the `ICurr
**Example: Get product count of a specific tenant**
-````csharp
+```csharp
using System;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
@@ -134,11 +134,11 @@ namespace MultiTenancyDemo.Products
}
}
}
-````
+```
-* `Change` method can be used in a **nested way**. It restores the `CurrentTenant.Id` to the previous value after the `using` statement.
-* When you use `CurrentTenant.Id` inside the `Change` scope, you get the `tenantId` provided to the `Change` method. So, the repository also get this `tenantId` and can filter the database query accordingly.
-* Use `CurrentTenant.Change(null)` to change scope to the host context.
+- `Change` method can be used in a **nested way**. It restores the `CurrentTenant.Id` to the previous value after the `using` statement.
+- When you use `CurrentTenant.Id` inside the `Change` scope, you get the `tenantId` provided to the `Change` method. So, the repository also get this `tenantId` and can filter the database query accordingly.
+- Use `CurrentTenant.Change(null)` to change scope to the host context.
> Always use the `Change` method with a `using` statement like done in this example.
@@ -148,7 +148,7 @@ As mentioned before, ABP handles data isolation between tenants using the [Data
**Example: Get count of products in the database, including all the products of all the tenants.**
-````csharp
+```csharp
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
@@ -181,7 +181,7 @@ namespace MultiTenancyDemo.Products
}
}
-````
+```
See the [Data Filtering document](../../infrastructure/data-filtering.md) for more.
@@ -201,15 +201,15 @@ ABP provides an extensible **Tenant Resolving** system for that purpose. Tenant
The following resolvers are provided and configured by default;
-* `CurrentUserTenantResolveContributor`: Gets the tenant id from claims of the current user, if the current user has logged in. **This should always be the first contributor for the security**.
-* `QueryStringTenantResolveContributor`: Tries to find current tenant id from query string parameters. The parameter name is `__tenant` by default.
-* `RouteTenantResolveContributor`: Tries to find current tenant id from route (URL path). The variable name is `__tenant` by default. If you defined a route with this variable, then it can determine the current tenant from the route.
-* `HeaderTenantResolveContributor`: Tries to find current tenant id from HTTP headers. The header name is `__tenant` by default.
-* `CookieTenantResolveContributor`: Tries to find current tenant id from cookie values. The cookie name is `__tenant` by default.
+- `CurrentUserTenantResolveContributor`: Gets the tenant id from claims of the current user, if the current user has logged in. **This should always be the first contributor for the security**.
+- `QueryStringTenantResolveContributor`: Tries to find current tenant id from query string parameters. The parameter name is `__tenant` by default.
+- `RouteTenantResolveContributor`: Tries to find current tenant id from route (URL path). The variable name is `__tenant` by default. If you defined a route with this variable, then it can determine the current tenant from the route.
+- `HeaderTenantResolveContributor`: Tries to find current tenant id from HTTP headers. The header name is `__tenant` by default.
+- `CookieTenantResolveContributor`: Tries to find current tenant id from cookie values. The cookie name is `__tenant` by default.
###### Problems with the NGINX
-You may have problems with the `__tenant` in the HTTP Headers if you're using the [nginx](https://www.nginx.com/) as the reverse proxy server. Because it doesn't allow to use underscore and some other special characters in the HTTP headers and you may need to manually configure it. See the following documents please:
+You may have problems with the `__tenant` in the HTTP Headers if you're using the [nginx](https://www.nginx.com/) as the reverse proxy server. Because it doesn't allow to use underscore and some other special characters in the HTTP headers and you may need to manually configure it. See the following documents please:
http://nginx.org/en/docs/http/ngx_http_core_module.html#ignore_invalid_headers
http://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers
@@ -219,22 +219,24 @@ http://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers
**Example:**
-````csharp
+```csharp
services.Configure(options =>
{
options.TenantKey = "MyTenantKey";
});
-````
+```
-If you change the `TenantKey`, make sure to pass it to `CoreModule` in the Angular client as follows:
+If you change the `TenantKey`, make sure to pass it to `provideAbpCore` via `withOptions` method in the Angular client as follows:
```js
@NgModule({
- imports: [
- CoreModule.forRoot({
- // ...
- tenantKey: 'MyTenantKey'
- }),
+ providers: [
+ provideAbpCore(
+ withOptions({
+ // ...
+ tenantKey: "MyTenantKey",
+ })
+ ),
],
// ...
})
@@ -249,7 +251,7 @@ import { TENANT_KEY } from '@abp/ng.core';
class SomeComponent {
constructor(@Inject(TENANT_KEY) private tenantKey: string) {}
-}
+}
```
> However, we don't suggest to change this value since some clients may assume the the `__tenant` as the parameter name and they might need to manually configure then.
@@ -277,12 +279,12 @@ In a real application, most of times you will want to determine the current tena
**Example: Add a subdomain resolver**
-````csharp
+```csharp
Configure(options =>
{
options.AddDomainTenantResolver("{0}.mydomain.com");
});
-````
+```
* `{0}` is the placeholder to determine the current tenant's unique name.
* Add this code to the `ConfigureServices` method of your [module](../modularity/basics.md).
@@ -293,14 +295,14 @@ Openiddict is the default Auth Server in ABP (since v6.0). When you use OpenIddi
```csharp
// using Volo.Abp.OpenIddict.WildcardDomains
-PreConfigure(options =>
+PreConfigure(options =>
{
options.EnableWildcardDomainSupport = true;
options.WildcardDomainsFormat.Add("https://{0}.mydomain.com");
});
```
-You must add this code to the `Configure` method as well.
+You must add this code to the `Configure` method as well.
```csharp
// using Volo.Abp.MultiTenancy;
@@ -312,7 +314,7 @@ Configure(options =>
```
-> There is an [example](https://github.com/abpframework/abp-samples/tree/master/DomainTenantResolver) that uses the subdomain to determine the current tenant.
+> There is an [example](https://github.com/abpframework/abp-samples/tree/master/DomainTenantResolver) that uses the subdomain to determine the current tenant.
If you use a sepereted Auth server, you must install `[Owl.TokenWildcardIssuerValidator](https://www.nuget.org/packages/Owl.TokenWildcardIssuerValidator)` on the `HTTPApi.Host` project
@@ -332,7 +334,7 @@ context.Services
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
options.Audience = "ExampleProjectName";
-
+
// start of added block
options.TokenValidationParameters.IssuerValidator = TokenWildcardIssuerValidator.IssuerValidator;
options.TokenValidationParameters.ValidIssuers = new[]
@@ -348,16 +350,16 @@ context.Services
You can add implement your custom tenant resolver and configure the `AbpTenantResolveOptions` in your module's `ConfigureServices` method as like below:
-````csharp
+```csharp
Configure(options =>
{
options.TenantResolvers.Add(new MyCustomTenantResolveContributor());
});
-````
+```
`MyCustomTenantResolveContributor` must inherit from the `TenantResolveContributorBase` (or implement the `ITenantResolveContributor`) as shown below:
-````csharp
+```csharp
using System.Threading.Tasks;
using Volo.Abp.MultiTenancy;
@@ -373,7 +375,7 @@ namespace MultiTenancyDemo.Web
}
}
}
-````
+```
* A tenant resolver should set `context.TenantIdOrName` if it can determine it. If not, just leave it as is to allow the next resolver to determine it.
* `context.ServiceProvider` can be used if you need to additional services to resolve from the [dependency injection](../../fundamentals/dependency-injection.md) system.
@@ -384,9 +386,9 @@ Multi-Tenancy middleware is an ASP.NET Core request pipeline [middleware](https:
Multi-Tenancy middleware is typically placed just under the [authentication](https://docs.microsoft.com/en-us/aspnet/core/security/authentication) middleware (`app.UseAuthentication()`):
-````csharp
+```csharp
app.UseMultiTenancy();
-````
+```
> This middleware is already configured in the startup templates, so you normally don't need to manually add it.
@@ -406,7 +408,7 @@ The [tenant management module](../../../modules/tenant-management.md) is **inclu
**Example: Define tenants in appsettings.json**
-````json
+```json
"Tenants": [
{
"Id": "446a5211-3d72-4339-9adc-845151f8ada0",
@@ -422,7 +424,7 @@ The [tenant management module](../../../modules/tenant-management.md) is **inclu
}
}
]
-````
+```
> It is recommended to **use the Tenant Management module**, which is already pre-configured when you create a new application with the ABP startup templates.
diff --git a/docs/en/framework/ui/angular/localization.md b/docs/en/framework/ui/angular/localization.md
index 5f8f3c4332..9f2b71bc7b 100644
--- a/docs/en/framework/ui/angular/localization.md
+++ b/docs/en/framework/ui/angular/localization.md
@@ -11,7 +11,7 @@ The Localization key format consists of 2 sections which are **Resource Name** a
const environment = {
//...
localization: {
- defaultResourceName: 'MyProjectName',
+ defaultResourceName: "MyProjectName",
},
};
```
@@ -38,7 +38,8 @@ You can also specify a default value as shown below:
```html
```
@@ -82,17 +83,17 @@ After that, you are able to use localization service.
```js
this.localizationService.instant(
- 'AbpIdentity::UserDeletionConfirmation',
- 'John'
+ "AbpIdentity::UserDeletionConfirmation",
+ "John"
);
// with fallback value
this.localizationService.instant(
{
- key: 'AbpIdentity::UserDeletionConfirmation',
- defaultValue: 'Default Value',
+ key: "AbpIdentity::UserDeletionConfirmation",
+ defaultValue: "Default Value",
},
- 'John'
+ "John"
);
// Output
@@ -102,12 +103,12 @@ this.localizationService.instant(
To get a localized text as [_Observable_](https://rxjs.dev/guide/observable) use `get` method instead of `instant`:
```js
-this.localizationService.get('Resource::Key');
+this.localizationService.get("Resource::Key");
// with fallback value
this.localizationService.get({
- key: 'Resource::Key',
- defaultValue: 'Default Value',
+ key: "Resource::Key",
+ defaultValue: "Default Value",
});
```
@@ -118,41 +119,46 @@ Localizations can be determined on backend side. Angular UI gets the localizatio
See an example:
```ts
-// app.module.ts
+import { provideAbpCore, withOptions } from '@abp/ng.core';
@NgModule({
- imports: [
- //...other imports
- CoreModule.forRoot({
- localizations: [
- {
- culture: 'en',
- resources: [
- {
- resourceName: 'MyProjectName',
- texts: {
- Administration: 'Administration',
- HomePage: 'Home',
+ providers: [
+ // ...
+ provideAbpCore(
+ withOptions({
+ ...,
+ localizations: [
+ {
+ culture: 'en',
+ resources: [
+ {
+ resourceName: 'MyProjectName',
+ texts: {
+ Administration: 'Administration',
+ HomePage: 'Home',
+ },
},
- },
- ],
- },
- {
- culture: 'de',
- resources: [
- {
- resourceName: 'MyProjectName',
- texts: {
- Administration: 'Verwaltung',
- HomePage: 'Startseite',
+ ],
+ },
+ {
+ culture: 'de',
+ resources: [
+ {
+ resourceName: 'MyProjectName',
+ texts: {
+ Administration: 'Verwaltung',
+ HomePage: 'Startseite',
+ },
},
- },
- ],
- },
- ],
- }),
- ]
+ ],
+ },
+ ],
+ }),
+ ),
+ ...
+ ],
})
+export class AppModule {}
```
...or, you can determine the localizations in a feature module:
@@ -256,10 +262,10 @@ Find [styles configuration in angular.json](https://angular.io/guide/workspace-c
If you have created and injected chunks for Fontawesome as seen above, you no longer need the lazy loading in the `AppComponent` which was implemented before v2.9. Simply remove them. The `AppComponent` in the template of the new version looks like this:
```js
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
@Component({
- selector: 'app-root',
+ selector: "app-root",
template: `
@@ -274,33 +280,32 @@ Since ABP has more than one language, Angular locale files loads lazily using [W
### registerLocaleFn
-`registerLocale` function that exported from `@abp/ng.core/locale` package is a higher order function that accepts `cultureNameLocaleFileMap` object and `errorHandlerFn` function as params and returns Webpack `import` function. A `registerLocale` function must be passed to the `forRoot` of the `CoreModule` as shown below:
-
-```js
-// app.module.ts
+`registerLocale` function that exported from `@abp/ng.core/locale` package is a higher order function that accepts `cultureNameLocaleFileMap` object and `errorHandlerFn` function as params and returns Webpack `import` function. A `registerLocale` function must be passed to the `withOptions` of the `provideAbpCore` as shown below:
+```ts
+import { provideAbpCore, withOptions } from '@abp/ng.core';
import { registerLocale } from '@abp/ng.core/locale';
-// if you have commercial license and the language management module, add the below import
-// import { registerLocale } from '@volo/abp.ng.language-management/locale';
-
@NgModule({
- imports: [
- // ...
- CoreModule.forRoot({
- // ...other options,
- registerLocaleFn: registerLocale(
- // you can pass the cultureNameLocaleFileMap and errorHandlerFn as optionally
- {
- cultureNameLocaleFileMap: { 'pt-BR': 'pt' },
- errorHandlerFn: ({ resolve, reject, locale, error }) => {
- // the error can be handled here
+ providers: [
+ provideAbpCore(
+ withOptions({
+ ...,
+ registerLocaleFn: registerLocale(
+ // you can pass the cultureNameLocaleFileMap and errorHandlerFn as optionally
+ {
+ cultureNameLocaleFileMap: { 'pt-BR': 'pt' },
+ errorHandlerFn: ({ resolve, reject, locale, error }) => {
+ // the error can be handled here
+ },
},
- },
- )
- }),
- //...
- ]
+ ),
+ }),
+ ),
+ ...
+ ],
+})
+export class AppModule {}
```
### Mapping of Culture Name to Angular Locale File Name
@@ -320,20 +325,23 @@ import { registerLocale } from '@abp/ng.core/locale';
@NgModule({
- imports: [
+ providers: [
// ...
- CoreModule.forRoot({
- // ...other options,
- registerLocaleFn: registerLocale(
- {
- cultureNameLocaleFileMap: {
- "DotnetCultureName": "AngularLocaleFileName",
- "pt-BR": "pt" // example
+ provideAbpCore(
+ withOptions({
+ ...,
+ registerLocaleFn: registerLocale(
+ {
+ cultureNameLocaleFileMap: {
+ "DotnetCultureName": "AngularLocaleFileName",
+ "pt-BR": "pt" // example
+ },
},
- },
- )
- }),
- //...
+ )
+ }),
+ ),
+ ]
+})
```
See [all locale files in Angular](https://github.com/angular/angular/tree/master/packages/common/locales).
@@ -345,12 +353,12 @@ Add the below code to the `app.module.ts` by replacing `your-locale` placeholder
```js
//app.module.ts
-import { storeLocaleData } from '@abp/ng.core/locale';
+import { storeLocaleData } from "@abp/ng.core/locale";
import(
/* webpackChunkName: "_locale-your-locale-js"*/
/* webpackMode: "eager" */
- '@angular/common/locales/your-locale.js'
-).then((m) => storeLocaleData(m.default, 'your-locale'));
+ "@angular/common/locales/your-locale.js"
+).then((m) => storeLocaleData(m.default, "your-locale"));
```
...or a custom `registerLocale` function can be passed to the `CoreModule`:
@@ -373,14 +381,17 @@ export function registerLocale(locale: string) {
import { registerLocale } from './register-locale';
@NgModule({
- imports: [
+ providers: [
// ...
- CoreModule.forRoot({
- // ...other options,
- registerLocaleFn: registerLocale
- }),
+ provideAbpCore(
+ withOptions({
+ ...,
+ registerLocaleFn: registerLocale,
+ }),
+ ),
//...
]
+})
```
After this custom `registerLocale` function, since the en and fr added to the `webpackInclude`, only en and fr locale files will be created as chunks:
@@ -392,4 +403,4 @@ Which locale files you add to `webpackInclude` magic comment, they will be inclu
## See Also
* [Localization in ASP.NET Core](../../fundamentals/localization.md)
-* [Video tutorial](https://abp.io/video-courses/essentials/localization)
\ No newline at end of file
+* [Video tutorial](https://abp.io/video-courses/essentials/localization)
diff --git a/docs/en/framework/ui/angular/quick-start.md b/docs/en/framework/ui/angular/quick-start.md
index 2a8986f965..df2d6331b9 100644
--- a/docs/en/framework/ui/angular/quick-start.md
+++ b/docs/en/framework/ui/angular/quick-start.md
@@ -4,8 +4,8 @@
Please follow the steps below to prepare your development environment for Angular.
-1. **Install Node.js:** Please visit [Node.js downloads page](https://nodejs.org/en/download/) and download proper Node.js v16 or v18 installer for your OS. An alternative is to install [NVM](https://github.com/nvm-sh/nvm) and use it to have multiple versions of Node.js in your operating system.
-2. **[Optional] Install Yarn:** You may install Yarn v1 (not v2) following the instructions on [the installation page](https://classic.yarnpkg.com/en/docs/install). Yarn v1 delivers an arguably better developer experience compared to npm v6 and below. You may skip this step and work with npm, which is built-in in Node.js, instead.
+1. **Install Node.js:** Please visit [Node.js downloads page](https://nodejs.org/en/download/) and download proper Node.js `v18.19+` installer for your OS. An alternative is to install [NVM](https://github.com/nvm-sh/nvm) and use it to have multiple versions of Node.js in your operating system.
+2. **[Optional] Install Yarn:** You may install Yarn v1.22+ (not v2) following the instructions on [the installation page](https://classic.yarnpkg.com/en/docs/install). Yarn v1 delivers an arguably better developer experience compared to npm v10 and below. You may skip this step and work with npm, which is built-in in Node.js, instead.
3. **[Optional] Install VS Code:** [VS Code](https://code.visualstudio.com/) is a free, open-source IDE which works seamlessly with TypeScript. Although you can use any IDE including Visual Studio or Rider, VS Code will most likely deliver the best developer experience when it comes to Angular projects. ABP project templates even contain plugin recommendations for VS Code users, which VS Code will ask you to install when you open the Angular project folder. Here is a list of recommended extensions:
- [Angular Language Service](https://marketplace.visualstudio.com/items?itemName=angular.ng-template)
- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
diff --git a/docs/en/get-started/images/abp-studio-created-new-solution.png b/docs/en/get-started/images/abp-studio-created-new-solution.png
index 4a7d4f0b01..c089c276f6 100644
Binary files a/docs/en/get-started/images/abp-studio-created-new-solution.png and b/docs/en/get-started/images/abp-studio-created-new-solution.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options-microservice.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options-microservice.png
index 87bd86755c..9f9df8991f 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options-microservice.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options-microservice.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options.png
new file mode 100644
index 0000000000..4a2d3c2dd2
Binary files /dev/null and b/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-database-configurations-efcore.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-database-configurations-efcore.png
index e71cbb7036..e9a5bcee19 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-database-configurations-efcore.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-database-configurations-efcore.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-database-configurations-mongo.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-database-configurations-mongo.png
index f0b0ed136b..4b00156e3f 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-database-configurations-mongo.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-database-configurations-mongo.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-database-provider-efcore.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-database-provider-efcore.png
index 6f8e937b09..138d1904f5 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-database-provider-efcore.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-database-provider-efcore.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-database-provider-mongo.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-database-provider-mongo.png
index a1175b81bf..1e3f54a9d8 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-database-provider-mongo.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-database-provider-mongo.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-mobile-framework-microservice.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-mobile-framework-microservice.png
index b7ccfb2976..7e43e784f3 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-mobile-framework-microservice.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-mobile-framework-microservice.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-mobile-framework.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-mobile-framework.png
index 20b89c059d..f773d887d8 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-mobile-framework.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-mobile-framework.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-optional-modules.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-optional-modules.png
new file mode 100644
index 0000000000..992760e3fc
Binary files /dev/null and b/docs/en/get-started/images/abp-studio-new-solution-dialog-optional-modules.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-public-website.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-public-website.png
new file mode 100644
index 0000000000..e10d4a965c
Binary files /dev/null and b/docs/en/get-started/images/abp-studio-new-solution-dialog-public-website.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-solution-properties.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-solution-properties.png
index 93b3154e7c..7412b4b6e1 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-solution-properties.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-solution-properties.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-solution-structure.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-solution-structure.png
index 3cdd22f555..310488c1bc 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-solution-structure.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-solution-structure.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-ui-framework.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-ui-framework.png
index 228c711a1a..d373a55344 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-ui-framework.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-ui-framework.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-ui-theme.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-ui-theme.png
index d17d1d766d..8594f02d58 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-ui-theme.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-ui-theme.png differ
diff --git a/docs/en/get-started/images/abp-studio-quick-start-application-solution-runner.png b/docs/en/get-started/images/abp-studio-quick-start-application-solution-runner.png
index 2e4a9aa583..f5ca4c97e7 100644
Binary files a/docs/en/get-started/images/abp-studio-quick-start-application-solution-runner.png and b/docs/en/get-started/images/abp-studio-quick-start-application-solution-runner.png differ
diff --git a/docs/en/get-started/images/abp-studio-quick-start-browse-command.png b/docs/en/get-started/images/abp-studio-quick-start-browse-command.png
index 186ff2d55d..c97b3c9700 100644
Binary files a/docs/en/get-started/images/abp-studio-quick-start-browse-command.png and b/docs/en/get-started/images/abp-studio-quick-start-browse-command.png differ
diff --git a/docs/en/get-started/images/abp-studio-quick-start-browse.png b/docs/en/get-started/images/abp-studio-quick-start-browse.png
index d63c20c8ac..47b4bf29cf 100644
Binary files a/docs/en/get-started/images/abp-studio-quick-start-browse.png and b/docs/en/get-started/images/abp-studio-quick-start-browse.png differ
diff --git a/docs/en/get-started/images/abp-studio-quick-start-example-applications-in-solution-runner.png b/docs/en/get-started/images/abp-studio-quick-start-example-applications-in-solution-runner.png
index 46adf8bfc0..44cef603fb 100644
Binary files a/docs/en/get-started/images/abp-studio-quick-start-example-applications-in-solution-runner.png and b/docs/en/get-started/images/abp-studio-quick-start-example-applications-in-solution-runner.png differ
diff --git a/docs/en/get-started/images/solution-runner-public-website.png b/docs/en/get-started/images/solution-runner-public-website.png
index a00368ee79..b1e76a4ce6 100644
Binary files a/docs/en/get-started/images/solution-runner-public-website.png and b/docs/en/get-started/images/solution-runner-public-website.png differ
diff --git a/docs/en/get-started/layered-web-application.md b/docs/en/get-started/layered-web-application.md
index 43a067ed6a..0b051b9681 100644
--- a/docs/en/get-started/layered-web-application.md
+++ b/docs/en/get-started/layered-web-application.md
@@ -22,8 +22,8 @@ The following tools should be installed on your development machine:
* [Visual Studio 2022](https://visualstudio.microsoft.com/vs/) (v17.3+) for Windows / [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/). [1](#f-editor)
* [.NET 8.0+](https://dotnet.microsoft.com/en-us/download/dotnet)
{{ if UI != "Blazor" }}
-* [Node v16 or v18](https://nodejs.org/)
-* [Yarn v1.20+ (not v2)](https://classic.yarnpkg.com/en/docs/install) [2](#f-yarn) or npm v6+ (already installed with Node)
+* [Node v18.19+](https://nodejs.org/)
+* [Yarn v1.22+ (not v2)](https://classic.yarnpkg.com/en/docs/install) [2](#f-yarn) or npm v10+ (already installed with Node)
{{ end }}
{{ if Tiered == "Yes" }}
* [Redis](https://redis.io/) (as the [distributed cache](../framework/fundamentals/caching.md)).
@@ -77,17 +77,25 @@ LeptonX is the suggested UI theme that is proper for production usage. Select on
Here, you see all the mobile applications available in that startup solution template. These mobile applications are well-integrated into your solution and can use the same backend with your web application. They are simple (do not have pre-built features as much as the web application) but a very good starting point to build your mobile application.
-Pick the one best for you, or select the *None* if you don't want a mobile application in your solution, then click Next to navigate to the *Additional UI options* screen:
+Pick the one best for you, or select the *None* if you don't want a mobile application in your solution, then click Next to navigate to the *Public website* screen:
-
+
That startup solution template also provides an option to create a second web application inside the solution. The second application is called the Public website, an ASP.NET Core MVC / Razor Page application. It can be used to create a public landing/promotion for your product. It is well integrated into the solution (can share the same services, entities, database, and the same authentication logic, for example). If you want, you can also include the [CMS Kit module](../modules/cms-kit) to your solution to add dynamic content features to your web application.
-So, either select the *Public website* or skip it and click the Next button for the *Solution Structure* selection:
+So, either select the *Public website* or skip it and click the Next button for the *Optional Modules* selection:
+
+
+
+Each item in that list is a pre-built application module. You can click the blue icon near to the module name to get more information about the module. You can leave the list as is (so, it installs the most common and used modules for you) or customize based on your preference.
+
+Installing a module after creating the solution may require manual steps. So, it is better to decide the modules in the beginning. You can create an example solutions before your real solution to explore the solution and modules.
+
+Once you select the desired modules, click the *Next* button for the *Solution Structure* screen:

-The *Tiered* option is used to physically separate the web application (the UI part) from the backend HTTP APIs. It creates a separate host application that only serves the HTTP (REST) APIs. The web application then performs remote HTTP calls to that application for every operation. If the *Tiered* option is not selected, then the web and HTTP APIs are hosted in a single application, and the calls from the UI layer to the API layer are performed in-process.
+It creates a separate host application that only serves the HTTP (REST) APIs. The web application then performs remote HTTP calls to that application for every operation. If the *Tiered* option is not selected, then the web and HTTP APIs are hosted in a single application, and the calls from the UI layer to the API layer are performed in-process.
The tiered architecture allows you to host the web (UI) application in a server that can not access to your database server. However, it brings a slight loss of performance (because of the HTTP calls between UI and HTTP API applications) and makes your architecture, development, and deployment more complex. If you don't understand the tiered structure, just skip it.
@@ -107,9 +115,13 @@ On that screen, you can decide on your database provider by selecting one of the

{{ end }}
-Here, you can select the database management systems (DBMS){{ if DB == "EF" }} and the connection string{{ end }}. Now, we are ready to allow ABP Studio to create our solution. Just click the *Create* button and let the ABP Studio do the rest for you.
+Here, you can select the database management systems (DBMS){{ if DB == "EF" }} and the connection string{{ end }}. Click *Next* button to see the *Additional Options*.
+
+
+
+If you uncheck the *Kubernetes Configuration* option, the solution will not include the Kubernetes configuration files, such as Helm charts and other Kubernetes-related files. You can also specify *Social Logins*; if you uncheck this option, the solution will not be configured for social login.
-After clicking the Create button, the dialog is closed and your solution is loaded into ABP Studio:
+Now, we are ready to allow ABP Studio to create our solution. Just click the *Create* button and let the ABP Studio do the rest for you. After clicking the Create button, the dialog is closed and your solution is loaded into ABP Studio:

@@ -129,7 +141,7 @@ Open the [Solution Runner](../studio/running-applications.md) section on the lef
Once you click the *Play* icon on the left side, the section is open in the same place as the Solution Explorer section. ABP Studio also opens the *Application Monitor* view on the main content area. *Application Monitor* shows useful insights for your applications (e.g. *HTTP Request*, *Events* and *Exceptions*) in real-time. You can use it to see the happenings in your applications, so you can easily track errors and many helpful details.
-In the Solution Runner section (on the left side) you can see all the runnable applications in the current solution. For the MVC with public website example, we have three applications:
+In the Solution Runner section (on the left side) you can see all the runnable applications in the current solution. For the MVC with public website and MAUI mobile example, we have four applications:

@@ -230,4 +242,4 @@ Before starting the mobile application, ensure that you configure it for [react-
> For example in non-tiered MVC with public website application:
-
+
\ No newline at end of file
diff --git a/docs/en/get-started/microservice.md b/docs/en/get-started/microservice.md
index 9a90be00da..47f1091b14 100644
--- a/docs/en/get-started/microservice.md
+++ b/docs/en/get-started/microservice.md
@@ -71,7 +71,7 @@ Click the Next button to see *Additional Options* selection:

-If you unchecked the *Kubernetes Configuration* option, the solution will not include the Kubernetes configuration files which include the Helm charts and other Kubernetes related files.
+If you unchecked the *Kubernetes Configuration* option, the solution will not include the Kubernetes configuration files which include the Helm charts and other Kubernetes related files. You can also specify *Social Logins*; if you uncheck this option, the solution will not be configured for social login.
Now, we are ready to allow ABP Studio to create our solution. Just click the *Create* button and let the ABP Studio do the rest for you. After clicking the Create button, the dialog is closed and your solution is loaded into ABP Studio:
@@ -125,6 +125,8 @@ In the *Solution Runner* section (on the left side) you can see all the runnable
> All the leaf items in the *Solution Runner* is called as an *Application* as they are executable applications.
+> For a faster start process, first start the *Docker-Dependencies*, then you can start all applications.
+
As shown in the figure above, the executable applications are grouped into folders like `apps`, `gateways`, `infrastructure`, and `services`. You can start/stop them all, a group (folder) of them, or one by one.
Before running the applications, it is good to be sure that all applications are built. To do that, right-click the root item in the *Solution Runner* and select *Build* -> *Build All* action.
diff --git a/docs/en/get-started/single-layer-web-application.md b/docs/en/get-started/single-layer-web-application.md
index fc86aad667..319fb19c9a 100644
--- a/docs/en/get-started/single-layer-web-application.md
+++ b/docs/en/get-started/single-layer-web-application.md
@@ -21,8 +21,8 @@ The following tools should be installed on your development machine:
* [Visual Studio 2022](https://visualstudio.microsoft.com/vs/) (v17.3+) for Windows / [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/). [1](#f-editor)
* [.NET 8.0+](https://dotnet.microsoft.com/en-us/download/dotnet)
{{ if UI != "Blazor" }}
-* [Node v16 or v18](https://nodejs.org/)
-* [Yarn v1.20+ (not v2)](https://classic.yarnpkg.com/en/docs/install) [2](#f-yarn) or npm v6+ (already installed with Node)
+* [Node v18.19+](https://nodejs.org/)
+* [Yarn v1.22+ (not v2)](https://classic.yarnpkg.com/en/docs/install) [2](#f-yarn) or npm v10+ (already installed with Node)
{{ end }}
{{ if Tiered == "Yes" }}
* [Redis](https://redis.io/) (as the [distributed cache](../framework/fundamentals/caching.md)).
diff --git a/docs/en/images/cmskit-module-markedItems.png b/docs/en/images/cmskit-module-markedItems.png
new file mode 100644
index 0000000000..52eb61f285
Binary files /dev/null and b/docs/en/images/cmskit-module-markedItems.png differ
diff --git a/docs/en/images/cmskit-module-markedItemsFilter.gif b/docs/en/images/cmskit-module-markedItemsFilter.gif
new file mode 100644
index 0000000000..641975c892
Binary files /dev/null and b/docs/en/images/cmskit-module-markedItemsFilter.gif differ
diff --git a/docs/en/images/docs-referencing.png b/docs/en/images/docs-referencing.png
new file mode 100644
index 0000000000..2bc3f5da3c
Binary files /dev/null and b/docs/en/images/docs-referencing.png differ
diff --git a/docs/en/images/issuemanagement-module-solution.png b/docs/en/images/issuemanagement-module-solution.png
index 3e01ff1b92..b224045596 100644
Binary files a/docs/en/images/issuemanagement-module-solution.png and b/docs/en/images/issuemanagement-module-solution.png differ
diff --git a/docs/en/modules/account/authority-delegation.md b/docs/en/modules/account/authority-delegation.md
index 9a973d65e0..fafe297677 100644
--- a/docs/en/modules/account/authority-delegation.md
+++ b/docs/en/modules/account/authority-delegation.md
@@ -77,6 +77,8 @@ You can click the `Delegate New User` button to delegate a new user:
* You can specify a time range to ensure the delegation is only available within the time range.
* You can make multiple delegates to the same user and set different delegate time ranges.
+> You have to enter the full username to query and delegate a user.
+
> The delegation has three states: `Expired`, `Active`, and `Future`. These states are set automatically by checking the specified time interval.
### My delegated users
@@ -87,4 +89,4 @@ You can see a list of users who delegated you to login on their behalf of them,
You can click the `Login` button to log in to the application as a delegated user and go back to your account by clicking the `Back to my account` icon:
-
\ No newline at end of file
+
diff --git a/docs/en/modules/cms-kit/index.md b/docs/en/modules/cms-kit/index.md
index ad86be8e04..5c30806028 100644
--- a/docs/en/modules/cms-kit/index.md
+++ b/docs/en/modules/cms-kit/index.md
@@ -17,6 +17,7 @@ The following features are currently available:
* Provides a [**menu**](./menus.md) system to manage public menus dynamically.
* Provides a [**global resources**](./global-resources.md) system to add global styles and scripts dynamically.
* Provides a [**Dynamic Widget**](./dynamic-widget.md) system to create dynamic widgets for page and blog posts.
+* Provides a [**Marked Item**](./marked-items.md) system to mark any kind of resource, like a blog post or a product, as a favorite, starred, flagged, or bookmarked.
> You can click on the any feature links above to understand and learn how to use it.
diff --git a/docs/en/modules/cms-kit/marked-items.md b/docs/en/modules/cms-kit/marked-items.md
new file mode 100644
index 0000000000..b6b0af4173
--- /dev/null
+++ b/docs/en/modules/cms-kit/marked-items.md
@@ -0,0 +1,123 @@
+# CMS Kit: Marked Item System
+
+CMS kit provides a marking system to mark any kind of resource, like a blog post or a product, as a favorite, starred, flagged, or bookmarked.
+
+Marked toggling component allows users to mark your items via pre-defined icons/emojis. Here how the marked toggling components may look like:
+
+
+
+
+you can also customize the marking icons shown in the toggling components.
+
+## Enabling the Marked Item Feature
+
+By default, CMS Kit features are disabled. Therefore, you need to enable the features you want, before starting to use it. You can use the [Global Feature](../../Global-Features.md) system to enable/disable CMS Kit features on development time. Alternatively, you can use the ABP Framework's [Feature System](https://docs.abp.io/en/abp/latest/Features) to disable a CMS Kit feature on runtime.
+
+> Check the ["How to Install" section of the CMS Kit Module documentation](Index.md#how-to-install) to see how to enable/disable CMS Kit features on development time.
+
+## Options
+
+Marking system provides a simple approach to define your entity type with mark types like favorite or starred. For example, if you want to use the marking system for products, you need to define an entity type named `product` with the icon name.
+
+`CmsKitMarkedItemOptions` can be configured in YourModule.cs, in the `ConfigureServices` method of your [module](https://docs.abp.io/en/abp/latest/Module-Development-Basics). Example:
+
+```csharp
+Configure(options =>
+{
+ options.EntityTypes.Add(
+ new MarkedItemEntityTypeDefinition(
+ "product",
+ StandardMarkedItems.Favorite
+ )
+ );
+});
+```
+
+`CmsKitMarkedItemOptions` properties:
+
+- `EntityTypes`: List of defined entity types (`CmsKitMarkedItemOptions`) in the marking system.
+
+`MarkedItemEntityTypeDefinition` properties:
+
+- `EntityType`: Name of the entity type.
+- `IconName`: The name of the icon.
+
+## The Marked Item widget
+
+The marking system provides a toggle widget to allow users to add/remove the marks from an item. You can place the widget with the item as shown below:
+
+``` csharp
+@await Component.InvokeAsync(typeof (MarkedItemToggleViewComponent), new
+{
+ entityId = "...",
+ entityType = "product",
+ needsConfirmation = true // (optional)
+})
+```
+* `entityType` was explained in the previous section.
+* `entityId` should be the unique id of the product, in this example. If you have a Product entity, you can use its Id here.
+* `needsConfirmation` An optional parameter to let the user confirm when removing the mark.
+
+# Internals
+
+## Domain Layer
+
+#### Aggregates
+
+This module follows the [Entity Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Entities) guide.
+
+##### UserMarkedItem
+
+A user markedItem represents a user has marking on the item.
+
+- `UserMarkedItem` (aggregate root): Represents a marked item in the system.
+
+#### Repositories
+
+This module follows the [Repository Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Repositories) guide.
+
+Following custom repositories are defined for this feature:
+
+- `IUserMarkedItemRepository`
+
+
+#### Domain services
+
+This module follows the [Domain Services Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Domain-Services) guide.
+
+##### Marked Item Manager
+
+`MarkedItemManager` is used to perform some operations for the `UserMarkedItem` aggregate root.
+
+### Application layer
+
+#### Application services
+
+- `MarkedItemPublicAppService` (implements `IMarkedItemPublicAppService`): Implements the use cases of marking system.
+
+### Database providers
+
+#### Common
+
+##### Table / collection prefix & schema
+
+All tables/collections use the `Cms` prefix by default. Set static properties on the `CmsKitDbProperties` class if you need to change the table prefix or set a schema name (if supported by your database provider).
+
+##### Connection string
+
+This module uses `CmsKit` for the connection string name. If you don't define a connection string with this name, it fallbacks to the `Default` connection string.
+
+See the [connection strings](https://docs.abp.io/en/abp/latest/Connection-Strings) documentation for details.
+
+#### Entity Framework Core
+
+##### Tables
+
+- CmsUserMarkedItems
+
+#### MongoDB
+
+##### Collections
+
+- **CmsUserMarkedItems**
+
diff --git a/docs/en/modules/docs.md b/docs/en/modules/docs.md
index 6aaf1f2f0a..6ab4f566c0 100644
--- a/docs/en/modules/docs.md
+++ b/docs/en/modules/docs.md
@@ -666,9 +666,61 @@ See the following examples:
```
```
----
+## Referencing Next & Previous Documents
+The **Docs Module** supports referencing previous and next documents. It's useful if you have a series of documents that are strictly related to each other and need to be followed one after the other.
+To reference the previous and next documents from a document, you should specify the documentation titles and their paths as follows:
+
+```
+
+ ````json
+ //[doc-nav]
+ {
+ "Previous": {
+ "Name": "Overall",
+ "Path": "testing/overall"
+ },
+ "Next": {
+ "Name": "Integration tests",
+ "Path": "testing/integration-tests"
+ }
+ }
+ ````
+
+```
+
+After you specify the next & previous documents, they will appear at the end of the current documentation like in the following figure:
+
+
+
+## Single Project Mode
+
+The **single project mode** allows you to use a single name as a project name in your application. If you are not considering supporting multiple projects with their multiple docs and instead if you have a single project and want to have documentation only for it, it's especially useful for you.
+
+You just need to configure the `DocsUiOptions`, set the single project mode as **enabled** and also define a constant project name:
+
+```csharp
+Configure(options =>
+{
+ options.RoutePrefix = "docs";
+ options.SingleProjectMode.Enable = true;
+ options.SingleProjectMode.ProjectName = "abp";
+});
+```
+
+## Multi Language Mode
+
+The **multi language mode** allows you to show a combobox that lists and shows all documentation languages and configures the related languages in routes.
+
+It's enabled by default and supports multiple languages, but if you are considering only supporting a single language, and don't want to show the language combobox in the sidebar of your docs system, you can configure the `DocsUiOptions` and set the multi language mode support as **false** to disable it:
+
+```csharp
+Configure(options =>
+{
+ options.MultiLanguageMode = false;
+});
+```
## See Also
diff --git a/docs/en/modules/openiddict-pro.md b/docs/en/modules/openiddict-pro.md
index e2c2715d62..b9102cee6d 100644
--- a/docs/en/modules/openiddict-pro.md
+++ b/docs/en/modules/openiddict-pro.md
@@ -415,6 +415,17 @@ public override void PreConfigureServices(ServiceConfigurationContext context)
}
```
+### Disable Transport Security Requirement
+
+By default, OpenIddict requires the use of HTTPS for all endpoints. You can disable it if it's needed. You just need to configure the `OpenIddictServerAspNetCoreOptions` and set `DisableTransportSecurityRequirement` as **true**:
+
+```cs
+Configure(options =>
+{
+ options.DisableTransportSecurityRequirement = true;
+});
+```
+
https://documentation.openiddict.com/configuration/token-formats.html#disabling-jwt-access-token-encryption
### Request/Response Process
diff --git a/docs/en/modules/openiddict.md b/docs/en/modules/openiddict.md
index 0d126b42c0..80f1a54776 100644
--- a/docs/en/modules/openiddict.md
+++ b/docs/en/modules/openiddict.md
@@ -375,6 +375,17 @@ public override void PreConfigureServices(ServiceConfigurationContext context)
}
```
+### Disable Transport Security Requirement
+
+By default, OpenIddict requires the use of HTTPS for all endpoints. You can disable it if it's needed. You just need to configure the `OpenIddictServerAspNetCoreOptions` and set `DisableTransportSecurityRequirement` as **true**:
+
+```cs
+Configure(options =>
+{
+ options.DisableTransportSecurityRequirement = true;
+});
+```
+
https://documentation.openiddict.com/configuration/token-formats.html#disabling-jwt-access-token-encryption
### Request/Response Process
diff --git a/docs/en/release-info/migration-guides/abp-8-3.md b/docs/en/release-info/migration-guides/abp-8-3.md
new file mode 100644
index 0000000000..50a7f274a4
--- /dev/null
+++ b/docs/en/release-info/migration-guides/abp-8-3.md
@@ -0,0 +1,68 @@
+# ABP Version 8.3 Migration Guide
+
+This document is a guide for upgrading ABP v8.x solutions to ABP v8.3. There are some changes in this version that may affect your applications, please read it carefully and apply the necessary changes to your application.
+
+## Open-Source (Framework)
+
+### Added `AdminUserName` parameter to `IIdentityDataSeeder.SeedAsync` method
+
+Prior to this version, `IIdentityDataSeeder.SeedAsync` was used to seed the initial user data with the `admin` as the username, to be able to easily test all applications with all permissions granted.
+
+In this version on, we allow you to set the default **adminUserName**. So, you can set the default user name to any name you want or leave it as it is and let the username be `admin` as before.
+
+For example, in the `MyProjectNameDbMigrationService.SeedDataAsync` method (under the domain project's **Data** folder), you can pass the username as below:
+
+```diff
+ private async Task SeedDataAsync(Tenant? tenant = null)
+ {
+ Logger.LogInformation($"Executing {(tenant == null ? "host" : tenant.Name + " tenant")} database seed...");
+
+ await _dataSeeder.SeedAsync(new DataSeedContext(tenant?.Id)
+ .WithProperty(IdentityDataSeedContributor.AdminEmailPropertyName, IdentityDataSeedContributor.AdminEmailDefaultValue)
+ .WithProperty(IdentityDataSeedContributor.AdminPasswordPropertyName, IdentityDataSeedContributor.AdminPasswordDefaultValue)
++ .WithProperty(IdentityDataSeedContributor.AdminUserNamePropertyName, "your-admin-user-name")
+ );
+ }
+```
+
+Normally, you don't need to make any changes in your code related to this change. However, if you used the `IIdentityDataSeeder.SeedAsync` method in your application, now also gets additional (and optional) `adminUserName` parameter that you can pass the value on.
+
+See the PR for more info: https://github.com/abpframework/abp/pull/20131/
+
+### Docs Module: Improvements & Single Project Mode Support
+
+In this version, we made some improvements in the [Docs Module](../../modules/docs.md) and introduced single project mode, which allows you to use a single project name for all of your documents.
+
+While implementing this new feature, we made some small changes to the existing classes. For example, the constructor methods of the following classes have been changed, and need to be updated in your code, if you use them:
+
+* `TreeTagHelper.cs`: https://github.com/abpframework/abp/pull/19419/files#diff-e0fb91c1b564d61dedf9dfc60d08e7e0af57b433797fcb3bd664f3fd4768ea0d
+
+* `MarkdownDocumentToHtmlConverter.cs`: https://github.com/abpframework/abp/pull/19419/files#diff-948e25b2d8851576888f8053b5f2c9416e23576aff95a88ef8ec8ca2841b3622
+
+See the PR for more info: https://github.com/abpframework/abp/pull/19419
+
+### Updated `datatables.net` to 2.0.2
+
+In this version, the `datatables.net` library version was updated from v1.11.4 to v2.0.2. We made all related changes at the framework level and updated the dependency and its resource mapping configurations. Also, we made it backward compatible so it should not directly affect your application.
+
+However, notice this package is used by the `@abp/aspnetcore.mvc.ui.theme.shared` package, which is used by the official themes. Therefore, if you used any methods from the **datatables.net** library it might be already deprecated or removed.
+
+See the PR for more info: https://github.com/abpframework/abp/pull/19340
+
+### Angular UI
+
+We wish to formally inform you that ABP version 8.3 has been upgraded to incorporate Angular version 18. Consequently, we recommend migrating your application to [Angular v18](https://angular.dev/update-guide) to ensure compatibility.
+
+## PRO
+
+> Please check the **Open-Source (Framework)** section before reading this section. The listed topics might affect your application and you might need to take care of them.
+
+If you are a paid-license owner and using the ABP's paid version, then please follow the following sections to get informed about the breaking changes and apply the necessary ones:
+
+### Added RegEx Support to CMS Kit's (PRO) URL Forwarding System
+
+ABP provides a [URL Forwarding System](../../modules/cms-kit-pro/url-forwarding.md), which allows you to create URLs that redirect to other pages or external websites. Prior to this version, the URL Forwarding System was only working for static URLs and didn't support RegEx. In this version, we introduced the RegEx support for the URL Forwarding System and now you can pass regular expressions for not static URLs.
+
+Since a new property has been added to the `CmsShortenedUrl` entity, you should create a new migration and apply it to your database.
+
+> After creating a new migration and applying it to your database, typically you don't need to make any changes, however, if you have overridden a page/method or class related to the URL Forwarding System, you might need to update it accordingly. For this purpose, you can get the source code of the [CMS Kit Module's](../../modules/cms-kit-pro/index.md) and update the related parts in your application.
\ No newline at end of file
diff --git a/docs/en/release-info/migration-guides/index.md b/docs/en/release-info/migration-guides/index.md
index 6670e9ba3a..804b17b376 100644
--- a/docs/en/release-info/migration-guides/index.md
+++ b/docs/en/release-info/migration-guides/index.md
@@ -2,6 +2,7 @@
The following documents explain how to migrate your existing ABP applications. We write migration documents only if you need to take an action while upgrading your solution. Otherwise, you can easily upgrade your solution using the [abp update command](../upgrading.md).
+- [8.x to 8.3](abp-8-3.md)
- [8.1 to 8.2](abp-8-2.md)
- [8.0 to 8.1](abp-8-1.md)
- [7.x to 8.0](abp-8-0.md)
diff --git a/docs/en/release-info/release-notes.md b/docs/en/release-info/release-notes.md
index d091a5840b..a94ed9d0b8 100644
--- a/docs/en/release-info/release-notes.md
+++ b/docs/en/release-info/release-notes.md
@@ -4,11 +4,20 @@ This document contains **brief release notes** for each release. Release notes o
> If you want to read detailed release posts for each version, please see the [official ABP blog](https://abp.io/blog).
-## 8.2 (2024-05-25)
+## 8.3.0-rc.1 (2024-07-31)
-> This version is currently in preview. The final release date is planned for July, 2024.
+> This version is currently in preview. The final release date is planned for August, 2024.
-See the detailed **[blog post / announcement](https://abp.io/blog/announcing-abp-8-2-release-candidate)** for the v8.2 release.
+See the detailed **[blog post / announcement](https://abp.io/blog/announcing-abp-8-3-release-candidate)** for the v8.3 release.
+
+* CMS Kit: Marked Items & Approvement System for Commenting Feature
+* Enhancements on the Docs Module (Google Translation support & new single project mode)
+* Using DbFunction for generating more precise SQL commands for Global Query Filters
+* CMS Kit (Pro): FAQ System
+
+## 8.2 (2024-06-26)
+
+See the detailed **[blog post / announcement](https://abp.io/blog/announcing-abp-8-2-stable-release)** for the v8.2 release.
* Blazor Full-Stack Web App UI.
* Introducing the `IBlockUiService` for Blazor UI (disables/blocks the page or a part of the page).
diff --git a/docs/en/release-info/road-map.md b/docs/en/release-info/road-map.md
index 6c14efefda..82da0a0b8e 100644
--- a/docs/en/release-info/road-map.md
+++ b/docs/en/release-info/road-map.md
@@ -4,55 +4,119 @@ This document provides a road map, release schedule, and planned features for th
## Next Versions
-### v8.3
-
-The next version will be 8.3 and we will be mostly working on the following topics:
-
-* CMS Kit: Marked Items/Favorites & Approvement System for Comments
-* Docs Module: Added Google Translation Support & Introducing the Single Project Mode
-* Using DBFunction for Global Query Filters
-* Upgrade Angular Version to v18.1.x
-* Improvements on the existing features and provide more guides...
-
-See the [8.3 milestone](https://github.com/abpframework/abp/milestone/106) for all the issues we've planned to work on.
+### v9.0
+
+The next version will be 9.0 and planned to release the stable 9.0 version in November 2024. We will be mostly working on the following topics:
+
+* Framework
+ * Upgrading to .NET 9.0
+ * Google Cloud Storage BLOB Provider
+ * Better handling localization resources in a microservice scenario
+ * SSR support for the Angular UI
+ * Upgrading 3rd-party dependencies
+
+* ABP Suite
+ * Multiple navigation properties to the same target entity
+ * Define navigation properties without target string property dependency
+ * Improvements one-to-many scenarios
+ * Access to default code generation templates for customized templates
+
+* ABP Studio
+ * Blazor WebApp UI option for the new startup templates
+ * Execution order (dependency management) for Solution Runner
+ * Automate more details on new service creation for a microservice solution
+ * Support multiple concurrent Kubernetes deployment/integration scenarios
+ * Show the README file when you create a new solution or open an existing solution
+ * Improve ABP Suite code-generation possibilities for microservice solutions
+ * Improve the module installation experience
+ * Auto-install 3rd-party dependencies
+ * Better handle long log files
+ * Allow to directly create new solutions with ABP's RC (Release Candidate) versions
+ * Support Intel processors for Mac computers, support ARM chipset for Windows and support Linux OS
+ * Improve client proxy generation experience
+
+* Application modules
+ * Account module: Support mixed social/local login scenarios
+ * UI/UX improvements on existing application modules
+
+* New tutorials
+ * Modular monolith development
+ * Microservice development
## Backlog Items
-The *Next Versions* section above shows the main focus of the planned versions. However, in each release, we add new features to the core framework and the [application modules](../modules).
-
-Here is a list of major items in the backlog we are considering working on in the next versions.
+The *Next Versions* section above shows the main focus of the planned versions. However, in each release, we add new features to the ABP platform.
### Framework
-* [#86](https://github.com/abpframework/abp/issues/86) / GrapQL Integration
+The ABP framework is [open source](https://github.com/abpframework/abp) and free for everyone. You can see its [public backlog](https://github.com/abpframework/abp/milestone/2). Here, are some of the important features you can expect from next versions:
+
* [#236](https://github.com/abpframework/abp/issues/236) / Resource based authorization system
-* [#2882](https://github.com/abpframework/abp/issues/2882) / Providing a gRPC integration infrastructure (while it is [already possible](https://github.com/abpframework/abp-samples/tree/master/GrpcDemo) to create or consume gRPC endpoints for your application, we plan to create endpoints for the [standard application modules](../modules))
+* [#2882](https://github.com/abpframework/abp/issues/2882) / Providing a gRPC integration infrastructure (while it is [already possible](https://github.com/abpframework/abp-samples/tree/master/GrpcDemo) to create or consume gRPC endpoints for your application, we plan to create endpoints for the [standard application modules](../modules/index.md))
* [#57](https://github.com/abpframework/abp/issues/57) / Built-in CQRS infrastructure
+* [#58](https://github.com/abpframework/abp/issues/58) / Content localization system (multilingual entities)
* [#4223](https://github.com/abpframework/abp/issues/4223) / WebHook system
* [#162](https://github.com/abpframework/abp/issues/162) / Azure ElasticDB Integration for multitenancy
* [#2296](https://github.com/abpframework/abp/issues/2296) / Feature toggling infrastructure
-* [#16342](https://github.com/abpframework/abp/issues/16342) / CMS Kit: Meta information for SEO
-* [#16260](https://github.com/abpframework/abp/issues/16260) / GCP Blob Storage Provider
* [#15932](https://github.com/abpframework/abp/issues/15932) / Introduce ABP Diagnostics Module
-* [#16756](https://github.com/abpframework/abp/issues/16756) / Blob Storing - Provider configuration UI
* [#16744](https://github.com/abpframework/abp/issues/16744) / State Management API
-
-### Modules / Themes
-
-* New styles, components and features for the LeptonX theme.
-* Payment module: Invoice system.
-* Dynamic dashboard system.
-* User guiding module.
-* gRPC integration and implementation for all the pre-built modules.
-* Chat Module: Deleting messages & conversations
-
-### Tooling
-
-* Suite: File, DateOnly and TimeOnly types
-* Suite: Export child/detail entity records
-* CMS Kit features, including FAQ, spam protection, social media feeds, multi-language support, and so on.
-
-You can always check the milestone planning and the prioritized backlog issues on [the GitHub repository](https://github.com/abpframework/abp/milestones) for a detailed road map. The backlog items are subject to change. We are adding new items and changing priorities based on the community feedbacks and goals of the project.
+* [#17815](https://github.com/abpframework/abp/issues/17815) / Operation Rate Limiting
+
+### Application Modules / UI Themes
+
+ABP Platform provides many (free and commercial) [pre-built application modules](../modules/index.md) and modern [UI themes](../ui-themes/index.md). In every release, many enhancements and bugfixes are already done on the existing modules. In addition, here some of the planned features for next versions:
+
+* LeptonX theme: New layouts, styles and components
+* CMS Kit module: Meta information for SEO, media gallery, RSS feed, content versioning, social media streams
+* Identity module: Idle session warning
+* Payment module: Invoice system
+* New module: User notification
+* New module: Dynamic dashboard
+* New module: User guiding
+* New module: Keycloak integration
+
+### ABP Studio
+
+[ABP Studio](../studio/index.md) is a cross-platform desktop application for ABP and .NET developers to simplify and automate daily tasks of developers. It has a community (free) edition as well as commercial editions. It is released and versioned independently from the ABP platform and frequently released.
+
+Here, are some of the important planned features for next ABP Studio versions:
+
+* Theme builder for the LeptonX theme
+* Analyze user solutions to explore entities, domain services, application services, pages and other fundamental objects.
+* Add status bar to the built-in browser to easily see errors
+* Swagger authentication support for the built-in browser
+* Show related requests/events (traces) together in the solution runner panel
+* Integrate common tool dashboards into ABP Studio (such a Garana, Redis, RabbitMQ, Kibana, etc)
+* Built-in command terminal
+* Automate all steps of new service creation for microservice solutions
+* Container application type support for Solution Runner (to individually control docker dependencies)
+* More options while creating new solutions
+* Downloading samples in ABP studio
+* Built-in ABP documentation experience
+* Auto-execute terminal commands in markdown files
+* Compare changed on the startup templates when a new ABP version is published
+* Remove unused projects while downloading source code of an existing module
+* Testing/hosting applications for module templates
+* Easily explore all module and package dependencies of a large solution
+* Built-in deployment options
+* Rapid application development features
+* ABP support integration
+
+### ABP Suite
+
+[ABP Suite](../suite/index.md) is a GUI application that is mainly used to generate CRUD style pages in your application. You define your entity and it can generate all the code from the database layer to the UI layer. The generated code is clean and a perfect starting point to implement your custom requirements on top of it.
+
+Here, are some of the important planned features for next ABP Suite versions:
+
+* Handle image properties for entities
+* Allow to define extra properties for DTOs those are not a part of the entity
+* Allow to create pages instead of modals for CRUD page generation
+* View-only (detail view) modal/page for an entity
+* Export child/detail entity records as a part of export operation for a main (master) entity
+* Allow to accept attachments (files) for an entity
+* Allow to add custom entity actions for an entity
+* Allow to inherit from an existing entity class
+* Custom form layouts on CRUD page generation
## Feature Requests
diff --git a/docs/en/solution-templates/application-module/index.md b/docs/en/solution-templates/application-module/index.md
index f8e2d7adb6..60f53a7018 100644
--- a/docs/en/solution-templates/application-module/index.md
+++ b/docs/en/solution-templates/application-module/index.md
@@ -15,17 +15,25 @@ dotnet tool install -g Volo.Abp.Studio.Cli
Then use the `abp new` command in an empty folder to create a new solution:
```bash
-abp new Acme.IssueManagement -t module
+abp new-module Acme.BookStore
```
- `Acme.IssueManagement` is the solution name, like *YourCompany.YourProduct*. You can use single level, two-levels or three-levels naming.
-### Without User Interface
+### Specifying the User Interface
-The template comes with MVC, Blazor & Angular user interfaces by default. You can use `--no-ui` option to not include any of these UI layers.
+The template comes without a user interface by default. You can use the `mvc`, `blazor`, `blazor-server`, or `angular` options to include any of these UI layers. You can also combine them. For example, you can use `mvc,angular` to include both MVC and Angular UI. To create a module without a user interface, don't specify any value.
````bash
-abp new Acme.IssueManagement -t module --no-ui
+abp new-module Acme.IssueManagement -u mvc,angular
+````
+
+#### Specifying the Database Provider
+
+The template comes with the *EntityFrameworkCore* database provider by default. You can use the `ef` or `mongodb` options to include either of these providers. You can also combine them. For example, you can use `ef,mongodb` to include both EntityFrameworkCore and MongoDB.
+
+````bash
+abp new-module Acme.IssueManagement -d ef,mongodb
````
## Solution Structure
@@ -34,11 +42,10 @@ Based on the options you've specified, you will get a slightly different solutio

-Projects are organized as `src`, `test` and `host` folders:
+Projects are organized as `src` and`test` folders:
* `src` folder contains the actual module which is layered based on [DDD](../../framework/architecture/domain-driven-design) principles.
* `test` folder contains unit & integration tests.
-* `host` folder contains applications with different configurations to demonstrate how to host the module in an application. These are not a part of the module, but useful on development.
The diagram below shows the layers & project dependencies of the module:
@@ -105,8 +112,6 @@ The solution has multiple test projects, one for each layer:
- `.MongoDB.Tests` is used to test MongoDB configuration and custom repositories.
- `.TestBase` is a base (shared) project for all tests.
-In addition, `.HttpApi.Client.ConsoleTestApp` is a console application (not an automated test project) which demonstrate the usage of HTTP APIs from a Dotnet application.
-
Test projects are prepared for integration testing;
- It is fully integrated to ABP and all services in your application.
@@ -117,49 +122,9 @@ You can still create unit tests for your classes which will be harder to write (
> Domain & Application tests are using EF Core. If you remove EF Core integration or you want to use MongoDB for testing these layers, you should manually change project references & module dependencies.
-### Host Projects
-
-The solution has a few host applications to run your module. Host applications are used to run your module in a fully configured application. It is useful on development. Host applications includes some other modules in addition to the module being developed:
-
-Host applications support two types of scenarios.
-
-#### Single (Unified) Application Scenario
-
-If your module has a UI, then `.Web.Unified` application is used to host the UI and API on a single point. It has its own `appsettings.json` file (that includes the database connection string) and EF Core database migrations.
-
-For the `.Web.Unified` application, there is a single database, named `YourProjectName_Unified` (like *IssueManagement_Unified* for this sample).
-
-> If you've selected the `--no-ui` option, this project will not be in your solution.
-
-##### How to Run?
-
-Set `host/YourProjectName.Web.Unified` as the startup project, run `Update-Database` command for the EF Core from Package Manager Console and run your application. Default username is `admin` and password is `1q2w3E*`.
-
-#### Separated Deployment & Databases Scenario
-
-In this scenario, there are three applications;
-
-* `.AuthServer` application is an authentication server used by other applications. It has its own `appsettings.json` that contains database connection and other configurations.
-* `.HttpApi.Host` hosts the HTTP API of the module. It has its own `appsettings.json` that contains database connections and other configurations.
-* `.Web.Host` host the UI of the module. This project contains an `appsettings.json` file, but it does not have a connection string because it never connects to the database. Instead, it mainly contains endpoint of the remote API server and the authentication server.
-
-The diagram below shows the relation of the applications:
-
-
-
-`.Web.Host` project uses OpenId Connect Authentication to get identity and access tokens for the current user from the `.AuthServer`. Then uses the access token to call the `.HttpApi.Host`. HTTP API server uses bearer token authentication to obtain claims from the access token to authorize the current user.
-
-##### Pre-requirements
-
-* [Redis](https://redis.io/): The applications use Redis as as distributed cache. So, you need to have Redis installed & running.
-
-##### How to Run?
-
-You should run the application with the given order:
+### Host Project
-- First, run the `.AuthServer` since other applications depends on it.
-- Then run the `.HttpApi.Host` since it is used by the `.Web.Host` application.
-- Finally, you can run the `.Web.Host` project and login to the application using `admin` as the username and `1q2w3E*` as the password.
+The solution doesn't have a host application to run your module. However, you can create a [single-layer](../../get-started/single-layer-web-application.md) or [layered](../../get-started/layered-web-application.md) application and [import](../../studio/solution-explorer.md#imports) the created module into the host application.
## UI
@@ -172,7 +137,7 @@ The solution will have a folder called `angular` in it. This is where the Angula
* _angular/projects/issue-management_ folder contains the Angular module project.
* _angular/projects/dev-app_ folder contains a development application that runs your module.
-The server-side is similar to the solution described above. `*.HttpApi.Host` project serves the API and the `Angular` demo application consumes it. You will not need to run the `.Web.Host` project though.
+The server-side is similar to the solution described above. After you create a *Host* application, the API and the `Angular` demo application consume it.
#### How to Run the Angular Development App
@@ -195,9 +160,10 @@ The module you will develop depends on two of these ABP packages: _@abp/ng.core_
Once all dependencies are installed, follow the steps below to serve your development app:
-1. Make sure `.AuthServer` and `*.HttpApi.Host` projects are up and running.
-2. Open your terminal at the root folder, i.e. `angular`.
-3. Run `yarn start` or `npm start`.
+1. Make sure *Host* application project is up and running.
+2. Change the `environment.ts` file in the `angular/projects/dev-app/src/environments` folder to match your *Host* application URL.
+3. Open your terminal at the root folder, i.e. `angular`.
+4. Run `yarn start` or `npm start`.

diff --git a/docs/en/solution-templates/microservice/adding-new-api-gateways.md b/docs/en/solution-templates/microservice/adding-new-api-gateways.md
index a026f6e884..415452a3bd 100644
--- a/docs/en/solution-templates/microservice/adding-new-api-gateways.md
+++ b/docs/en/solution-templates/microservice/adding-new-api-gateways.md
@@ -155,12 +155,6 @@ We should configure the AuthServer for **CORS** and **RedirectAllowedUrls**.
}
```
-### Add the New Gateway to the Solution Runner
-
-We should add the new gateway to the solution runner [profile](../../studio/running-applications.md#profile) for running applications in the ABP Studio. You can follow the steps explained in the [Solution Runner](../../studio/running-applications.md#c-application) document to add the new gateway to the solution runner profile. Afterwards, you can start the new gateway by selecting it in the solution runner.
-
-
-
## Creating Helm Chart for the New Gateway
If you want to deploy the new gateway to Kubernetes, you should create a Helm chart for the new application.
diff --git a/docs/en/solution-templates/microservice/adding-new-applications.md b/docs/en/solution-templates/microservice/adding-new-applications.md
index 7e3a53cbae..352b18f763 100644
--- a/docs/en/solution-templates/microservice/adding-new-applications.md
+++ b/docs/en/solution-templates/microservice/adding-new-applications.md
@@ -120,12 +120,6 @@ Add the new application URL to the `appsettings.json` file in the `Identity` ser
}
```
-### Add the New Application to the Solution Runner
-
-We should add the new application to the solution runner [profile](../../studio/running-applications.md#profile) for running applications in the ABP Studio. You can follow the steps explained in the [Solution Runner](../../studio/running-applications.md#c-application) document to add the new application to the solution runner profile. Afterwards, you can start the new application by selecting it in the solution runner.
-
-
-
## Docker Configuration for Prometheus
If you want to monitor the new application with Prometheus when you debug the solution, you should add the new application to the `prometheus.yml` file in the `etc/docker/prometheus` folder. You can copy the configurations from the existing applications and modify them according to the new application. Below is an example of the `prometheus.yml` file for the `WebPublic` application.
diff --git a/docs/en/solution-templates/microservice/adding-new-microservices.md b/docs/en/solution-templates/microservice/adding-new-microservices.md
index 2ff864cd0d..9cb482c552 100644
--- a/docs/en/solution-templates/microservice/adding-new-microservices.md
+++ b/docs/en/solution-templates/microservice/adding-new-microservices.md
@@ -16,6 +16,8 @@ This document explains how to add new microservices to the microservice solution
Additionally, there is a folder named `_templates` in the root directory. This folder contains templates you can use to create new microservices, API gateways, and applications. These templates can be customized according to your needs.
+
+
## Adding a New Microservice
To add a new microservice to the solution, you can use the `service_nolayers` template. This template creates a new ASP.NET Core application with the necessary configurations and dependencies. Follow the steps below to add a new microservice:
@@ -32,6 +34,11 @@ Select the database provider and click the `Create` button.

+When you create a new microservice, you can choose to enable integration with the current solution. If you check *Enable integration*, the new microservice is added to the solution, and the necessary configurations are made automatically, so no manual configuration is needed. If you uncheck the *Enable integration* option, you will need to manually configure the new microservice. You can follow the steps in this documentation, starting from the [Configuring the appsettings.json](#configuring-the-appsettingsjson) section.
+
+
+
+
The new microservice is created and added to the solution. You can see the new microservice in the `services` folder.

@@ -39,14 +46,12 @@ The new microservice is created and added to the solution. You can see the new m
### Configuring the appsettings.json
The new microservice is created with the necessary configurations and dependencies. We should configure several sections by modifying the `appsettings.json` file:
- * Set the `Administration` & `AbpBlobStoring` connection strings.
- * Set the correct `StringEncryption` key.
* Set the `CorsOrigins` to allow the web gateway to access the microservice.
* Set the `AuthServer` configurations to enable the microservice to authenticate and authorize users.
You can copy the configurations from the existing microservices and modify them according to the new microservice. Below is an example of the `appsettings.json` file for the `ProductService` microservice.
-```json
+```diff
{
"ConnectionStrings": {
"Administration": "Server=localhost,1434; User Id=sa; Password=myPassw@rd; Database=Bookstore_Administration; TrustServerCertificate=true",
@@ -54,15 +59,18 @@ You can copy the configurations from the existing microservices and modify them
"ProductService": "Server=localhost,1434; User Id=sa; Password=myPassw@rd; Database=Bookstore_ProductService; TrustServerCertificate=true"
},
"App": {
- "CorsOrigins": "http://localhost:44333",
+- "CorsOrigins": "http://localhost:webgateway_port",
++ "CorsOrigins": "http://localhost:44333",
"EnablePII": false
},
"Swagger": {
"IsEnabled": true
},
"AuthServer": {
- "Authority": "http://localhost:44387",
- "MetaAddress": "http://localhost:44387",
+- "Authority": "http://localhost:authserver_port",
+- "MetaAddress": "http://localhost:authserver_port",
++ "Authority": "http://localhost:44387",
++ "MetaAddress": "http://localhost:44387",
"RequireHttpsMetadata": "false",
"SwaggerClientId": "SwaggerTestUI",
"Audience": "ProductService"
@@ -93,24 +101,24 @@ You can copy the configurations from the existing microservices and modify them
"Url": "http://localhost:9200"
},
"StringEncryption": {
- "DefaultPassPhrase": "PDAWjbshpwlOwNB6"
+ "DefaultPassPhrase": "PDAWjbshpwlOwNB6"
}
}
```
### Configuring the OpenId Options
-We should configure the OpenId options by modifying the `OpenIddictDataSeeder` in the `Identity` service. Below is an example of the `OpenIddictDataSeeder` options for the `ProductService` microservice.
+We should configure the OpenId options by modifying the `OpenIddictDataSeeder` in the `Identity` service. Below is an example of the `OpenIddictDataSeeder` options for the `Product` microservice.
Create API scopes and add the required API scope for Swagger clients in the `CreateApiScopesAsync` and `CreateSwaggerClientsAsync` methods in the `OpenIddictDataSeeder` class.
-```csharp
+```diff
private async Task CreateApiScopesAsync()
{
await CreateScopesAsync("AuthServer");
await CreateScopesAsync("IdentityService");
await CreateScopesAsync("AdministrationService");
- await CreateScopesAsync("ProductService"); // new service
++ await CreateScopesAsync("ProductService");
}
private async Task CreateSwaggerClientsAsync()
@@ -120,21 +128,21 @@ private async Task CreateSwaggerClientsAsync()
"AuthServer",
"IdentityService",
"AdministrationService",
- "ProductService" // new service
++ "ProductService"
});
}
```
Add the redirect URL for the new service in the `CreateSwaggerClientAsync` method.
-```csharp
+```diff
private async Task CreateSwaggerClientAsync(string clientId, string[] scopes)
{
...
...
...
var administrationServiceRootUrl = _configuration["OpenIddict:Resources:AdministrationService:RootUrl"]!.TrimEnd('/');
- var productServiceServiceRootUrl = _configuration["OpenIddict:Resources:ProductService:RootUrl"]!.TrimEnd('/'); // new service
++ var productServiceRootUrl = _configuration["OpenIddict:Resources:ProductService:RootUrl"]!.TrimEnd('/');
await CreateOrUpdateApplicationAsync(
name: clientId,
@@ -152,15 +160,15 @@ private async Task CreateSwaggerClientAsync(string clientId, string[] scopes)
$"{authServerRootUrl}/swagger/oauth2-redirect.html",
$"{identityServiceRootUrl}/swagger/oauth2-redirect.html",
$"{administrationServiceRootUrl}/swagger/oauth2-redirect.html",
- $"{productServiceServiceRootUrl}/swagger/oauth2-redirect.html", // new service
++ $"{productServiceRootUrl}/swagger/oauth2-redirect.html"
}
);
}
```
-Add the allowed scope for the web (front-end) application(s) in the `CreateClientsAsync` method. You might have different clients for different UI applications such as web, Angular, React, etc. Ensure you add the new service to the allowed scopes of these clients.
+Add the allowed scope for the web (front-end) application(s) in the `CreateClientsAsync` method. You might have different clients for different UI applications such as web, Angular, React, etc. Ensure you add the new microservice to the allowed scopes of these clients.
-```csharp
+```diff
private async Task CreateClientsAsync()
{
var commonScopes = new List
@@ -192,7 +200,7 @@ private async Task CreateClientsAsync()
"SaasService",
"AuditLoggingService",
"AdministrationService",
- "ProductService" // new service
++ "ProductService"
}).ToList(),
redirectUris: new List { $"{webClientRootUrl}signin-oidc" },
postLogoutRedirectUris: new List() { $"{webClientRootUrl}signout-callback-oidc" },
@@ -202,110 +210,130 @@ private async Task CreateClientsAsync()
}
```
-Add the new service URL to the `appsettings.json` file in the `Identity` service.
+Add the new service URL to the `appsettings.json` file in the `Identity` microservice. In this example we're gonna edit the *Acme.Bookstore.IdentityService* project `appsettings.json` file.
-```json
+```diff
"OpenIddict": {
"Applications": {
...
},
"Resources": {
...
- "ProductService": {
- "RootUrl": "http://localhost:44350"
- }
++ "ProductService": {
++ "RootUrl": "http://localhost:44350"
++ }
}
}
```
### Configuring the AuthServer
-We should configure the AuthServer for **CORS** and **RedirectAllowedUrls**.
+We should configure the *AuthServer* application `appsettings.json` file for the **CorsOrigins** and **RedirectAllowedUrls** sections.
-```json
+```diff
+...
"App": {
"SelfUrl": "http://localhost:***",
- "CorsOrigins": "...... ,http://localhost:44350",
+- "CorsOrigins": "http://localhost:44358,..",
++ "CorsOrigins": "http://localhost:44358,..,http://localhost:44350",
"EnablePII": false,
- "RedirectAllowedUrls": "...... ,http://localhost:44350"
-}
+- "RedirectAllowedUrls": "http://localhost:44358,..",
++ "RedirectAllowedUrls": "http://localhost:44358,..,http://localhost:44350"
+},
+...
```
### Configuring the API Gateway
-We should configure the API Gateway to allow the web gateway to access the new microservice. First, we should add the **ProductService** sections to the `appsettings.json` file in the `WebGateway` project.
+We should configure the API Gateway to access the new microservice. First, add the **Product** sections to the `appsettings.json` file in the `WebGateway` project. In this example we're gonna edit the *Acme.Bookstore.WebGateway* project `appsettings.json` file.
-```json
+```diff
"ReverseProxy": {
"Routes": {
...
- "ProductService": {
- "ClusterId": "ProductService",
- "Match": {
- "Path": "/api/productservice/{**catch-all}"
- }
- },
- "ProductServiceSwagger": {
- "ClusterId": "ProductService",
- "Match": {
- "Path": "/swagger-json/ProductService/swagger/v1/swagger.json"
- },
- "Transforms": [
- { "PathRemovePrefix": "/swagger-json/ProductService" }
- ]
- }
++ "Product": {
++ "ClusterId": "Product",
++ "Match": {
++ "Path": "/api/product/{**catch-all}"
++ }
++ },
++ "ProductSwagger": {
++ "ClusterId": "Product",
++ "Match": {
++ "Path": "/swagger-json/Product/swagger/v1/swagger.json"
++ },
++ "Transforms": [
++ { "PathRemovePrefix": "/swagger-json/Product" }
++ ]
++ }
},
"Clusters": {
...
- "ProductService": {
- "Destinations": {
- "ProductService": {
- "Address": "http://localhost:44350/"
- }
- }
- }
++ "Product": {
++ "Destinations": {
++ "Product": {
++ "Address": "http://localhost:44350/"
++ }
++ }
++ }
}
}
```
-Afterwards, open the `ProjectNameWebGatewayModule` class in the `WebGateway` and add the `ProductService` to the `ConfigureSwaggerUI` method.
+Afterwards, open the `ProjectNameWebGatewayModule` class in the `WebGateway` project and add the `ProductService` to the `ConfigureSwaggerUI` method. In this example we're gonna edit the `BookstoreWebGatewayModule` file.
+
+```diff
+private static void ConfigureSwaggerUI(
+ IProxyConfig proxyConfig,
+ SwaggerUIOptions options,
+ IConfiguration configuration)
+{
+ foreach (var cluster in proxyConfig.Clusters)
+ {
+ options.SwaggerEndpoint($"/swagger-json/{cluster.ClusterId}/swagger/v1/swagger.json", $"{cluster.ClusterId} API");
+ }
-```csharp
-options.OAuthScopes(
- "AdministrationService",
- "AuthServer",
- "IdentityService",
- "ProductService" // new service
-);
+ options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]);
+ options.OAuthScopes(
+ "AdministrationService",
+ "AuthServer",
+ ...,
++ "ProductService"
+ );
+}
```
### Configuring the UI Services
-We should configure the UI application(s) to allow the new microservice to access through the web gateway. To do this, we should add the new service scope to the `ConfigureAuthentication` method in the `ProjectName...Module` class in the `Web` or `Blazor` application.
+We should configure the UI application(s) to allow the new microservice to access through the web gateway. To do this, we should add the new microservice scope to the `ConfigureAuthentication` method in the `ProjectName...Module` class in the `Web` or `Blazor` application. In this example we're gonna edit the `BookstoreWebModule` file.
-```csharp
-context.Services.AddAuthentication(options =>
-{
- options.DefaultScheme = "Cookies";
- options.DefaultChallengeScheme = "oidc";
-})
-.AddCookie("Cookies", options =>
+```diff
+private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{
- options.ExpireTimeSpan = TimeSpan.FromDays(365);
-})
-.AddAbpOpenIdConnect("oidc", options =>
-{
- ...
- options.Scope.Add("AuthServer");
- options.Scope.Add("IdentityService");
- options.Scope.Add("AdministrationService");
- options.Scope.Add("ProductService"); // new servie
-});
+ context.Services.AddAuthentication(options =>
+ {
+ options.DefaultScheme = "Cookies";
+ options.DefaultChallengeScheme = "oidc";
+ })
+ .AddCookie("Cookies", options =>
+ {
+ options.ExpireTimeSpan = TimeSpan.FromDays(365);
+ })
+ .AddAbpOpenIdConnect("oidc", options =>
+ {
+ ...
+ options.Scope.Add("AuthServer");
+ options.Scope.Add("IdentityService");
+ options.Scope.Add("AdministrationService");
++ options.Scope.Add("ProductService");
+ });
+ ...
+}
```
Similarly, if you have an Angular application, you should add the new service scope to the `oAuthConfig` in `environment.ts`:
-```typescript
+```diff
const baseUrl = 'http://localhost:4200';
const oAuthConfig = {
@@ -313,69 +341,83 @@ const oAuthConfig = {
redirectUri: baseUrl,
clientId: 'Angular',
responseType: 'code',
- scope: 'openid profile email roles AuthServer IdentityService AdministrationService ProductService', // new service
+- scope: 'openid profile email roles AuthServer IdentityService AdministrationService',
++ scope: 'openid profile email roles AuthServer IdentityService AdministrationService ProductService',
requireHttps: false
};
```
-### Add the New Microservice to the Solution Runner
-
-We should add the new microservice to the solution runner [profile](../../studio/running-applications.md#profile) for running applications in the ABP Studio. You can follow the steps explained in the [Solution Runner](../../studio/running-applications.md#c-application) document to add the new microservice to the solution runner profile. Afterwards, you can start the new microservice by selecting it in the solution runner.
-
-
-
## Docker Configuration for Prometheus
-If you want to monitor the new microservice with Prometheus when you debug the solution, you should add the new microservice to the `prometheus.yml` file in the `etc/docker/prometheus` folder. You can copy the configurations from the existing microservices and modify them according to the new microservice. Below is an example of the `prometheus.yml` file for the `ProductService` microservice.
+If you want to monitor the new microservice with Prometheus when you debug the solution, you should add the new microservice to the `prometheus.yml` file in the `etc/docker/prometheus` folder. You can copy the configurations from the existing microservices and modify them according to the new microservice. Below is an example of the `prometheus.yml` file for the `Product` microservice.
-```yml
- - job_name: 'product'
+```diff
+ - job_name: 'authserver'
scheme: http
metrics_path: 'metrics'
static_configs:
- - targets: ['host.docker.internal:44350']
+ - targets: ['host.docker.internal:44398']
+ ...
++ - job_name: 'product'
++ scheme: http
++ metrics_path: 'metrics'
++ static_configs:
++ - targets: ['host.docker.internal:44350']
```
## Creating Helm Chart for the New Microservice
If you want to deploy the new microservice to Kubernetes, you should create a Helm chart for the new microservice.
-First, we need to add the new microservice to the `build-all-images.ps1` script in the `etc/helm` folder. You can copy the configurations from the existing microservices and modify them according to the new microservice. Below is an example of the `build-all-images.ps1` script for the `ProductService` microservice.
+First, we need to add the new microservice to the `build-all-images.ps1` script in the `etc/helm` folder. You can copy the configurations from the existing microservices and modify them according to the new microservice. Below is an example of the `build-all-images.ps1` script for the `Product` microservice.
-```powershell
-./build-image.ps1 -ProjectPath "../../services/product/Acme.Bookstore.ProductService/Acme.Bookstore.ProductService.csproj" -ImageName bookstore/productservice
+```diff
+...
+ ./build-image.ps1 -ProjectPath "../../apps/auth-server/Acme.Bookstore.AuthServer/Acme.Bookstore.AuthServer.csproj" -ImageName bookstore/authserver
++ ./build-image.ps1 -ProjectPath "../../services/product/Acme.Bookstore.ProductService/Acme.Bookstore.ProductService.csproj" -ImageName bookstore/product
```
-Then, we need to add the connection string to the `values.projectname-local.yaml` file in the `etc/helm/projectname` folder. Below is an example of the `values.bookstore-local.yaml` file for the `ProductService` microservice.
+Then, we need to add the connection string to the `values.projectname-local.yaml` file in the `etc/helm/projectname` folder. Below is an example of the `values.bookstore-local.yaml` file for the `Product` microservice.
-```yaml
+```diff
global:
...
connectionStrings:
...
- productService: "Server=[RELEASE_NAME]-sqlserver,1433; Database=Bookstore_ProductService; User Id=sa; Password=myPassw@rd; TrustServerCertificate=True"
++ product: "Server=[RELEASE_NAME]-sqlserver,1433; Database=Bookstore_ProductService; User Id=sa; Password=myPassw@rd; TrustServerCertificate=True"
```
-Afterwards, we need to create a new Helm chart for the new microservice. You can copy the configurations from the existing microservices and modify them according to the new microservice. Below is an example of the `productservice` Helm chart for the `ProductService` microservice.
+Afterwards, we need to create a new Helm chart for the new microservice. You can copy the configurations from the existing microservices and modify them according to the new microservice. Below is an example of the `product` Helm chart for the `Product` microservice.
+
+Product microservice `values.yaml` file.
{%{
```yaml
-# values.yaml
image:
- repository: "bookstore/productservice"
+ repository: "bookstore/product"
tag: "latest"
pullPolicy: IfNotPresent
swagger:
isEnabled: "true"
+```
+}%}
+
+Product microservice `Chart.yaml` file.
-# Chart.yaml
+{%{
+```yaml
apiVersion: v2
-name: productservice
+name: product
version: 1.0.0
appVersion: "1.0"
description: Bookstore Product Service
+```
+}%}
-# product.yaml
+Product microservice `product.yaml` file.
+
+{%{
+```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -404,10 +446,15 @@ spec:
- name: "ConnectionStrings__AbpBlobStoring"
value: "{{ .Values.global.connectionStrings.blobStoring | replace "[RELEASE_NAME]" .Release.Name }}"
- name: "ConnectionStrings__ProductService"
- value: "{{ .Values.global.connectionStrings.productService | replace "[RELEASE_NAME]" .Release.Name }}"
+ value: "{{ .Values.global.connectionStrings.product | replace "[RELEASE_NAME]" .Release.Name }}"
...
+```
+}%}
+
+Product microservice `product-service.yaml` file.
-# product-service.yaml
+{%{
+```yaml
apiVersion: v1
kind: Service
metadata:
@@ -427,32 +474,113 @@ After creating the Helm chart, you can *Refresh Sub Charts* in the ABP Studio.

-Then, update *Metadata* information right-click the *microservicename* [sub-chart](../../studio/kubernetes.md#subchart), select *Properties* it open *Chart Properties* window. You can edit in the *Metadata* tab.
+Then, update *Metadata* information right-click the *microservicename* [sub-chart](../../studio/kubernetes.md#subchart), select *Properties* it open *Chart Properties* window. You should add the following keys in the *Metadata* tab.

+- `projectPath`: The path to the microservice host application project. In the bookstore example, this value is `../../services/product/Acme.Bookstore.ProductService/Acme.Bookstore.ProductService.csproj`.
+- `imageName`: When we build the Docker image, it uses this value as the Docker image name. We're going to use it in the Helm chart values.
+- `projectType`: You can add a Helm chart for Angular and .NET projects, which is why we should explicitly specify the project type.
+
Add the *Kubernetes Services* in the *Chart Properties* -> *Kubernetes Services* tab.

+> This value should be the same as the [solution runner application](./../../studio/running-applications.md#properties) *Kubernetes service* value. It's necessary for browsing because when we connect to the Kubernetes cluster, we should browse the Kubernetes services instead of using the Launch URL.
+
Last but not least, we need to configure the helm chart environments for identity, auth-server, and gateway applications.
+Below is an example of the *Identity* microservice `identity.yaml` file.
+
{%{
-```yaml
-# identity.yaml
-# Add this line to the "env:" section
-- name: "OpenIddict__Resources__ProductService__RootUrl"
- value: "http://{{ .Release.Name }}-productservice"
-
-# authserver.yaml
-# Concat the following lines for "App__CorsOrigins" section
-- name: "App__CorsOrigins"
- value: "...,http://{{ .Release.Name }}-administration,http://{{ .Release.Name }}-productservice"
-
-# webapigateway.yaml
-# Add this line to the "env:" section
-- name: "ReverseProxy__Clusters__ProductService__Destinations__ProductService__Address"
- value: "http://{{ .Release.Name }}-productservice"
+```diff
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: "{{ .Release.Name }}-{{ .Chart.Name }}"
+spec:
+ selector:
+ matchLabels:
+ app: "{{ .Release.Name }}-{{ .Chart.Name }}"
+ template:
+ metadata:
+ labels:
+ app: "{{ .Release.Name }}-{{ .Chart.Name }}"
+ spec:
+ containers:
+ - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: "{{ .Values.image.pullPolicy }}"
+ name: "{{ .Release.Name }}-{{ .Chart.Name }}"
+ ports:
+ - name: "http"
+ containerPort: 80
+ env:
+ ...
++ - name: "OpenIddict__Resources__ProductService__RootUrl"
++ value: "http://{{ .Release.Name }}-product"
+```
+}%}
+
+Below is an example of the *AuthServer* application `authserver.yaml` file.
+
+{%{
+```diff
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: "{{ .Release.Name }}-{{ .Chart.Name }}"
+spec:
+ selector:
+ matchLabels:
+ app: "{{ .Release.Name }}-{{ .Chart.Name }}"
+ template:
+ metadata:
+ labels:
+ app: "{{ .Release.Name }}-{{ .Chart.Name }}"
+ spec:
+ containers:
+ - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: "{{ .Values.image.pullPolicy }}"
+ name: "{{ .Release.Name }}-{{ .Chart.Name }}"
+ ports:
+ - name: "http"
+ containerPort: 80
+ env:
+ ...
+ - name: "App__CorsOrigins"
+- value: "...,http://{{ .Release.Name }}-administration"
++ value: "...,http://{{ .Release.Name }}-administration,http://{{ .Release.Name }}-product"
+```
+}%}
+
+Below is an example of the *WebApiGateway* application `webapigateway.yaml` file.
+
+{%{
+```diff
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: "{{ .Release.Name }}-{{ .Chart.Name }}"
+spec:
+ selector:
+ matchLabels:
+ app: "{{ .Release.Name }}-{{ .Chart.Name }}"
+ template:
+ metadata:
+ labels:
+ app: "{{ .Release.Name }}-{{ .Chart.Name }}"
+ spec:
+ containers:
+ - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: "{{ .Values.image.pullPolicy }}"
+ name: "{{ .Release.Name }}-{{ .Chart.Name }}"
+ ports:
+ - name: "http"
+ containerPort: 80
+ env:
+ ...
++ - name: "ReverseProxy__Clusters__Product__Destinations__Product__Address"
++ value: "http://{{ .Release.Name }}-product"
```
}%}
@@ -465,11 +593,11 @@ You can customize the microservice template if needed. Add new configurations, d
After adding the new microservice to the solution, you can develop the UI for the new microservice. For .NET applications, you can add the microservice *Contracts* package to the UI application(s) to access the services provided by the new microservice. Afterwards, you can use the [generate-proxy](../../cli/index.md#generate-proxy) command to generate the proxy classes for the new microservice.
```bash
-abp generate-proxy -t csharp -url http://localhost:44333/ -m productService --without-contracts
+abp generate-proxy -t csharp -url http://localhost:44333/ -m product --without-contracts
```
Next, start creating *Pages* and *Components* for the new microservice in the UI application(s). Similarly, if you have an Angular application, you can use the [generate-proxy](../../cli/index.md#generate-proxy) command to generate the proxy classes for the new microservice and start developing the UI.
```bash
-abp generate-proxy -t ng -url http://localhost:44333/ -m productService
+abp generate-proxy -t ng -url http://localhost:44333/ -m product
```
\ No newline at end of file
diff --git a/docs/en/solution-templates/microservice/images/create-new-microservice-nolayers-enable-integration.png b/docs/en/solution-templates/microservice/images/create-new-microservice-nolayers-enable-integration.png
new file mode 100644
index 0000000000..a1aa31887f
Binary files /dev/null and b/docs/en/solution-templates/microservice/images/create-new-microservice-nolayers-enable-integration.png differ
diff --git a/docs/en/solution-templates/microservice/images/folder-structure.png b/docs/en/solution-templates/microservice/images/folder-structure.png
new file mode 100644
index 0000000000..926bfaa3d5
Binary files /dev/null and b/docs/en/solution-templates/microservice/images/folder-structure.png differ
diff --git a/docs/en/studio/images/solution-explorer/abp-solution.png b/docs/en/studio/images/solution-explorer/abp-solution.png
index 8348e71778..b15e7f46f0 100644
Binary files a/docs/en/studio/images/solution-explorer/abp-solution.png and b/docs/en/studio/images/solution-explorer/abp-solution.png differ
diff --git a/docs/en/studio/images/solution-explorer/create-new-microservice-nolayers-enable-integration.png b/docs/en/studio/images/solution-explorer/create-new-microservice-nolayers-enable-integration.png
new file mode 100644
index 0000000000..a1aa31887f
Binary files /dev/null and b/docs/en/studio/images/solution-explorer/create-new-microservice-nolayers-enable-integration.png differ
diff --git a/docs/en/studio/installation.md b/docs/en/studio/installation.md
index 11f390f9f3..4dc158e464 100644
--- a/docs/en/studio/installation.md
+++ b/docs/en/studio/installation.md
@@ -8,7 +8,7 @@
Before you begin the installation process for ABP Studio, ensure that your system meets the following pre-requirements:
### Node
-Make sure [Node.js](https://nodejs.org/en) is installed on your system. If you have not installed Node.js, you can download the `v16` or `v18` version from the official [Node.js website](https://nodejs.org/en/download/prebuilt-installer).
+Make sure [Node.js](https://nodejs.org/en) is installed on your system. If you have not installed Node.js, you can download the `v18.19+` version from the official [Node.js website](https://nodejs.org/en/download/prebuilt-installer).
### WireGuard (Optional)
ABP Studio needs [WireGuard](https://www.wireguard.com/) for Kubernetes operations. You can find the installation instructions for your specific operating system below:
diff --git a/docs/en/studio/kubernetes.md b/docs/en/studio/kubernetes.md
index 666fdf0a99..f05a30ee04 100644
--- a/docs/en/studio/kubernetes.md
+++ b/docs/en/studio/kubernetes.md
@@ -150,9 +150,9 @@ Upon disconnection from the cluster, we clean up the hosts file, excluding ingre

-> When you list the services in the Kubernetes cluster with the `kubectl get svc` command, you should see the *abp-wg-easy* and *abp-wg-easy-vpn* services. After a while, if the *EXTERNAL-IP* is still *pending*, then it can't connect to the cluster. This could be caused by if you try to install the WireGuard VPN to a Docker Desktop Kubernetes cluster more than once. You can delete the previous WireGuard VPN by running the `helm uninstall abp-wg-easy` command in the previous namespace.
+> When you list the services in the Kubernetes cluster with the `kubectl get svc` command, you should see the *abp-wg-easy* and *abp-wg-easy-vpn* services. Each WireGuard installation has a unique port number for the related services. If you have multiple WireGuard installations for different Kubernetes profiles or solutions, you can see the port numbers in the *PORT(S)* field when you list them with the `kubectl get svc` command.
-> Connecting to the Kubernetes cluster is limited to one instance of ABP Studio at a time. Trying to connect with another instance simultaneously won't work as expected.
+> Connecting to the Kubernetes cluster is limited to one instance of ABP Studio at the same time. Trying to connect with another instance simultaneously won't work as expected.
### Intercept a Service
diff --git a/docs/en/studio/release-notes.md b/docs/en/studio/release-notes.md
index f30d4855af..d3afbe008e 100644
--- a/docs/en/studio/release-notes.md
+++ b/docs/en/studio/release-notes.md
@@ -2,6 +2,26 @@
This document contains **brief release notes** for each ABP Studio release. Release notes only include **major features** and **visible enhancements**. Therefore, they don't include all the development done in the related version.
+## 0.8.3 (2024-09-24)
+
+* Allowed to set Execution Order (or dependency) from Solution Runner
+* Added Icons for the Solution Runner's Context Menu
+* Fixed MongoDB database issues for the Microservice Template
+* Allowed parallel running for background tasks
+
+## 0.8.2 (2024-09-19)
+
+* Fixed WireGuard connection random port bug
+* Automated steps after microservice solution creation
+* Fixed unusable options/features for Trial License
+* Fixed blazor-server single-layer template
+
+## 0.8.1 (2024-09-12)
+
+* Fixed MySQL connection problem for nolayers template
+* Ignored failed solution runner profiles while loading
+* Added required ModalBuilder extensions for the imported/installed modules for EF Core
+
## 0.8.0 (2024-09-11)
* Added `Blazor WebApp UI` to **app-nolayers** and **microservice** templates
diff --git a/docs/en/studio/solution-explorer.md b/docs/en/studio/solution-explorer.md
index 76e3543269..8aa0ea4404 100644
--- a/docs/en/studio/solution-explorer.md
+++ b/docs/en/studio/solution-explorer.md
@@ -47,6 +47,8 @@ It is the main solution that you can open with ABP Studio, an ABP solution can c
- `Open With`
- `Terminal`: Opens the terminal in the solution directory.
- `Explorer`: Opens the file explorer in the solution directory.
+- `Solution Configuration`: You can see the project creation options in this menu. It opens the *Solution Configuration* window.
+- `Open Readme`: Opens the README file in the solution if available. If there is no README file, this option will not be visible.
## Folder
@@ -143,6 +145,10 @@ You can choose the database provider for your microservice module. Select one of

+When you create a microservice, you must edit some [configurations](../solution-templates/microservice/adding-new-microservices.md#configuring-the-appsettingsjson). If you select the *Enable integration* option, it automatically configures the required settings for the microservice to work with the gateway, web, and other modules.
+
+
+
After creating the *Microservice (service-nolayers)* module, it will be added to the solution, and you should see the following structure in the solution explorer.

@@ -157,7 +163,7 @@ ABP modules have their own file extension `.abpmdl`, and they are located in the
### Difference Between ABP Module Template and ABP Studio Module Approach
-In ABP, creating a module solution using the [CLI](../cli/index.md) results in a solution with numerous projects, some of which may not be necessary for a specific use case. The ABP Studio module approach differs from the ABP module template, offering greater flexibility. With ABP Studio, we can create a module containing only the required projects; for example, an empty module with only the `Domain` and `Application` projects. In this approach, the term [Package](./concepts.md#package) is used for module projects.
+In ABP, creating a module solution using the [old CLI](../cli/differences-between-old-and-new-cli.md) results in a solution with numerous projects, some of which may not be necessary for a specific use case. The ABP Studio new module approach differs from the ABP old module template, offering greater flexibility. With ABP Studio, we can create a module containing only the required projects; for example, an empty module with only the `Domain` and `Application` projects. In this approach, the term [Package](./concepts.md#package) is used for module projects.
Furthermore, it's important to mention that we can create not just DDD-principled modules. The [Modularity](../framework/architecture/modularity/basics.md) document clarifies the difference between *Framework* and *Application* modules. Basically, every C# project refers to the `Volo.Abp.Core` package and defines the *Module* class as an ABP Class Library. We have the option to develop an infrastructure module using only the *ABP Class Library* packages and provide a module reference to other modules.
diff --git a/docs/en/studio/version-compatibility.md b/docs/en/studio/version-compatibility.md
index 812db493b9..1bf8ee4be5 100644
--- a/docs/en/studio/version-compatibility.md
+++ b/docs/en/studio/version-compatibility.md
@@ -4,6 +4,7 @@ This document provides an overview of the compatibility between various versions
| **ABP Studio Version** | **ABP Version** |
|------------------------|---------------------------|
+| 0.8.1 to 0.8.3 | 8.3.0 |
| 0.8.0 | 8.2.3 |
| 0.7.8 - 0.7.9 | 8.2.2 |
| 0.7.4 to 0.7.7 | 8.2.1 |
diff --git a/docs/en/tutorials/index.md b/docs/en/tutorials/index.md
index 87484d2acb..1f03c87d8e 100644
--- a/docs/en/tutorials/index.md
+++ b/docs/en/tutorials/index.md
@@ -1,7 +1,7 @@
-## ABP Tutorials
+# ABP Tutorials
-The following guides explains how to build ABP based applications:
+The following introductory tutorials explain how to build applications based on the ABP platform:
* [TODO Application](todo/index.md): This is a single-part, quick-start tutorial to build a simple application with ABP. Start with this tutorial if you want to quickly understand how ABP works.
* [Book Store Application](book-store/index.md): This is a multi-part, complete tutorial to build a bookstore application with ABP. Start with this tutorial if you want to create a layered solution with ABP and apply DDD best practices.
-* [Modular Monolith Application](modular-crm/index.md): This is a multi-part tutorial that demonstrates how to create application modules, compose and communicate them to build a monolith modular web application.
\ No newline at end of file
+* [Modular Monolith Application](modular-crm/index.md): This is a multi-part tutorial that demonstrates how to create application modules, compose and communicate them to build a monolith modular web application.
diff --git a/docs/en/tutorials/todo/layered/index.md b/docs/en/tutorials/todo/layered/index.md
index 78f49df9dd..b58d95a034 100644
--- a/docs/en/tutorials/todo/layered/index.md
+++ b/docs/en/tutorials/todo/layered/index.md
@@ -53,7 +53,7 @@ This documentation has a video tutorial on **YouTube**!! You can watch it here:
## Pre-Requirements
* An IDE (e.g. [Visual Studio](https://visualstudio.microsoft.com/vs/)) that supports [.NET 8.0+](https://dotnet.microsoft.com/download/dotnet) development.
-* [Node v16.x](https://nodejs.org/)
+* [Node v18.19+](https://nodejs.org/)
{{if DB=="Mongo"}}
diff --git a/docs/en/tutorials/todo/single-layer/index.md b/docs/en/tutorials/todo/single-layer/index.md
index 9afbbd8833..3b4f755c70 100644
--- a/docs/en/tutorials/todo/single-layer/index.md
+++ b/docs/en/tutorials/todo/single-layer/index.md
@@ -49,7 +49,7 @@ This documentation has a video tutorial on **YouTube**!! You can watch it here:
## Pre-Requirements
* An IDE (e.g. [Visual Studio](https://visualstudio.microsoft.com/vs/)) that supports [.NET 8.0+](https://dotnet.microsoft.com/download/dotnet) development.
-* [Node v16.x](https://nodejs.org/)
+* [Node v18.19+](https://nodejs.org/)
{{if DB=="Mongo"}}
diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/Authentication/AbpAspNetCoreTokenUnauthorizedErrorInfo.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/Authentication/AbpAspNetCoreTokenUnauthorizedErrorInfo.cs
new file mode 100644
index 0000000000..2702f4f19f
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/Authentication/AbpAspNetCoreTokenUnauthorizedErrorInfo.cs
@@ -0,0 +1,12 @@
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.AspNetCore.Authentication;
+
+public class AbpAspNetCoreTokenUnauthorizedErrorInfo : IScopedDependency
+{
+ public string? Error { get; set; }
+
+ public string? ErrorDescription { get; set; }
+
+ public string? ErrorUri { get; set; }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Microsoft/Extensions/DependencyInjection/AbpJwtBearerExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Microsoft/Extensions/DependencyInjection/AbpJwtBearerExtensions.cs
index 5f48cc92d5..8973b68a1f 100644
--- a/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Microsoft/Extensions/DependencyInjection/AbpJwtBearerExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Microsoft/Extensions/DependencyInjection/AbpJwtBearerExtensions.cs
@@ -1,6 +1,7 @@
using System;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Volo.Abp.AspNetCore.Authentication;
using Volo.Abp.Security.Claims;
namespace Microsoft.Extensions.DependencyInjection;
@@ -31,6 +32,33 @@ public static class AbpJwtBearerExtensions
return builder.AddJwtBearer(authenticationScheme, displayName, options =>
{
configureOptions?.Invoke(options);
+
+ options.Events ??= new JwtBearerEvents();
+ var previousOnChallenge = options.Events.OnChallenge;
+ options.Events.OnChallenge = async eventContext =>
+ {
+ await previousOnChallenge(eventContext);
+
+ if (eventContext.Handled ||
+ !string.IsNullOrEmpty(eventContext.Error) ||
+ !string.IsNullOrEmpty(eventContext.ErrorDescription) ||
+ !string.IsNullOrEmpty(eventContext.ErrorUri))
+ {
+ return;
+ }
+
+ var tokenUnauthorizedErrorInfo = eventContext.HttpContext.RequestServices.GetRequiredService();
+ if (string.IsNullOrEmpty(tokenUnauthorizedErrorInfo.Error) &&
+ string.IsNullOrEmpty(tokenUnauthorizedErrorInfo.ErrorDescription) &&
+ string.IsNullOrEmpty(tokenUnauthorizedErrorInfo.ErrorUri))
+ {
+ return;
+ }
+
+ eventContext.Error = tokenUnauthorizedErrorInfo.Error;
+ eventContext.ErrorDescription = tokenUnauthorizedErrorInfo.ErrorDescription;
+ eventContext.ErrorUri = tokenUnauthorizedErrorInfo.ErrorUri;
+ };
});
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj b/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj
index 4d7b852b9c..839053bc90 100644
--- a/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj
@@ -19,6 +19,7 @@
+
diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo/Abp/AspNetCore/Authentication/JwtBearer/AbpAspNetCoreAuthenticationJwtBearerModule.cs b/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo/Abp/AspNetCore/Authentication/JwtBearer/AbpAspNetCoreAuthenticationJwtBearerModule.cs
index 89d957fe57..c0b9122b7d 100644
--- a/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo/Abp/AspNetCore/Authentication/JwtBearer/AbpAspNetCoreAuthenticationJwtBearerModule.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo/Abp/AspNetCore/Authentication/JwtBearer/AbpAspNetCoreAuthenticationJwtBearerModule.cs
@@ -7,7 +7,7 @@ using Volo.Abp.Security.Claims;
namespace Volo.Abp.AspNetCore.Authentication.JwtBearer;
-[DependsOn(typeof(AbpSecurityModule), typeof(AbpCachingModule))]
+[DependsOn(typeof(AbpSecurityModule), typeof(AbpCachingModule), typeof(AbpAspNetCoreAbstractionsModule))]
public class AbpAspNetCoreAuthenticationJwtBearerModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
@@ -21,5 +21,6 @@ public class AbpAspNetCoreAuthenticationJwtBearerModule : AbpModule
context.Services.AddTransient();
context.Services.AddTransient();
}
+
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBodyTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBodyTagHelperService.cs
index e50d0a791a..b8462f4b5b 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBodyTagHelperService.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBodyTagHelperService.cs
@@ -32,7 +32,7 @@ public class AbpCardBodyTagHelperService : AbpTagHelperService
var small = new TagBuilder("small");
small.Attributes.Add("id", idAttr?.Value?.ToString() + "InfoText");
- small.AddCssClass("form-text text-muted");
+ small.AddCssClass("form-text");
small.InnerHtml.Append(localizedText);
return small.ToHtmlString();
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/AbpAspNetCoreMvcUiBundlingModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/AbpAspNetCoreMvcUiBundlingModule.cs
index bdd4cb2a27..f0f7f94439 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/AbpAspNetCoreMvcUiBundlingModule.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/AbpAspNetCoreMvcUiBundlingModule.cs
@@ -1,4 +1,6 @@
-using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap;
+using Volo.Abp.AspNetCore.Mvc.Libs;
+using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap;
+using Volo.Abp.Data;
using Volo.Abp.Minify;
using Volo.Abp.Modularity;
@@ -11,5 +13,14 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling;
)]
public class AbpAspNetCoreMvcUiBundlingModule : AbpModule
{
-
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ if (!context.Services.IsDataMigrationEnvironment())
+ {
+ Configure(options =>
+ {
+ options.CheckLibs = true;
+ });
+ }
+ }
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/DatatablesNet/DatatablesNetScriptContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/DatatablesNet/DatatablesNetScriptContributor.cs
index daea15328f..2ad3bb2bdb 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/DatatablesNet/DatatablesNetScriptContributor.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/DatatablesNet/DatatablesNetScriptContributor.cs
@@ -10,6 +10,14 @@ public class DatatablesNetScriptContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
- context.Files.AddIfNotContains("/libs/datatables.net/js/jquery.dataTables.js");
+ if (context.FileProvider.GetFileInfo("/libs/datatables.net/js/dataTables.min.js").Exists)
+ {
+ context.Files.AddIfNotContains("/libs/datatables.net/js/dataTables.min.js");
+ }
+ else
+ {
+ //TODO: Compatible code, Remove it after 8.3 rc1.
+ context.Files.AddIfNotContains("/libs/datatables.net/js/jquery.dataTables.js");
+ }
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js
index b4000d6cbc..e43c7caad9 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js
@@ -90,7 +90,7 @@ var abp = abp || {};
return "";
}
- var $button = $('');
+ var $button = $('');
if (firstItem.displayNameHtml) {
$button.html(abp.utils.isFunction(firstItem.text) ? firstItem.text(record, tableInstance) : firstItem.text);
@@ -240,10 +240,17 @@ var abp = abp || {};
if (tableInstance.aoColumns) {
columns = tableInstance.aoColumns;
- } else {
+ } else if (abp.utils.isFunction(tableInstance.fnSettings)) {
columns = tableInstance.fnSettings().aoColumns;
}
+ if (!columns && abp.utils.isFunction(tableInstance.api)) {
+ var settings = tableInstance.api().settings();
+ if (settings.length === 1 && settings[0].aoColumns) {
+ columns = settings[0].aoColumns;
+ }
+ }
+
if (!columns) {
return;
}
@@ -271,8 +278,9 @@ var abp = abp || {};
}
};
- var _existingApiRenderRowActionsFunction = $.fn.dataTableExt.oApi.renderRowActions;
- $.fn.dataTableExt.oApi.renderRowActions =
+ if ($.fn.dataTableExt.oApi) {
+ var _existingApiRenderRowActionsFunction = $.fn.dataTableExt.oApi.renderRowActions;
+ $.fn.dataTableExt.oApi.renderRowActions =
function (tableInstance, nRow, aData, iDisplayIndex, iDisplayIndexFull) {
if (_existingApiRenderRowActionsFunction) {
_existingApiRenderRowActionsFunction(tableInstance, nRow, aData, iDisplayIndex, iDisplayIndexFull);
@@ -280,7 +288,8 @@ var abp = abp || {};
renderRowActions(tableInstance, nRow, aData, iDisplayIndex, iDisplayIndexFull);
};
-
+ }
+
if (!$.fn.dataTable) {
return;
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
index 7b68fca32d..379523b659 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
@@ -32,6 +32,7 @@ using Volo.Abp.AspNetCore.Mvc.DataAnnotations;
using Volo.Abp.AspNetCore.Mvc.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc.Infrastructure;
using Volo.Abp.AspNetCore.Mvc.Json;
+using Volo.Abp.AspNetCore.Mvc.Libs;
using Volo.Abp.AspNetCore.Mvc.Localization;
using Volo.Abp.AspNetCore.VirtualFileSystem;
using Volo.Abp.DependencyInjection;
@@ -231,6 +232,7 @@ public class AbpAspNetCoreMvcModule : AbpModule
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
AddApplicationParts(context);
+ CheckLibs(context);
}
private static void AddApplicationParts(ApplicationInitializationContext context)
@@ -277,4 +279,9 @@ public class AbpAspNetCoreMvcModule : AbpModule
partManager.ApplicationParts.AddIfNotContains(moduleAssembly);
}
}
+
+ private static void CheckLibs(ApplicationInitializationContext context)
+ {
+ context.ServiceProvider.GetRequiredService().CheckLibs(context);
+ }
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs
index d2abae0902..3b60e74d78 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs
@@ -75,10 +75,18 @@ public class AbpExceptionFilter : IAsyncExceptionFilter, IAbpFilter, ITransientD
}
else
{
- context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true");
- context.HttpContext.Response.StatusCode = (int)context
- .GetRequiredService()
- .GetStatusCode(context.HttpContext, context.Exception);
+ if (!context.HttpContext.Response.HasStarted)
+ {
+ context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true");
+ context.HttpContext.Response.StatusCode = (int)context
+ .GetRequiredService()
+ .GetStatusCode(context.HttpContext, context.Exception);
+ }
+ else
+ {
+ var logger = context.GetService>(NullLogger.Instance)!;
+ logger.LogWarning("HTTP response has already started, cannot set headers and status code!");
+ }
context.Result = new ObjectResult(new RemoteServiceErrorResponse(remoteServiceErrorInfo));
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs
index f404f52e5d..56814718b6 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs
@@ -103,10 +103,17 @@ public class AbpExceptionPageFilter : IAsyncPageFilter, IAbpFilter, ITransientDe
}
else
{
- context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true");
- context.HttpContext.Response.StatusCode = (int)context
- .GetRequiredService()
- .GetStatusCode(context.HttpContext, context.Exception!);
+ if (!context.HttpContext.Response.HasStarted)
+ {
+ context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true");
+ context.HttpContext.Response.StatusCode = (int)context
+ .GetRequiredService()
+ .GetStatusCode(context.HttpContext, context.Exception!);
+ }
+ else
+ {
+ logger.LogWarning("HTTP response has already started, cannot set headers and status code!");
+ }
context.Result = new ObjectResult(new RemoteServiceErrorResponse(remoteServiceErrorInfo));
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Libs/AbpMvcLibsOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Libs/AbpMvcLibsOptions.cs
new file mode 100644
index 0000000000..d166528a05
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Libs/AbpMvcLibsOptions.cs
@@ -0,0 +1,6 @@
+namespace Volo.Abp.AspNetCore.Mvc.Libs;
+
+public class AbpMvcLibsOptions
+{
+ public bool CheckLibs { get; set; }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Libs/AbpMvcLibsService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Libs/AbpMvcLibsService.cs
new file mode 100644
index 0000000000..b59cbefa45
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Libs/AbpMvcLibsService.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using Microsoft.Extensions.FileProviders;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.AspNetCore.Mvc.Libs;
+
+public class AbpMvcLibsService : IAbpMvcLibsService, ITransientDependency
+{
+ private Task? _checkLibsTask;
+
+ public virtual void CheckLibs(ApplicationInitializationContext context)
+ {
+ var options = context.ServiceProvider.GetRequiredService>().Value;
+ if (options.CheckLibs)
+ {
+ var app = context.GetApplicationBuilderOrNull();
+ if (app == null)
+ {
+ var logger = context.ServiceProvider.GetRequiredService>();
+ logger.LogWarning($"The {nameof(IApplicationBuilder)} is not available. The 'CheckLibs' feature is disabled!");
+ return;
+ }
+
+ app.Use(async (httpContext, next) =>
+ {
+ if (!await CheckLibsAsyncOnceAsync(httpContext))
+ {
+ httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
+ httpContext.Response.ContentType = "text/html";
+ await httpContext.Response.WriteAsync(
+ "" +
+ " " +
+ " Error - The Libs folder is missing!" +
+ " " +
+ " " +
+ "
⚠️ The Libs folder under the wwwroot/libs directory is empty!
" +
+ "
The Libs folder contains mandatory NPM Packages for running the project.
" +
+ "
Make sure you run the abp install-libs CLI tool command.