diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
index 58e4b561d6..04da7d097d 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
@@ -45,7 +45,7 @@
"IndexPageHeroSection": "A complete web development platformbuilt-on framework",
"AbpCommercialShortDescription": "ABP Commercial provides pre-built application modules, rapid application development tooling, professional UI themes, premium support and more.",
"LiveDemo": "Live Demo",
- "GetLicence" :"Get a Licence",
+ "GetLicence": "Get a Licence",
"Application": "Application",
"StartupTemplates": "Startup Templates",
"Startup": "Startup",
@@ -174,8 +174,8 @@
"HowManyProductsExplanation": "There is no limit to create an ABP project. You can create as many project as you want, develop and upload them to different servers.",
"HowManyDevelopers": "How many developers can work on the ABP Commercial?",
"HowManyDevelopersExplanation": "ABP Commercial licenses are per developer. Different license types have different developer limits. However, you can add more developers to any license type whenever you need. See the prices page for license types, developer limits and additional developer costs.",
- "ChangingLicenseType": "Can I change my license type in the future?",
- "ChangingLicenseTypeExplanation": "You can always add new developers in your same license type. See also \"How many developers can work on the ABP Commercial?\". You can also upgrade to a higher license by paying the calculated price difference. When you upgrade to a higher license plan, you get the benefits of the new plan, but the license upgrade does not change the license expiry date.",
+ "ChangingLicenseType": "Can I upgrade my license type later?",
+ "ChangingLicenseTypeExplanation": "You can upgrade to a higher license by paying the difference within your active license period. When you upgrade to a higher license plan, you get the benefits of the new plan, but the license upgrade does not change the license expiry date. Besides, you can also add new developer seats to your existing license, see \"How many developers can work on the ABP Commercial?\"",
"LicenseExtendUpgradeDiff": "What is the difference between license extend and upgrade?",
"LicenseExtendUpgradeDiffExplanation": "Extending: By extending/renewing your license, you will continue to get premium support and get major updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development.
Upgrading: By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. See the license comparison table to check the differences between the license plans.On the other hand, when you upgrade, your license expiry date will not change!To extend your license end date, you need to extend your license.",
"LicenseRenewalCost": "What is the license renewal cost after 1 year?",
@@ -196,14 +196,14 @@
"WhatHappensWhenLicenseEndsExplanation4": "You can not install new modules and themes added to the ABP Commercial platform after your license ends.",
"WhatHappensWhenLicenseEndsExplanation5": "You can not use the ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "You can not get the premium support anymore.",
- "WhatHappensWhenLicenseEndsExplanation7": "You can renew your subscription if you want to continue to get these benefits. There is a 20% discount when you renew your subscription.",
+ "WhatHappensWhenLicenseEndsExplanation7": "You can renew your subscription if you want to continue to get these benefits. If you renew your subscription within 1 month after your license expires, a 20% discount is applied.",
"WhenShouldIRenewMyLicense": "When should I renew my license?",
- "WhenShouldIRenewMyLicenseExplanation1": "If you renew your license within 1 month after your license expires, %20 discount will be applied to total license price.",
+ "WhenShouldIRenewMyLicenseExplanation1": "If you renew your license within 1 month after your license expires, a %20 discount is be applied.",
"WhenShouldIRenewMyLicenseExplanation2": "If you renew your license after 1 month from your license expire date, the renew price will be same as license purchase price and there will be no discount for your renewal.",
"TrialPlan": "Do you have a trial plan?",
"TrialPlanExplanation": "For now, ABP Commercial doesn't have a trial plan. For the Team licenses we provide 30 days money back guarantee. You can just request a refund in the first 30 days. For the Business and Enterprise licenses, we provide 60% refund in 30 days. This is because Business and Enterprise licenses include the full source code of all the modules and the themes.",
"DoYouAcceptBankWireTransfer": "Do you accept bank wire transfer?",
- "DoYouAcceptBankWireTransferExplanation": "Yes, we accept bank wire transfer. After sending the license amount via bank wire transfer, send us your receipt and the requested license type via e-mail. Our international bank account information:",
+ "DoYouAcceptBankWireTransferExplanation": "Yes, we accept bank wire transfer. After sending the license fee via bank transfer, email us at info@abp.io your receipt and the type of license requested. Our international bank account information:",
"HowToUpgrade": "How to upgrade existing applications when a new version is available?",
"HowToUpgradeExplanation1": "When you create a new application using ABP Commercial, all the modules and the theme are used as NuGet and NPM packages. So, you can easily upgrade the packages when a new version is available.",
"HowToUpgradeExplanation2": "In addition to the standard NuGet/NPM upgrades, ABP CLI provides an update command that automatically finds and upgrades all ABP related packages in your solution.",
diff --git a/common.props b/common.props
index 457a937d22..6ce5cae828 100644
--- a/common.props
+++ b/common.props
@@ -1,7 +1,7 @@
latest
- 4.4.0
+ 5.0.0$(NoWarn);CS1591;CS0436https://abp.io/assets/abp_nupkg.pnghttps://abp.io/
diff --git a/docs/en/Background-Jobs-Hangfire.md b/docs/en/Background-Jobs-Hangfire.md
index cfa2e12a6b..a690d9d17b 100644
--- a/docs/en/Background-Jobs-Hangfire.md
+++ b/docs/en/Background-Jobs-Hangfire.md
@@ -79,3 +79,26 @@ After you have installed these NuGet packages, you need to configure your projec
}
````
+
+### Dashboard Authorization
+
+Hangfire Dashboard provides information about your background jobs, including method names and serialized arguments as well as gives you an opportunity to manage them by performing different actions – retry, delete, trigger, etc. So it is important to restrict access to the Dashboard.
+To make it secure by default, only local requests are allowed, however you can change this by following the [official documentation](http://docs.hangfire.io/en/latest/configuration/using-dashboard.html) of Hangfire.
+
+You can integrate the Hangfire dashboard to [ABP authorization system](Authorization.md) using the **AbpHangfireAuthorizationFilter**
+class. This class is defined in the `Volo.Abp.Hangfire` package. The following example, checks if the current user is logged in to the application:
+
+ app.UseHangfireDashboard("/hangfire", new DashboardOptions
+ {
+ AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() }
+ });
+
+If you want to require an additional permission, you can pass it into the constructor as below:
+
+ app.UseHangfireDashboard("/hangfire", new DashboardOptions
+ {
+ AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter("MyHangFireDashboardPermissionName") }
+ });
+
+**Important**: `UseHangfireDashboard` should be called after the authentication middleware in your `Startup` class (probably at the last line). Otherwise,
+authorization will always fail!
diff --git a/docs/en/Blog-Posts/2020-10-15 v3_3_Preview/POST.md b/docs/en/Blog-Posts/2020-10-15 v3_3_Preview/POST.md
index 4e19a294c1..886e8a145d 100644
--- a/docs/en/Blog-Posts/2020-10-15 v3_3_Preview/POST.md
+++ b/docs/en/Blog-Posts/2020-10-15 v3_3_Preview/POST.md
@@ -213,7 +213,7 @@ There are some breaking changes with the Blazor UI. If you've built an applicati
When you create a new project, profile management doesn't work, you get an exception because it can't find the `/libs/cropperjs/css/cropper.min.css` file. To fix the issue;
* Add `"@volo/account": "^3.3.0-rc.1"` to the `package.json` in the `.Host` project.
-* Run `yarn` (or `npm install`), then `gulp` on a command line terminal in the root folder of the `.Host` project.
+* Run `yarn` (or `npm install`), then `abp install-libs` on a command line terminal in the root folder of the `.Host` project.
### Multi-Tenant Social Logins
diff --git a/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/POST.md b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/POST.md
new file mode 100644
index 0000000000..dff6d1af77
--- /dev/null
+++ b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/POST.md
@@ -0,0 +1,174 @@
+# ABP Platform 4.4 RC Has Been Released
+
+Today, we have released the [ABP Framework](https://abp.io/) and the [ABP Commercial](https://commercial.abp.io/) version 4.4 RC (Release Candidate). This blog post introduces the new features and important changes in this new version.
+
+> **The planned release date for the [4.4.0 final](https://github.com/abpframework/abp/milestone/53) version is July 13, 2021**.
+
+## Get Started with the 4.4 RC
+
+If you want to try the version 4.4.0 today, follow the steps below;
+
+1) **Upgrade** the ABP CLI to the version `4.4.0-rc.1` using a command line terminal:
+
+````bash
+dotnet tool update Volo.Abp.Cli -g --version 4.4.0-rc.1
+````
+
+**or install** if you haven't installed before:
+
+````bash
+dotnet tool install Volo.Abp.Cli -g --version 4.4.0-rc.1
+````
+
+2) Create a **new application** with the `--preview` option:
+
+````bash
+abp new BookStore --preview
+````
+
+See the [ABP CLI documentation](https://docs.abp.io/en/abp/latest/CLI) for all the available options.
+
+> You can also use the *Direct Download* tab on the [Get Started](https://abp.io/get-started) page by selecting the **Preview checkbox**.
+
+### Migration Notes
+
+There is **no breaking change** with this version. However, if you are using Entity Framework Core, you will need to run the `Add-Migration` command to add a new **database migration** since some changes done in the module database mappings.
+
+## What's new with the ABP Framework 4.4
+
+### Removed EntityFrameworkCore.DbMigrations Project
+
+With this version, we are doing an important change in the application startup solution template. The startup solution was containing an `EntityFrameworkCore.DbMigrations` project that contains a separate `DbContext` class which was responsible to unify the module database mappings and maintain the code-first database migrations. With the v4.4, we've removed that project from the solution. In the new structure, the `EntityFrameworkCore` integration project will be used for database migrations as well as on runtime.
+
+We'd published [a community article](https://community.abp.io/articles/unifying-dbcontexts-for-ef-core-removing-the-ef-core-migrations-project-nsyhrtna) about that change. Please see the article to understand the motivation behind the change.
+
+Beside the `DbContext` unification, we've also used the new `ReplaceDbContext` attribute and [replaced](https://github.com/abpframework/abp/blob/ea2205f0855f52015152ae066a5c239af4b8511f/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs#L18-L19) the `IIdentityDbContext` and `ITenantManagementDbContext` interfaces to make it possible to perform join queries over repositories for these modules easily. In the next days, we will publish another community article to explain the problem and the solution. However, most of times, you don't need to know these details.
+
+### Dynamic Menu Management for the CMS Kit Module
+
+CMS Kit is a set of reusable *Content Management System* features packaged as an ABP application module. We had published the first usable version with the previous release. With this release, we are adding another feature to the CMS Kit module: You can now dynamically arrange the main menu on the UI, which is an essential feature for any kind of content management system. In this way, you can add pages or any kind of arbitrary URLs to the main menu from the UI.
+
+A screenshot from the menu management page (from the CMS Kit admin side):
+
+
+
+And the items rendered in a public website:
+
+
+
+Note that this feature is also available with the open source [CMS Kit module](https://docs.abp.io/en/abp/4.4/Modules/Cms-Kit/Index) (while the screenshots have been taken from the ABP Commercial).
+
+### Razor Engine Support for Text Templating
+
+[Text Templating](https://docs.abp.io/en/abp/4.4/Text-Templating) is a system to generate content on runtime by using a model (data) and a template. It was running on the [Scriban](https://github.com/scriban/scriban) templating engine. Beginning from this version, we have a second option: We can use the familiar **razor syntax** to build and render the templates. See the text templating [razor integration document](https://docs.abp.io/en/abp/4.4/Text-Templating-Razor) to get started with the new engine!
+
+### New Customization Points for DbContext/Entities
+
+Two new extension methods are added to `ObjectExtensionManager.Instance` to override EF Core mappings of [pre-built application modules](https://docs.abp.io/en/abp/latest/Modules/Index).
+
+**Example: Change mappings for the `IdentityDbContext` to override mappings for the `IdentityUser` entity**
+
+````csharp
+ObjectExtensionManager.Instance.MapEfCoreDbContext(modelBuilder =>
+{
+ modelBuilder.Entity(b =>
+ {
+ b.ToTable("MyUsers");
+ b.Property(x => x.Email).HasMaxLength(300);
+ });
+});
+````
+
+The startup template contains a class, like `YourProjectNameEfCoreEntityExtensionMappings`, that can be used to place that code.
+
+### New ABP CLI Commands
+
+There are new [ABP CLI](https://docs.abp.io/en/abp/4.4/CLI) commands introduced with the v4.4:
+
+* `abp install-libs` command is used for MVC / Razor Pages and Blazor Server applications to restore the `wwwroot/libs` folder. Previously we were running the `yarn` and `gulp` commands to restore that folder. While the `install-libs` command still uses yarn (if available), it is no longer needed to use `gulp`.
+* `abp prompt` command can be used to open a prompt for the ABP CLI and run multiple commands without needing to specify the `abp` command every time. For example, if you run `abp prompt`, then you can directly run `install-libs` instead of `abp install-libs`. Use `exit` to quit from the ABP prompt.
+* `abp batch` command can be used to run multiple ABP commands with one command. Prepare a text file, write each command as a line (without the `abp` command prefix), then execute `abp batch ` (ex: `abp batch your_commands.txt`) command to execute all the commands in that file.
+
+### appsettings.secrets.json
+
+Added `appsettings.secrets.json` to the startup template that can be used to set your sensitive/secret configuration values. You can ignore this file from source control (by adding to `.gitignore` if you're using git) and keep it only in developer/production machines.
+
+### Other ABP Framework Improvements
+
+* [#9350](https://github.com/abpframework/abp/pull/9350) Extracted `IRemoteServiceConfigurationProvider` to get remote service configurations. You can replace this service to get the configuration from any source.
+* [#8829](https://github.com/abpframework/abp/pull/8829) Implemented error handler and retry for distributed event bus.
+* [#9288](https://github.com/abpframework/abp/issues/9288) Use default CORS policy instead of a named one in the startup template. It is suggested to update your own solutions to make it simpler.
+* Translated the framework and module localization strings to Hindi, Italian, Finnish and French languages.
+
+Beside these, there are a lot of enhancements and bug fixes. See the [4.4-preview milestone](https://github.com/abpframework/abp/milestone/52?closed=1) for all issues and pull requests closed with this version.
+
+## What's new with the ABP Commercial 4.4
+
+### New Features for the SaaS Module
+
+We've implemented some important features to the [SaaS module](https://commercial.abp.io/modules/Volo.Saas):
+
+* Integrated to the [Payment module](https://commercial.abp.io/modules/Volo.Payment) and implemented **subscription system** for the SaaS module.
+* Allow to make a **tenant active/passive**. In this way, you can take a tenant to passive to prevent the users of that tenant from using the system. In addition, you can set a date to automatically make a tenant passive when the date comes.
+* Allow to **limit user count** for a tenant.
+* Allow to set **different connection strings** for a tenant for each database/module, which makes possible to create different databases for a tenant for each microservice in a microservice solution.
+
+### New ABP Suite Code Generation Features
+
+There are many improvements done for for [ABP Suite](https://commercial.abp.io/tools/suite), including CRUD page generation for the **[microservice solution](https://docs.abp.io/en/commercial/latest/startup-templates/microservice/index) template**.
+
+### Angular UI: Two Factor Authentication for the Resource Owner Password Flow
+
+In the previous version, we had implemented the resource owner password authentication flow for the Angular UI, which makes the login process easier for simpler applications. With this release, we've implemented two-factor authentication for that flow. Authorization code flow already supports 2FA.
+
+### Other ABP Commercial Improvements
+
+* Added web layers to microservices in the microservice solution. You can use them to create modular UI or override existing pages/components of pre-built modules (e.g. Identity and SaaS).
+* ABP Commercial license code has been moved to `appsettings.secrets.json` in the new startup templates.
+* Added new language options: Hindi, Italian, Arabic, Finnish, French.
+
+Beside these, there are many minor improvements and fixes done in the modules and themes.
+
+## Other News
+
+In this section, I will share some news that you may be interested in.
+
+### New Article: Using Elsa Workflow with ABP Framework
+
+We have been frequently asked how to use [Elsa Workflows](https://elsa-workflows.github.io/elsa-core/) with the ABP Framework. Finally, we have [created an article](https://community.abp.io/articles/using-elsa-workflow-with-the-abp-framework-773siqi9) to demonstrate it.
+
+
+
+You can [check it](https://community.abp.io/articles/using-elsa-workflow-with-the-abp-framework-773siqi9) to see how to integrate Elsa into an ABP based solution easily.
+
+### Free E-Book: Implementing Domain Driven Design
+
+We've published a free e-book for the ABP Community in the beginning of June. This is a practical guide for implementing Domain Driven Design (DDD). While the implementation details are based on the ABP Framework infrastructure, the basic concepts, principles and models can be applied to any solution, even if it is not a .NET solution.
+
+
+
+Thousands of copies are already downloaded. If you haven't seen it yet, [click here to get a free copy of that e-book](https://abp.io/books/implementing-domain-driven-design).
+
+### The LeptonX Theme
+
+We have been working on a new ABP theme, named the *LeptonX*, for a long time. The theme will be available for ABP Framework (free - lite version) and ABP Commercial (pro version). It is being finalized in the next weeks and we will release the first version in a short time.
+
+
+
+See [this blog post](https://volosoft.com/blog/introducing-the-lepton-theme-next-generation) to learn more about that project.
+
+### Volosoft & .NET Foundation
+
+[Volosoft](https://volosoft.com/), the company leads the ABP Framework project, has been a corporate sponsor of the [.NET Foundation](https://dotnetfoundation.org/). We are happy by taking our place among other great sponsors!
+
+
+
+We will continue to contribute to and support open source! See this [blog post for the announcement](https://volosoft.com/blog/Volosoft-Announces-the-NET-Foundation-Sponsorship).
+
+### Looking for Developer Advocate(s)
+
+We are actively looking for professional developer advocates for the ABP.IO platform. If you want to create content and touch to the ABP community, please check our [job post](https://github.com/volosoft/vs-home/issues/13).
+
+## About the Next Version
+
+The next version will be a major version: 5.0, which will be based on .NET 6.0. We are planning to release it in the end of 2021, short time after the .NET 6.0 release. We will release multiple preview/beta versions before the RC version. See the [road map](https://docs.abp.io/en/abp/latest/Road-Map) for details of the planned works for the version 5.0.
diff --git a/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/abp-44-cover.png b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/abp-44-cover.png
new file mode 100644
index 0000000000..1f231aac00
Binary files /dev/null and b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/abp-44-cover.png differ
diff --git a/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/ddd-book.png b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/ddd-book.png
new file mode 100644
index 0000000000..747fcc1d13
Binary files /dev/null and b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/ddd-book.png differ
diff --git a/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/dotnetfoundation-sponsor-volosoft.png b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/dotnetfoundation-sponsor-volosoft.png
new file mode 100644
index 0000000000..e1f70929f4
Binary files /dev/null and b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/dotnetfoundation-sponsor-volosoft.png differ
diff --git a/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/elsa-overview.gif b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/elsa-overview.gif
new file mode 100644
index 0000000000..ba589cabfc
Binary files /dev/null and b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/elsa-overview.gif differ
diff --git a/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/leptonx.png b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/leptonx.png
new file mode 100644
index 0000000000..46faaf13e6
Binary files /dev/null and b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/leptonx.png differ
diff --git a/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/menu-items-admin.png b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/menu-items-admin.png
new file mode 100644
index 0000000000..63075eed70
Binary files /dev/null and b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/menu-items-admin.png differ
diff --git a/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/menu-items-public.png b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/menu-items-public.png
new file mode 100644
index 0000000000..42c12c6801
Binary files /dev/null and b/docs/en/Blog-Posts/2021-06-28 v4_4 Preview/menu-items-public.png differ
diff --git a/docs/en/Blog-Posts/2021-07-08 Introducing_the_eShopOnAbp/POST.md b/docs/en/Blog-Posts/2021-07-08 Introducing_the_eShopOnAbp/POST.md
new file mode 100644
index 0000000000..efba693145
--- /dev/null
+++ b/docs/en/Blog-Posts/2021-07-08 Introducing_the_eShopOnAbp/POST.md
@@ -0,0 +1,52 @@
+# Introducing the eShopOnAbp Project
+
+We are happy to introduce the **eShopOnAbp** project as an example microservice solution built with the ABP Framework by the core ABP team. This solution demonstrates the strength of ABP Framework and using it in a real-life case. The goal of the project is to create a full-featured cloud-native microservices reference application. The project is inspired by the [eShopOnContainers](https://github.com/dotnet-architecture/eShopOnContainers) project and shows how it can be implemented with the ABP Framework.
+
+> **Project Status**: Currently, the project doesn't have any business logic. We've just brought ABP's pre-built modules (Identity, Tenant Management, IdentityServer, etc) together as a base solution. However, it is fully working and you can now take it as a base solution for your microservice project. From now on, we will build the example application functionalities / business logic on top of it.
+
+## Source Code
+
+The source code is available on [abpframework/eShopOnAbp](https://github.com/abpframework/eShopOnAbp) repository.
+
+## The Big Picture
+
+The project follows micro-service architecture and overall structure is presented below.
+
+
+
+## How to Run?
+
+You can either run in Visual Studio, or using [Microsoft Tye](https://github.com/dotnet/tye). Tye is a developer tool that makes developing, testing, and deploying micro-services and distributed applications easier.
+
+ ### Requirements
+
+- .NET 5.0+
+- Docker
+- Yarn
+
+### Instructions
+
+- Clone the repository ( [eShopOnAbp](https://github.com/abpframework/eShopOnAbp) )
+
+- Install Tye (*follow [these steps](https://github.com/dotnet/tye/blob/main/docs/getting_started.md#installing-tye)*)
+
+- Execute `run-tye.ps1`
+
+- Wait until all applications are up!
+
+ - You can check running application from tye dashboard ([localhost:8000](http://127.0.0.1:8000/))
+
+- After all your backend services are up, start the angular application:
+
+ ```bash
+ cd apps/angular
+ yarn start
+ ```
+
+## What's Next?
+
+We'll work on deployment & CI-CD processes as a next step and build the business logic on. First goal is deploying the entire application on [Kubernetes](https://kubernetes.io/).
+
+## Feedback
+
+Your comments and suggestions is important for us. You can ask your questions or post your feedback under [this discussion entry](https://github.com/abpframework/abp/discussions/9536).
diff --git a/docs/en/Blog-Posts/2021-07-08 Introducing_the_eShopOnAbp/overall-solution.png b/docs/en/Blog-Posts/2021-07-08 Introducing_the_eShopOnAbp/overall-solution.png
new file mode 100644
index 0000000000..e3ef175316
Binary files /dev/null and b/docs/en/Blog-Posts/2021-07-08 Introducing_the_eShopOnAbp/overall-solution.png differ
diff --git a/docs/en/Blog-Posts/2021-08-02 v4_4_Release_Stable/POST.md b/docs/en/Blog-Posts/2021-08-02 v4_4_Release_Stable/POST.md
new file mode 100644
index 0000000000..a2c812bb74
--- /dev/null
+++ b/docs/en/Blog-Posts/2021-08-02 v4_4_Release_Stable/POST.md
@@ -0,0 +1,42 @@
+# ABP.IO Platform 4.4 Final Has Been Released!
+
+[ABP Framework](https://abp.io/) and [ABP Commercial](https://commercial.abp.io/) 4.4 versions have been released today.
+
+## What's New With 4.4?
+
+Since all the new features are already explained in details with the 4.4 RC announcement posts, I will not repeat all the details again. See [the related blog post](https://blog.abp.io/abp/ABP-Platform-4-4-RC-Has-Been-Released) for all the features and enhancements.
+
+## How to Upgrade an Existing Solution
+
+### Install/Update the ABP CLI
+
+First of all, install the ABP CLI or upgrade to the latest version.
+
+If you haven't installed yet:
+
+```bash
+dotnet tool install -g Volo.Abp.Cli
+```
+
+To update an existing installation:
+
+```bash
+dotnet tool update -g Volo.Abp.Cli
+```
+
+### ABP UPDATE Command
+
+[ABP CLI](https://docs.abp.io/en/abp/latest/CLI) provides a handy command to update all the ABP related NuGet and NPM packages in your solution with a single command:
+
+```bash
+abp update
+```
+
+Run this command in the root folder of your solution.
+
+## The Road Map
+
+The next feature version will be 5.0. It is planned to release the 5.0 RC (Release Candidate) in November 2021. See the updated road maps;
+
+* [ABP Framework Road Map](https://docs.abp.io/en/abp/latest/Road-Map)
+* [ABP Commercial Road Map](https://docs.abp.io/en/commercial/latest/road-map)
\ No newline at end of file
diff --git a/docs/en/Modules/Docs.md b/docs/en/Modules/Docs.md
index 4c764ee2c6..3894e29d20 100644
--- a/docs/en/Modules/Docs.md
+++ b/docs/en/Modules/Docs.md
@@ -188,7 +188,7 @@ Open `package.json` and add `@abp/docs": "^2.9.0` as shown below:
Then open the command line terminal in the `Acme.MyProject.Web` project folder and run the following command:
1. `yarn`
- 2. `gulp`
+ 2. `abp install-libs`
### 4- Database Integration
diff --git a/docs/en/Modules/Virtual-File-Explorer.md b/docs/en/Modules/Virtual-File-Explorer.md
index bae87ba95a..b0e25a2d65 100644
--- a/docs/en/Modules/Virtual-File-Explorer.md
+++ b/docs/en/Modules/Virtual-File-Explorer.md
@@ -61,7 +61,7 @@ Or you can also manually install nuget package to `Acme.MyProject.Web` project:
Then open the command line terminal in the `Acme.MyProject.Web` project folder and run the following command:
1. `yarn`
- 2. `gulp`
+ 2. `abp install-libs`
That's all,Now run the application and Navigate to `/VirtualFileExplorer`. You will see virtual file explorer page:
diff --git a/docs/en/SignalR-Integration.md b/docs/en/SignalR-Integration.md
index 29c37e30b2..c8a25215de 100644
--- a/docs/en/SignalR-Integration.md
+++ b/docs/en/SignalR-Integration.md
@@ -70,10 +70,10 @@ This will add the `@abp/signalr` to the dependencies in the `package.json` of yo
}
````
-Run the `gulp` in the root folder of your web project:
+Run `abp install-libs` command in the root folder of your web project:
````bash
-gulp
+abp install-libs
````
This will copy the SignalR JavaScript files into your project:
diff --git a/docs/en/UI/AspNetCore/Basic-Theme.md b/docs/en/UI/AspNetCore/Basic-Theme.md
index 50a82142ef..0a5b2c152f 100644
--- a/docs/en/UI/AspNetCore/Basic-Theme.md
+++ b/docs/en/UI/AspNetCore/Basic-Theme.md
@@ -15,7 +15,7 @@ The Basic Theme has RTL (Right-to-Left language) support.
* Install the [Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic) NuGet package to your web project.
* Add `AbpAspNetCoreMvcUiBasicThemeModule` into the `[DependsOn(...)]` attribute for your [module class](../../Module-Development-Basics.md) in the web project.
* Install the [@abp/aspnetcore.mvc.ui.theme.basic](https://www.npmjs.com/package/@abp/aspnetcore.mvc.ui.theme.basic) NPM package to your web project (e.g. `npm install @abp/aspnetcore.mvc.ui.theme.basic` or `yarn add @abp/aspnetcore.mvc.ui.theme.basic`).
-* Run `gulp` command in a command line terminal in the web project's folder.
+* Run `abp install-libs` command in a command line terminal in the web project's folder.
## Layouts
diff --git a/docs/en/UI/AspNetCore/Client-Side-Package-Management.md b/docs/en/UI/AspNetCore/Client-Side-Package-Management.md
index 645200a363..259461adf3 100644
--- a/docs/en/UI/AspNetCore/Client-Side-Package-Management.md
+++ b/docs/en/UI/AspNetCore/Client-Side-Package-Management.md
@@ -18,7 +18,7 @@ To solve the versioning problem, we created a **standard set of packages** those
The benefit of a **standard package** is:
* It depends on a **standard version** of a package. Depending on this package is **safe** because all modules depend on the same version.
-* It contains the gulp task to copy library resources (js, css, img... files) from the **node_modules** folder to **wwwroot/libs** folder. See the *Mapping The Library Resources* section for more.
+* It contains the necessary mapping configuration to copy library resources (js, css, img... files) from the **node_modules** folder to **wwwroot/libs** folder. See the *Mapping The Library Resources* section for more.
Depending on a standard package is easy. Just add it to your **package.json** file like you normally do. Example:
@@ -61,7 +61,13 @@ Using NPM packages and NPM/Yarn tool is the de facto standard for client side li
Next challenge is copying needed resources (js, css, img... files) from the `node_modules` into a folder inside the **wwwroot** folder to make it accessible to the clients/browsers.
-ABP defines a [Gulp](https://gulpjs.com/) based task to **copy resources** from **node_modules** to **wwwroot/libs** folder. Each **standard package** (see the *@ABP NPM Packages* section) defines the mapping for its own files. So, most of the time, you only configure dependencies.
+[ABP CLI](../../CLI.md) offers the command below to **copy resources** from **node_modules** to **wwwroot/libs** folder. You have to run it in the root folder of your web project:
+
+````bash
+abp install-libs
+````
+
+Each **standard package** (see the *@ABP NPM Packages* section) defines the mapping for its own files. So, most of the time, you only configure dependencies.
The **startup templates** are already configured to work all these out of the box. This section will explain the configuration options.
@@ -100,17 +106,17 @@ mappings: {
}
````
-#### Using The Gulp
+#### Using ABP CLI To Copy Resources
-Once you properly configure the `abp.resourcemapping.js` file, you can run the gulp command from the command line:
+Once you properly configure the `abp.resourcemapping.js` file, you can run the [ABP CLI](../../CLI.md) command from the command line:
-````
-gulp
+````bash
+abp install-libs
````
-When you run the `gulp`, all packages will copy their own resources into the **wwwroot/libs** folder. Running `yarn & gulp` is only necessary if you make a change in your dependencies in the **package.json** file.
+When you run this command, all packages will copy their own resources into the **wwwroot/libs** folder. Running `yarn` & `abp install-libs` are only necessary if you make a change in your dependencies in the **package.json** file.
-> When you run the Gulp command, dependencies of the application are resolved using the package.json file. The Gulp task automatically discovers and maps all resources from all dependencies (recursively).
+> When you run the `abp install-libs` command, dependencies of the application are resolved using the package.json file. [ABP CLI](../../CLI.md) automatically discovers and maps all resources from all dependencies (recursively).
#### See Also
diff --git a/docs/en/Validation.md b/docs/en/Validation.md
index c4821adf65..1d24c5e2a6 100644
--- a/docs/en/Validation.md
+++ b/docs/en/Validation.md
@@ -149,8 +149,8 @@ Once ABP determines a validation error, it throws an exception of type `AbpValid
In addition to the automatic validation, you may want to manually validate an object. In this case, [inject](Dependency-Injection.md) and use the `IObjectValidator` service:
-* `Validate` method validates the given object based on the validation rules and throws an `AbpValidationException` if it is not in a valid state.
-* `GetErrors` doesn't throw an exception, but only returns the validation errors.
+* `ValidateAsync` method validates the given object based on the validation rules and throws an `AbpValidationException` if it is not in a valid state.
+* `GetErrorsAsync` doesn't throw an exception, but only returns the validation errors.
`IObjectValidator` is implemented by the `ObjectValidator` by default. `ObjectValidator` is extensible; you can implement `IObjectValidationContributor` interface to contribute a custom logic. Example:
@@ -158,13 +158,14 @@ In addition to the automatic validation, you may want to manually validate an ob
public class MyObjectValidationContributor
: IObjectValidationContributor, ITransientDependency
{
- public void AddErrors(ObjectValidationContext context)
+ public Task AddErrorsAsync(ObjectValidationContext context)
{
//Get the validating object
var obj = context.ValidatingObject;
//Add the validation errors if available
context.Errors.Add(...);
+ return Task.CompletedTask;
}
}
````
diff --git a/docs/en/Virtual-File-System.md b/docs/en/Virtual-File-System.md
index 307c6e92bc..6cdf9a7649 100644
--- a/docs/en/Virtual-File-System.md
+++ b/docs/en/Virtual-File-System.md
@@ -38,7 +38,7 @@ This configuration recursively adds all files under the **MyResources** folder o
Embedding a file in the project/assembly may cause problems if a file name contains some special chars. To overcome this limitation;
1. Add [Microsoft.Extensions.FileProviders.Embedded](https://www.nuget.org/packages/Microsoft.Extensions.FileProviders.Embedded) NuGet package to the project that contains the embedded resource(s).
-2. Add `true` into the `...` section of your `.csproj` file.
+2. Add `true` into the `...` section of your `.csproj` file.
> While these two steps are optional and ABP can work without these configuration, it is strongly suggested to make it.
@@ -193,4 +193,4 @@ So, if you need to replace a file of a module, just create the file in the exact
### Physical Files
-Physical files always override the virtual files. That means if you put a file under the `/wwwroot/my-folder/my-file.css`, it will override the file in the same location of the virtual file system. So, you need to know the file paths defined in the modules to override them.
\ No newline at end of file
+Physical files always override the virtual files. That means if you put a file under the `/wwwroot/my-folder/my-file.css`, it will override the file in the same location of the virtual file system. So, you need to know the file paths defined in the modules to override them.
diff --git a/docs/pt-BR/MongoDB.md b/docs/pt-BR/MongoDB.md
new file mode 100644
index 0000000000..bc4a7882a7
--- /dev/null
+++ b/docs/pt-BR/MongoDB.md
@@ -0,0 +1,466 @@
+# Integração do MongoDB
+
+Este documento explica como integrar e configurar o MongoDB como um provedor de banco de dados para aplicações baseadas no ABP.
+
+## Instalação
+
+`Volo.Abp.MongoDB` é o pacote nuget principal para a integração do MongoDB. Instale-o em seu projeto (para uma aplicação em camadas, será sua camada de dados ou infraestrutura):
+
+```
+Install-Package Volo.Abp.MongoDB
+```
+
+Então adicione a dependência de módulo `AbpMongoDbModule` para o seu [module](Module-Development-Basics.md):
+
+```c#
+using Volo.Abp.MongoDB;
+using Volo.Abp.Modularity;
+
+namespace MyCompany.MyProject
+{
+ [DependsOn(typeof(AbpMongoDbModule))]
+ public class MyModule : AbpModule
+ {
+ // ...
+ }
+}
+```
+
+## Criando um Mongo Db Context
+
+ABP apresenta o conceito **Mongo Db Context** (que é semelhante ao Entity Framework Core DbContext) para tornar mais fácil usar coleções e configurá-las. Um exemplo é mostrado abaixo:
+
+```c#
+public class MyDbContext : AbpMongoDbContext
+{
+ public IMongoCollection Questions => Collection();
+
+ public IMongoCollection Categories => Collection();
+
+ protected override void CreateModel(IMongoModelBuilder modelBuilder)
+ {
+ base.CreateModel(modelBuilder);
+
+ // Personalize a configuração para as suas collections.
+ }
+}
+```
+
+* É derivado da classe `AbpMongoDbContext`.
+* Adiciona uma propriedade pública `IMongoCollection` para cada mongo collection. Por padrão ABP usa essas propriedades para criar repositórios padrão.
+* Substituir o método `CreateModel` permite definir a configuração da collection.
+
+### Configurar o Mapeamento para uma Collection
+
+ABP registra automaticamente entidades MongoDB client library para todas propriedades `IMongoCollection` em seu DbContext. Para o exemplo acima, as entidades `Question` e `Category` são registradas automaticamente.
+
+Para cada entidade registrada, chama `AutoMap()` e configura propriedades conhecidas de sua entidade. Por exemplo, se sua entidade implementa uma interface `IHasExtraProperties` (que já está implementada para cada raiz agregada por padrão), ele configura automaticamente `ExtraProperties`.
+
+Portanto, na maioria das vezes, você não precisa configurar explicitamente o registro de suas entidades. No entanto, se você precisar, pode fazer isso sobrescrevendo o método `CreateModel` em seu DbContext. Exemplo:
+
+````csharp
+protected override void CreateModel(IMongoModelBuilder modelBuilder)
+{
+ base.CreateModel(modelBuilder);
+
+ modelBuilder.Entity(b =>
+ {
+ b.CollectionName = "MyQuestions"; // Define o nome da collection
+ b.BsonMap.UnmapProperty(x => x.MyProperty); // Ignora 'MyProperty'
+ });
+}
+````
+
+Este exemplo altera o nome da collection mapeada para 'MyQuestions' no banco de dados e ignora uma propriedade na classe `Question`.
+
+Se você só precisa configurar o nome da collection, você também pode usar o atributo `[MongoCollection]` para a collection em seu DbContext. Exemplo:
+
+````csharp
+[MongoCollection("MyQuestions")] // Define o nome da collection
+public IMongoCollection Questions => Collection();
+````
+
+### Configurar a Seleção da String de Conexão
+
+Se você tiver vários bancos de dados em seu aplicativo, você pode configurar o nome da string de conexão para o seu DbContext usando o atributo `[ConnectionStringName]`. Exemplo:
+
+````csharp
+[ConnectionStringName("MySecondConnString")]
+public class MyDbContext : AbpMongoDbContext
+{
+
+}
+````
+
+Se você não configurar, a string de conexão `Default` é usada. Se você configurar um nome de string de conexão, mas não definir este nome da string de conexão na configuração da aplicação, então ele retorna para a string de conexão `Default`.
+
+## Registrando DbContext para Injeção de Dependência
+
+Use o método `AddAbpDbContext` em seu module para registrar sua classe DbContext para o sistema de [injeção de dependência](Dependency-Injection.md).
+
+```c#
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.MongoDB;
+using Volo.Abp.Modularity;
+
+namespace MyCompany.MyProject
+{
+ [DependsOn(typeof(AbpMongoDbModule))]
+ public class MyModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.AddMongoDbContext();
+
+ // ...
+ }
+ }
+}
+```
+
+### Adicionar Repositories Padrão
+
+O ABP pode criar automaticamente [repositories genéricas](Repositories.md) padrão para as entidades em seu DbContext. Basta usar a opção `AddDefaultRepositories()` no registro:
+
+````C#
+services.AddMongoDbContext(options =>
+{
+ options.AddDefaultRepositories();
+});
+````
+
+Isso criará uma repository para cada [aggregate root entity](Entities.md) (classes derivadas de `AggregateRoot`) por padrão. Se você quiser criar repositories para outras entidades também, em seguida defina `includeAllEntities` para `true`:
+
+```c#
+services.AddMongoDbContext(options =>
+{
+ options.AddDefaultRepositories(includeAllEntities: true);
+});
+```
+
+Então você pode injetar e usar `IRepository` nas suas services. Suponha que você tenha uma entidade `Book` com a chave primária `Guid`:
+
+```csharp
+public class Book : AggregateRoot
+{
+ public string Name { get; set; }
+
+ public BookType Type { get; set; }
+}
+```
+
+(`BookType` é um simples `enum` aqui) E você deseja criar uma nova entidade `Book` em uma [domain service](Domain-Services.md):
+
+```csharp
+public class BookManager : DomainService
+{
+ private readonly IRepository _bookRepository;
+
+ public BookManager(IRepository bookRepository) // injetar repositório padrão
+ {
+ _bookRepository = bookRepository;
+ }
+
+ public async Task CreateBook(string name, BookType type)
+ {
+ Check.NotNullOrWhiteSpace(name, nameof(name));
+
+ var book = new Book
+ {
+ Id = GuidGenerator.Create(),
+ Name = name,
+ Type = type
+ };
+
+ await _bookRepository.InsertAsync(book); // Use um método de repositório padrão
+
+ return book;
+ }
+}
+```
+
+Este exemplo usa o método `InsertAsync` para inserir uma nova entity no banco de dados.
+
+### Adicionar Repositories Personalizadas
+
+Repositories genéricas padrão são poderosas e suficiente na maioria dos casos (uma vez que implementam `IQueryable`). No entanto, pode ser necessário criar uma repository customizada para adicionar seus próprios métodos de repository.
+
+Suponha que você deseja excluir todos os books por type. É sugerido definir uma interface para sua repository personalizada:
+
+```csharp
+public interface IBookRepository : IRepository
+{
+ Task DeleteBooksByType(
+ BookType type,
+ CancellationToken cancellationToken = default(CancellationToken)
+ );
+}
+```
+
+Você geralmente vai querer derivar de `IRepository` para herdar métodos de repository padrão. No entanto, você não precisa. As interfaces de repository são definidas na camada de domínio de uma aplicação em camadas. Elas são implementadas na camada de dados ou infraestrutura (projeto `MongoDB` em um [startup template](https://abp.io/Templates)).
+
+Exemplo de implementação da interface `IBookRepository`:
+
+```csharp
+public class BookRepository :
+ MongoDbRepository,
+ IBookRepository
+{
+ public BookRepository(IMongoDbContextProvider dbContextProvider)
+ : base(dbContextProvider)
+ {
+ }
+
+ public async Task DeleteBooksByType(
+ BookType type,
+ CancellationToken cancellationToken = default(CancellationToken))
+ {
+ var collection = await GetCollectionAsync(cancellationToken);
+ await collection.DeleteManyAsync(
+ Builders.Filter.Eq(b => b.Type, type),
+ cancellationToken
+ );
+ }
+}
+```
+
+Agora é possível [injetar](Dependency-Injection.md) a `IBookRepository` e usar o método `DeleteBooksByType` quando necessário.
+
+#### Substituir Repository Genérica Padrão
+
+Mesmo se você criar uma repository personalizada, você ainda pode injetar a repository genérica padrão (`IRepository` para este exemplo). A implementação da repository padrão não usará a classe que você criou.
+
+Se você querer substituir a implementação da repository padrão pela sua repository personalizada, faça dentro das opções `AddMongoDbContext`:
+
+```csharp
+context.Services.AddMongoDbContext(options =>
+{
+ options.AddDefaultRepositories();
+ options.AddRepository(); //Replaces IRepository
+});
+```
+
+Isso é especialmente importante quando você deseja dar **override em um método da base repository** para customizar. Por exemplo, você pode querer substituir o método `DeleteAsync` para excluir uma entidade de uma forma mais eficiente:
+
+```csharp
+public async override Task DeleteAsync(
+ Guid id,
+ bool autoSave = false,
+ CancellationToken cancellationToken = default)
+{
+ // TODO: Implementação customizada do método delete
+}
+```
+
+### Acesso à API MongoDB
+
+Na maioria dos casos, você vai querer ocultar APIs do MongoDB atrás de uma repository (este é o objetivo principal da repository). No entanto, se você quiser acessar a API MongoDB através da Repository, você pode usar os métodos de extensão `GetDatabaseAsync()`, `GetCollectionAsync()` ou `GetAggregateAsync()`. Exemplo:
+
+```csharp
+public class BookService
+{
+ private readonly IRepository _bookRepository;
+
+ public BookService(IRepository bookRepository)
+ {
+ _bookRepository = bookRepository;
+ }
+
+ public async Task FooAsync()
+ {
+ IMongoDatabase database = await _bookRepository.GetDatabaseAsync();
+ IMongoCollection books = await _bookRepository.GetCollectionAsync();
+ IAggregateFluent bookAggregate = await _bookRepository.GetAggregateAsync();
+ }
+}
+```
+
+> Importante: Você deve fazer referência ao pacote `Volo.Abp.MongoDB` do projeto que deseja acessar a API MongoDB. Isso quebra o encapsulamento, mas é o que você deseja nesse caso.
+
+### Transactions
+
+O MongoDB oferece suporte multi-document transactions a partir da versão 4.0 e o ABP Framework oferece suporte para isso. No entanto, o [startup template](Startup-templates/Index.md) **desativa** transactions por padrão. Se o seu **servidor** MongoDB suportar transactions, você pode habilitar esse recurso na classe *YourProjectMongoDbModule*:
+
+```csharp
+Configure(options =>
+{
+ options.TransactionBehavior = UnitOfWorkTransactionBehavior.Auto;
+});
+```
+
+> Ou você pode excluir este código, pois este já é o comportamento padrão.
+
+### Tópicos Avançados
+
+### Controlando o Multi-Tenancy
+
+Se sua solução for [multi-tenant](Multi-Tenancy.md), os tenants podem ter **bancos de dados separados**, você tem **múltiplas** classes `DbContext` em sua solução e algumas de suas classes `DbContext` devem ser utilizáveis **apenas do lado do host**, é recomendado adicionar o atributo `[IgnoreMultiTenancy]` em sua classe `DbContext`. Nesse caso, a ABP garante que o `DbContext` relacionado sempre usa a [connection string](Connection-Strings.md) do host, mesmo se você estiver em um tenant context.
+
+**Exemplo:**
+
+````csharp
+[IgnoreMultiTenancy]
+public class MyDbContext : AbpMongoDbContext
+{
+ ...
+}
+````
+
+Não use o atributo `[IgnoreMultiTenancy]` se qualquer uma de suas entidades em seu `DbContext` puder ser persistida em um outro banco de dados de um tenant.
+
+> When you use repositories, ABP already uses the host database for the entities don't implement the `IMultiTenant` interface. So, most of time you don't need to `[IgnoreMultiTenancy]` attribute if you are using the repositories to work with the database.
+
+#### Definir Classes Repository Padrão
+
+Repositories genéricas padrão são implementadas pela classe `MongoDbRepository` por padrão. Você pode criar sua própria implementação e usá-la para implementação da repository padrão.
+
+Primeiro, defina suas classes de repository assim:
+
+```csharp
+public class MyRepositoryBase
+ : MongoDbRepository
+ where TEntity : class, IEntity
+{
+ public MyRepositoryBase(IMongoDbContextProvider dbContextProvider)
+ : base(dbContextProvider)
+ {
+ }
+}
+
+public class MyRepositoryBase
+ : MongoDbRepository
+ where TEntity : class, IEntity
+{
+ public MyRepositoryBase(IMongoDbContextProvider dbContextProvider)
+ : base(dbContextProvider)
+ {
+ }
+}
+```
+
+O primeiro é para [entities com chaves compostas](Entities.md), o segundo é para entities com uma única chave primária.
+
+É sugerido herdar da classe `MongoDbRepository` e substituir os métodos, se necessário. Caso contrário, você terá que implementar todos os métodos de repository padrão manualmente.
+
+Agora, você pode usar a opção `SetDefaultRepositoryClasses`:
+
+```csharp
+context.Services.AddMongoDbContext(options =>
+{
+ options.SetDefaultRepositoryClasses(
+ typeof(MyRepositoryBase<,>),
+ typeof(MyRepositoryBase<>)
+ );
+ // ...
+});
+```
+
+#### Definir classe base MongoDbContext ou Interface para Repositories padrão
+
+Se seu MongoDbContext herda de outro MongoDbContext ou implementa uma interface, você pode usar essa classe base ou interface como o MongoDbContext para repositories padrão. Exemplo:
+
+```csharp
+public interface IBookStoreMongoDbContext : IAbpMongoDbContext
+{
+ Collection Books { get; }
+}
+```
+
+`IBookStoreMongoDbContext` é implementado pela classe `BookStoreMongoDbContext`. Então você pode usar sobrecarga genérica do `AddDefaultRepositories`:
+
+```csharp
+context.Services.AddMongoDbContext(options =>
+{
+ options.AddDefaultRepositories();
+ // ...
+});
+```
+
+Agora, seu `BookRepository` personalizado também pode usar a interface `IBookStoreMongoDbContext`:
+
+```csharp
+public class BookRepository
+ : MongoDbRepository,
+ IBookRepository
+{
+ // ...
+}
+```
+
+Uma vantagem de usar a interface para um MongoDbContext é que ela pode ser substituída por outra implementação.
+
+#### Substituir Outros DbContexts
+
+Depois de definir e usar adequadamente uma interface para um MongoDbContext, qualquer outra implementação pode usar as seguintes maneiras de substituí-lo:
+
+**ReplaceDbContextAttribute**
+
+```csharp
+[ReplaceDbContext(typeof(IBookStoreMongoDbContext))]
+public class OtherMongoDbContext : AbpMongoDbContext, IBookStoreMongoDbContext
+{
+ // ...
+}
+```
+
+**Opção ReplaceDbContext**
+
+```csharp
+context.Services.AddMongoDbContext(options =>
+{
+ // ...
+ options.ReplaceDbContext();
+});
+```
+
+Neste exemplo, `OtherMongoDbContext` implementa `IBookStoreMongoDbContext`. Este recurso permite que você tenha vários MongoDbContext (um por módulo) no desenvolvimento, mas um único MongoDbContext (implementa todas as interfaces de todos os MongoDbContexts) no tempo de execução.
+
+### Personalizar Operações em Massa
+
+Se você tiver uma lógica melhor ou usar uma biblioteca externa para operações em massa, pode substituir a lógica por meio da implementação de `IMongoDbBulkOperationProvider`.
+
+- Você pode usar o modelo de exemplo abaixo:
+
+```csharp
+public class MyCustomMongoDbBulkOperationProvider
+ : IMongoDbBulkOperationProvider, ITransientDependency
+{
+ public async Task DeleteManyAsync(
+ IMongoDbRepository repository,
+ IEnumerable entities,
+ IClientSessionHandle sessionHandle,
+ bool autoSave,
+ CancellationToken cancellationToken)
+ where TEntity : class, IEntity
+ {
+ // Sua lógica aqui.
+ }
+
+ public async Task InsertManyAsync(
+ IMongoDbRepository repository,
+ IEnumerable entities,
+ IClientSessionHandle sessionHandle,
+ bool autoSave,
+ CancellationToken cancellationToken)
+ where TEntity : class, IEntity
+ {
+ // Sua lógica aqui.
+ }
+
+ public async Task UpdateManyAsync(
+ IMongoDbRepository repository,
+ IEnumerable entities,
+ IClientSessionHandle sessionHandle,
+ bool autoSave,
+ CancellationToken cancellationToken)
+ where TEntity : class, IEntity
+ {
+ // Sua lógica aqui.
+ }
+}
+```
+
+## Veja Também
+
+* [Entities](Entities.md)
+* [Repositories](Repositories.md)
\ No newline at end of file
diff --git a/docs/zh-Hans/Validation.md b/docs/zh-Hans/Validation.md
index f6b2daf31f..6e46b07aed 100644
--- a/docs/zh-Hans/Validation.md
+++ b/docs/zh-Hans/Validation.md
@@ -130,8 +130,8 @@ namespace Acme.BookStore
除了自动验证你可能需要手动验证对象,这种情况下[注入](Dependency-Injection.md)并使用 `IObjectValidator` 服务:
-* `Validate` 方法根据验证规则验证给定对象,如果对象没有被验证通过会抛出 `AbpValidationException` 异常.
-* `GetErrors` 不会抛出异常,只返回验证错误.
+* `ValidateAsync` 方法根据验证规则验证给定对象,如果对象没有被验证通过会抛出 `AbpValidationException` 异常.
+* `GetErrorsAsync` 不会抛出异常,只返回验证错误.
`IObjectValidator` 默认由 `ObjectValidator` 实现. `ObjectValidator`是可扩展的; 可以实现`IObjectValidationContributor`接口提供自定义逻辑.
示例 :
@@ -140,13 +140,14 @@ namespace Acme.BookStore
public class MyObjectValidationContributor
: IObjectValidationContributor, ITransientDependency
{
- public void AddErrors(ObjectValidationContext context)
+ public Task AddErrorsAsync(ObjectValidationContext context)
{
//Get the validating object
var obj = context.ValidatingObject;
//Add the validation errors if available
context.Errors.Add(...);
+ return Task.CompletedTask;
}
}
````
diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln
index 0605f5c103..8d5432f4c6 100644
--- a/framework/Volo.Abp.sln
+++ b/framework/Volo.Abp.sln
@@ -383,6 +383,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TextTemplating.Scr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.MongoDB.Tests.SecondContext", "test\Volo.Abp.MongoDB.Tests.SecondContext\Volo.Abp.MongoDB.Tests.SecondContext.csproj", "{90B1866A-EF99-40B9-970E-B898E5AA523F}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Threading.Tests", "test\Volo.Abp.Threading.Tests\Volo.Abp.Threading.Tests.csproj", "{7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1141,6 +1143,10 @@ Global
{90B1866A-EF99-40B9-970E-B898E5AA523F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90B1866A-EF99-40B9-970E-B898E5AA523F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90B1866A-EF99-40B9-970E-B898E5AA523F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1334,6 +1340,7 @@ Global
{C996F458-98FB-483D-9306-4701290E2FC1} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{75D8DADB-3FA9-4C1D-B23A-DBFD08133B7C} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{90B1866A-EF99-40B9-970E-B898E5AA523F} = {447C8A77-E5F0-4538-8687-7383196D04EA}
+ {7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B} = {447C8A77-E5F0-4538-8687-7383196D04EA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs
index d9de135e7f..be088b0154 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs
@@ -54,7 +54,29 @@ namespace Volo.Abp.AspNetCore.Mvc
displayMetadata.DisplayName = () =>
{
- var localizedString = localizer[PropertyLocalizationKeyPrefix + context.Key.Name];
+ /*
+ * DisplayName:ClassName:PropertyName
+ * DisplayName:PropertyName
+ * ClassName:PropertyName
+ * PropertyName
+ */
+
+ LocalizedString localizedString = null;
+
+ if (context.Key.ContainerType != null)
+ {
+ localizedString = localizer[PropertyLocalizationKeyPrefix + context.Key.ContainerType.Name + ":" + context.Key.Name];
+ }
+
+ if (localizedString == null || localizedString.ResourceNotFound)
+ {
+ localizedString = localizer[PropertyLocalizationKeyPrefix + context.Key.Name];
+ }
+
+ if (localizedString.ResourceNotFound && context.Key.ContainerType != null)
+ {
+ localizedString = localizer[context.Key.ContainerType.Name + ":" + context.Key.Name];
+ }
if (localizedString.ResourceNotFound)
{
@@ -65,4 +87,4 @@ namespace Volo.Abp.AspNetCore.Mvc
};
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Threading/HttpContextCancellationTokenProvider.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Threading/HttpContextCancellationTokenProvider.cs
index c7c961176c..ce722b1176 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Threading/HttpContextCancellationTokenProvider.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Threading/HttpContextCancellationTokenProvider.cs
@@ -6,13 +6,26 @@ using Volo.Abp.Threading;
namespace Volo.Abp.AspNetCore.Threading
{
[Dependency(ReplaceServices = true)]
- public class HttpContextCancellationTokenProvider : ICancellationTokenProvider, ITransientDependency
+ public class HttpContextCancellationTokenProvider : CancellationTokenProviderBase, ITransientDependency
{
- public CancellationToken Token => _httpContextAccessor.HttpContext?.RequestAborted ?? CancellationToken.None;
-
private readonly IHttpContextAccessor _httpContextAccessor;
- public HttpContextCancellationTokenProvider(IHttpContextAccessor httpContextAccessor)
+ public override CancellationToken Token
+ {
+ get
+ {
+ if (OverrideValue != null)
+ {
+ return OverrideValue.CancellationToken;
+ }
+ return _httpContextAccessor.HttpContext?.RequestAborted ?? CancellationToken.None;
+ }
+ }
+
+ public HttpContextCancellationTokenProvider(
+ IAmbientScopeProvider cancellationTokenOverrideScopeProvider,
+ IHttpContextAccessor httpContextAccessor)
+ : base(cancellationTokenOverrideScopeProvider)
{
_httpContextAccessor = httpContextAccessor;
}
diff --git a/framework/src/Volo.Abp.Core/Microsoft/Extensions/Hosting/AbpHostingHostBuilderExtensions.cs b/framework/src/Volo.Abp.Core/Microsoft/Extensions/Hosting/AbpHostingHostBuilderExtensions.cs
new file mode 100644
index 0000000000..e2f55142e7
--- /dev/null
+++ b/framework/src/Volo.Abp.Core/Microsoft/Extensions/Hosting/AbpHostingHostBuilderExtensions.cs
@@ -0,0 +1,25 @@
+using Microsoft.Extensions.Configuration;
+
+namespace Microsoft.Extensions.Hosting
+{
+ public static class AbpHostingHostBuilderExtensions
+ {
+ public const string AppSettingsSecretJsonPath = "appsettings.secrets.json";
+
+ public static IHostBuilder AddAppSettingsSecretsJson(
+ this IHostBuilder hostBuilder,
+ bool optional = true,
+ bool reloadOnChange = true,
+ string path = AppSettingsSecretJsonPath)
+ {
+ return hostBuilder.ConfigureAppConfiguration((_, builder) =>
+ {
+ builder.AddJsonFile(
+ path: AppSettingsSecretJsonPath,
+ optional: optional,
+ reloadOnChange: reloadOnChange
+ );
+ });
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyBasicRepository.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyBasicRepository.cs
index ed97d87ffa..a6988e5c10 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyBasicRepository.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyBasicRepository.cs
@@ -1,6 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq.Expressions;
+using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
@@ -18,19 +16,7 @@ namespace Volo.Abp.Domain.Repositories
/// A to observe while waiting for the task to complete.
/// Entity
Task> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default);
-
- ///
- /// Gets a list entities by the given .
- ///
- /// A condition to find the entity
- /// Set true to include all children of this entity
- /// A to observe while waiting for the task to complete.
- /// Entity
- Task> GetListAsync(
- [NotNull] Expression> predicate,
- bool includeDetails = false,
- CancellationToken cancellationToken = default);
-
+
///
/// Gets total count of all entities.
///
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyRepository.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyRepository.cs
index 80d1425044..7aeffdad12 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyRepository.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyRepository.cs
@@ -1,7 +1,10 @@
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
+using System.Threading;
using System.Threading.Tasks;
+using JetBrains.Annotations;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Linq;
@@ -23,6 +26,17 @@ namespace Volo.Abp.Domain.Repositories
Task> WithDetailsAsync(params Expression>[] propertySelectors); //TODO: CancellationToken
Task> GetQueryableAsync(); //TODO: CancellationToken
+
+ ///
+ /// Gets a list of entities by the given .
+ ///
+ /// A condition to filter the entities
+ /// Set true to include details (sub-collections) of this entity
+ /// A to observe while waiting for the task to complete.
+ Task> GetListAsync(
+ [NotNull] Expression> predicate,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default);
}
public interface IReadOnlyRepository : IReadOnlyRepository, IReadOnlyBasicRepository
diff --git a/framework/src/Volo.Abp.FluentValidation/Volo/Abp/FluentValidation/FluentObjectValidationContributor.cs b/framework/src/Volo.Abp.FluentValidation/Volo/Abp/FluentValidation/FluentObjectValidationContributor.cs
index ccc290f354..e2d0f39372 100644
--- a/framework/src/Volo.Abp.FluentValidation/Volo/Abp/FluentValidation/FluentObjectValidationContributor.cs
+++ b/framework/src/Volo.Abp.FluentValidation/Volo/Abp/FluentValidation/FluentObjectValidationContributor.cs
@@ -2,6 +2,7 @@ using FluentValidation;
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
+using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Validation;
@@ -17,7 +18,7 @@ namespace Volo.Abp.FluentValidation
_serviceProvider = serviceProvider;
}
- public void AddErrors(ObjectValidationContext context)
+ public virtual async Task AddErrorsAsync(ObjectValidationContext context)
{
var serviceType = typeof(IValidator<>).MakeGenericType(context.ValidatingObject.GetType());
var validator = _serviceProvider.GetService(serviceType) as IValidator;
@@ -26,7 +27,7 @@ namespace Volo.Abp.FluentValidation
return;
}
- var result = validator.Validate((IValidationContext) Activator.CreateInstance(
+ var result = await validator.ValidateAsync((IValidationContext) Activator.CreateInstance(
typeof(ValidationContext<>).MakeGenericType(context.ValidatingObject.GetType()),
context.ValidatingObject));
diff --git a/framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj b/framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj
index 4ec9d0a3b5..6b598d0edd 100644
--- a/framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj
+++ b/framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj
@@ -19,6 +19,7 @@
+
diff --git a/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireAuthorizationFilter.cs b/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireAuthorizationFilter.cs
new file mode 100644
index 0000000000..15fbb4f60c
--- /dev/null
+++ b/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireAuthorizationFilter.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Threading.Tasks;
+using Hangfire.Dashboard;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Authorization.Permissions;
+using Volo.Abp.Users;
+
+namespace Volo.Abp.Hangfire
+{
+ public class AbpHangfireAuthorizationFilter : IDashboardAsyncAuthorizationFilter
+ {
+ private readonly string _requiredPermissionName;
+
+ public AbpHangfireAuthorizationFilter(string requiredPermissionName = null)
+ {
+ _requiredPermissionName = requiredPermissionName;
+ }
+
+ public async Task AuthorizeAsync(DashboardContext context)
+ {
+ if (!IsLoggedIn(context))
+ {
+ return false;
+ }
+
+ if (_requiredPermissionName.IsNullOrEmpty())
+ {
+ return true;
+ }
+
+ return await IsPermissionGrantedAsync(context, _requiredPermissionName);
+ }
+
+ private static bool IsLoggedIn(DashboardContext context)
+ {
+ var currentUser = context.GetHttpContext().RequestServices.GetRequiredService();
+ return currentUser.IsAuthenticated;
+ }
+
+ private static async Task IsPermissionGrantedAsync(DashboardContext context, string requiredPermissionName)
+ {
+ var permissionChecker = context.GetHttpContext().RequestServices.GetRequiredService();
+ return await permissionChecker.IsGrantedAsync(requiredPermissionName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireModule.cs b/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireModule.cs
index d69edb0b5d..1628d2f37f 100644
--- a/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireModule.cs
+++ b/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireModule.cs
@@ -1,10 +1,12 @@
using Hangfire;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
+using Volo.Abp.Authorization;
using Volo.Abp.Modularity;
namespace Volo.Abp.Hangfire
{
+ [DependsOn(typeof(AbpAuthorizationAbstractionsModule))]
public class AbpHangfireModule : AbpModule
{
private BackgroundJobServer _backgroundJobServer;
diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs
index b94a5a339d..df890812bb 100644
--- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs
+++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs
@@ -174,7 +174,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying
var response = await client.SendAsync(
requestMessage,
HttpCompletionOption.ResponseHeadersRead /*this will buffer only the headers, the content will be used as a stream*/,
- GetCancellationToken()
+ GetCancellationToken(invocation)
);
if (!response.IsSuccessStatusCode)
@@ -306,8 +306,18 @@ namespace Volo.Abp.Http.Client.DynamicProxying
return input;
}
- protected virtual CancellationToken GetCancellationToken()
+ protected virtual CancellationToken GetCancellationToken(IAbpMethodInvocation invocation)
{
+ var cancellationTokenArg = invocation.Arguments.LastOrDefault(x => x is CancellationToken);
+ if (cancellationTokenArg != null)
+ {
+ var cancellationToken = (CancellationToken) cancellationTokenArg;
+ if (cancellationToken != default)
+ {
+ return cancellationToken;
+ }
+ }
+
return CancellationTokenProvider.Token;
}
}
diff --git a/framework/src/Volo.Abp.Sms.Aliyun/Volo.Abp.Sms.Aliyun.csproj b/framework/src/Volo.Abp.Sms.Aliyun/Volo.Abp.Sms.Aliyun.csproj
index cae6301daf..83cea09848 100644
--- a/framework/src/Volo.Abp.Sms.Aliyun/Volo.Abp.Sms.Aliyun.csproj
+++ b/framework/src/Volo.Abp.Sms.Aliyun/Volo.Abp.Sms.Aliyun.csproj
@@ -18,6 +18,7 @@
+
diff --git a/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/CancellationTokenOverride.cs b/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/CancellationTokenOverride.cs
new file mode 100644
index 0000000000..371e3d6652
--- /dev/null
+++ b/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/CancellationTokenOverride.cs
@@ -0,0 +1,14 @@
+using System.Threading;
+
+namespace Volo.Abp.Threading
+{
+ public class CancellationTokenOverride
+ {
+ public CancellationToken CancellationToken { get; }
+
+ public CancellationTokenOverride(CancellationToken cancellationToken)
+ {
+ CancellationToken = cancellationToken;
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/CancellationTokenProviderBase.cs b/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/CancellationTokenProviderBase.cs
new file mode 100644
index 0000000000..20101a95da
--- /dev/null
+++ b/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/CancellationTokenProviderBase.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Threading;
+
+namespace Volo.Abp.Threading
+{
+ public abstract class CancellationTokenProviderBase : ICancellationTokenProvider
+ {
+ public const string CancellationTokenOverrideContextKey = "Volo.Abp.Threading.CancellationToken.Override";
+
+ public abstract CancellationToken Token { get; }
+
+ protected IAmbientScopeProvider CancellationTokenOverrideScopeProvider { get; }
+
+ protected CancellationTokenOverride OverrideValue => CancellationTokenOverrideScopeProvider.GetValue(CancellationTokenOverrideContextKey);
+
+ protected CancellationTokenProviderBase(IAmbientScopeProvider cancellationTokenOverrideScopeProvider)
+ {
+ CancellationTokenOverrideScopeProvider = cancellationTokenOverrideScopeProvider;
+ }
+
+ public IDisposable Use(CancellationToken cancellationToken)
+ {
+ return CancellationTokenOverrideScopeProvider.BeginScope(CancellationTokenOverrideContextKey, new CancellationTokenOverride(cancellationToken));
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/ICancellationTokenProvider.cs b/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/ICancellationTokenProvider.cs
index 24e303adde..06dc008d52 100644
--- a/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/ICancellationTokenProvider.cs
+++ b/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/ICancellationTokenProvider.cs
@@ -1,9 +1,12 @@
-using System.Threading;
+using System;
+using System.Threading;
namespace Volo.Abp.Threading
{
public interface ICancellationTokenProvider
{
CancellationToken Token { get; }
+
+ IDisposable Use(CancellationToken cancellationToken);
}
}
diff --git a/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/NullCancellationTokenProvider.cs b/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/NullCancellationTokenProvider.cs
index ab6320546c..6c2b4d364c 100644
--- a/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/NullCancellationTokenProvider.cs
+++ b/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/NullCancellationTokenProvider.cs
@@ -2,15 +2,15 @@
namespace Volo.Abp.Threading
{
- public class NullCancellationTokenProvider : ICancellationTokenProvider
+ public class NullCancellationTokenProvider : CancellationTokenProviderBase
{
public static NullCancellationTokenProvider Instance { get; } = new NullCancellationTokenProvider();
- public CancellationToken Token { get; } = CancellationToken.None;
+ public override CancellationToken Token => OverrideValue?.CancellationToken ?? CancellationToken.None;
private NullCancellationTokenProvider()
+ : base(new AmbientDataContextAmbientScopeProvider(new AsyncLocalAmbientDataContext()))
{
-
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs
index 912f68e4af..15e367cefc 100644
--- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs
+++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
+using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@@ -26,9 +27,10 @@ namespace Volo.Abp.Validation
Options = options.Value;
}
- public void AddErrors(ObjectValidationContext context)
+ public Task AddErrorsAsync(ObjectValidationContext context)
{
ValidateObjectRecursively(context.Errors, context.ValidatingObject, currentDepth: 1);
+ return Task.CompletedTask;
}
protected virtual void ValidateObjectRecursively(List errors, object validatingObject, int currentDepth)
diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IMethodInvocationValidator.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IMethodInvocationValidator.cs
index fd413bc498..89eec62116 100644
--- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IMethodInvocationValidator.cs
+++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IMethodInvocationValidator.cs
@@ -1,7 +1,9 @@
-namespace Volo.Abp.Validation
+using System.Threading.Tasks;
+
+namespace Volo.Abp.Validation
{
public interface IMethodInvocationValidator
{
- void Validate(MethodInvocationValidationContext context);
+ Task ValidateAsync(MethodInvocationValidationContext context);
}
}
diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidationContributor.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidationContributor.cs
index ca50901bcd..45d0ddcd9b 100644
--- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidationContributor.cs
+++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidationContributor.cs
@@ -1,7 +1,9 @@
-namespace Volo.Abp.Validation
+using System.Threading.Tasks;
+
+namespace Volo.Abp.Validation
{
public interface IObjectValidationContributor
{
- void AddErrors(ObjectValidationContext context);
+ Task AddErrorsAsync(ObjectValidationContext context);
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidator.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidator.cs
index 0ce723bab8..1b7c5881ee 100644
--- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidator.cs
+++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidator.cs
@@ -1,20 +1,21 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
+using System.Threading.Tasks;
namespace Volo.Abp.Validation
{
public interface IObjectValidator
{
- void Validate(
+ Task ValidateAsync(
object validatingObject,
string name = null,
bool allowNull = false
);
- List GetErrors(
+ Task> GetErrorsAsync(
object validatingObject,
string name = null,
bool allowNull = false
);
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/MethodInvocationValidator.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/MethodInvocationValidator.cs
index 584f787a6e..3aeaf57fc7 100644
--- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/MethodInvocationValidator.cs
+++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/MethodInvocationValidator.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Reflection;
@@ -16,7 +17,7 @@ namespace Volo.Abp.Validation
_objectValidator = objectValidator;
}
- public virtual void Validate(MethodInvocationValidationContext context)
+ public virtual async Task ValidateAsync(MethodInvocationValidationContext context)
{
Check.NotNull(context, nameof(context));
@@ -46,7 +47,7 @@ namespace Volo.Abp.Validation
ThrowValidationError(context);
}
- AddMethodParameterValidationErrors(context);
+ await AddMethodParameterValidationErrorsAsync(context);
if (context.Errors.Any())
{
@@ -60,7 +61,7 @@ namespace Volo.Abp.Validation
{
return false;
}
-
+
if (ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(context.Method) != null)
{
return true;
@@ -82,22 +83,22 @@ namespace Volo.Abp.Validation
);
}
- protected virtual void AddMethodParameterValidationErrors(MethodInvocationValidationContext context)
+ protected virtual async Task AddMethodParameterValidationErrorsAsync(MethodInvocationValidationContext context)
{
for (var i = 0; i < context.Parameters.Length; i++)
{
- AddMethodParameterValidationErrors(context, context.Parameters[i], context.ParameterValues[i]);
+ await AddMethodParameterValidationErrorsAsync(context, context.Parameters[i], context.ParameterValues[i]);
}
}
- protected virtual void AddMethodParameterValidationErrors(IAbpValidationResult context, ParameterInfo parameterInfo, object parameterValue)
+ protected virtual async Task AddMethodParameterValidationErrorsAsync(IAbpValidationResult context, ParameterInfo parameterInfo, object parameterValue)
{
var allowNulls = parameterInfo.IsOptional ||
parameterInfo.IsOut ||
TypeHelper.IsPrimitiveExtended(parameterInfo.ParameterType, includeEnums: true);
context.Errors.AddRange(
- _objectValidator.GetErrors(
+ await _objectValidator.GetErrorsAsync(
parameterValue,
parameterInfo.Name,
allowNulls
@@ -105,4 +106,4 @@ namespace Volo.Abp.Validation
);
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ObjectValidator.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ObjectValidator.cs
index d8e0c60b65..8e13d72938 100644
--- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ObjectValidator.cs
+++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ObjectValidator.cs
@@ -2,6 +2,7 @@ using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
+using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
@@ -18,9 +19,9 @@ namespace Volo.Abp.Validation
Options = options.Value;
}
- public virtual void Validate(object validatingObject, string name = null, bool allowNull = false)
+ public virtual async Task ValidateAsync(object validatingObject, string name = null, bool allowNull = false)
{
- var errors = GetErrors(validatingObject, name, allowNull);
+ var errors = await GetErrorsAsync(validatingObject, name, allowNull);
if (errors.Any())
{
@@ -31,7 +32,7 @@ namespace Volo.Abp.Validation
}
}
- public virtual List GetErrors(object validatingObject, string name = null, bool allowNull = false)
+ public virtual async Task> GetErrorsAsync(object validatingObject, string name = null, bool allowNull = false)
{
if (validatingObject == null)
{
@@ -58,7 +59,7 @@ namespace Volo.Abp.Validation
{
var contributor = (IObjectValidationContributor)
scope.ServiceProvider.GetRequiredService(contributorType);
- contributor.AddErrors(context);
+ await contributor.AddErrorsAsync(context);
}
}
diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs
index b4ce642471..0a0f4fcf5f 100644
--- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs
+++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs
@@ -15,13 +15,13 @@ namespace Volo.Abp.Validation
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
- Validate(invocation);
+ await ValidateAsync(invocation);
await invocation.ProceedAsync();
}
- protected virtual void Validate(IAbpMethodInvocation invocation)
+ protected virtual async Task ValidateAsync(IAbpMethodInvocation invocation)
{
- _methodInvocationValidator.Validate(
+ await _methodInvocationValidator.ValidateAsync(
new MethodInvocationValidationContext(
invocation.TargetObject,
invocation.Method,
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/LocalizationTestController.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/LocalizationTestController.cs
index 1defcf4809..ff26083a83 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/LocalizationTestController.cs
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/LocalizationTestController.cs
@@ -21,12 +21,20 @@ namespace Volo.Abp.AspNetCore.App
public class PersonModel
{
- //[Display(Name = nameof(BirthDate))]
public string BirthDate { get; set; }
+ public string BirthDate1 { get; set; }
+
+ public string BirthDate2 { get; set; }
+
+ public string BirthDate3 { get; set; }
+
public PersonModel()
{
BirthDate = DateTime.Now.ToString("yyyy-MM-dd");
+ BirthDate1 = BirthDate;
+ BirthDate2 = BirthDate;
+ BirthDate3 = BirthDate;
}
}
}
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/Views/LocalizationTest/PersonForm.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/Views/LocalizationTest/PersonForm.cshtml
index 7f0a0d470f..31dee8bf83 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/Views/LocalizationTest/PersonForm.cshtml
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/Views/LocalizationTest/PersonForm.cshtml
@@ -5,4 +5,13 @@
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/MvcLocalization_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/MvcLocalization_Tests.cs
index 4d9a4f4624..fe7912951c 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/MvcLocalization_Tests.cs
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/MvcLocalization_Tests.cs
@@ -30,7 +30,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Localization
var result = await GetResponseAsStringAsync("/LocalizationTest/HelloJohn");
result.ShouldBe("Hello John.");
}
-
+
[Fact]
public async Task Should_Localize_Display_Attribute()
{
@@ -38,12 +38,18 @@ namespace Volo.Abp.AspNetCore.Mvc.Localization
{
var result = await GetResponseAsStringAsync("/LocalizationTest/PersonForm");
result.ShouldContain("");
+ result.ShouldContain("");
+ result.ShouldContain("");
+ result.ShouldContain("");
}
using (CultureHelper.Use("tr"))
{
var result = await GetResponseAsStringAsync("/LocalizationTest/PersonForm");
result.ShouldContain("");
+ result.ShouldContain("");
+ result.ShouldContain("");
+ result.ShouldContain("");
}
}
}
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json
index 2451c1b294..f11c5458db 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json
@@ -1,7 +1,10 @@
{
"culture": "en",
"texts": {
+ "DisplayName:PersonModel:BirthDate1": "Birth date1",
+ "DisplayName:BirthDate2": "Birth date2",
+ "PersonModel:BirthDate3": "Birth date3",
"BirthDate": "Birth date",
- "Value1": "Value One"
+ "Value1": "Value One"
}
-}
\ No newline at end of file
+}
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/tr.json b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/tr.json
index 546e672ede..b99e81bec0 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/tr.json
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/tr.json
@@ -1,7 +1,10 @@
{
"culture": "tr",
"texts": {
+ "DisplayName:PersonModel:BirthDate1": "Dogum gunu1",
+ "DisplayName:BirthDate2": "Dogum gunu2",
+ "PersonModel:BirthDate3": "Dogum gunu3",
"BirthDate": "Dogum gunu",
- "Value1": "Değer Bir"
+ "Value1": "Değer Bir"
}
-}
\ No newline at end of file
+}
diff --git a/framework/test/Volo.Abp.FluentValidation.Tests/Volo/Abp/FluentValidation/ApplicationService_FluentValidation_Tests.cs b/framework/test/Volo.Abp.FluentValidation.Tests/Volo/Abp/FluentValidation/ApplicationService_FluentValidation_Tests.cs
index a93eabda1d..6263d03ddd 100644
--- a/framework/test/Volo.Abp.FluentValidation.Tests/Volo/Abp/FluentValidation/ApplicationService_FluentValidation_Tests.cs
+++ b/framework/test/Volo.Abp.FluentValidation.Tests/Volo/Abp/FluentValidation/ApplicationService_FluentValidation_Tests.cs
@@ -39,7 +39,8 @@ namespace Volo.Abp.FluentValidation
},
MyMethodInput3 = new MyMethodInput3
{
- MyStringValue3 = "ccc"
+ MyStringValue3 = "ccc",
+ MyBoolValue3 = true
}
});
@@ -62,12 +63,13 @@ namespace Volo.Abp.FluentValidation
},
MyMethodInput3 = new MyMethodInput3
{
- MyStringValue3 = "c"
+ MyStringValue3 = "c",
+ MyBoolValue3 = false
}
}
)
);
-
+
exception.ValidationErrors.ShouldContain(x => x.MemberNames.Contains("MyStringValue"));
exception.ValidationErrors.ShouldContain(x => x.MemberNames.Contains("MyMethodInput2.MyStringValue2"));
exception.ValidationErrors.ShouldContain(x => x.MemberNames.Contains("MyMethodInput3.MyStringValue3"));
@@ -100,7 +102,7 @@ namespace Volo.Abp.FluentValidation
output.ShouldBe("444");
}
-
+
[DependsOn(typeof(AbpAutofacModule))]
[DependsOn(typeof(AbpFluentValidationModule))]
public class TestModule : AbpModule
@@ -162,6 +164,8 @@ namespace Volo.Abp.FluentValidation
{
public string MyStringValue3 { get; set; }
+
+ public bool MyBoolValue3 { get; set; }
}
public class MyMethodInput4
@@ -175,7 +179,8 @@ namespace Volo.Abp.FluentValidation
{
RuleFor(x => x.MyStringValue).Equal("aaa");
RuleFor(x => x.MyMethodInput2.MyStringValue2).Equal("bbb");
- RuleFor(customer => customer.MyMethodInput3).SetValidator(new MyMethodInput3Validator());
+ RuleFor(x => x.MyMethodInput3).SetValidator(new MyMethodInput3Validator());
+ RuleFor(x => x.MyMethodInput3).SetValidator(new MyMethodInput3AsyncValidator());
}
}
@@ -194,5 +199,15 @@ namespace Volo.Abp.FluentValidation
RuleFor(x => x.MyStringValue3).Equal("ccc");
}
}
+
+ public class MyMethodInput3AsyncValidator : MethodInputBaseValidator
+ {
+ public MyMethodInput3AsyncValidator()
+ {
+ RuleFor(x => x.MyStringValue3).Equal("ccc");
+
+ RuleFor(x => x.MyBoolValue3).MustAsync((myBookValue3, cancellation) => Task.FromResult(myBookValue3));
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/IRegularTestController.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/IRegularTestController.cs
index 23694e4e72..d1c1275db7 100644
--- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/IRegularTestController.cs
+++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/IRegularTestController.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading;
using System.Threading.Tasks;
namespace Volo.Abp.Http.DynamicProxying
@@ -36,5 +37,7 @@ namespace Volo.Abp.Http.DynamicProxying
Task PatchValueWithHeaderAndQueryStringAsync(string headerValue, string qsValue);
Task DeleteByIdAsync(int id);
+
+ Task AbortRequestAsync(CancellationToken cancellationToken = default);
}
}
diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestController.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestController.cs
index e18c2f8f4a..782b839626 100644
--- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestController.cs
+++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestController.cs
@@ -1,11 +1,10 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
-using Volo.Abp.Application.Services;
using Volo.Abp.AspNetCore.Mvc;
-using Volo.Abp.UI;
namespace Volo.Abp.Http.DynamicProxying
{
@@ -129,6 +128,14 @@ namespace Volo.Abp.Http.DynamicProxying
{
return Task.FromResult(id + 1);
}
+
+ [HttpGet]
+ [Route("abort-request")]
+ public async Task AbortRequestAsync(CancellationToken cancellationToken = default)
+ {
+ await Task.Delay(100, cancellationToken);
+ return "AbortRequestAsync";
+ }
}
public class Car
diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs
index bd35016989..8df3e94b3c 100644
--- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs
+++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs
@@ -1,10 +1,10 @@
using System;
+using System.Net.Http;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Localization;
using Shouldly;
using Volo.Abp.Http.Client;
-using Volo.Abp.Http.Localization;
using Volo.Abp.Localization;
using Xunit;
@@ -159,5 +159,17 @@ namespace Volo.Abp.Http.DynamicProxying
(await _controller.DeleteByIdAsync(42)).ShouldBe(43);
}
+ [Fact]
+ public async Task AbortRequestAsync()
+ {
+ var cts = new CancellationTokenSource();
+ cts.CancelAfter(10);
+
+ var result = await _controller.AbortRequestAsync(default);
+ result.ShouldBe("AbortRequestAsync");
+
+ var exception = await Assert.ThrowsAsync(async () => await _controller.AbortRequestAsync(cts.Token));
+ exception.InnerException.InnerException.Message.ShouldBe("The client aborted the request.");
+ }
}
}
diff --git a/framework/test/Volo.Abp.Threading.Tests/Volo.Abp.Threading.Tests.csproj b/framework/test/Volo.Abp.Threading.Tests/Volo.Abp.Threading.Tests.csproj
new file mode 100644
index 0000000000..cbca0b1329
--- /dev/null
+++ b/framework/test/Volo.Abp.Threading.Tests/Volo.Abp.Threading.Tests.csproj
@@ -0,0 +1,16 @@
+
+
+
+
+
+ net5.0
+
+
+
+
+
+
+
+
+
+
diff --git a/framework/test/Volo.Abp.Threading.Tests/Volo/Abp/Threading/AbpThreadingTestModule.cs b/framework/test/Volo.Abp.Threading.Tests/Volo/Abp/Threading/AbpThreadingTestModule.cs
new file mode 100644
index 0000000000..de530512d3
--- /dev/null
+++ b/framework/test/Volo.Abp.Threading.Tests/Volo/Abp/Threading/AbpThreadingTestModule.cs
@@ -0,0 +1,15 @@
+using Volo.Abp.Modularity;
+
+namespace Volo.Abp.Threading
+{
+ [DependsOn(
+ typeof(AbpThreadingModule),
+ typeof(AbpTestBaseModule)
+ )]
+ public class AbpThreadingTestModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ }
+ }
+}
diff --git a/framework/test/Volo.Abp.Threading.Tests/Volo/Abp/Threading/NullCancellationTokenProvider_Tests.cs b/framework/test/Volo.Abp.Threading.Tests/Volo/Abp/Threading/NullCancellationTokenProvider_Tests.cs
new file mode 100644
index 0000000000..34c5988eb1
--- /dev/null
+++ b/framework/test/Volo.Abp.Threading.Tests/Volo/Abp/Threading/NullCancellationTokenProvider_Tests.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Shouldly;
+using Volo.Abp.Testing;
+using Xunit;
+
+namespace Volo.Abp.Threading
+{
+ public class NullCancellationTokenProvider_Tests : AbpIntegratedTest
+ {
+ private readonly ICancellationTokenProvider _cancellationTokenProvider;
+
+ public NullCancellationTokenProvider_Tests()
+ {
+ _cancellationTokenProvider = NullCancellationTokenProvider.Instance;
+ }
+
+ [Fact]
+ public void Should_Return_None_Token()
+ {
+ _cancellationTokenProvider.Token.ShouldBe(CancellationToken.None);
+ }
+
+ [Fact]
+ public void Should_Return_Specific_Token()
+ {
+ var cts = new CancellationTokenSource();
+
+ using (_cancellationTokenProvider.Use(cts.Token))
+ {
+ var newCancellationTokenProvider = NullCancellationTokenProvider.Instance;
+
+ newCancellationTokenProvider.Token.ShouldBe(cts.Token);
+ }
+
+ _cancellationTokenProvider.Token.ShouldBe(CancellationToken.None);
+ }
+
+ [Fact]
+ public void Should_Cancel_After_100_Milliseconds()
+ {
+ var cts = new CancellationTokenSource();
+ cts.CancelAfter(TimeSpan.FromMilliseconds(100));
+
+ using (_cancellationTokenProvider.Use(cts.Token))
+ {
+ var newCancellationTokenProvider = NullCancellationTokenProvider.Instance;
+ Should.Throw(() => LongTask(1000, newCancellationTokenProvider.Token));
+ }
+ }
+
+ private void LongTask(int loopCounter, CancellationToken cancellationToken = default)
+ {
+ for (var i = 0; i < loopCounter; i++)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ Thread.Sleep(10);
+ }
+ }
+ }
+}
diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs
index 31666504d4..7f24616280 100644
--- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs
+++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs
@@ -21,6 +21,7 @@ namespace Volo.Abp.AuditLogging
Guid? userId = null,
string userName = null,
string applicationName = null,
+ string clientIpAddress = null,
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
@@ -37,6 +38,7 @@ namespace Volo.Abp.AuditLogging
Guid? userId = null,
string userName = null,
string applicationName = null,
+ string clientIpAddress = null,
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs
index 6b2a440f1f..361ae25f91 100644
--- a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs
+++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs
@@ -32,6 +32,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
Guid? userId = null,
string userName = null,
string applicationName = null,
+ string clientIpAddress = null,
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
@@ -48,6 +49,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
userId,
userName,
applicationName,
+ clientIpAddress,
correlationId,
maxExecutionDuration,
minExecutionDuration,
@@ -72,6 +74,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
Guid? userId = null,
string userName = null,
string applicationName = null,
+ string clientIpAddress = null,
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
@@ -87,6 +90,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
userId,
userName,
applicationName,
+ clientIpAddress,
correlationId,
maxExecutionDuration,
minExecutionDuration,
@@ -107,6 +111,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
Guid? userId = null,
string userName = null,
string applicationName = null,
+ string clientIpAddress = null,
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
@@ -126,6 +131,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
.WhereIf(userId != null, auditLog => auditLog.UserId == userId)
.WhereIf(userName != null, auditLog => auditLog.UserName == userName)
.WhereIf(applicationName != null, auditLog => auditLog.ApplicationName == applicationName)
+ .WhereIf(clientIpAddress != null, auditLog => auditLog.ClientIpAddress != null && auditLog.ClientIpAddress == clientIpAddress)
.WhereIf(correlationId != null, auditLog => auditLog.CorrelationId == correlationId)
.WhereIf(httpStatusCode != null && httpStatusCode > 0, auditLog => auditLog.HttpStatusCode == nHttpStatusCode)
.WhereIf(maxExecutionDuration != null && maxExecutionDuration.Value > 0, auditLog => auditLog.ExecutionDuration <= maxExecutionDuration)
diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs
index e67f78a2a8..06bf102fed 100644
--- a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs
+++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs
@@ -33,6 +33,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
Guid? userId = null,
string userName = null,
string applicationName = null,
+ string clientIpAddress = null,
string correlationId = null,
int? maxDuration = null,
int? minDuration = null,
@@ -49,6 +50,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
userId,
userName,
applicationName,
+ clientIpAddress,
correlationId,
maxDuration,
minDuration,
@@ -73,6 +75,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
Guid? userId = null,
string userName = null,
string applicationName = null,
+ string clientIpAddress = null,
string correlationId = null,
int? maxDuration = null,
int? minDuration = null,
@@ -88,6 +91,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
userId,
userName,
applicationName,
+ clientIpAddress,
correlationId,
maxDuration,
minDuration,
@@ -110,6 +114,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
Guid? userId = null,
string userName = null,
string applicationName = null,
+ string clientIpAddress = null,
string correlationId = null,
int? maxDuration = null,
int? minDuration = null,
@@ -128,6 +133,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
.WhereIf(userId != null, auditLog => auditLog.UserId == userId)
.WhereIf(userName != null, auditLog => auditLog.UserName == userName)
.WhereIf(applicationName != null, auditLog => auditLog.ApplicationName == applicationName)
+ .WhereIf(clientIpAddress != null, auditLog => auditLog.ClientIpAddress == clientIpAddress)
.WhereIf(correlationId != null, auditLog => auditLog.CorrelationId == correlationId)
.WhereIf(httpStatusCode != null && httpStatusCode > 0, auditLog => auditLog.HttpStatusCode == (int?)httpStatusCode)
.WhereIf(maxDuration != null && maxDuration > 0, auditLog => auditLog.ExecutionDuration <= maxDuration)
diff --git a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs
index e581a39c40..31026fdc8f 100644
--- a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs
+++ b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs
@@ -102,7 +102,7 @@ namespace Volo.CmsKit
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak"));
diff --git a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs
index fa95f3c6d1..bd3bb70cd4 100644
--- a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs
+++ b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs
@@ -108,7 +108,7 @@ namespace Volo.CmsKit
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak"));
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs
index 7351ddc9c2..ba573a6eb5 100644
--- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs
@@ -129,7 +129,7 @@ namespace Volo.CmsKit
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português (Brasil)"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak"));
diff --git a/modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs b/modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs
index 07556b9b1a..32779b6acf 100644
--- a/modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs
+++ b/modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs
@@ -127,7 +127,7 @@ namespace VoloDocs.Web
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak"));
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs
index 3814ab96e3..5675bf1fd4 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs
@@ -56,6 +56,8 @@ namespace Volo.Abp.Identity
int skipCount = 0,
string filter = null,
bool includeDetails = false,
+ Guid? roleId = null,
+ Guid? organizationUnitId = null,
CancellationToken cancellationToken = default
);
@@ -86,6 +88,8 @@ namespace Volo.Abp.Identity
Task GetCountAsync(
string filter = null,
+ Guid? roleId = null,
+ Guid? organizationUnitId = null,
CancellationToken cancellationToken = default
);
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserRepositoryExternalUserLookupServiceProvider.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserRepositoryExternalUserLookupServiceProvider.cs
index c0fb15d80c..40b4575afe 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserRepositoryExternalUserLookupServiceProvider.cs
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserRepositoryExternalUserLookupServiceProvider.cs
@@ -71,7 +71,7 @@ namespace Volo.Abp.Identity
string filter = null,
CancellationToken cancellationToken = new CancellationToken())
{
- return await UserRepository.GetCountAsync(filter, cancellationToken);
+ return await UserRepository.GetCountAsync(filter, cancellationToken: cancellationToken);
}
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs
index dfed75c804..b463cd6497 100644
--- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs
+++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs
@@ -136,6 +136,8 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
int skipCount = 0,
string filter = null,
bool includeDetails = false,
+ Guid? roleId = null,
+ Guid? organizationUnitId = null,
CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
@@ -149,6 +151,8 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
(u.Surname != null && u.Surname.Contains(filter)) ||
(u.PhoneNumber != null && u.PhoneNumber.Contains(filter))
)
+ .WhereIf(roleId.HasValue, identityUser => identityUser.Roles.Any(x => x.RoleId == roleId.Value))
+ .WhereIf(organizationUnitId.HasValue, identityUser => identityUser.OrganizationUnits.Any(x => x.OrganizationUnitId == organizationUnitId.Value))
.OrderBy(sorting.IsNullOrWhiteSpace() ? nameof(IdentityUser.UserName) : sorting)
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
@@ -186,6 +190,8 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
public virtual async Task GetCountAsync(
string filter = null,
+ Guid? roleId = null,
+ Guid? organizationUnitId = null,
CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
@@ -198,6 +204,8 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
(u.Surname != null && u.Surname.Contains(filter)) ||
(u.PhoneNumber != null && u.PhoneNumber.Contains(filter))
)
+ .WhereIf(roleId.HasValue, identityUser => identityUser.Roles.Any(x => x.RoleId == roleId.Value))
+ .WhereIf(organizationUnitId.HasValue, identityUser => identityUser.OrganizationUnits.Any(x => x.OrganizationUnitId == organizationUnitId.Value))
.LongCountAsync(GetCancellationToken(cancellationToken));
}
diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs
index 82db48b3ed..83181a6af8 100644
--- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs
+++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs
@@ -138,6 +138,8 @@ namespace Volo.Abp.Identity.MongoDB
int skipCount = 0,
string filter = null,
bool includeDetails = false,
+ Guid? roleId = null,
+ Guid? organizationUnitId = null,
CancellationToken cancellationToken = default)
{
return await (await GetMongoQueryableAsync(cancellationToken))
@@ -150,6 +152,8 @@ namespace Volo.Abp.Identity.MongoDB
(u.Surname != null && u.Surname.Contains(filter)) ||
(u.PhoneNumber != null && u.PhoneNumber.Contains(filter))
)
+ .WhereIf>(roleId.HasValue, identityUser => identityUser.Roles.Any(x => x.RoleId == roleId.Value))
+ .WhereIf>(organizationUnitId.HasValue, identityUser => identityUser.OrganizationUnits.Any(x => x.OrganizationUnitId == organizationUnitId.Value))
.OrderBy(sorting.IsNullOrWhiteSpace() ? nameof(IdentityUser.UserName) : sorting)
.As>()
.PageBy>(skipCount, maxResultCount)
@@ -195,6 +199,8 @@ namespace Volo.Abp.Identity.MongoDB
public virtual async Task GetCountAsync(
string filter = null,
+ Guid? roleId = null,
+ Guid? organizationUnitId = null,
CancellationToken cancellationToken = default)
{
return await (await GetMongoQueryableAsync(cancellationToken))
@@ -207,6 +213,8 @@ namespace Volo.Abp.Identity.MongoDB
(u.Surname != null && u.Surname.Contains(filter)) ||
(u.PhoneNumber != null && u.PhoneNumber.Contains(filter))
)
+ .WhereIf>(roleId.HasValue, identityUser => identityUser.Roles.Any(x => x.RoleId == roleId.Value))
+ .WhereIf>(organizationUnitId.HasValue, identityUser => identityUser.OrganizationUnits.Any(x => x.OrganizationUnitId == organizationUnitId.Value))
.LongCountAsync(GetCancellationToken(cancellationToken));
}
diff --git a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/DemoAppModule.cs b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/DemoAppModule.cs
index e2a35ad542..f20f081c33 100644
--- a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/DemoAppModule.cs
+++ b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/DemoAppModule.cs
@@ -88,7 +88,7 @@ namespace Volo.Abp.SettingManagement.DemoApp
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
});
Configure(options =>
diff --git a/modules/virtual-file-explorer/app/Volo.Abp.VirtualFileExplorer.DemoApp/AbpVirtualFileExplorerDemoAppModule.cs b/modules/virtual-file-explorer/app/Volo.Abp.VirtualFileExplorer.DemoApp/AbpVirtualFileExplorerDemoAppModule.cs
index e5b7f56374..e55beb118a 100644
--- a/modules/virtual-file-explorer/app/Volo.Abp.VirtualFileExplorer.DemoApp/AbpVirtualFileExplorerDemoAppModule.cs
+++ b/modules/virtual-file-explorer/app/Volo.Abp.VirtualFileExplorer.DemoApp/AbpVirtualFileExplorerDemoAppModule.cs
@@ -23,7 +23,7 @@ namespace Volo.Abp.VirtualFileExplorer.DemoApp
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak"));
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyProjectNameBlazorModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyProjectNameBlazorModule.cs
index 5586e7ba5c..fac76131e3 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyProjectNameBlazorModule.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyProjectNameBlazorModule.cs
@@ -219,7 +219,7 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Tiered
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak"));
@@ -338,4 +338,4 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Tiered
app.UseConfiguredEndpoints();
}
}
-}
\ No newline at end of file
+}
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Program.cs
index 5b9b0d2617..5ec3416569 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Program.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Program.cs
@@ -45,10 +45,7 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Tiered
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/gulpfile.js b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/gulpfile.js
deleted file mode 100644
index f7ebc78f23..0000000000
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/gulpfile.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-var gulp = require("gulp"),
- path = require('path'),
- copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js');
-
-exports.default = function(){
- return copyResources(path.resolve('./'));
-};
\ No newline at end of file
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs
index f1c8343cf2..a0f1537fb5 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs
@@ -180,7 +180,7 @@ namespace MyCompanyName.MyProjectName.Blazor.Server
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak"));
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Program.cs
index 0c1f77c869..636f823d17 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Program.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Program.cs
@@ -45,10 +45,7 @@ namespace MyCompanyName.MyProjectName.Blazor.Server
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/gulpfile.js b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/gulpfile.js
deleted file mode 100644
index f7ebc78f23..0000000000
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/gulpfile.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-var gulp = require("gulp"),
- path = require('path'),
- copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js');
-
-exports.default = function(){
- return copyResources(path.resolve('./'));
-};
\ No newline at end of file
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.DbMigrator/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.DbMigrator/Program.cs
index 0bc45f3f34..e6f095308c 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.DbMigrator/Program.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.DbMigrator/Program.cs
@@ -32,10 +32,7 @@ namespace MyCompanyName.MyProjectName.DbMigrator
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureLogging((context, logging) => logging.ClearProviders())
.ConfigureServices((hostContext, services) =>
{
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs
index 6c03362a7e..0bec7e6271 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs
@@ -131,7 +131,7 @@ namespace MyCompanyName.MyProjectName
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
@@ -191,12 +191,6 @@ namespace MyCompanyName.MyProjectName
}
app.UseAbpRequestLocalization();
-
- if (!env.IsDevelopment())
- {
- app.UseErrorPage();
- }
-
app.UseCorrelationId();
app.UseStaticFiles();
app.UseRouting();
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs
index 75cea3c4d9..e16edddb92 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs
@@ -45,10 +45,7 @@ namespace MyCompanyName.MyProjectName
internal static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs
index 9cf637218d..29e0877ce3 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs
@@ -158,7 +158,7 @@ namespace MyCompanyName.MyProjectName
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/Program.cs
index 75cea3c4d9..e16edddb92 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/Program.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/Program.cs
@@ -45,10 +45,7 @@ namespace MyCompanyName.MyProjectName
internal static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/gulpfile.js b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/gulpfile.js
deleted file mode 100644
index f7ebc78f23..0000000000
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/gulpfile.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-var gulp = require("gulp"),
- path = require('path'),
- copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js');
-
-exports.default = function(){
- return copyResources(path.resolve('./'));
-};
\ No newline at end of file
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs
index 23bbec502d..5e76b19724 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs
@@ -65,7 +65,7 @@ namespace MyCompanyName.MyProjectName
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/Program.cs
index 5ffee2ba95..8a57ded111 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/Program.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/Program.cs
@@ -45,10 +45,7 @@ namespace MyCompanyName.MyProjectName
internal static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/gulpfile.js b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/gulpfile.js
deleted file mode 100644
index 5dcf4c5c6f..0000000000
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/gulpfile.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-var gulp = require("gulp"),
- path = require('path'),
- copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js');
-
-exports.default = function(){
- return copyResources(path.resolve('./'));
-};
\ No newline at end of file
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Program.cs
index 7ef69fa2b3..e6d0635c7c 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Program.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Program.cs
@@ -45,10 +45,7 @@ namespace MyCompanyName.MyProjectName.Web
internal static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/gulpfile.js b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/gulpfile.js
deleted file mode 100644
index f7ebc78f23..0000000000
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/gulpfile.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-var gulp = require("gulp"),
- path = require('path'),
- copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js');
-
-exports.default = function(){
- return copyResources(path.resolve('./'));
-};
\ No newline at end of file
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs
index 7e53230a60..8ab982a275 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs
@@ -168,7 +168,7 @@ namespace MyCompanyName.MyProjectName.Web
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak"));
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Program.cs
index 7ef69fa2b3..e6d0635c7c 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Program.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Program.cs
@@ -45,10 +45,7 @@ namespace MyCompanyName.MyProjectName.Web
internal static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/gulpfile.js b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/gulpfile.js
deleted file mode 100644
index f7ebc78f23..0000000000
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/gulpfile.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-var gulp = require("gulp"),
- path = require('path'),
- copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js');
-
-exports.default = function(){
- return copyResources(path.resolve('./'));
-};
\ No newline at end of file
diff --git a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp/Program.cs b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp/Program.cs
index e296ed9a11..2055438bc5 100644
--- a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp/Program.cs
+++ b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp/Program.cs
@@ -14,10 +14,7 @@ namespace MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService();
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs
index 9f736c7e98..9f5fd42006 100644
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs
+++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs
@@ -158,6 +158,7 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host
Configure(options =>
{
+ options.Languages.Add(new LanguageInfo("ar", "ar", "العربية"));
options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)"));
@@ -172,6 +173,8 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
+ options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch"));
+ options.Languages.Add(new LanguageInfo("es", "es", "Español"));
});
Configure(options =>
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Program.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Program.cs
index 80a6d4b8b7..14ab96b609 100644
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Program.cs
+++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Program.cs
@@ -45,10 +45,7 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host
public static IHostBuilder CreateHostBuilder(string[] args) =>
Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureWebHostDefaults(webBuilder =>
{
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/gulpfile.js b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/gulpfile.js
deleted file mode 100644
index f7ebc78f23..0000000000
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/gulpfile.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-var gulp = require("gulp"),
- path = require('path'),
- copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js');
-
-exports.default = function(){
- return copyResources(path.resolve('./'));
-};
\ No newline at end of file
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs
index ef1c345dc3..b8ad8580af 100644
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs
+++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs
@@ -93,13 +93,14 @@ namespace MyCompanyName.MyProjectName
Configure(options =>
{
+ options.Languages.Add(new LanguageInfo("ar", "ar", "العربية"));
options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)"));
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
@@ -107,6 +108,8 @@ namespace MyCompanyName.MyProjectName
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
+ options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch"));
+ options.Languages.Add(new LanguageInfo("es", "es", "Español"));
});
context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
@@ -161,7 +164,6 @@ namespace MyCompanyName.MyProjectName
}
else
{
- app.UseErrorPage();
app.UseHsts();
}
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs
index 0c22a68c1d..b2811a98ba 100644
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs
+++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs
@@ -45,10 +45,7 @@ namespace MyCompanyName.MyProjectName
internal static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs
index 6733fcecae..beab7c5132 100644
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs
+++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs
@@ -103,13 +103,14 @@ namespace MyCompanyName.MyProjectName
Configure(options =>
{
+ options.Languages.Add(new LanguageInfo("ar", "ar", "العربية"));
options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)"));
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
@@ -117,6 +118,8 @@ namespace MyCompanyName.MyProjectName
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
+ options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch"));
+ options.Languages.Add(new LanguageInfo("es", "es", "Español"));
});
Configure(options =>
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Program.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Program.cs
index 0c22a68c1d..b2811a98ba 100644
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Program.cs
+++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Program.cs
@@ -45,10 +45,7 @@ namespace MyCompanyName.MyProjectName
internal static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/gulpfile.js b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/gulpfile.js
deleted file mode 100644
index 5dcf4c5c6f..0000000000
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/gulpfile.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-var gulp = require("gulp"),
- path = require('path'),
- copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js');
-
-exports.default = function(){
- return copyResources(path.resolve('./'));
-};
\ No newline at end of file
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/Program.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/Program.cs
index 0c22a68c1d..b2811a98ba 100644
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/Program.cs
+++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/Program.cs
@@ -45,10 +45,7 @@ namespace MyCompanyName.MyProjectName
internal static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/gulpfile.js b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/gulpfile.js
deleted file mode 100644
index f7ebc78f23..0000000000
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/gulpfile.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-var gulp = require("gulp"),
- path = require('path'),
- copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js');
-
-exports.default = function(){
- return copyResources(path.resolve('./'));
-};
\ No newline at end of file
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs
index 035a1fe753..57bd71c2eb 100644
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs
+++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs
@@ -100,13 +100,14 @@ namespace MyCompanyName.MyProjectName
Configure(options =>
{
+ options.Languages.Add(new LanguageInfo("ar", "ar", "العربية"));
options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)"));
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
- options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it"));
+ options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português (Brasil)"));
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
@@ -114,6 +115,8 @@ namespace MyCompanyName.MyProjectName
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
+ options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch"));
+ options.Languages.Add(new LanguageInfo("es", "es", "Español"));
});
Configure(options =>
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Program.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Program.cs
index 1a36da255f..9e4d072019 100644
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Program.cs
+++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Program.cs
@@ -41,10 +41,7 @@ namespace MyCompanyName.MyProjectName
internal static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/gulpfile.js b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/gulpfile.js
deleted file mode 100644
index 5dcf4c5c6f..0000000000
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/gulpfile.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-var gulp = require("gulp"),
- path = require('path'),
- copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js');
-
-exports.default = function(){
- return copyResources(path.resolve('./'));
-};
\ No newline at end of file
diff --git a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp/Program.cs b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp/Program.cs
index e296ed9a11..2055438bc5 100644
--- a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp/Program.cs
+++ b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp/Program.cs
@@ -14,10 +14,7 @@ namespace MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(build =>
- {
- build.AddJsonFile("appsettings.secrets.json", optional: true);
- })
+ .AddAppSettingsSecretsJson()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService();