Browse Source

Merge branch 'dev' into auto-merge/rel-4-4/507

pull/9716/head
ebicoglu 5 years ago
committed by GitHub
parent
commit
0712a8d2c4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
  2. 2
      common.props
  3. 23
      docs/en/Background-Jobs-Hangfire.md
  4. 2
      docs/en/Blog-Posts/2020-10-15 v3_3_Preview/POST.md
  5. 174
      docs/en/Blog-Posts/2021-06-28 v4_4 Preview/POST.md
  6. BIN
      docs/en/Blog-Posts/2021-06-28 v4_4 Preview/abp-44-cover.png
  7. BIN
      docs/en/Blog-Posts/2021-06-28 v4_4 Preview/ddd-book.png
  8. BIN
      docs/en/Blog-Posts/2021-06-28 v4_4 Preview/dotnetfoundation-sponsor-volosoft.png
  9. BIN
      docs/en/Blog-Posts/2021-06-28 v4_4 Preview/elsa-overview.gif
  10. BIN
      docs/en/Blog-Posts/2021-06-28 v4_4 Preview/leptonx.png
  11. BIN
      docs/en/Blog-Posts/2021-06-28 v4_4 Preview/menu-items-admin.png
  12. BIN
      docs/en/Blog-Posts/2021-06-28 v4_4 Preview/menu-items-public.png
  13. 52
      docs/en/Blog-Posts/2021-07-08 Introducing_the_eShopOnAbp/POST.md
  14. BIN
      docs/en/Blog-Posts/2021-07-08 Introducing_the_eShopOnAbp/overall-solution.png
  15. 42
      docs/en/Blog-Posts/2021-08-02 v4_4_Release_Stable/POST.md
  16. 2
      docs/en/Modules/Docs.md
  17. 2
      docs/en/Modules/Virtual-File-Explorer.md
  18. 4
      docs/en/SignalR-Integration.md
  19. 2
      docs/en/UI/AspNetCore/Basic-Theme.md
  20. 22
      docs/en/UI/AspNetCore/Client-Side-Package-Management.md
  21. 7
      docs/en/Validation.md
  22. 4
      docs/en/Virtual-File-System.md
  23. 466
      docs/pt-BR/MongoDB.md
  24. 7
      docs/zh-Hans/Validation.md
  25. 7
      framework/Volo.Abp.sln
  26. 26
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs
  27. 21
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Threading/HttpContextCancellationTokenProvider.cs
  28. 25
      framework/src/Volo.Abp.Core/Microsoft/Extensions/Hosting/AbpHostingHostBuilderExtensions.cs
  29. 18
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyBasicRepository.cs
  30. 14
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyRepository.cs
  31. 5
      framework/src/Volo.Abp.FluentValidation/Volo/Abp/FluentValidation/FluentObjectValidationContributor.cs
  32. 1
      framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj
  33. 46
      framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireAuthorizationFilter.cs
  34. 2
      framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireModule.cs
  35. 14
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs
  36. 1
      framework/src/Volo.Abp.Sms.Aliyun/Volo.Abp.Sms.Aliyun.csproj
  37. 14
      framework/src/Volo.Abp.Threading/Volo/Abp/Threading/CancellationTokenOverride.cs
  38. 26
      framework/src/Volo.Abp.Threading/Volo/Abp/Threading/CancellationTokenProviderBase.cs
  39. 5
      framework/src/Volo.Abp.Threading/Volo/Abp/Threading/ICancellationTokenProvider.cs
  40. 8
      framework/src/Volo.Abp.Threading/Volo/Abp/Threading/NullCancellationTokenProvider.cs
  41. 4
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs
  42. 6
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IMethodInvocationValidator.cs
  43. 8
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidationContributor.cs
  44. 7
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidator.cs
  45. 17
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/MethodInvocationValidator.cs
  46. 9
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ObjectValidator.cs
  47. 6
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs
  48. 10
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/LocalizationTestController.cs
  49. 11
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/Views/LocalizationTest/PersonForm.cshtml
  50. 8
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/MvcLocalization_Tests.cs
  51. 7
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json
  52. 7
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/tr.json
  53. 27
      framework/test/Volo.Abp.FluentValidation.Tests/Volo/Abp/FluentValidation/ApplicationService_FluentValidation_Tests.cs
  54. 3
      framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/IRegularTestController.cs
  55. 11
      framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestController.cs
  56. 16
      framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs
  57. 16
      framework/test/Volo.Abp.Threading.Tests/Volo.Abp.Threading.Tests.csproj
  58. 15
      framework/test/Volo.Abp.Threading.Tests/Volo/Abp/Threading/AbpThreadingTestModule.cs
  59. 63
      framework/test/Volo.Abp.Threading.Tests/Volo/Abp/Threading/NullCancellationTokenProvider_Tests.cs
  60. 2
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs
  61. 6
      modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs
  62. 6
      modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs
  63. 2
      modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs
  64. 2
      modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs
  65. 2
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs
  66. 2
      modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs
  67. 4
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs
  68. 2
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserRepositoryExternalUserLookupServiceProvider.cs
  69. 8
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs
  70. 8
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs
  71. 2
      modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/DemoAppModule.cs
  72. 2
      modules/virtual-file-explorer/app/Volo.Abp.VirtualFileExplorer.DemoApp/AbpVirtualFileExplorerDemoAppModule.cs
  73. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyProjectNameBlazorModule.cs
  74. 5
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Program.cs
  75. 9
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/gulpfile.js
  76. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs
  77. 5
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Program.cs
  78. 9
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/gulpfile.js
  79. 5
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.DbMigrator/Program.cs
  80. 8
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs
  81. 5
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs
  82. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs
  83. 5
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/Program.cs
  84. 9
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/gulpfile.js
  85. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs
  86. 5
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/Program.cs
  87. 9
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/gulpfile.js
  88. 5
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Program.cs
  89. 9
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/gulpfile.js
  90. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs
  91. 5
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Program.cs
  92. 9
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/gulpfile.js
  93. 5
      templates/app/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp/Program.cs
  94. 3
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs
  95. 5
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Program.cs
  96. 9
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/gulpfile.js
  97. 6
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs
  98. 5
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs
  99. 5
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs
  100. 5
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Program.cs

12
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json

@ -45,7 +45,7 @@
"IndexPageHeroSection": "<span class=\"first-line\">A complete</span><span class=\"second-line\"> web development platform</span><span class=\"third-line\">built-on <img src=\"{0}\" width=\"110\" class=\"ml-1\" /> framework</span>",
"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 <a href=\"{0}\">the prices</a> 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": "<strong>Extending:</strong> 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.<hr/><strong>Upgrading:</strong> By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. See the <a href=\"/pricing\">license comparison table</a> to check the differences between the license plans.<strong>On the other hand, when you upgrade, your license expiry date will not change!</strong>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 <a href=\"{0}\">premium support</a> 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 <strong>1 month</strong> after your license expires, %20 discount will be applied to total license price.",
"WhenShouldIRenewMyLicenseExplanation1": "If you renew your license within <strong>1 month</strong> 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.<br />After sending the license amount via bank wire transfer, send us your receipt and the requested license type via e-mail.<br />Our international bank account information:",
"DoYouAcceptBankWireTransferExplanation": "Yes, we accept bank wire transfer.<br />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, <a href=\"{0}\">ABP CLI</a> provides an update command that automatically finds and upgrades all ABP related packages in your solution.",

2
common.props

@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>4.4.0</Version>
<Version>5.0.0</Version>
<NoWarn>$(NoWarn);CS1591;CS0436</NoWarn>
<PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl>
<PackageProjectUrl>https://abp.io/</PackageProjectUrl>

23
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!

2
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

174
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):
![menu-items-admin](menu-items-admin.png)
And the items rendered in a public website:
![menu-items-public](menu-items-public.png)
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<IdentityDbContext>(modelBuilder =>
{
modelBuilder.Entity<IdentityUser>(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 <batch-file>` (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.
![elsa-overview](elsa-overview.gif)
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.
![ddd-book](ddd-book.png)
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.
![leptonx](leptonx.png)
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!
![dotnetfoundation-sponsor-volosoft](dotnetfoundation-sponsor-volosoft.png)
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.

BIN
docs/en/Blog-Posts/2021-06-28 v4_4 Preview/abp-44-cover.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
docs/en/Blog-Posts/2021-06-28 v4_4 Preview/ddd-book.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
docs/en/Blog-Posts/2021-06-28 v4_4 Preview/dotnetfoundation-sponsor-volosoft.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
docs/en/Blog-Posts/2021-06-28 v4_4 Preview/elsa-overview.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

BIN
docs/en/Blog-Posts/2021-06-28 v4_4 Preview/leptonx.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

BIN
docs/en/Blog-Posts/2021-06-28 v4_4 Preview/menu-items-admin.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
docs/en/Blog-Posts/2021-06-28 v4_4 Preview/menu-items-public.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

52
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.
![eShopOnAbp Overall Solution](overall-solution.png)
## 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).

BIN
docs/en/Blog-Posts/2021-07-08 Introducing_the_eShopOnAbp/overall-solution.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

42
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)

2
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

2
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:

4
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:

2
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

22
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

7
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;
}
}
````

4
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 `<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>` into the `<PropertyConfig>...</PropertyConfig>` section of your `.csproj` file.
2. Add `<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>` into the `<PropertyGroup>...</PropertyGroup>` 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.
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.

466
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<Question> Questions => Collection<Question>();
public IMongoCollection<Category> Categories => Collection<Category>();
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<TEntity>` 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<TEntity>` 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<Question>(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<Question> Questions => Collection<Question>();
````
### 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<MyDbContext>();
// ...
}
}
}
```
### 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<MyDbContext>(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<MyDbContext>(options =>
{
options.AddDefaultRepositories(includeAllEntities: true);
});
```
Então você pode injetar e usar `IRepository<TEntity, TPrimaryKey>` nas suas services. Suponha que você tenha uma entidade `Book` com a chave primária `Guid`:
```csharp
public class Book : AggregateRoot<Guid>
{
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<Book, Guid> _bookRepository;
public BookManager(IRepository<Book, Guid> bookRepository) // injetar repositório padrão
{
_bookRepository = bookRepository;
}
public async Task<Book> 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<Book, Guid>
{
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<BookStoreMongoDbContext, Book, Guid>,
IBookRepository
{
public BookRepository(IMongoDbContextProvider<BookStoreMongoDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task DeleteBooksByType(
BookType type,
CancellationToken cancellationToken = default(CancellationToken))
{
var collection = await GetCollectionAsync(cancellationToken);
await collection.DeleteManyAsync(
Builders<Book>.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<Book, Guid>` 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<BookStoreMongoDbContext>(options =>
{
options.AddDefaultRepositories();
options.AddRepository<Book, BookRepository>(); //Replaces IRepository<Book, Guid>
});
```
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<Book, Guid> _bookRepository;
public BookService(IRepository<Book, Guid> bookRepository)
{
_bookRepository = bookRepository;
}
public async Task FooAsync()
{
IMongoDatabase database = await _bookRepository.GetDatabaseAsync();
IMongoCollection<Book> books = await _bookRepository.GetCollectionAsync();
IAggregateFluent<Book> 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<AbpUnitOfWorkDefaultOptions>(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<TEntity>
: MongoDbRepository<BookStoreMongoDbContext, TEntity>
where TEntity : class, IEntity
{
public MyRepositoryBase(IMongoDbContextProvider<BookStoreMongoDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
}
public class MyRepositoryBase<TEntity, TKey>
: MongoDbRepository<BookStoreMongoDbContext, TEntity, TKey>
where TEntity : class, IEntity<TKey>
{
public MyRepositoryBase(IMongoDbContextProvider<BookStoreMongoDbContext> 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<BookStoreMongoDbContext>(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<Book> Books { get; }
}
```
`IBookStoreMongoDbContext` é implementado pela classe `BookStoreMongoDbContext`. Então você pode usar sobrecarga genérica do `AddDefaultRepositories`:
```csharp
context.Services.AddMongoDbContext<BookStoreMongoDbContext>(options =>
{
options.AddDefaultRepositories<IBookStoreMongoDbContext>();
// ...
});
```
Agora, seu `BookRepository` personalizado também pode usar a interface `IBookStoreMongoDbContext`:
```csharp
public class BookRepository
: MongoDbRepository<IBookStoreMongoDbContext, Book, Guid>,
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<OtherMongoDbContext>(options =>
{
// ...
options.ReplaceDbContext<IBookStoreMongoDbContext>();
});
```
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<TEntity>(
IMongoDbRepository<TEntity> repository,
IEnumerable<TEntity> entities,
IClientSessionHandle sessionHandle,
bool autoSave,
CancellationToken cancellationToken)
where TEntity : class, IEntity
{
// Sua lógica aqui.
}
public async Task InsertManyAsync<TEntity>(
IMongoDbRepository<TEntity> repository,
IEnumerable<TEntity> entities,
IClientSessionHandle sessionHandle,
bool autoSave,
CancellationToken cancellationToken)
where TEntity : class, IEntity
{
// Sua lógica aqui.
}
public async Task UpdateManyAsync<TEntity>(
IMongoDbRepository<TEntity> repository,
IEnumerable<TEntity> entities,
IClientSessionHandle sessionHandle,
bool autoSave,
CancellationToken cancellationToken)
where TEntity : class, IEntity
{
// Sua lógica aqui.
}
}
```
## Veja Também
* [Entities](Entities.md)
* [Repositories](Repositories.md)

7
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;
}
}
````

7
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}

26
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
};
}
}
}
}

21
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<CancellationTokenOverride> cancellationTokenOverrideScopeProvider,
IHttpContextAccessor httpContextAccessor)
: base(cancellationTokenOverrideScopeProvider)
{
_httpContextAccessor = httpContextAccessor;
}

25
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
);
});
}
}
}

18
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
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>Entity</returns>
Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default);
/// <summary>
/// Gets a list entities by the given <paramref name="predicate"/>.
/// </summary>
/// <param name="predicate">A condition to find the entity</param>
/// <param name="includeDetails">Set true to include all children of this entity</param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>Entity</returns>
Task<List<TEntity>> GetListAsync(
[NotNull] Expression<Func<TEntity, bool>> predicate,
bool includeDetails = false,
CancellationToken cancellationToken = default);
/// <summary>
/// Gets total count of all entities.
/// </summary>

14
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<IQueryable<TEntity>> WithDetailsAsync(params Expression<Func<TEntity, object>>[] propertySelectors); //TODO: CancellationToken
Task<IQueryable<TEntity>> GetQueryableAsync(); //TODO: CancellationToken
/// <summary>
/// Gets a list of entities by the given <paramref name="predicate"/>.
/// </summary>
/// <param name="predicate">A condition to filter the entities</param>
/// <param name="includeDetails">Set true to include details (sub-collections) of this entity</param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
Task<List<TEntity>> GetListAsync(
[NotNull] Expression<Func<TEntity, bool>> predicate,
bool includeDetails = false,
CancellationToken cancellationToken = default);
}
public interface IReadOnlyRepository<TEntity, TKey> : IReadOnlyRepository<TEntity>, IReadOnlyBasicRepository<TEntity, TKey>

5
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));

1
framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj

@ -19,6 +19,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Authorization.Abstractions\Volo.Abp.Authorization.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" />
</ItemGroup>

46
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<bool> 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<ICurrentUser>();
return currentUser.IsAuthenticated;
}
private static async Task<bool> IsPermissionGrantedAsync(DashboardContext context, string requiredPermissionName)
{
var permissionChecker = context.GetHttpContext().RequestServices.GetRequiredService<IPermissionChecker>();
return await permissionChecker.IsGrantedAsync(requiredPermissionName);
}
}
}

2
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;

14
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;
}
}

1
framework/src/Volo.Abp.Sms.Aliyun/Volo.Abp.Sms.Aliyun.csproj

@ -18,6 +18,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="AlibabaCloud.OpenApiUtil" Version="1.0.10" />
<PackageReference Include="AlibabaCloud.SDK.Dysmsapi20170525" Version="1.0.2"/>
</ItemGroup>

14
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;
}
}
}

26
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<CancellationTokenOverride> CancellationTokenOverrideScopeProvider { get; }
protected CancellationTokenOverride OverrideValue => CancellationTokenOverrideScopeProvider.GetValue(CancellationTokenOverrideContextKey);
protected CancellationTokenProviderBase(IAmbientScopeProvider<CancellationTokenOverride> cancellationTokenOverrideScopeProvider)
{
CancellationTokenOverrideScopeProvider = cancellationTokenOverrideScopeProvider;
}
public IDisposable Use(CancellationToken cancellationToken)
{
return CancellationTokenOverrideScopeProvider.BeginScope(CancellationTokenOverrideContextKey, new CancellationTokenOverride(cancellationToken));
}
}
}

5
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);
}
}

8
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<CancellationTokenOverride>(new AsyncLocalAmbientDataContext()))
{
}
}
}
}

4
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<ValidationResult> errors, object validatingObject, int currentDepth)

6
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);
}
}

8
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);
}
}
}

7
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<ValidationResult> GetErrors(
Task<List<ValidationResult>> GetErrorsAsync(
object validatingObject,
string name = null,
bool allowNull = false
);
}
}
}

17
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<DisableValidationAttribute>(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
);
}
}
}
}

9
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<ValidationResult> GetErrors(object validatingObject, string name = null, bool allowNull = false)
public virtual async Task<List<ValidationResult>> 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);
}
}

6
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,

10
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;
}
}
}

11
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/Views/LocalizationTest/PersonForm.cshtml

@ -5,4 +5,13 @@
<form>
<label asp-for="BirthDate"></label>
<input asp-for="BirthDate" />
</form>
<label asp-for="BirthDate1"></label>
<input asp-for="BirthDate1" />
<label asp-for="BirthDate2"></label>
<input asp-for="BirthDate2" />
<label asp-for="BirthDate3"></label>
<input asp-for="BirthDate3" />
</form>

8
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 <b>John</b>.");
}
[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("<label for=\"BirthDate\">Birth date</label>");
result.ShouldContain("<label for=\"BirthDate1\">Birth date1</label>");
result.ShouldContain("<label for=\"BirthDate2\">Birth date2</label>");
result.ShouldContain("<label for=\"BirthDate3\">Birth date3</label>");
}
using (CultureHelper.Use("tr"))
{
var result = await GetResponseAsStringAsync("/LocalizationTest/PersonForm");
result.ShouldContain("<label for=\"BirthDate\">Dogum gunu</label>");
result.ShouldContain("<label for=\"BirthDate1\">Dogum gunu1</label>");
result.ShouldContain("<label for=\"BirthDate2\">Dogum gunu2</label>");
result.ShouldContain("<label for=\"BirthDate3\">Dogum gunu3</label>");
}
}
}

7
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"
}
}
}

7
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"
}
}
}

27
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));
}
}
}
}
}

3
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<string> PatchValueWithHeaderAndQueryStringAsync(string headerValue, string qsValue);
Task<int> DeleteByIdAsync(int id);
Task<string> AbortRequestAsync(CancellationToken cancellationToken = default);
}
}

11
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<string> AbortRequestAsync(CancellationToken cancellationToken = default)
{
await Task.Delay(100, cancellationToken);
return "AbortRequestAsync";
}
}
public class Car

16
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<HttpRequestException>(async () => await _controller.AbortRequestAsync(cts.Token));
exception.InnerException.InnerException.Message.ShouldBe("The client aborted the request.");
}
}
}

16
framework/test/Volo.Abp.Threading.Tests/Volo.Abp.Threading.Tests.csproj

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.test.props" />
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.Threading\Volo.Abp.Threading.csproj" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
</ItemGroup>
</Project>

15
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)
{
}
}
}

63
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<AbpThreadingTestModule>
{
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<OperationCanceledException>(() => LongTask(1000, newCancellationTokenProvider.Token));
}
}
private void LongTask(int loopCounter, CancellationToken cancellationToken = default)
{
for (var i = 0; i < loopCounter; i++)
{
cancellationToken.ThrowIfCancellationRequested();
Thread.Sleep(10);
}
}
}
}

2
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,

6
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)

6
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)

2
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"));

2
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"));

2
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"));

2
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"));

4
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<long> GetCountAsync(
string filter = null,
Guid? roleId = null,
Guid? organizationUnitId = null,
CancellationToken cancellationToken = default
);
}

2
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);
}
}
}

8
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<long> 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));
}

8
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<IdentityUser, IMongoQueryable<IdentityUser>>(roleId.HasValue, identityUser => identityUser.Roles.Any(x => x.RoleId == roleId.Value))
.WhereIf<IdentityUser, IMongoQueryable<IdentityUser>>(organizationUnitId.HasValue, identityUser => identityUser.OrganizationUnits.Any(x => x.OrganizationUnitId == organizationUnitId.Value))
.OrderBy(sorting.IsNullOrWhiteSpace() ? nameof(IdentityUser.UserName) : sorting)
.As<IMongoQueryable<IdentityUser>>()
.PageBy<IdentityUser, IMongoQueryable<IdentityUser>>(skipCount, maxResultCount)
@ -195,6 +199,8 @@ namespace Volo.Abp.Identity.MongoDB
public virtual async Task<long> 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<IdentityUser, IMongoQueryable<IdentityUser>>(roleId.HasValue, identityUser => identityUser.Roles.Any(x => x.RoleId == roleId.Value))
.WhereIf<IdentityUser, IMongoQueryable<IdentityUser>>(organizationUnitId.HasValue, identityUser => identityUser.OrganizationUnits.Any(x => x.OrganizationUnitId == organizationUnitId.Value))
.LongCountAsync(GetCancellationToken(cancellationToken));
}

2
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<AbpMultiTenancyOptions>(options =>

2
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"));

4
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();
}
}
}
}

5
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<Startup>();

9
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/gulpfile.js

@ -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('./'));
};

2
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"));

5
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<Startup>();

9
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/gulpfile.js

@ -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('./'));
};

5
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) =>
{

8
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();

5
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<Startup>();

2
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", "Русский"));

5
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<Startup>();

9
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/gulpfile.js

@ -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('./'));
};

2
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", "Русский"));

5
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<Startup>();

9
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/gulpfile.js

@ -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('./'));
};

5
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<Startup>();

9
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/gulpfile.js

@ -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('./'));
};

2
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"));

5
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<Startup>();

9
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/gulpfile.js

@ -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('./'));
};

5
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<ConsoleTestAppHostedService>();

3
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs

@ -158,6 +158,7 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host
Configure<AbpLocalizationOptions>(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<AbpMultiTenancyOptions>(options =>

5
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 =>
{

9
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/gulpfile.js

@ -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('./'));
};

6
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs

@ -93,13 +93,14 @@ namespace MyCompanyName.MyProjectName
Configure<AbpLocalizationOptions>(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();
}

5
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<Startup>();

5
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs

@ -103,13 +103,14 @@ namespace MyCompanyName.MyProjectName
Configure<AbpLocalizationOptions>(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<AbpAuditingOptions>(options =>

5
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<Startup>();

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save