diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
index cf6b6a124c..a292da5f9b 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
@@ -199,9 +199,20 @@
"Optional": "Optional",
"CreateArticleLanguageInfo": "The language in which the post is written",
"Enum:ContentSource:2": "Video Post",
+ "VideoPreview": "Video Preview",
+ "VideoPreviewErrorMessage": "Given video url couldn't retrieve from Youtube. This can be caused by either video is private or the given URL is not available.",
"DeleteCoverImage": "Delete Cover Image",
"DeleteCoverImageConfirmationMessage": "Are you sure you want to delete the cover image for \"{0}\"?",
- "DeleteCoverImageSuccessMessage": "Cover image successfully deleted"
+ "DeleteCoverImageSuccessMessage": "Cover image successfully deleted",
+ "PaymentsOf": "Payments of",
+ "ShowPaymentsOfOrganization": "Show payments",
+ "Date": "Date",
+ "Products": "Products",
+ "TotalAmount": "Total amount",
+ "Currency": "Currency",
+ "Gateway": "Gateway",
+ "State": "State",
+ "FailReason": "Fail reason"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
index 5bf922f012..9c1e434ac1 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
@@ -132,6 +132,10 @@
"ChooseYourContentType": "Please choose the way you want to add your content.",
"PostContentViaGithub": "I want to add my article with GitHub in accordance with the markdown rules.",
"PostContentViaYoutube": "I want to share my videos available on Youtube here.",
- "PostContentViaExternalSource": "I want to add the content I published on another platform here."
+ "PostContentViaExternalSource": "I want to add the content I published on another platform here.",
+ "GitHubUserNameValidationMessage": "Your Github username can not include whitespace, please be sure your Github username is correct.",
+ "PersonalSiteUrlValidationMessage": "Your personal site URL can not include whitespace, please be sure your personal site URL is correct.",
+ "TwitterUserNameValidationMessage": "Your Twitter username can not include whitespace, please be sure your Twitter username is correct.",
+ "LinkedinUrlValidationMessage": "Your Linkedin URL can not include whitespace, please be sure your Linkedin URL is correct."
}
}
diff --git a/common.props b/common.props
index f4765e5c7d..593fe92213 100644
--- a/common.props
+++ b/common.props
@@ -1,7 +1,7 @@
- latest
- 4.3.0
+ latest
+ 4.3.0$(NoWarn);CS1591;CS0436https://abp.io/assets/abp_nupkg.pnghttps://abp.io/
diff --git a/docs/en/Application-Services.md b/docs/en/Application-Services.md
index 7fe9825f2a..5d779ec8c9 100644
--- a/docs/en/Application-Services.md
+++ b/docs/en/Application-Services.md
@@ -43,12 +43,14 @@ public class Book : AggregateRoot
{
if (string.IsNullOrWhiteSpace(name))
{
- throw new ArgumentException($"name can not be empty or white space!");
+ throw new ArgumentException(
+ $"name can not be empty or white space!");
}
if (name.Length > MaxNameLength)
{
- throw new ArgumentException($"name can not be longer than {MaxNameLength} chars!");
+ throw new ArgumentException(
+ $"name can not be longer than {MaxNameLength} chars!");
}
return name;
@@ -349,8 +351,9 @@ public class DistrictAppService
protected async override Task GetEntityByIdAsync(DistrictKey id)
{
+ var queryable = await Repository.GetQueryableAsync();
return await AsyncQueryableExecuter.FirstOrDefaultAsync(
- Repository.Where(d => d.CityId == id.CityId && d.Name == id.Name)
+ queryable.Where(d => d.CityId == id.CityId && d.Name == id.Name)
);
}
}
diff --git a/docs/en/AspNet-Boilerplate-Migration-Guide.md b/docs/en/AspNet-Boilerplate-Migration-Guide.md
index f4c2ec712b..52a2fced6a 100644
--- a/docs/en/AspNet-Boilerplate-Migration-Guide.md
+++ b/docs/en/AspNet-Boilerplate-Migration-Guide.md
@@ -184,7 +184,7 @@ public class PersonAppService : ApplicationService, IPersonAppService
}
````
-ABP Framework's repository doesn't have this method. Instead, it implements the `IQueryable` itself. So, you can directly use LINQ on the repository:
+ABP Framework's repository have `GetQueryableAsync` instead:
````csharp
public class PersonAppService : ApplicationService, IPersonAppService
@@ -198,14 +198,15 @@ public class PersonAppService : ApplicationService, IPersonAppService
public async Task DoIt()
{
- var people = await _personRepository
+ var queryable = await _personRepository.GetQueryableAsync();
+ var people = await queryable
.Where(p => p.BirthYear > 2000) //Use LINQ extension methods
.ToListAsync();
}
}
````
-> Note that in order to use the async LINQ extension methods (like `ToListAsync` here), you may need to depend on the database provider (like EF Core) since these methods are defined in the database provider package, they are not standard LINQ methods.
+> Note that in order to use the async LINQ extension methods (like `ToListAsync` here), you may need to depend on the database provider (like EF Core) since these methods are defined in the database provider package, they are not standard LINQ methods. See the [repository document](Repositories.md) for alternative approaches for async query execution.
#### FirstOrDefault(predicate), Single()... Methods
diff --git a/docs/en/Best-Practices/Entity-Framework-Core-Integration.md b/docs/en/Best-Practices/Entity-Framework-Core-Integration.md
index f487f9d61d..04ddeaeba4 100644
--- a/docs/en/Best-Practices/Entity-Framework-Core-Integration.md
+++ b/docs/en/Best-Practices/Entity-Framework-Core-Integration.md
@@ -144,7 +144,7 @@ public virtual async Task FindByNormalizedUserNameAsync(
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
- return await DbSet
+ return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.FirstOrDefaultAsync(
u => u.NormalizedUserName == normalizedUserName,
@@ -175,14 +175,15 @@ public static IQueryable IncludeDetails(
}
````
-* **Do** use the `IncludeDetails` extension method in the repository methods just like used in the example code above (see FindByNormalizedUserNameAsync).
+* **Do** use the `IncludeDetails` extension method in the repository methods just like used in the example code above (see `FindByNormalizedUserNameAsync`).
- **Do** override `WithDetails` method of the repository for aggregates root which have **sub collections**. Example:
````C#
-public override IQueryable WithDetails()
+public override async Task> WithDetailsAsync()
{
- return GetQueryable().IncludeDetails(); // Uses the extension method defined above
+ // Uses the extension method defined above
+ return (await GetQueryableAsync()).IncludeDetails();
}
````
diff --git a/docs/en/Best-Practices/MongoDB-Integration.md b/docs/en/Best-Practices/MongoDB-Integration.md
index 74a0e429f1..90f7871a70 100644
--- a/docs/en/Best-Practices/MongoDB-Integration.md
+++ b/docs/en/Best-Practices/MongoDB-Integration.md
@@ -128,7 +128,7 @@ public async Task FindByNormalizedUserNameAsync(
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
- return await GetMongoQueryable()
+ return await (await GetMongoQueryableAsync())
.FirstOrDefaultAsync(
u => u.NormalizedUserName == normalizedUserName,
GetCancellationToken(cancellationToken)
@@ -139,8 +139,8 @@ public async Task FindByNormalizedUserNameAsync(
`GetCancellationToken` fallbacks to the `ICancellationTokenProvider.Token` to obtain the cancellation token if it is not provided by the caller code.
* **Do** ignore the `includeDetails` parameters for the repository implementation since MongoDB loads the aggregate root as a whole (including sub collections) by default.
-* **Do** use the `GetMongoQueryable()` method to obtain an `IQueryable` to perform queries wherever possible. Because;
- * `GetMongoQueryable()` method automatically uses the `ApplyDataFilters` method to filter the data based on the current data filters (like soft delete and multi-tenancy).
+* **Do** use the `GetMongoQueryableAsync()` method to obtain an `IQueryable` to perform queries wherever possible. Because;
+ * `GetMongoQueryableAsync()` method automatically uses the `ApplyDataFilters` method to filter the data based on the current data filters (like soft delete and multi-tenancy).
* Using `IQueryable` makes the code as much as similar to the EF Core repository implementation and easy to write and read.
* **Do** implement data filtering if it is not possible to use the `GetMongoQueryable()` method.
diff --git a/docs/en/Best-Practices/Repositories.md b/docs/en/Best-Practices/Repositories.md
index c0058df433..4f646a7d94 100644
--- a/docs/en/Best-Practices/Repositories.md
+++ b/docs/en/Best-Practices/Repositories.md
@@ -42,24 +42,6 @@ Task FindByNormalizedUserNameAsync(
);
````
-* **Do** create a **synchronous extension** method for each asynchronous repository method. Example:
-
-````C#
-public static class IdentityUserRepositoryExtensions
-{
- public static IdentityUser FindByNormalizedUserName(
- this IIdentityUserRepository repository,
- [NotNull] string normalizedUserName)
- {
- return AsyncHelper.RunSync(
- () => repository.FindByNormalizedUserNameAsync(normalizedUserName)
- );
- }
-}
-````
-
-This will allow synchronous code to use the repository methods easier.
-
* **Do** add an optional `bool includeDetails = true` parameter (default value is `true`) for every repository method which returns a **single entity**. Example:
````C#
diff --git a/docs/en/Blog-Posts/2021-01-28 v4_2_Release_Stable/POST.md b/docs/en/Blog-Posts/2021-01-28 v4_2_Release_Stable/POST.md
new file mode 100644
index 0000000000..fac8484411
--- /dev/null
+++ b/docs/en/Blog-Posts/2021-01-28 v4_2_Release_Stable/POST.md
@@ -0,0 +1,53 @@
+# ABP.IO Platform 4.2 Final Has Been Released!
+
+[ABP Framework](https://abp.io/) and [ABP Commercial](https://commercial.abp.io/) 4.2 versions have been released today.
+
+## What's New With 4.2?
+
+Since all the new features are already explained in details with the [4.2 RC Announcement Post](https://blog.abp.io/abp/ABP-IO-Platform-v4-2-RC-Has-Been-Released), I will not repeat all the details again. See the [RC Blog Post](https://blog.abp.io/abp/ABP-IO-Platform-v4-2-RC-Has-Been-Released) for all the features and enhancements.
+
+## Creating New Solutions
+
+You can create a new solution with the ABP Framework version 4.2 by either using the `abp new` command or using the **direct download** tab on the [get started page](https://abp.io/get-started).
+
+> See the [getting started document](https://docs.abp.io/en/abp/latest/Getting-Started) for details.
+
+## 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.
+
+## Migration Guide
+
+Check [the migration guide](https://docs.abp.io/en/abp/latest/Migration-Guides/Abp-4_2) for the applications with the version 4.x upgrading to the version 4.2.
+
+> It is strongly recommended to check the migration guide for this version. Especially, the new `IRepository.GetQueryableAsync()` method is a core change should be considered after upgrading the solution.
+
+## About the Next Version
+
+The next feature version will be 4.3. It is planned to release the 4.3 RC (Release Candidate) on March 11 and the final version on March 25, 2021.
+
+We decided to slow down the feature development for the [next milestone](https://github.com/abpframework/abp/milestone/49). We will continue to improve the existing features and introduce new ones, sure, but wanted to have more time for the planning, documentation, creating guides and improving the development experience.
\ No newline at end of file
diff --git a/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/POST.md b/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/POST.md
new file mode 100644
index 0000000000..f30f31d541
--- /dev/null
+++ b/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/POST.md
@@ -0,0 +1,103 @@
+## Using MatBlazor UI Components With the ABP Framework
+
+Hi, in this step by step article, I will show you how to integrate [MatBlazor](https://www.matblazor.com/), a blazor UI components into ABP Framework-based applications.
+
+
+
+*(A screenshot from the example application developed in this article)*
+
+## Create the Project
+
+> First thing is to create the project. ABP Framework offers startup templates to get into business faster.
+
+In this article, I will create a new startup template with EF Core as a database provider and Blazor for UI framework. But if you already have a project with Blazor UI, you don't need to create a new startup template, you can directly implement the following steps to your existing project.
+
+> If you already have a project with the Blazor UI, you can skip this section.
+
+* Before starting the development, we will create a new solution named `MatBlazorSample` (or whatever you want). We will create a new startup template with EF Core as a database provider and Blazor for UI framework by using [ABP CLI](https://docs.abp.io/en/abp/latest/CLI):
+
+````bash
+abp new MatBlazorSample -u blazor
+````
+
+This will create new project inside of `aspnet-core`, so:
+
+````bash
+cd aspnet-core
+````
+
+and
+
+````bash
+dotnet restore
+````
+
+* Our project boilerplate will be ready after the download is finished. Then, we can open the solution in the Visual Studio (or any other IDE) and run the `MatBlazorSample.DbMigrator` to create the database and seed initial data (which creates the admin user, admin role, permissions etc.)
+
+
+
+* After database and initial data created,
+* Run the `MatBlazorSample.HttpApi.Host` to see our server side working and
+* Run the `MatBlazorSample.Blazor` to see our UI working properly.
+
+> _Default login credentials for admin: username is **admin** and password is **1q2w3E\***_
+
+## Install MatBlazor
+
+You can follow [this documentation](https://www.matblazor.com/) to install MatBlazor packages into your computer.
+
+### Adding MatBlazor NuGet Packages
+
+```bash
+Install-Package MatBlazor
+```
+
+### Register MatBlazor Resources
+
+1. Add the following line to the HEAD section of the `wwwroot/index.html` file within the `MatBlazorSample.Blazor` project:
+
+ ```Razor
+
+
+
+
+
+ ```
+
+2. In the `MatBlazorSampleBlazorModule` class, call the `AddMatBlazor()` method from your project's `ConfigureServices()` method:
+
+ ```csharp
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ var environment = context.Services.GetSingletonInstance();
+ var builder = context.Services.GetSingletonInstance();
+ // ...
+ builder.Services.AddMatBlazor();
+ }
+ ```
+
+3. Register the **MatBlazorSample.Blazor** namespace in the `_Imports.razor` file:
+
+ ```Razor
+ @using MatBlazor
+ ```
+
+## The Sample Application
+
+We have created a sample application with [Table](https://www.matblazor.com/Table) example.
+
+### The Source Code
+
+You can download the source code from [here](https://github.com/abpframework/abp-samples/tree/master/MatBlazorSample).
+
+The related files for this example are marked in the following screenshots.
+
+
+
+
+
+
+
+## Conclusion
+
+In this article, I've explained how to use [MatBlazor](https://www.matblazor.com/) components in your application. ABP Framework is designed so that it can work with any UI library/framework.
\ No newline at end of file
diff --git a/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/example-result.png b/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/example-result.png
new file mode 100644
index 0000000000..89a2fecdce
Binary files /dev/null and b/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/example-result.png differ
diff --git a/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/initial-project.png b/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/initial-project.png
new file mode 100644
index 0000000000..85e71d5692
Binary files /dev/null and b/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/initial-project.png differ
diff --git a/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/table-app-contract.png b/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/table-app-contract.png
new file mode 100644
index 0000000000..8108cdc606
Binary files /dev/null and b/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/table-app-contract.png differ
diff --git a/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/table-application.png b/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/table-application.png
new file mode 100644
index 0000000000..7f07af97e1
Binary files /dev/null and b/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/table-application.png differ
diff --git a/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/table-web.png b/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/table-web.png
new file mode 100644
index 0000000000..0034aec095
Binary files /dev/null and b/docs/en/Community-Articles/2021-01-20-How-to-Integrate-the-MatBlazor-Blazor-Component/table-web.png differ
diff --git a/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/POST.md b/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/POST.md
new file mode 100644
index 0000000000..7a854291d5
--- /dev/null
+++ b/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/POST.md
@@ -0,0 +1,343 @@
+# How to Use PrimeNG Components with the ABP Angular UI
+
+## Introduction
+
+In this article, we will use components of the [PrimeNG](https://www.primefaces.org/primeng/) that is a popular UI component library for Angular with the ABP Framework Angular UI that will be generated via [ABP CLI](https://docs.abp.io/en/abp/latest/CLI).
+
+We will create an organization units page and use PrimeNG's [OrganizationChart](https://primefaces.org/primeng/showcase/#/organizationchart) and [Table](https://primefaces.org/primeng/showcase/#/table) components on the page.
+
+
+
+The UI shown above contains many PrimeNG components. You can reach the source code of this rich UI. Take a look at the source code section below.
+
+> This article does not cover any backend code. I used mock data to provide data source to the components.
+
+## Pre-Requirements
+
+The following tools should be installed on your development machine:
+
+* [.NET Core 5.0+](https://www.microsoft.com/net/download/dotnet-core/)
+* [Node v12 or v14](https://nodejs.org/)
+* [VS Code](https://code.visualstudio.com/) or another IDE
+
+## Source Code
+
+I have prepared a sample project that contains more PrimeNG components than described in this article. You can download the source code [on GitHub](https://github.com/abpframework/abp-samples/tree/master/PrimengSample).
+
+## Creating a New Solution
+
+In this step, we will create a new solution that contains Angular UI and backend startup templates. If you have a startup template with Angular UI, you can skip this step.
+
+Run the following command to install the ABP CLI:
+
+```bash
+dotnet tool install -g Volo.Abp.Cli
+```
+
+...or update:
+
+```bash
+dotnet tool update -g Volo.Abp.Cli
+```
+
+Create a new solution named `AbpPrimengSample` by running the following command:
+
+```bash
+abp new AbpPrimengSample -u angular -csf
+```
+
+See the [ABP CLI documentation](https://docs.abp.io/en/abp/latest/CLI) for all available options.
+
+You can also use the Direct Download tab on the [Get Started](https://abp.io/get-started) page.
+
+## Running the Solution
+
+You can run the solution as described in [here](https://docs.abp.io/en/abp/latest/Getting-Started-Running-Solution?UI=NG&DB=EF&Tiered=No).
+
+## PrimeNG Setup
+
+Open the `angular` folder and run the following command to install packages:
+
+```bash
+npm install
+```
+
+Next, we need to install `primeng` and required packages (`primeicons` and `@angular/cdk`) for the library. Run the command below to install these packages:
+
+```bash
+npm install primeng primeicons @angular/cdk --save
+```
+
+The packages we have installed;
+
+ - `primeng` is the main package that is a component library.
+ - `primeicons` is an icon font library. Many PrimeNG components use this font internally.
+ - `@angular/cdk` is a component dev kit created by the Angular team. Some PrimeNG modules depend on it.
+
+As the last step of the setup, we should add the required style files for the library to `angular.json`:
+
+```js
+//angular.json
+
+"projects": {
+ "AbpPrimengSample": {
+ //...
+ "styles": {
+ "node_modules/primeicons/primeicons.css",
+ "node_modules/primeng/resources/themes/saga-blue/theme.css",
+ "node_modules/primeng/resources/primeng.min.css",
+ //...other styles
+ }
+ }
+}
+```
+
+We have added the `primeng.min.css`, Saga Blue theme's `theme.css`, and `primeicons.css` files to the project. You can choose another theme instead of the Sage Blue. See available themes on the [Get Started](https://www.primefaces.org/primeng/showcase/#/setup) document of the PrimeNG.
+
+
+> You have to restart the running `ng serve` process to see the effect of the changes you made in the `angular.json`.
+
+
+## Creating the Organization Units Page
+
+Run the following command to create a new module named `OrganizationUnits`:
+
+```bash
+npm run ng -- generate module organization-units --route organization-units --module app.module
+```
+
+Then open the `src/route.provider.ts` and add a new route as an array element to add a navigation link labeled "Organization Units" to the menu:
+
+```js
+//route.provider.ts
+
+import { eThemeSharedRouteNames } from '@abp/ng.theme.shared';
+//...
+
+routesService.add([
+ //...
+ {
+ path: '/organization-units',
+ name: 'Organization Units',
+ parentName: eThemeSharedRouteNames.Administration,
+ iconClass: 'fas fa-sitemap',
+ layout: eLayoutType.application,
+ },
+]);
+```
+
+We have created a lazy-loadable module and defined a menu navigation link. We can navigate to the page as shown below:
+
+
+
+## Using the PrimeNG Components
+
+### Implementing the Organization Chart Component
+
+When you would like to use any component from PrimeNG, you have to import the component's module to your module. Since we will use the `OrganizationChart` on the organization units page, we need to import `OrganizationChartModule` into `OrganizationUnitsModule`.
+
+Open the `src/organization-units/organization-units.module.ts` and add the `OrganizationChartModule` to the imports array as shown below:
+
+```js
+import { OrganizationChartModule } from 'primeng/organizationchart';
+//...
+
+@NgModule({
+ //...
+ imports: [
+ //...
+ OrganizationChartModule
+ ],
+})
+export class OrganizationUnitsModule {}
+```
+
+> Since NGCC need to work in some cases, restarting the `ng serve` process would be good when you import any modules from `primeng` package to your module.
+
+Let's define a mock data source for the `OrganizationChartComponent` and add the component to the page.
+
+Open the `src/organization-units/organization-units.component.ts` and add two variables as shown below:
+
+```js
+//...
+import { TreeNode } from 'primeng/api';
+
+@Component(/* component metadata*/)
+export class OrganizationUnitsComponent implements OnInit {
+ //...
+
+ organizationUnits: TreeNode[] = [
+ {
+ label: 'Management',
+ expanded: true,
+ children: [
+ {
+ label: 'Selling',
+ expanded: true,
+ children: [
+ {
+ label: 'Customer Relations',
+ },
+ {
+ label: 'Marketing',
+ },
+ ],
+ },
+ {
+ label: 'Supporting',
+ expanded: true,
+ children: [
+ {
+ label: 'Buying',
+ },
+ {
+ label: 'Human Resources',
+ },
+ ],
+ },
+ ],
+ },
+ ];
+
+ selectedUnit: TreeNode;
+```
+
+- First variable is `organizationUnits`. It provides mock data source to `OrganizationChartComponent`.
+- Second variable is `selectedUnit`. It keeps chosen unit on the chart.
+
+Then, open the `src/organization-units/organization-units.component.html` and replace the file content with the following:
+
+```html
+
+
+
Organization Units
+
+
+
+
+
+```
+
+We have implemented the `OrganizationChart`. The final UI looks like below:
+
+
+
+## Implementing the Table Component
+
+In order to use the `TableComponent`, we have to import the `TableModule` to the `OrganizationUnitsModule`.
+
+Open the `organization-units.module.ts` and add `TableModule` to the imports array as shown below:
+
+```js
+import { TableModule } from 'primeng/table';
+//...
+
+@NgModule({
+ //...
+ imports: [
+ //...
+ TableModule
+ ],
+})
+export class OrganizationUnitsModule {}
+```
+
+Open the `organization-units.component.ts` and add a variable named `members` with initial value and add a getter named `tableData` as shown below:
+
+```js
+//...
+export class OrganizationUnitsComponent implements OnInit {
+ //...
+
+ members = [
+ {
+ fullName: 'John Doe',
+ username: 'John.Doe',
+ phone: '+1-202-555-0125',
+ email: 'john.doe@example.com',
+ parent: 'Customer Relations',
+ },
+ {
+ fullName: 'Darrion Walter',
+ username: 'Darrion.Walter',
+ phone: '+1-262-155-0355',
+ email: 'Darrion_Walter@example.com',
+ parent: 'Marketing',
+ },
+ {
+ fullName: 'Rosa Labadie',
+ username: 'Rosa.Labadie',
+ phone: '+1-262-723-2255',
+ email: 'Rosa.Labadie@example.com',
+ parent: 'Marketing',
+ },
+ {
+ fullName: 'Adelle Hills',
+ username: 'Adelle.Hills',
+ phone: '+1-491-112-9011',
+ email: 'Adelle.Hills@example.com',
+ parent: 'Buying',
+ },
+ {
+ fullName: 'Brian Hane',
+ username: 'Brian.Hane',
+ phone: '+1-772-509-1823',
+ email: 'Brian.Hane@example.com',
+ parent: 'Human Resources',
+ },
+ ];
+
+ get tableData() {
+ return this.members.filter(user => user.parent === this.selectedUnit.label);
+ }
+```
+
+What we have done above?
+
+- We defined a variable named `members` to provide mock data to the table.
+- We have defined a getter named `tableData` to provide filtered data source to the table using `members` variable.
+
+We are now ready to add the table to the HTML template.
+
+Open the `organization-units.component.html`, find the `p-organizationChart` tag and place the following code to the bottom of this tag:
+
+```html
+
+
Members of {{ selectedUnit.label }}
+
+
+
+
+
Name
+
Username
+
Email
+
Phone
+
+
+
+
+
{{ member.fullName }}
+
{{ member.username }}
+
{{ member.email }}
+
{{ member.phone }}
+
+
+
+
+```
+
+We have added a new `div` that contains the `TableComponent`. The table appears when an organization unit is selected.
+The table contains 4 columns which are name, username, email, and phone for displaying the members' information.
+
+After adding the table, the final UI looks like this:
+
+
+
+
+## Conclusion
+
+We have implemented the PrimeNG component library on the ABP Angular UI project and used two components on a page in a short time. You can use any PrimeNG components by following the documentation. The ABP Angular UI will not block you in any case.
diff --git a/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/intro.gif b/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/intro.gif
new file mode 100644
index 0000000000..5f96a65422
Binary files /dev/null and b/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/intro.gif differ
diff --git a/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/organization-chart.jpg b/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/organization-chart.jpg
new file mode 100644
index 0000000000..9d18f35ba1
Binary files /dev/null and b/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/organization-chart.jpg differ
diff --git a/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/organization-units-menu-item.jpg b/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/organization-units-menu-item.jpg
new file mode 100644
index 0000000000..dc6111f553
Binary files /dev/null and b/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/organization-units-menu-item.jpg differ
diff --git a/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/table.gif b/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/table.gif
new file mode 100644
index 0000000000..d27dcb26bd
Binary files /dev/null and b/docs/en/Community-Articles/2021-01-20-How-to-Use-PrimeNG-Components-with-the-ABP-Angular-UI/table.gif differ
diff --git a/docs/en/Dependency-Injection.md b/docs/en/Dependency-Injection.md
index 335e829461..f94901ad84 100644
--- a/docs/en/Dependency-Injection.md
+++ b/docs/en/Dependency-Injection.md
@@ -1,6 +1,6 @@
# Dependency Injection
-ABP's Dependency Injection system is developed based on Microsoft's [dependency injection extension](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) library (Microsoft.Extensions.DependencyInjection nuget package). So, it's documentation is valid in ABP too.
+ABP's Dependency Injection system is developed based on Microsoft's [dependency injection extension](https://medium.com/volosoft/asp-net-core-dependency-injection-best-practices-tips-tricks-c6e9c67f9d96) library (Microsoft.Extensions.DependencyInjection nuget package). So, it's documentation is valid in ABP too.
> While ABP has no core dependency to any 3rd-party DI provider, it's required to use a provider that supports dynamic proxying and some other advanced features to make some ABP features properly work. Startup templates come with Autofac installed. See [Autofac integration](Autofac-Integration.md) document for more information.
diff --git a/docs/en/Domain-Driven-Design-Implementation-Guide.md b/docs/en/Domain-Driven-Design-Implementation-Guide.md
index 9341df703b..cf2ce6bf14 100644
--- a/docs/en/Domain-Driven-Design-Implementation-Guide.md
+++ b/docs/en/Domain-Driven-Design-Implementation-Guide.md
@@ -754,7 +754,8 @@ namespace IssueTracking.Issues
{
var daysAgo30 = DateTime.Now.Subtract(TimeSpan.FromDays(30));
- return await DbSet.Where(i =>
+ var dbSet = await GetDbSetAsync();
+ return await dbSet.Where(i =>
//Open
!i.IsClosed &&
@@ -906,7 +907,8 @@ public class EfCoreIssueRepository :
public async Task> GetIssuesAsync(ISpecification spec)
{
- return await DbSet
+ var dbSet = await GetDbSetAsync();
+ return await dbSet
.Where(spec.ToExpression())
.ToListAsync();
}
@@ -952,8 +954,9 @@ public class IssueAppService : ApplicationService, IIssueAppService
public async Task DoItAsync()
{
+ var queryable = await _issueRepository.GetQueryableAsync();
var issues = AsyncExecuter.ToListAsync(
- _issueRepository.Where(new InActiveIssueSpecification())
+ queryable.Where(new InActiveIssueSpecification())
);
}
}
@@ -996,8 +999,9 @@ public class IssueAppService : ApplicationService, IIssueAppService
public async Task DoItAsync(Guid milestoneId)
{
+ var queryable = await _issueRepository.GetQueryableAsync();
var issues = AsyncExecuter.ToListAsync(
- _issueRepository
+ queryable
.Where(
new InActiveIssueSpecification()
.And(new MilestoneSpecification(milestoneId))
diff --git a/docs/en/Entity-Framework-Core.md b/docs/en/Entity-Framework-Core.md
index b2b216397a..a2c0e79996 100644
--- a/docs/en/Entity-Framework-Core.md
+++ b/docs/en/Entity-Framework-Core.md
@@ -236,7 +236,8 @@ public class BookRepository
public async Task DeleteBooksByType(BookType type)
{
- await DbContext.Database.ExecuteSqlRawAsync(
+ var dbContext = await GetDbContextAsync();
+ await dbContext.Database.ExecuteSqlRawAsync(
$"DELETE FROM Books WHERE Type = {(int)type}"
);
}
@@ -344,7 +345,7 @@ You have different options when you want to load the related entities while quer
#### Repository.WithDetails
-`IRepository.WithDetails(...)` can be used to include one relation collection/property to the query.
+`IRepository.WithDetailsAsync(...)` can be used to get an `IQueryable` by including one relation collection/property.
**Example: Get an order with lines**
@@ -355,7 +356,7 @@ using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Domain.Services;
-namespace MyCrm
+namespace AbpDemo.Orders
{
public class OrderManager : DomainService
{
@@ -368,35 +369,39 @@ namespace MyCrm
public async Task TestWithDetails(Guid id)
{
- var query = _orderRepository
- .WithDetails(x => x.Lines)
- .Where(x => x.Id == id);
-
+ //Get a IQueryable by including sub collections
+ var queryable = await _orderRepository.WithDetailsAsync(x => x.Lines);
+
+ //Apply additional LINQ extension methods
+ var query = queryable.Where(x => x.Id == id);
+
+ //Execute the query and get the result
var order = await AsyncExecuter.FirstOrDefaultAsync(query);
}
}
}
````
-> `AsyncExecuter` is used to execute async LINQ extensions without depending on the EF Core. If you add EF Core NuGet package reference to your project, then you can directly use `await _orderRepository.WithDetails(x => x.Lines).FirstOrDefaultAsync()`. But, this time you depend on the EF Core in your domain layer. See the [repository document](Repositories.md) to learn more.
+> `AsyncExecuter` is used to execute async LINQ extensions without depending on the EF Core. If you add EF Core NuGet package reference to your project, then you can directly use `await query.FirstOrDefaultAsync()`. But, this time you depend on the EF Core in your domain layer. See the [repository document](Repositories.md) to learn more.
**Example: Get a list of orders with their lines**
````csharp
public async Task TestWithDetails()
{
- var query = _orderRepository
- .WithDetails(x => x.Lines);
+ //Get a IQueryable by including sub collections
+ var queryable = await _orderRepository.WithDetailsAsync(x => x.Lines);
- var orders = await AsyncExecuter.ToListAsync(query);
+ //Execute the query and get the result
+ var orders = await AsyncExecuter.ToListAsync(queryable);
}
````
-> `WithDetails` method can get more than one expression parameter if you need to include more than one navigation property or collection.
+> `WithDetailsAsync` method can get more than one expression parameter if you need to include more than one navigation property or collection.
#### DefaultWithDetailsFunc
-If you don't pass any expression to the `WithDetails` method, then it includes all the details using the `DefaultWithDetailsFunc` option you provide.
+If you don't pass any expression to the `WithDetailsAsync` method, then it includes all the details using the `DefaultWithDetailsFunc` option you provide.
You can configure `DefaultWithDetailsFunc` for an entity in the `ConfigureServices` method of your [module](Module-Development-Basics.md) in your `EntityFrameworkCore` project.
@@ -419,12 +424,15 @@ Then you can use the `WithDetails` without any parameter:
````csharp
public async Task TestWithDetails()
{
- var query = _orderRepository.WithDetails();
- var orders = await AsyncExecuter.ToListAsync(query);
+ //Get a IQueryable by including all sub collections
+ var queryable = await _orderRepository.WithDetailsAsync();
+
+ //Execute the query and get the result
+ var orders = await AsyncExecuter.ToListAsync(queryable);
}
````
-`WithDetails()` executes the expression you've setup as the `DefaultWithDetailsFunc`.
+`WithDetailsAsync()` executes the expression you've setup as the `DefaultWithDetailsFunc`.
#### Repository Get/Find Methods
@@ -466,7 +474,7 @@ public async Task TestWithDetails()
#### Alternatives
-The repository patters tries to encapsulate the EF Core, so your options are limited. If you need an advanced scenario, you can follow one of the options;
+The repository pattern tries to encapsulate the EF Core, so your options are limited. If you need an advanced scenario, you can follow one of the options;
* Create a custom repository method and use the complete EF Core API.
* Reference to the `Volo.Abp.EntityFrameworkCore` package from your project. In this way, you can directly use `Include` and `ThenInclude` in your code.
@@ -550,24 +558,15 @@ See also [lazy loading document](https://docs.microsoft.com/en-us/ef/core/queryi
In most cases, you want to hide EF Core APIs behind a repository (this is the main purpose of the repository pattern). However, if you want to access the `DbContext` instance over the repository, you can use `GetDbContext()` or `GetDbSet()` extension methods. Example:
````csharp
-public class BookService
+public async Task TestAsync()
{
- private readonly IRepository _bookRepository;
-
- public BookService(IRepository bookRepository)
- {
- _bookRepository = bookRepository;
- }
-
- public void Foo()
- {
- DbContext dbContext = _bookRepository.GetDbContext();
- DbSet books = _bookRepository.GetDbSet();
- }
+ var dbContext = await _orderRepository.GetDbContextAsync();
+ var dbSet = await _orderRepository.GetDbSetAsync();
+ //var dbSet = dbContext.Set(); //Alternative, when you have the DbContext
}
````
-* `GetDbContext` returns a `DbContext` reference instead of `BookStoreDbContext`. You can cast it, however in most cases you don't need it.
+* `GetDbContextAsync` returns a `DbContext` reference instead of `BookStoreDbContext`. You can cast it if you need. However, you don't need it in most cases.
> Important: You must reference to the `Volo.Abp.EntityFrameworkCore` package from the project you want to access to the `DbContext`. This breaks encapsulation, but this is what you want in that case.
@@ -742,32 +741,36 @@ If you have better logic or using an external library for bulk operations, you c
- You may use example template below:
```csharp
-public class MyCustomEfCoreBulkOperationProvider : IEfCoreBulkOperationProvider, ITransientDependency
-{
- public async Task DeleteManyAsync(IEfCoreRepository repository,
- IEnumerable entities,
- bool autoSave,
- CancellationToken cancellationToken)
+public class MyCustomEfCoreBulkOperationProvider
+ : IEfCoreBulkOperationProvider, ITransientDependency
+{
+ public async Task DeleteManyAsync(
+ IEfCoreRepository repository,
+ IEnumerable entities,
+ bool autoSave,
+ CancellationToken cancellationToken)
where TDbContext : IEfCoreDbContext
where TEntity : class, IEntity
{
// Your logic here.
}
- public async Task InsertManyAsync(IEfCoreRepository repository,
- IEnumerable entities,
- bool autoSave,
- CancellationToken cancellationToken)
+ public async Task InsertManyAsync(
+ IEfCoreRepository repository,
+ IEnumerable entities,
+ bool autoSave,
+ CancellationToken cancellationToken)
where TDbContext : IEfCoreDbContext
where TEntity : class, IEntity
{
// Your logic here.
}
- public async Task UpdateManyAsync(IEfCoreRepository repository,
- IEnumerable entities,
- bool autoSave,
- CancellationToken cancellationToken)
+ public async Task UpdateManyAsync(
+ IEfCoreRepository repository,
+ IEnumerable entities,
+ bool autoSave,
+ CancellationToken cancellationToken)
where TDbContext : IEfCoreDbContext
where TEntity : class, IEntity
{
@@ -779,3 +782,4 @@ public class MyCustomEfCoreBulkOperationProvider : IEfCoreBulkOperationProvider,
## See Also
* [Entities](Entities.md)
+* [Repositories](Repositories.md)
diff --git a/docs/en/Migration-Guides/Abp-4_2.md b/docs/en/Migration-Guides/Abp-4_2.md
new file mode 100644
index 0000000000..084ae24caa
--- /dev/null
+++ b/docs/en/Migration-Guides/Abp-4_2.md
@@ -0,0 +1,101 @@
+# ABP version 4.2 Migration Guide
+
+This version has no breaking changes but there is an important change on the repositories that should be applied for your application for an important performance and scalability gain.
+
+## IRepository.GetQueryableAsync
+
+`IRepository` interface inherits `IQueryable`, so you can directly use the standard LINQ extension methods, like `Where`, `OrderBy`, `First`, `Sum`... etc.
+
+**Example: Using LINQ directly over the repository object**
+
+````csharp
+public class BookAppService : ApplicationService, IBookAppService
+{
+ private readonly IRepository _bookRepository;
+
+ public BookAppService(IRepository bookRepository)
+ {
+ _bookRepository = bookRepository;
+ }
+
+ public async Task DoItInOldWayAsync()
+ {
+ //Apply any standard LINQ extension method
+ var query = _bookRepository
+ .Where(x => x.Price > 10)
+ .OrderBy(x => x.Name);
+
+ //Execute the query asynchronously
+ var books = await AsyncExecuter.ToListAsync(query);
+ }
+}
+````
+
+*See [the documentation](https://docs.abp.io/en/abp/4.2/Repositories#iqueryable-async-operations) if you wonder what is the `AsyncExecuter`.*
+
+**Beginning from the version 4.2, the recommended way is using `IRepository.GetQueryableAsync()` to obtain an `IQueryable`, then use the LINQ extension methods over it.**
+
+**Example: Using the new GetQueryableAsync method**
+
+````csharp
+public async Task DoItInNewWayAsync()
+{
+ //Use GetQueryableAsync to obtain the IQueryable first
+ var queryable = await _bookRepository.GetQueryableAsync();
+
+ //Then apply any standard LINQ extension method
+ var query = queryable
+ .Where(x => x.Price > 10)
+ .OrderBy(x => x.Name);
+
+ //Finally, execute the query asynchronously
+ var books = await AsyncExecuter.ToListAsync(query);
+}
+````
+
+ABP may start a database transaction when you get an `IQueryable` (If current [Unit Of Work](https://docs.abp.io/en/abp/latest/Unit-Of-Work) is transactional). In this new way, it is possible to **start the database transaction in an asynchronous way**. Previously, we could not get the advantage of asynchronous while starting the transactions.
+
+> **The new way has a significant performance and scalability gain. The old usage (directly using LINQ over the repositories) will be removed in the next major version (5.0).** You have a lot of time for the change, but we recommend to immediately take the action since the old usage has a big **scalability problem**.
+
+### Actions to Take
+
+* Use the repository's queryable feature as explained before.
+* If you've overridden `CreateFilteredQuery` in a class derived from `CrudAppService`, you should override the `CreateFilteredQueryAsync` instead and remove the `CreateFilteredQuery` in your class.
+* If you've overridden `WithDetails` in your custom repositories, remove it and override `WithDetailsAsync` instead.
+* If you've used `DbContext` or `DbSet` properties in your custom repositories, use `GetDbContextAsync()` and `GetDbSetAsync()` methods instead of them.
+
+You can re-build your solution and check the `Obsolete` warnings to find some of the usages need to change.
+
+#### About IRepository Async Extension Methods
+
+Using IRepository Async Extension Methods has no such a problem. The examples below are pretty fine:
+
+````csharp
+var countAll = await _personRepository
+ .CountAsync();
+
+var count = await _personRepository
+ .CountAsync(x => x.Name.StartsWith("A"));
+
+var book1984 = await _bookRepository
+ .FirstOrDefaultAsync(x => x.Name == "John");
+````
+
+See the [repository documentation](https://docs.abp.io/en/abp/4.2/Repositories#iqueryable-async-operations) to understand the relation between `IQueryable` and asynchronous operations.
+
+## .NET Package Upgrades
+
+ABP uses the latest 5.0.* .NET packages. If your application is using 5.0.0 packages, you may get an error on build. We recommend to depend on the .NET packages like `5.0.*` in the `.csproj` files to use the latest patch versions.
+
+Example:
+
+````xml
+
+````
+
+## Blazorise Library Upgrade
+
+If you are upgrading to 4.2, you also need also upgrade the following packages in your Blazor application;
+
+* `Blazorise.Bootstrap` to `0.9.3-preview6`
+* `Blazorise.Icons.FontAwesome` to `0.9.3-preview6`
\ No newline at end of file
diff --git a/docs/en/Migration-Guides/Index.md b/docs/en/Migration-Guides/Index.md
index 5973ee0a0d..26fe825f50 100644
--- a/docs/en/Migration-Guides/Index.md
+++ b/docs/en/Migration-Guides/Index.md
@@ -1,5 +1,6 @@
# ABP Framework Migration Guides
-* [3.3.x to 4.0 Migration Guide](Abp-4_0.md)
-* [2.9.x to 3.0 Migration Guide](../UI/Angular/Migration-Guide-v3.md)
+* [4.x to 4.2](Abp-4_2.md)
+* [3.3.x to 4.0](Abp-4_0.md)
+* [2.9.x to 3.0](../UI/Angular/Migration-Guide-v3.md)
diff --git a/docs/en/MongoDB.md b/docs/en/MongoDB.md
index 7fae9c3892..a12d216b3d 100644
--- a/docs/en/MongoDB.md
+++ b/docs/en/MongoDB.md
@@ -149,7 +149,7 @@ public class Book : AggregateRoot
}
```
-(`BookType` is a simple enum here) And you want to create a new `Book` entity in a [domain service](Domain-Services.md):
+(`BookType` is a simple `enum` here) And you want to create a new `Book` entity in a [domain service](Domain-Services.md):
```csharp
public class BookManager : DomainService
@@ -215,7 +215,8 @@ public class BookRepository :
BookType type,
CancellationToken cancellationToken = default(CancellationToken))
{
- await Collection.DeleteManyAsync(
+ var collection = await GetCollectionAsync(cancellationToken);
+ await collection.DeleteManyAsync(
Builders.Filter.Eq(b => b.Type, type),
cancellationToken
);
@@ -253,7 +254,7 @@ public async override Task DeleteAsync(
### Access to the MongoDB API
-In most cases, you want to hide MongoDB APIs behind a repository (this is the main purpose of the repository). However, if you want to access the MongoDB API over the repository, you can use `GetDatabase()` or `GetCollection()` extension methods. Example:
+In most cases, you want to hide MongoDB APIs behind a repository (this is the main purpose of the repository). However, if you want to access the MongoDB API over the repository, you can use `GetDatabaseAsync()`, `GetCollectionAsync()` or `GetAggregateAsync()` extension methods. Example:
```csharp
public class BookService
@@ -265,10 +266,11 @@ public class BookService
_bookRepository = bookRepository;
}
- public void Foo()
+ public async Task FooAsync()
{
- IMongoDatabase database = _bookRepository.GetDatabase();
- IMongoCollection books = _bookRepository.GetCollection();
+ IMongoDatabase database = await _bookRepository.GetDatabaseAsync();
+ IMongoCollection books = await _bookRepository.GetCollectionAsync();
+ IAggregateFluent bookAggregate = await _bookRepository.GetAggregateAsync();
}
}
```
@@ -390,36 +392,45 @@ If you have better logic or using an external library for bulk operations, you c
- You may use example template below:
```csharp
-public class MyCustomMongoDbBulkOperationProvider : IMongoDbBulkOperationProvider, ITransientDependency
+public class MyCustomMongoDbBulkOperationProvider
+ : IMongoDbBulkOperationProvider, ITransientDependency
{
- public async Task DeleteManyAsync(IMongoDbRepository repository,
- IEnumerable entities,
- IClientSessionHandle sessionHandle,
- bool autoSave,
- CancellationToken cancellationToken)
+ public async Task DeleteManyAsync(
+ IMongoDbRepository repository,
+ IEnumerable entities,
+ IClientSessionHandle sessionHandle,
+ bool autoSave,
+ CancellationToken cancellationToken)
where TEntity : class, IEntity
{
// Your logic here.
}
- public async Task InsertManyAsync(IMongoDbRepository repository,
- IEnumerable entities,
- IClientSessionHandle sessionHandle,
- bool autoSave,
- CancellationToken cancellationToken)
+ public async Task InsertManyAsync(
+ IMongoDbRepository repository,
+ IEnumerable entities,
+ IClientSessionHandle sessionHandle,
+ bool autoSave,
+ CancellationToken cancellationToken)
where TEntity : class, IEntity
{
// Your logic here.
}
- public async Task UpdateManyAsync(IMongoDbRepository repository,
- IEnumerable entities,
- IClientSessionHandle sessionHandle,
- bool autoSave,
- CancellationToken cancellationToken)
+ public async Task UpdateManyAsync(
+ IMongoDbRepository repository,
+ IEnumerable entities,
+ IClientSessionHandle sessionHandle,
+ bool autoSave,
+ CancellationToken cancellationToken)
where TEntity : class, IEntity
{
// Your logic here.
}
}
-```
\ No newline at end of file
+```
+
+## See Also
+
+* [Entities](Entities.md)
+* [Repositories](Repositories.md)
\ No newline at end of file
diff --git a/docs/en/Repositories.md b/docs/en/Repositories.md
index a2eb385094..3d0ea84821 100644
--- a/docs/en/Repositories.md
+++ b/docs/en/Repositories.md
@@ -222,7 +222,8 @@ public class PersonRepository : EfCoreRepository, IPe
public async Task FindByNameAsync(string name)
{
- return await DbContext.Set()
+ var dbSet = await GetDbSetAsync();
+ return await dbSet.Set()
.Where(p => p.Name == name)
.FirstOrDefaultAsync();
}
@@ -235,12 +236,13 @@ You can directly access the data access provider (`DbContext` in this case) to p
## IQueryable & Async Operations
-`IRepository` inherits from `IQueryable`, that means you can **directly use LINQ extension methods** on it, as shown in the example of the "*Generic Repositories*" section above.
+`IRepository` provides `GetQueryableAsync()` to obtain an `IQueryable`, that means you can **directly use LINQ extension methods** on it, as shown in the example of the "*Querying / LINQ over the Repositories*" section above.
**Example: Using the `Where(...)` and the `ToList()` extension methods**
````csharp
-var people = _personRepository
+var queryable = await _personRepository.GetQueryableAsync();
+var people = queryable
.Where(p => p.Name.Contains(nameFilter))
.ToList();
````
@@ -269,7 +271,8 @@ When you add the NuGet package to your project, you can take full power of the E
**Example: Directly using the `ToListAsync()` after adding the EF Core package**
````csharp
-var people = _personRepository
+var queryable = await _personRepository.GetQueryableAsync();
+var people = queryable
.Where(p => p.Name.Contains(nameFilter))
.ToListAsync();
````
@@ -285,7 +288,8 @@ If you are using [MongoDB](MongoDB.md), you need to add the [Volo.Abp.MongoDB](h
**Example: Cast `IQueryable` to `IMongoQueryable` and use `ToListAsync()`**
````csharp
-var people = ((IMongoQueryable)_personRepository
+var queryable = await _personRepository.GetQueryableAsync();
+var people = ((IMongoQueryable) queryable
.Where(p => p.Name.Contains(nameFilter)))
.ToListAsync();
````
@@ -312,10 +316,11 @@ The standard LINQ extension methods are supported: *AllAsync, AnyAsync, AverageA
This approach still **has a limitation**. You need to call the extension method directly on the repository object. For example, the below usage is **not supported**:
```csharp
-var count = await _bookRepository.Where(x => x.Name.Contains("A")).CountAsync();
+var queryable = await _bookRepository.GetQueryableAsync();
+var count = await queryable.Where(x => x.Name.Contains("A")).CountAsync();
```
-This is because the object returned from the `Where` method is not a repository object, it is a standard `IQueryable` interface. See the other options for such cases.
+This is because the `CountAsync()` method in this example is called on a `IQueryable` interface, not on the repository object. See the other options for such cases.
This method is suggested **wherever possible**.
@@ -352,8 +357,11 @@ namespace AbpDemo
public async Task> GetListAsync(string name)
{
+ //Obtain the IQueryable
+ var queryable = await _productRepository.GetQueryableAsync();
+
//Create the query
- var query = _productRepository
+ var query = queryable
.Where(p => p.Name.Contains(name))
.OrderBy(p => p.Name);
diff --git a/docs/en/Road-Map.md b/docs/en/Road-Map.md
index 6f4213a6bd..0920639106 100644
--- a/docs/en/Road-Map.md
+++ b/docs/en/Road-Map.md
@@ -18,4 +18,4 @@ You can always check the milestone planning and the prioritized backlog issues o
The backlog items are subject to change. We are adding new items and changing priorities based on the community feedbacks and goals of the project.
-Vote for your favorite feature on the related GitHub issues (and write your thoughts). You can create an issue on [the GitHub repository](https://github.com/abpframework/abp) for your feature requests, but first search in in the existing issues.
\ No newline at end of file
+Vote for your favorite feature on the related GitHub issues (and write your thoughts). You can create an issue on [the GitHub repository](https://github.com/abpframework/abp) for your feature requests, but first search in the existing issues.
diff --git a/docs/en/Specifications.md b/docs/en/Specifications.md
index 036baa749e..bfe1d031d3 100644
--- a/docs/en/Specifications.md
+++ b/docs/en/Specifications.md
@@ -122,7 +122,8 @@ namespace MyProject
public async Task> GetCustomersCanBuyAlcohol()
{
- var query = _customerRepository.Where(
+ var queryable = await _customerRepository.GetQueryableAsync();
+ var query = queryable.Where(
new Age18PlusCustomerSpecification().ToExpression()
);
@@ -137,7 +138,8 @@ namespace MyProject
Actually, using the `ToExpression()` method is not necessary since the specifications are automatically casted to Expressions. This would also work:
````csharp
-var query = _customerRepository.Where(
+var queryable = await _customerRepository.GetQueryableAsync();
+var query = queryable.Where(
new Age18PlusCustomerSpecification()
);
````
diff --git a/docs/en/Tutorials/Part-10.md b/docs/en/Tutorials/Part-10.md
index a9de3a062e..ec68dfe955 100644
--- a/docs/en/Tutorials/Part-10.md
+++ b/docs/en/Tutorials/Part-10.md
@@ -364,10 +364,11 @@ namespace Acme.BookStore.Books
public override async Task GetAsync(Guid id)
{
- await CheckGetPolicyAsync();
+ //Get the IQueryable from the repository
+ var queryable = await Repository.GetQueryableAsync();
//Prepare a query to join books and authors
- var query = from book in Repository
+ var query = from book in queryable
join author in _authorRepository on book.AuthorId equals author.Id
where book.Id == id
select new { book, author };
@@ -384,17 +385,24 @@ namespace Acme.BookStore.Books
return bookDto;
}
- public override async Task> GetListAsync(
- PagedAndSortedResultRequestDto input)
+ public override async Task> GetListAsync(PagedAndSortedResultRequestDto input)
{
- await CheckGetListPolicyAsync();
+ //Set a default sorting, if not provided
+ if (input.Sorting.IsNullOrWhiteSpace())
+ {
+ input.Sorting = nameof(Book.Name);
+ }
+
+ //Get the IQueryable from the repository
+ var queryable = await Repository.GetQueryableAsync();
//Prepare a query to join books and authors
- var query = from book in Repository
+ var query = from book in queryable
join author in _authorRepository on book.AuthorId equals author.Id
- orderby input.Sorting
+ orderby input.Sorting //TODO: Can not sort like that!
select new {book, author};
+ //Paging
query = query
.Skip(input.SkipCount)
.Take(input.MaxResultCount);
@@ -437,7 +445,7 @@ Let's see the changes we've done:
* Injected `IAuthorRepository` to query from the authors.
* Overrode the `GetAsync` method of the base `CrudAppService`, which returns a single `BookDto` object with the given `id`.
* Used a simple LINQ expression to join books and authors and query them together for the given book id.
- * Used `AsyncExecuter.FirstOrDefaultAsync(...)` to execute the query and get a result. `AsyncExecuter` was previously used in the `AuthorAppService`. Check the [repository documentation](../Repositories.md) to understand why we've used it.
+ * Used `AsyncExecuter.FirstOrDefaultAsync(...)` to execute the query and get a result. It is a way to use asynchronous LINQ extensions without depending on the database provider API. Check the [repository documentation](../Repositories.md) to understand why we've used it.
* Throws an `EntityNotFoundException` which results an `HTTP 404` (not found) result if requested book was not present in the database.
* Finally, created a `BookDto` object using the `ObjectMapper`, then assigning the `AuthorName` manually.
* Overrode the `GetListAsync` method of the base `CrudAppService`, which returns a list of books. The logic is similar to the previous method, so you can easily understand the code.
@@ -487,8 +495,6 @@ namespace Acme.BookStore.Books
public async override Task GetAsync(Guid id)
{
- await CheckGetPolicyAsync();
-
var book = await Repository.GetAsync(id);
var bookDto = ObjectMapper.Map(book);
@@ -501,17 +507,18 @@ namespace Acme.BookStore.Books
public async override Task>
GetListAsync(PagedAndSortedResultRequestDto input)
{
- await CheckGetListPolicyAsync();
-
//Set a default sorting, if not provided
if (input.Sorting.IsNullOrWhiteSpace())
{
input.Sorting = nameof(Book.Name);
}
+
+ //Get the IQueryable from the repository
+ var queryable = await Repository.GetQueryableAsync();
//Get the books
var books = await AsyncExecuter.ToListAsync(
- Repository
+ queryable
.OrderBy(input.Sorting)
.Skip(input.SkipCount)
.Take(input.MaxResultCount)
@@ -553,8 +560,10 @@ namespace Acme.BookStore.Books
.Distinct()
.ToArray();
+ var queryable = await _authorRepository.GetQueryableAsync();
+
var authors = await AsyncExecuter.ToListAsync(
- _authorRepository.Where(a => authorIds.Contains(a.Id))
+ queryable.Where(a => authorIds.Contains(a.Id))
);
return authors.ToDictionary(x => x.Id, x => x);
diff --git a/docs/en/Tutorials/Part-7.md b/docs/en/Tutorials/Part-7.md
index 97d28691ae..ec3ad9a8e0 100644
--- a/docs/en/Tutorials/Part-7.md
+++ b/docs/en/Tutorials/Part-7.md
@@ -127,7 +127,8 @@ namespace Acme.BookStore.Authors
public async Task FindByNameAsync(string name)
{
- return await DbSet.FirstOrDefaultAsync(author => author.Name == name);
+ var dbSet = await GetDbSetAsync();
+ return await dbSet.FirstOrDefaultAsync(author => author.Name == name);
}
public async Task> GetListAsync(
@@ -136,7 +137,8 @@ namespace Acme.BookStore.Authors
string sorting,
string filter = null)
{
- return await DbSet
+ var dbSet = await GetDbSetAsync();
+ return await dbSet
.WhereIf(
!filter.IsNullOrWhiteSpace(),
author => author.Name.Contains(filter)
@@ -186,8 +188,8 @@ namespace Acme.BookStore.Authors
public async Task FindByNameAsync(string name)
{
- return await GetMongoQueryable()
- .FirstOrDefaultAsync(author => author.Name == name);
+ var queryable = await GetMongoQueryableAsync();
+ return await queryable.FirstOrDefaultAsync(author => author.Name == name);
}
public async Task> GetListAsync(
@@ -196,7 +198,8 @@ namespace Acme.BookStore.Authors
string sorting,
string filter = null)
{
- return await GetMongoQueryable()
+ var queryable = await GetMongoQueryableAsync();
+ return await queryable
.WhereIf>(
!filter.IsNullOrWhiteSpace(),
author => author.Name.Contains(filter)
diff --git a/docs/en/Tutorials/Part-8.md b/docs/en/Tutorials/Part-8.md
index b7c805c17e..6ab14c714c 100644
--- a/docs/en/Tutorials/Part-8.md
+++ b/docs/en/Tutorials/Part-8.md
@@ -172,6 +172,7 @@ using System.Threading.Tasks;
using Acme.BookStore.Permissions;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
+using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore.Authors
{
@@ -230,12 +231,10 @@ public async Task> GetListAsync(GetAuthorListDto input
input.Filter
);
- var totalCount = await AsyncExecuter.CountAsync(
- _authorRepository.WhereIf(
- !input.Filter.IsNullOrWhiteSpace(),
- author => author.Name.Contains(input.Filter)
- )
- );
+ var totalCount = input.Filter == null
+ ? await _authorRepository.CountAsync()
+ : await _authorRepository.CountAsync(
+ author => author.Name.Contains(input.Filter));
return new PagedResultDto(
totalCount,
@@ -246,7 +245,7 @@ public async Task> GetListAsync(GetAuthorListDto input
* Default sorting is "by author name" which is done in the beginning of the method in case of it wasn't sent by the client.
* Used the `IAuthorRepository.GetListAsync` to get a paged, sorted and filtered list of authors from the database. We had implemented it in the previous part of this tutorial. Again, it actually was not needed to create such a method since we could directly query over the repository, but wanted to demonstrate how to create custom repository methods.
-* Directly queried from the `AuthorRepository` while getting the count of the authors. We preferred to use the `AsyncExecuter` service which allows us to perform async queries without depending on the EF Core. However, you could depend on the EF Core package and directly use the `_authorRepository.WhereIf(...).ToListAsync()` method. See the [repository document](../Repositories.md) to read the alternative approaches and the discussion.
+* Directly queried from the `AuthorRepository` while getting the count of the authors. If a filter is sent, then we are using it to filter entities while getting the count.
* Finally, returning a paged result by mapping the list of `Author`s to a list of `AuthorDto`s.
### CreateAsync
diff --git a/docs/en/UI/Angular/Ellipsis-Directive.md b/docs/en/UI/Angular/Ellipsis-Directive.md
new file mode 100644
index 0000000000..c462331574
--- /dev/null
+++ b/docs/en/UI/Angular/Ellipsis-Directive.md
@@ -0,0 +1,83 @@
+# Ellipsis
+
+Text inside an HTML element can be truncated easily with an ellipsis by using CSS. To make this even easier, you can use the `EllipsisDirective` which has been exposed by the `@abp/ng.theme.shared` package.
+
+
+## Getting Started
+
+In order to use the `EllipsisDirective` in an HTML template, the **`ThemeSharedModule`** should be imported into your module like this:
+
+```js
+// ...
+import { ThemeSharedModule } from '@abp/ng.theme.shared';
+
+@NgModule({
+ //...
+ imports: [..., ThemeSharedModule],
+})
+export class MyFeatureModule {}
+```
+
+or **if you would not like to import** the `ThemeSharedModule`, you can import the **`EllipsisModule`** as shown below:
+
+
+```js
+// ...
+import { EllipsisModule } from '@abp/ng.theme.shared';
+
+@NgModule({
+ //...
+ imports: [..., EllipsisModule],
+})
+export class MyFeatureModule {}
+```
+
+## Usage
+
+The `EllipsisDirective` is very easy to use. The directive's selector is **`abpEllipsis`**. By adding the `abpEllipsis` attribute to an HTML element, you can activate the `EllipsisDirective` for the HTML element.
+
+See an example usage:
+
+```html
+
+ Lorem ipsum dolor sit, amet consectetur adipisicing elit. Laboriosam commodi quae aspernatur,
+ corporis velit et suscipit id consequuntur amet minima expedita cum reiciendis dolorum
+ cupiditate? Voluptas eaque voluptatum odio deleniti quo vel illum nemo accusamus nulla ratione
+ impedit dolorum expedita necessitatibus fugiat ullam beatae, optio eum cupiditate ducimus
+ architecto.
+
+```
+
+The `abpEllipsis` attribute has been added to the `
` element that containing very long text inside to activate the `EllipsisDirective`.
+
+See the result:
+
+
+
+The long text has been truncated by using the directive.
+
+The UI before using the directive looks like this:
+
+
+
+### Specifying Max Width of an HTML Element
+
+An HTML element max width can be specified as shown below:
+
+```html
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque, optio!
+
+
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque, optio!
+
+
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque, optio!
+
+```
+
+See the result:
+
+
\ No newline at end of file
diff --git a/docs/en/UI/Angular/Modal.md b/docs/en/UI/Angular/Modal.md
new file mode 100644
index 0000000000..f1583d4813
--- /dev/null
+++ b/docs/en/UI/Angular/Modal.md
@@ -0,0 +1,248 @@
+# Modal
+
+`ModalComponent` is a pre-built component exposed by `@abp/ng.theme.shared` package to show modals. The component uses the [`ng-bootstrap`](https://ng-bootstrap.github.io/)'s modal service inside to render a modal.
+
+The `abp-modal` provides some additional benefits:
+
+ - It is **flexible**. You can pass header, body, footer templates easily by adding the templates to the `abp-modal` content. It can also be implemented quickly.
+ - Provides several inputs be able to customize the modal and several outputs be able to listen to some events.
+ - Automatically detects the close button which has a `#abpClose` template variable and closes the modal when pressed this button.
+ - Automatically detects the `abp-button` and triggers its loading spinner when the `busy` input value of the modal component is true.
+ - Automatically checks if the form inside the modal **has changed, but not saved**. It warns the user by displaying a [confirmation popup](Confirmation-Service) in this case when a user tries to close the modal or refresh/close the tab of the browser.
+
+
+> Note: A modal can also be rendered by using the `ng-bootstrap` modal. For further information, see [Modal doc](https://ng-bootstrap.github.io/#/components/modal) on the `ng-bootstrap` documentation.
+
+## Getting Started
+
+In order to use the `abp-modal` in an HTML template, the **`ThemeSharedModule`** should be imported into your module like this:
+
+```js
+// ...
+import { ThemeSharedModule } from '@abp/ng.theme.shared';
+
+@NgModule({
+ //...
+ imports: [..., ThemeSharedModule],
+})
+export class MyFeatureModule {}
+```
+
+## Usage
+
+You can add the `abp-modal` to your component very quickly. See an example:
+
+```html
+
+
+
+
+
+
+
Modal Title
+
+
+
+
Modal content
+
+
+
+
+
+
+```
+
+```js
+// sample.component.ts
+
+@Component(/* component metadata */)
+export class SampleComponent {
+ isModelOpen = false
+}
+```
+
+
+
+
+See an example form inside a modal:
+
+```html
+
+
+
+
+
Book
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```ts
+// book.component.ts
+
+import { Component } from '@angular/core';
+import { FormBuilder, Validators } from '@angular/forms';
+
+@Component(/* component metadata */)
+export class BookComponent {
+ form = this.fb.group({
+ author: [null, [Validators.required]],
+ name: [null, [Validators.required]],
+ price: [null, [Validators.required, Validators.min(0)]],
+ type: [null, [Validators.required]],
+ publishDate: [null, [Validators.required]],
+ });
+
+ inProgress: boolean;
+
+ isModalOpen: boolean;
+
+ constructor(private fb: FormBuilder, private service: BookService) {}
+
+ save() {
+ if (this.form.invalid) return;
+
+ this.inProgress = true;
+
+ this.service.save(this.form.value).subscribe(() => {
+ this.inProgress = false;
+ });
+ }
+}
+```
+
+The modal with form looks like this:
+
+
+
+## API
+
+### Inputs
+
+#### visible
+
+```js
+@Input() visible: boolean
+```
+
+**`visible`** is a boolean input that determines whether the modal is open. It is also can be used two-way binding.
+
+#### busy
+
+```js
+@Input() busy: boolean
+```
+
+**`busy`** is a boolean input that determines whether the busy status of the modal is true. When `busy` is true, the modal cannot be closed and the `abp-button` loading spinner is triggered.
+
+
+#### options
+
+```js
+@Input() options: NgbModalOptions
+```
+
+**`options`** is an input typed [NgbModalOptions](https://ng-bootstrap.github.io/#/components/modal/api#NgbModalOptions). It is configuration for the `ng-bootstrap` modal.
+
+#### suppressUnsavedChangesWarning
+
+```js
+@Input() suppressUnsavedChangesWarning: boolean
+```
+
+**`suppressUnsavedChangesWarning`** is a boolean input that determines whether the confirmation popup triggering active or not. It can also be set globally as shown below:
+
+```ts
+//app.module.ts
+
+// app.module.ts
+
+import { SUPPRESS_UNSAVED_CHANGES_WARNING } from '@abp/ng.theme.shared';
+
+// ...
+
+@NgModule({
+ // ...
+ providers: [{provide: SUPPRESS_UNSAVED_CHANGES_WARNING, useValue: true}]
+})
+export class AppModule {}
+```
+
+Note: The `suppressUnsavedChangesWarning` input of `abp-modal` value overrides the `SUPPRESS_UNSAVED_CHANGES_WARNING` injection token value.
+
+### Outputs
+
+#### visibleChange
+
+```js
+@Output() readonly visibleChange = new EventEmitter();
+```
+
+**`visibleChange`** is an event emitted when the modal visibility has changed. The event payload is a boolean.
+
+#### appear
+
+```js
+ @Output() readonly appear = new EventEmitter();
+```
+
+**`appear`** is an event emitted when the modal has opened.
+
+#### disappear
+
+```js
+ @Output() readonly disappear = new EventEmitter();
+```
+
+**`disappear`** is an event emitted when the modal has closed.
diff --git a/docs/en/UI/Angular/Router-Events.md b/docs/en/UI/Angular/Router-Events.md
new file mode 100644
index 0000000000..011d405b22
--- /dev/null
+++ b/docs/en/UI/Angular/Router-Events.md
@@ -0,0 +1,146 @@
+# Router Events Simplified
+
+`RouterEvents` is a utility service to provide an easy implementation for one of the most frequent needs in Angular templates: `TrackByFunction`. Please see [this page in Angular docs](https://angular.io/guide/template-syntax#ngfor-with-trackby) for its purpose.
+
+
+
+
+## Benefit
+
+You can use router events directly and filter them as seen below:
+
+```js
+import {
+ NavigationEnd,
+ NavigationError,
+ NavigationCancel,
+ Router,
+} from '@angular/router';
+import { filter } from 'rxjs/operators';
+
+@Injectable()
+class SomeService {
+ navigationFinish$ = this.router.events.pipe(
+ filter(
+ event =>
+ event instanceof NavigationEnd ||
+ event instanceof NavigationError ||
+ event instanceof NavigationCancel,
+ ),
+ );
+ /* Observable */
+
+ constructor(private router: Router) {}
+}
+```
+
+However, `RouterEvents` makes filtering router events easier.
+
+```js
+import { RouterEvents } from '@abp/ng.core';
+
+@Injectable()
+class SomeService {
+ navigationFinish$ = this.routerEvents.getNavigationEvents('End', 'Error', 'Cancel');
+ /* Observable */
+
+ constructor(private routerEvents: RouterEvents) {}
+}
+```
+
+`RouterEvents` also delivers improved type-safety. In the example above, `navigationFinish$` has inferred type of `Observable` whereas it would have `Observable` when router events are filtered directly.
+
+
+
+
+## Usage
+
+You do not have to provide `RouterEvents` at the module or component level, because it is already **provided in root**. You can inject and start using it immediately in your components.
+
+
+### How to Get Specific Navigation Events
+
+You can use `getNavigationEvents` to get a stream of navigation events matching given event keys.
+
+```js
+import { RouterEvents } from '@abp/ng.core';
+import { merge } from 'rxjs';
+import { mapTo } from 'rxjs/operators';
+
+@Injectable()
+class SomeService {
+ navigationStart$ = this.routerEvents.getNavigationEvents('Start');
+ /* Observable */
+
+ navigationFinish$ = this.routerEvents.getNavigationEvents('End', 'Error', 'Cancel');
+ /* Observable */
+
+ loading$ = merge(
+ this.navigationStart$.pipe(mapTo(true)),
+ this.navigationFinish$.pipe(mapTo(false)),
+ );
+ /* Observable */
+
+ constructor(private routerEvents: RouterEvents) {}
+}
+```
+
+
+### How to Get All Navigation Events
+
+You can use `getAllNavigationEvents` to get a stream of all navigation events without passing any keys.
+
+```js
+import { RouterEvents, NavigationStart } from '@abp/ng.core';
+import { map } from 'rxjs/operators';
+
+@Injectable()
+class SomeService {
+ navigationEvent$ = this.routerEvents.getAllNavigationEvents();
+ /* Observable */
+
+ loading$ = this.navigationEvent$.pipe(
+ map(event => event instanceof NavigationStart),
+ );
+ /* Observable */
+
+ constructor(private routerEvents: RouterEvents) {}
+}
+```
+
+
+### How to Get Specific Router Events
+
+You can use `getEvents` to get a stream of router events matching given event constructors.
+
+```js
+import { RouterEvents } from '@abp/ng.core';
+import { ActivationEnd, ChildActivationEnd } from '@angular/router';
+
+@Injectable()
+class SomeService {
+ moduleActivation$ = this.routerEvents.getEvents(ActivationEnd, ChildActivationEnd);
+ /* Observable */
+
+ constructor(private routerEvents: RouterEvents) {}
+}
+```
+
+
+### How to Get All Router Events
+
+You can use `getEvents` to get a stream of all router events without passing any event constructors. This is nothing different from accessing `events` property of `Router` and is added to the service just for convenience.
+
+```js
+import { RouterEvents } from '@abp/ng.core';
+import { ActivationEnd, ChildActivationEnd } from '@angular/router';
+
+@Injectable()
+class SomeService {
+ routerEvent$ = this.routerEvents.getAllEvents();
+ /* Observable */
+
+ constructor(private routerEvents: RouterEvents) {}
+}
+```
+
diff --git a/docs/en/UI/Angular/images/ellipsis-directive-before.jpg b/docs/en/UI/Angular/images/ellipsis-directive-before.jpg
new file mode 100644
index 0000000000..dc534d9a97
Binary files /dev/null and b/docs/en/UI/Angular/images/ellipsis-directive-before.jpg differ
diff --git a/docs/en/UI/Angular/images/ellipsis-directive-result1.jpg b/docs/en/UI/Angular/images/ellipsis-directive-result1.jpg
new file mode 100644
index 0000000000..fe693f4c8c
Binary files /dev/null and b/docs/en/UI/Angular/images/ellipsis-directive-result1.jpg differ
diff --git a/docs/en/UI/Angular/images/ellipsis-directive-result2.jpg b/docs/en/UI/Angular/images/ellipsis-directive-result2.jpg
new file mode 100644
index 0000000000..3a416bbc05
Binary files /dev/null and b/docs/en/UI/Angular/images/ellipsis-directive-result2.jpg differ
diff --git a/docs/en/UI/Angular/images/modal-result-1.jpg b/docs/en/UI/Angular/images/modal-result-1.jpg
new file mode 100644
index 0000000000..89dbbc0cb1
Binary files /dev/null and b/docs/en/UI/Angular/images/modal-result-1.jpg differ
diff --git a/docs/en/UI/Angular/images/modal-result-2.jpg b/docs/en/UI/Angular/images/modal-result-2.jpg
new file mode 100644
index 0000000000..e17f2631ab
Binary files /dev/null and b/docs/en/UI/Angular/images/modal-result-2.jpg differ
diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json
index 3fff6d67c1..7fd7762ad4 100644
--- a/docs/en/docs-nav.json
+++ b/docs/en/docs-nav.json
@@ -807,6 +807,10 @@
"text": "Easy *ngFor trackBy",
"path": "UI/Angular/Track-By-Service.md"
},
+ {
+ "text": "Router Events",
+ "path": "UI/Angular/Router-Events.md"
+ },
{
"text": "Inserting Scripts & Styles to DOM",
"path": "UI/Angular/Dom-Insertion-Service.md"
@@ -819,6 +823,10 @@
"text": "Projecting Angular Content",
"path": "UI/Angular/Content-Projection-Service.md"
},
+ {
+ "text": "Modal",
+ "path": "UI/Angular/Modal.md"
+ },
{
"text": "Confirmation Popup",
"path": "UI/Angular/Confirmation-Service.md"
@@ -830,6 +838,10 @@
{
"text": "Page Alerts",
"path": "UI/Angular/Page-Alerts.md"
+ },
+ {
+ "text": "Ellipsis",
+ "path": "UI/Angular/Ellipsis-Directive.md"
}
]
},
@@ -1056,10 +1068,6 @@
{
"text": "CLI",
"path": "CLI.md"
- },
- {
- "text": "API Documentation",
- "path": "{ApiDocumentationUrl}"
}
]
},
diff --git a/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md b/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md
index b8abe99cdc..1e9ae77f36 100644
--- a/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md
+++ b/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md
@@ -243,7 +243,7 @@ ObjectExtensionManager.Instance
这是定义实体属性的另一种方法( 有关 `ObjectExtensionManager` 更多信息,请参阅[文档](Object-Extensions.md)). 这次我们设置了 `CheckPairDefinitionOnMapping` 为false,在将实体映射到DTO时会跳过定义检查.
-如果你不喜欢这种方法,但想简单的向多个对象(DTO)添加单个属, `AddOrUpdateProperty` 可以使用类型数组添加额外的属性:
+如果你不喜欢这种方法,但想简单的向多个对象(DTO)添加单个属性, `AddOrUpdateProperty` 可以使用类型数组添加额外的属性:
````csharp
ObjectExtensionManager.Instance
diff --git a/docs/zh-Hans/MongoDB.md b/docs/zh-Hans/MongoDB.md
index 2ceeb1e00c..af63642a41 100644
--- a/docs/zh-Hans/MongoDB.md
+++ b/docs/zh-Hans/MongoDB.md
@@ -211,7 +211,7 @@ public async override Task DeleteAsync(
#### 访问MongoDB API
-大多数情况下,你想要将MongoDB API隐藏在仓储后面(这是仓储的主要目的).如果你想在仓储之上访问MongoDB API,你可以使用`GetDatabase()`或`GetCollection()`方法.例如:
+大多数情况下,你想要将MongoDB API隐藏在仓储后面(这是仓储的主要目的).如果你想在仓储之上访问MongoDB API,你可以使用`GetDatabaseAsync()`, `GetAggregateAsync()` 或`GetCollectionAsync()`方法.例如:
```csharp
public class BookService
@@ -223,10 +223,11 @@ public class BookService
_bookRepository = bookRepository;
}
- public void Foo()
+ public async Task FooAsync()
{
- IMongoDatabase database = _bookRepository.GetDatabase();
- IMongoCollection books = _bookRepository.GetCollection();
+ IMongoDatabase database = await _bookRepository.GetDatabaseAsync();
+ IMongoCollection books = await _bookRepository.GetCollectionAsync();
+ IAggregateFluent bookAggregate = await _bookRepository.GetAggregateAsync();
}
}
```
diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs
index 0aeb97e89d..eaf5c753fd 100644
--- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs
@@ -1,7 +1,14 @@
-using System.Threading.Tasks;
+using System;
+using System.Globalization;
+using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Localization;
+using Microsoft.AspNetCore.RequestLocalization;
+using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
+using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
+using Volo.Abp.Settings;
namespace Volo.Abp.AspNetCore.MultiTenancy
{
@@ -21,10 +28,71 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var tenant = await _tenantConfigurationProvider.GetAsync(saveResolveResult: true);
- using (_currentTenant.Change(tenant?.Id, tenant?.Name))
+ if (tenant?.Id != _currentTenant.Id)
+ {
+ using (_currentTenant.Change(tenant?.Id, tenant?.Name))
+ {
+ var requestCulture = await TryGetRequestCultureAsync(context);
+ if (requestCulture != null)
+ {
+ CultureInfo.CurrentCulture = requestCulture.Culture;
+ CultureInfo.CurrentUICulture = requestCulture.UICulture;
+ AbpRequestCultureCookieHelper.SetCultureCookie(
+ context,
+ requestCulture
+ );
+ }
+
+ await next(context);
+ }
+ }
+ else
{
await next(context);
}
}
+
+ private async Task TryGetRequestCultureAsync(HttpContext httpContext)
+ {
+ var requestCultureFeature = httpContext.Features.Get();
+
+ /* If requestCultureFeature == null, that means the RequestLocalizationMiddleware was not used
+ * and we don't want to set the culture. */
+ if (requestCultureFeature == null)
+ {
+ return null;
+ }
+
+ /* If requestCultureFeature.Provider is not null, that means RequestLocalizationMiddleware
+ * already picked a language, so we don't need to set the default. */
+ if (requestCultureFeature.Provider != null)
+ {
+ return null;
+ }
+
+ var settingProvider = httpContext.RequestServices.GetRequiredService();
+ var defaultLanguage = await settingProvider.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage);
+ if (defaultLanguage.IsNullOrWhiteSpace())
+ {
+ return null;
+ }
+
+ string culture;
+ string uiCulture;
+
+ if (defaultLanguage.Contains(';'))
+ {
+ var splitted = defaultLanguage.Split(';');
+ culture = splitted[0];
+ uiCulture = splitted[1];
+ }
+ else
+ {
+ culture = defaultLanguage;
+ uiCulture = defaultLanguage;
+ }
+
+ return new RequestCulture(culture, uiCulture);
+ }
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs
index 4b4a0e6301..ae013c4343 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs
@@ -7,7 +7,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Client
{
public static string CreateCacheKey(ICurrentUser currentUser)
{
- return $"ApplicationConfiguration_{currentUser.Id?.ToString("N") ?? "Anonymous"}_{CultureInfo.CurrentUICulture.Name}";
+ var userKey = currentUser.Id?.ToString("N") ?? "Anonymous";
+ return $"ApplicationConfiguration_{userKey}_{CultureInfo.CurrentUICulture.Name}";
}
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js
index b0c4873b59..1808f267eb 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js
@@ -30,7 +30,7 @@
var htmlEncode = function (html) {
return $('').text(html).html();
}
-
+
var _createDropdownItem = function (record, fieldItem, tableInstance) {
var $li = $('');
var $a = $('');
@@ -90,15 +90,15 @@
}
$button.append(htmlEncode(firstItem.text));
}
-
+
if (firstItem.enabled && !firstItem.enabled({ record: record, table: tableInstance })) {
$button.addClass('disabled');
}
-
+
if (firstItem.action) {
$button.click(function (e) {
e.preventDefault();
-
+
if (!$(this).hasClass('disabled')) {
if (firstItem.confirmMessage) {
abp.message.confirm(firstItem.confirmMessage({ record: record, table: tableInstance }))
@@ -217,7 +217,7 @@
var renderRowActions = function (tableInstance, nRow, aData, iDisplayIndex, iDisplayIndexFull) {
var columns;
-
+
if (tableInstance.aoColumns) {
columns = tableInstance.aoColumns;
} else {
@@ -463,7 +463,7 @@
datatables.defaultConfigurations.scrollX = true;
- datatables.defaultConfigurations.responsive = true;
+ datatables.defaultConfigurations.responsive = true;
datatables.defaultConfigurations.language = function () {
return {
@@ -484,6 +484,6 @@
};
};
- datatables.defaultConfigurations.dom = '<"dataTable_filters"f>rt<"row dataTable_footer"<"col-auto"l><"col-auto"i><"col"p>>';
+ datatables.defaultConfigurations.dom = '<"dataTable_filters"f>rt<"row dataTable_footer"<"col-auto"l><"col-auto mr-auto"i><"col-auto"p>>';
})(jQuery);
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs
index 449747d0cc..a2d02bb3fe 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs
@@ -27,6 +27,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.RazorPages
{
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
+ [Obsolete("Use LazyServiceProvider instead.")]
public IServiceProvider ServiceProvider { get; set; }
protected IClock Clock => LazyServiceProvider.LazyGetRequiredService();
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs
index 52f1d251cb..85822414cf 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs
@@ -25,6 +25,7 @@ namespace Volo.Abp.AspNetCore.Mvc
{
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
+ [Obsolete("Use LazyServiceProvider instead.")]
public IServiceProvider ServiceProvider { get; set; }
protected IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService();
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs
index 8cbba0fc46..873c532ba3 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc.Auditing;
-using Volo.Abp.AspNetCore.Mvc.Content;
+using Volo.Abp.AspNetCore.Mvc.ContentFormatters;
using Volo.Abp.AspNetCore.Mvc.Conventions;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.AspNetCore.Mvc.Features;
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpViewComponent.cs
index 2ac02b8ac5..215f31b855 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpViewComponent.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpViewComponent.cs
@@ -10,6 +10,7 @@ namespace Volo.Abp.AspNetCore.Mvc
{
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
+ [Obsolete("Use LazyServiceProvider instead.")]
public IServiceProvider ServiceProvider { get; set; }
protected Type ObjectMapperContext { get; set; }
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs
index 5cd1333f34..135b506e69 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs
@@ -25,17 +25,20 @@ namespace Volo.Abp.AspNetCore.Mvc
{
public ILogger Logger { get; set; }
+ private readonly AspNetCoreApiDescriptionModelProviderOptions _options;
private readonly IApiDescriptionGroupCollectionProvider _descriptionProvider;
- private readonly AbpAspNetCoreMvcOptions _options;
+ private readonly AbpAspNetCoreMvcOptions _abpAspNetCoreMvcOptions;
private readonly AbpApiDescriptionModelOptions _modelOptions;
public AspNetCoreApiDescriptionModelProvider(
+ IOptions options,
IApiDescriptionGroupCollectionProvider descriptionProvider,
- IOptions options,
+ IOptions abpAspNetCoreMvcOptions,
IOptions modelOptions)
{
- _descriptionProvider = descriptionProvider;
_options = options.Value;
+ _descriptionProvider = descriptionProvider;
+ _abpAspNetCoreMvcOptions = abpAspNetCoreMvcOptions.Value;
_modelOptions = modelOptions.Value;
Logger = NullLogger.Instance;
@@ -82,14 +85,14 @@ namespace Volo.Abp.AspNetCore.Mvc
var controllerModel = moduleModel.GetOrAddController(
controllerType.FullName,
- CalculateControllerName(controllerType, setting),
+ _options.ControllerNameGenerator(controllerType, setting),
controllerType,
_modelOptions.IgnoredInterfaces
);
var method = apiDescription.ActionDescriptor.GetMethodInfo();
- var uniqueMethodName = GetUniqueActionName(method);
+ var uniqueMethodName = _options.ActionNameGenerator(method);
if (controllerModel.Actions.ContainsKey(uniqueMethodName))
{
Logger.LogWarning(
@@ -119,44 +122,6 @@ namespace Volo.Abp.AspNetCore.Mvc
AddParameterDescriptionsToModel(actionModel, method, apiDescription);
}
- private static string CalculateControllerName(Type controllerType, ConventionalControllerSetting setting)
- {
- var controllerName = controllerType.Name.RemovePostFix("Controller")
- .RemovePostFix(ApplicationService.CommonPostfixes);
-
- if (setting?.UrlControllerNameNormalizer != null)
- {
- controllerName =
- setting.UrlControllerNameNormalizer(
- new UrlControllerNameNormalizerContext(setting.RootPath, controllerName));
- }
-
- return controllerName;
- }
-
- private static string GetUniqueActionName(MethodInfo method)
- {
- var methodNameBuilder = new StringBuilder(method.Name);
-
- var parameters = method.GetParameters();
- if (parameters.Any())
- {
- methodNameBuilder.Append("By");
-
- for (var i = 0; i < parameters.Length; i++)
- {
- if (i > 0)
- {
- methodNameBuilder.Append("And");
- }
-
- methodNameBuilder.Append(parameters[i].Name.ToPascalCase());
- }
- }
-
- return methodNameBuilder.ToString();
- }
-
private static List GetSupportedVersions(Type controllerType, MethodInfo method,
ConventionalControllerSetting setting)
{
@@ -377,7 +342,7 @@ namespace Volo.Abp.AspNetCore.Mvc
[CanBeNull]
private ConventionalControllerSetting FindSetting(Type controllerType)
{
- foreach (var controllerSetting in _options.ConventionalControllers.ConventionalControllerSettings)
+ foreach (var controllerSetting in _abpAspNetCoreMvcOptions.ConventionalControllers.ConventionalControllerSettings)
{
if (controllerSetting.ControllerTypes.Contains(controllerType))
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProviderOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProviderOptions.cs
new file mode 100644
index 0000000000..4cd607e07a
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProviderOptions.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Volo.Abp.Application.Services;
+using Volo.Abp.AspNetCore.Mvc.Conventions;
+
+namespace Volo.Abp.AspNetCore.Mvc
+{
+ public class AspNetCoreApiDescriptionModelProviderOptions
+ {
+ public Func ControllerNameGenerator { get; set; }
+
+ public Func ActionNameGenerator { get; set; }
+
+ public AspNetCoreApiDescriptionModelProviderOptions()
+ {
+ ControllerNameGenerator = (controllerType, setting) =>
+ {
+ var controllerName = controllerType.Name.RemovePostFix("Controller")
+ .RemovePostFix(ApplicationService.CommonPostfixes);
+
+ if (setting?.UrlControllerNameNormalizer != null)
+ {
+ controllerName =
+ setting.UrlControllerNameNormalizer(
+ new UrlControllerNameNormalizerContext(setting.RootPath, controllerName));
+ }
+
+ return controllerName;
+ };
+
+ ActionNameGenerator = (method) =>
+ {
+ var methodNameBuilder = new StringBuilder(method.Name);
+
+ var parameters = method.GetParameters();
+ if (parameters.Any())
+ {
+ methodNameBuilder.Append("By");
+
+ for (var i = 0; i < parameters.Length; i++)
+ {
+ if (i > 0)
+ {
+ methodNameBuilder.Append("And");
+ }
+
+ methodNameBuilder.Append(parameters[i].Name.ToPascalCase());
+ }
+ }
+
+ return methodNameBuilder.ToString();
+ };
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/InternalRemoteStreamContent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/InternalRemoteStreamContent.cs
deleted file mode 100644
index aaaa849f4f..0000000000
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/InternalRemoteStreamContent.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.IO;
-using Microsoft.AspNetCore.Http;
-using Volo.Abp.Content;
-
-namespace Volo.Abp.AspNetCore.Mvc.Content
-{
- internal class InternalRemoteStreamContent : IRemoteStreamContent
- {
- private readonly HttpContext _httpContext;
-
- public InternalRemoteStreamContent(HttpContext httpContext)
- {
- _httpContext = httpContext;
- }
-
- public string ContentType => _httpContext.Request.ContentType;
-
- public long? ContentLength => _httpContext.Request.ContentLength;
-
- public Stream GetStream()
- {
- return _httpContext.Request.Body;
- }
- }
-}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/RemoteStreamContentInputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentInputFormatter.cs
similarity index 70%
rename from framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/RemoteStreamContentInputFormatter.cs
rename to framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentInputFormatter.cs
index a4f5668b7d..ba07e28f77 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/RemoteStreamContentInputFormatter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentInputFormatter.cs
@@ -1,10 +1,10 @@
using System;
using System.Threading.Tasks;
-using Microsoft.Net.Http.Headers;
using Microsoft.AspNetCore.Mvc.Formatters;
+using Microsoft.Net.Http.Headers;
using Volo.Abp.Content;
-namespace Volo.Abp.AspNetCore.Mvc.Content
+namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
{
public class RemoteStreamContentInputFormatter : InputFormatter
{
@@ -20,9 +20,10 @@ namespace Volo.Abp.AspNetCore.Mvc.Content
public override Task ReadRequestBodyAsync(InputFormatterContext context)
{
- return InputFormatterResult.SuccessAsync(
- new InternalRemoteStreamContent(context.HttpContext)
- );
+ return InputFormatterResult.SuccessAsync(new RemoteStreamContent(context.HttpContext.Request.Body)
+ {
+ ContentType = context.HttpContext.Request.ContentType
+ });
}
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/RemoteStreamContentOutputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs
similarity index 65%
rename from framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/RemoteStreamContentOutputFormatter.cs
rename to framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs
index 706e514254..685822a4b6 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/RemoteStreamContentOutputFormatter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs
@@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Net.Http.Headers;
using Volo.Abp.Content;
-namespace Volo.Abp.AspNetCore.Mvc.Content
+namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
{
public class RemoteStreamContentOutputFormatter : OutputFormatter
{
@@ -21,9 +21,16 @@ namespace Volo.Abp.AspNetCore.Mvc.Content
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
{
var remoteStream = (IRemoteStreamContent)context.Object;
- using (var stream = remoteStream.GetStream())
+
+ if (remoteStream != null)
{
- await stream.CopyToAsync(context.HttpContext.Response.Body);
+ context.HttpContext.Response.ContentType = remoteStream.ContentType;
+
+ using (var stream = remoteStream.GetStream())
+ {
+ stream.Position = 0;
+ await stream.CopyToAsync(context.HttpContext.Response.Body);
+ }
}
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpLanguagesController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpLanguagesController.cs
index 06b9c9a620..6b73aa26da 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpLanguagesController.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpLanguagesController.cs
@@ -1,7 +1,7 @@
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Localization;
+using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using System;
+using Microsoft.AspNetCore.RequestLocalization;
using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Mvc.Localization
@@ -20,12 +20,10 @@ namespace Volo.Abp.AspNetCore.Mvc.Localization
throw new AbpException("Unknown language: " + culture + ". It must be a valid culture!");
}
- string cookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture, uiCulture));
-
- Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, cookieValue, new CookieOptions
- {
- Expires = Clock.Now.AddYears(2)
- });
+ AbpRequestCultureCookieHelper.SetCultureCookie(
+ HttpContext,
+ new RequestCulture(culture, uiCulture)
+ );
if (!string.IsNullOrWhiteSpace(returnUrl))
{
diff --git a/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpHub.cs b/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpHub.cs
index a9d9316f41..616cbd3706 100644
--- a/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpHub.cs
+++ b/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpHub.cs
@@ -17,6 +17,7 @@ namespace Volo.Abp.AspNetCore.SignalR
{
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
+ [Obsolete("Use LazyServiceProvider instead.")]
public IServiceProvider ServiceProvider { get; set; }
protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetService();
diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestCultureCookieHelper.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestCultureCookieHelper.cs
new file mode 100644
index 0000000000..0f27925496
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestCultureCookieHelper.cs
@@ -0,0 +1,23 @@
+using System;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Localization;
+
+namespace Microsoft.AspNetCore.RequestLocalization
+{
+ public static class AbpRequestCultureCookieHelper
+ {
+ public static void SetCultureCookie(
+ HttpContext httpContext,
+ RequestCulture requestCulture)
+ {
+ httpContext.Response.Cookies.Append(
+ CookieRequestCultureProvider.DefaultCookieName,
+ CookieRequestCultureProvider.MakeCookieValue(requestCulture),
+ new CookieOptions
+ {
+ Expires = DateTime.Now.AddYears(2)
+ }
+ );
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs
index 9125a0c8ab..f3cb291f56 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs
@@ -22,7 +22,7 @@ namespace Volo.Abp.Cli.Auth
{
var configuration = new IdentityClientConfiguration(
CliUrls.AccountAbpIo,
- "role email abpio abpio_www abpio_commercial offline_access",
+ "role email abpio abpio_www abpio_commercial offline_access",
"abp-cli",
"1q2w3e*",
OidcConstants.GrantTypes.Password,
@@ -43,6 +43,7 @@ namespace Volo.Abp.Cli.Auth
public Task LogoutAsync()
{
FileHelper.DeleteIfExists(CliPaths.AccessToken);
+ FileHelper.DeleteIfExists(CliPaths.Lic);
return Task.CompletedTask;
}
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliPaths.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliPaths.cs
index 2b422446ca..068911ac8c 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliPaths.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliPaths.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Text;
namespace Volo.Abp.Cli
{
@@ -10,7 +11,8 @@ namespace Volo.Abp.Cli
public static string Root => Path.Combine(AbpRootPath, "cli");
public static string AccessToken => Path.Combine(AbpRootPath, "cli", "access-token.bin");
public static string Build => Path.Combine(AbpRootPath, "build");
-
+ public static string Lic => Path.Combine(Path.GetTempPath(), Encoding.ASCII.GetString(new byte[] { 65, 98, 112, 76, 105, 99, 101, 110, 115, 101, 46, 98, 105, 110 }));
+
private static readonly string AbpRootPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".abp");
}
-}
+}
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs
index 96e59152de..c82c434916 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs
@@ -12,11 +12,13 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.Auth;
+using Volo.Abp.Cli.Commands.Services;
using Volo.Abp.Cli.Http;
using Volo.Abp.Cli.ProjectBuilding;
using Volo.Abp.Cli.ProjectBuilding.Building;
using Volo.Abp.Cli.ProjectBuilding.Templates.App;
using Volo.Abp.Cli.ProjectBuilding.Templates.Console;
+using Volo.Abp.Cli.ProjectBuilding.Templates.Microservice;
using Volo.Abp.Cli.ProjectModification;
using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection;
@@ -31,14 +33,17 @@ namespace Volo.Abp.Cli.Commands
protected TemplateProjectBuilder TemplateProjectBuilder { get; }
public ITemplateInfoProvider TemplateInfoProvider { get; }
+ public ConnectionStringProvider ConnectionStringProvider { get; }
public NewCommand(TemplateProjectBuilder templateProjectBuilder
, ITemplateInfoProvider templateInfoProvider,
- EfCoreMigrationManager efCoreMigrationManager)
+ EfCoreMigrationManager efCoreMigrationManager,
+ ConnectionStringProvider connectionStringProvider)
{
_efCoreMigrationManager = efCoreMigrationManager;
TemplateProjectBuilder = templateProjectBuilder;
TemplateInfoProvider = templateInfoProvider;
+ ConnectionStringProvider = connectionStringProvider;
Logger = NullLogger.Instance;
}
@@ -164,7 +169,7 @@ namespace Volo.Abp.Cli.Commands
databaseManagementSystem != DatabaseManagementSystem.NotSpecified &&
databaseManagementSystem != DatabaseManagementSystem.SQLServer)
{
- connectionString = GetNewConnectionStringByDbms(databaseManagementSystem, outputFolder);
+ connectionString = ConnectionStringProvider.GetByDbms(databaseManagementSystem, outputFolder);
}
commandLineArgs.Options.Add(CliConsts.Command, commandLineArgs.Command);
@@ -234,23 +239,9 @@ namespace Volo.Abp.Cli.Commands
var isCommercial = template == AppProTemplate.TemplateName;
OpenThanksPage(uiFramework, databaseProvider, isTiered || commandLineArgs.Options.ContainsKey("separate-identity-server"), isCommercial);
}
- }
-
- private string GetNewConnectionStringByDbms(DatabaseManagementSystem databaseManagementSystem, string outputFolder)
- {
- switch (databaseManagementSystem)
- {
- case DatabaseManagementSystem.MySQL:
- return "Server=localhost;Port=3306;Database=MyProjectName;Uid=root;Pwd=myPassword;";
- case DatabaseManagementSystem.PostgreSQL:
- return "User ID=root;Password=myPassword;Host=localhost;Port=5432;Database=MyProjectName;Pooling=true;Min Pool Size=0;Max Pool Size=100;Connection Lifetime=0;";
- //case DatabaseManagementSystem.Oracle:
- case DatabaseManagementSystem.OracleDevart:
- return "Data Source=MyProjectName;Integrated Security=yes;";
- case DatabaseManagementSystem.SQLite:
- return $"Data Source={Path.Combine(outputFolder , "MyProjectName.db")};".Replace("\\", "\\\\");
- default:
- return null;
+ else if (MicroserviceTemplateBase.IsMicroserviceTemplate(template))
+ {
+ OpenMicroserviceDocumentPage();
}
}
@@ -263,19 +254,14 @@ namespace Volo.Abp.Cli.Commands
var tieredYesNo = tiered ? "yes" : "no";
var url = $"https://{urlPrefix}.abp.io/project-created-success?ui={uiFramework:g}&db={databaseProvider:g}&tiered={tieredYesNo}";
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- url = url.Replace("&", "^&");
- Process.Start(new ProcessStartInfo("cmd", $"/c start {url}") { CreateNoWindow = true });
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- {
- Process.Start("xdg-open", url);
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- Process.Start("open", url);
- }
+ CmdHelper.OpenWebPage(url);
+ }
+
+ private void OpenMicroserviceDocumentPage()
+ {
+ var url = "https://docs.abp.io/en/commercial/latest/startup-templates/microservice/index";
+
+ CmdHelper.OpenWebPage(url);
}
private bool GetCreateSolutionFolderPreference(CommandLineArgs commandLineArgs)
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/ConnectionStringProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/ConnectionStringProvider.cs
new file mode 100644
index 0000000000..32e09b3339
--- /dev/null
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/ConnectionStringProvider.cs
@@ -0,0 +1,30 @@
+using System.IO;
+using Volo.Abp.Cli.ProjectBuilding.Building;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.Cli.Commands.Services
+{
+ public class ConnectionStringProvider : ITransientDependency
+ {
+ public string GetByDbms(DatabaseManagementSystem databaseManagementSystem, string outputFolder = "")
+ {
+ switch (databaseManagementSystem)
+ {
+ case DatabaseManagementSystem.NotSpecified:
+ case DatabaseManagementSystem.SQLServer:
+ return "Server=localhost;Database=MyProjectName;Trusted_Connection=True";
+ case DatabaseManagementSystem.MySQL:
+ return "Server=localhost;Port=3306;Database=MyProjectName;Uid=root;Pwd=myPassword;";
+ case DatabaseManagementSystem.PostgreSQL:
+ return "User ID=root;Password=myPassword;Host=localhost;Port=5432;Database=MyProjectName;Pooling=true;Min Pool Size=0;Max Pool Size=100;Connection Lifetime=0;";
+ //case DatabaseManagementSystem.Oracle:
+ case DatabaseManagementSystem.OracleDevart:
+ return "Data Source=MyProjectName;Integrated Security=yes;";
+ case DatabaseManagementSystem.SQLite:
+ return $"Data Source={Path.Combine(outputFolder , "MyProjectName.db")};".Replace("\\", "\\\\");
+ default:
+ return null;
+ }
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleInfo.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleInfo.cs
index fadd830c93..260fbb745f 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleInfo.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleInfo.cs
@@ -21,5 +21,7 @@
public bool AngularUi { get; set; }
public bool MvcUi { get; set; }
+
+ public bool BlazorUi { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs
index 99625d830f..2a596b73a7 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs
@@ -297,7 +297,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.App
private static void CleanupFolderHierarchy(ProjectBuildContext context, List steps)
{
- if (context.BuildArgs.UiFramework == UiFramework.Mvc && context.BuildArgs.MobileApp == MobileApp.None)
+ if ((context.BuildArgs.UiFramework == UiFramework.Mvc || context.BuildArgs.UiFramework == UiFramework.Blazor) &&
+ context.BuildArgs.MobileApp == MobileApp.None)
{
steps.Add(new MoveFolderStep("/aspnet-core/", "/"));
}
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs
index a9ffccd142..52ff3c9c91 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs
@@ -12,6 +12,11 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice
{
}
+ public static bool IsMicroserviceTemplate(string templateName)
+ {
+ return templateName == MicroserviceProTemplate.TemplateName;
+ }
+
public override IEnumerable GetCustomSteps(ProjectBuildContext context)
{
var steps = new List();
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs
index 69ec43e276..e26e4a6d25 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs
@@ -77,6 +77,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Module
private static void UpdateNuGetConfig(ProjectBuildContext context, List steps)
{
steps.Add(new UpdateNuGetConfigStep("/aspnet-core/NuGet.Config"));
+ steps.Add(new UpdateNuGetConfigStep("/NuGet.Config"));
}
private static void ChangeConnectionString(ProjectBuildContext context, List steps)
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs
index d8571843fe..8fc800c146 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs
@@ -345,11 +345,20 @@ namespace Volo.Abp.Cli.ProjectModification
protected virtual List GetPackageVersionList(JProperty package)
{
- var versionListAsJson = CmdHelper.RunCmdAndGetOutput($"npm show {package.Name} versions");
+ var output = CmdHelper.RunCmdAndGetOutput($"npm show {package.Name} versions --json");
+
+ var versionListAsJson = ExtractVersions(output);
+
return JsonConvert.DeserializeObject(versionListAsJson)
.OrderByDescending(SemanticVersion.Parse, new VersionComparer()).ToList();
}
+ protected virtual string ExtractVersions(string output)
+ {
+ var arrayStart = output.IndexOf('[');
+ return output.Substring(arrayStart, output.IndexOf(']') - arrayStart + 1);
+ }
+
protected virtual bool SpecifiedVersionExists(string version, JProperty package)
{
var versionList = GetPackageVersionList(package);
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/CmdHelper.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/CmdHelper.cs
index 4fde5dfe80..07b470225a 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/CmdHelper.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/CmdHelper.cs
@@ -1,4 +1,5 @@
using System.Diagnostics;
+using System.IO;
using System.Runtime.InteropServices;
namespace Volo.Abp.Cli.Utils
@@ -7,6 +8,23 @@ namespace Volo.Abp.Cli.Utils
{
public static int SuccessfulExitCode = 0;
+ public static void OpenWebPage(string url)
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ url = url.Replace("&", "^&");
+ Process.Start(new ProcessStartInfo("cmd", $"/c start {url}") { CreateNoWindow = true });
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ Process.Start("xdg-open", url);
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ Process.Start("open", url);
+ }
+ }
+
public static void Run(string file, string arguments)
{
var procStartInfo = new ProcessStartInfo(file, arguments);
@@ -86,14 +104,28 @@ namespace Volo.Abp.Cli.Utils
public static string GetFileName()
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ //Windows
+ return "cmd.exe";
+ }
+
+ //Linux or OSX
+ if (File.Exists("/bin/bash"))
{
- //TODO: Test this. it should work for both operation systems.
return "/bin/bash";
}
- //Windows default.
- return "cmd.exe";
+ if (File.Exists("/bin/sh"))
+ {
+ return "/bin/sh"; //some Linux distributions like Alpine doesn't have bash
+ }
+
+ throw new AbpException($"Cannot determine shell command for this OS! " +
+ $"Running on OS: {System.Runtime.InteropServices.RuntimeInformation.OSDescription} | " +
+ $"OS Architecture: {System.Runtime.InteropServices.RuntimeInformation.OSArchitecture} | " +
+ $"Framework: {System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription} | " +
+ $"Process Architecture{System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture}");
}
}
}
diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs
index 232afb4280..4ac41663e4 100644
--- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs
+++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs
@@ -35,6 +35,7 @@ namespace Volo.Abp.Application.Services
{
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
+ [Obsolete("Use LazyServiceProvider instead.")]
public IServiceProvider ServiceProvider { get; set; }
public static string[] CommonPostfixes { get; set; } = { "AppService", "ApplicationService", "Service" };
@@ -51,7 +52,7 @@ namespace Volo.Abp.Application.Services
? provider.GetRequiredService()
: (IObjectMapper) provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext)));
- public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance);
+ protected IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance);
protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService();
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs
index 5e81e2270d..2f8dd28afc 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs
@@ -1,7 +1,5 @@
using System;
-using System.Collections.Concurrent;
using System.Collections.Generic;
-using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using JetBrains.Annotations;
@@ -15,6 +13,17 @@ namespace Volo.Abp.Domain.Entities
///
public static class EntityHelper
{
+ public static bool IsMultiTenant()
+ where TEntity : IEntity
+ {
+ return IsMultiTenant(typeof(TEntity));
+ }
+
+ public static bool IsMultiTenant(Type type)
+ {
+ return typeof(IMultiTenant).IsAssignableFrom(type);
+ }
+
public static bool EntityEquals(IEntity entity1, IEntity entity2)
{
if (entity1 == null || entity2 == null)
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs
index 751b938f1d..39938b081a 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs
@@ -13,11 +13,12 @@ namespace Volo.Abp.Domain.Services
{
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
+ [Obsolete("Use LazyServiceProvider instead.")]
public IServiceProvider ServiceProvider { get; set; }
protected IClock Clock => LazyServiceProvider.LazyGetRequiredService();
- public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance);
+ protected IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance);
protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService();
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo.Abp.EntityFrameworkCore.PostgreSql.csproj b/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo.Abp.EntityFrameworkCore.PostgreSql.csproj
index 8616838cc0..e8c90ccf13 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo.Abp.EntityFrameworkCore.PostgreSql.csproj
+++ b/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo.Abp.EntityFrameworkCore.PostgreSql.csproj
@@ -19,7 +19,7 @@
-
+
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Microsoft/EntityFrameworkCore/AbpModelBuilderExtensions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Microsoft/EntityFrameworkCore/AbpModelBuilderExtensions.cs
index 7148cb69bd..1ccfee1506 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Microsoft/EntityFrameworkCore/AbpModelBuilderExtensions.cs
+++ b/framework/src/Volo.Abp.EntityFrameworkCore/Microsoft/EntityFrameworkCore/AbpModelBuilderExtensions.cs
@@ -1,10 +1,72 @@
using Volo.Abp.EntityFrameworkCore;
+using Volo.Abp.MultiTenancy;
namespace Microsoft.EntityFrameworkCore
{
public static class AbpModelBuilderExtensions
{
private const string ModelDatabaseProviderAnnotationKey = "_Abp_DatabaseProvider";
+ private const string ModelMultiTenancySideAnnotationKey = "_Abp_MultiTenancySide";
+
+ #region MultiTenancySide
+
+ public static void SetMultiTenancySide(
+ this ModelBuilder modelBuilder,
+ MultiTenancySides side)
+ {
+ modelBuilder.Model.SetAnnotation(ModelMultiTenancySideAnnotationKey, side);
+ }
+
+ public static MultiTenancySides GetMultiTenancySide(this ModelBuilder modelBuilder)
+ {
+ var value = modelBuilder.Model[ModelMultiTenancySideAnnotationKey];
+ if (value == null)
+ {
+ return MultiTenancySides.Both;
+ }
+
+ return (MultiTenancySides) value;
+ }
+
+ ///
+ /// Returns true if this is a database schema that is used by the host
+ /// but can also be shared with the tenants.
+ ///
+ public static bool IsHostDatabase(this ModelBuilder modelBuilder)
+ {
+ return modelBuilder.GetMultiTenancySide().HasFlag(MultiTenancySides.Host);
+ }
+
+ ///
+ /// Returns true if this is a database schema that is used by the tenants
+ /// but can also be shared with the host.
+ ///
+ public static bool IsTenantDatabase(this ModelBuilder modelBuilder)
+ {
+ return modelBuilder.GetMultiTenancySide().HasFlag(MultiTenancySides.Tenant);
+ }
+
+ ///
+ /// Returns true if this is a database schema that is only used by the host
+ /// and should not contain tenant-only tables.
+ ///
+ public static bool IsHostOnlyDatabase(this ModelBuilder modelBuilder)
+ {
+ return modelBuilder.GetMultiTenancySide() == MultiTenancySides.Host;
+ }
+
+ ///
+ /// Returns true if this is a database schema that is only used by tenants.
+ /// and should not contain host-only tables.
+ ///
+ public static bool IsTenantOnlyDatabase(this ModelBuilder modelBuilder)
+ {
+ return modelBuilder.GetMultiTenancySide() == MultiTenancySides.Tenant;
+ }
+
+ #endregion
+
+ #region DatabaseProvider
public static void SetDatabaseProvider(
this ModelBuilder modelBuilder,
@@ -61,7 +123,7 @@ namespace Microsoft.EntityFrameworkCore
{
modelBuilder.SetDatabaseProvider(EfCoreDatabaseProvider.InMemory);
}
-
+
public static bool IsUsingInMemory(
this ModelBuilder modelBuilder)
{
@@ -73,7 +135,7 @@ namespace Microsoft.EntityFrameworkCore
{
modelBuilder.SetDatabaseProvider(EfCoreDatabaseProvider.Cosmos);
}
-
+
public static bool IsUsingCosmos(
this ModelBuilder modelBuilder)
{
@@ -85,11 +147,13 @@ namespace Microsoft.EntityFrameworkCore
{
modelBuilder.SetDatabaseProvider(EfCoreDatabaseProvider.Firebird);
}
-
+
public static bool IsUsingFirebird(
this ModelBuilder modelBuilder)
{
return modelBuilder.GetDatabaseProvider() == EfCoreDatabaseProvider.Firebird;
}
+
+ #endregion
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
index 4ba5457677..055c9c2de9 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
+++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
@@ -13,6 +13,7 @@ using Volo.Abp.Domain.Entities;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.DependencyInjection;
using Volo.Abp.Guids;
+using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
{
@@ -21,18 +22,42 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
where TEntity : class, IEntity
{
[Obsolete("Use GetDbContextAsync() method.")]
- protected virtual TDbContext DbContext => _dbContextProvider.GetDbContext();
+ protected virtual TDbContext DbContext => GetDbContext();
[Obsolete("Use GetDbContextAsync() method.")]
- DbContext IEfCoreRepository.DbContext => DbContext.As();
+ DbContext IEfCoreRepository.DbContext => GetDbContext() as DbContext;
async Task IEfCoreRepository.GetDbContextAsync()
{
return await GetDbContextAsync() as DbContext;
}
+ [Obsolete("Use GetDbContextAsync() method.")]
+ private TDbContext GetDbContext()
+ {
+ // Multi-tenancy unaware entities should always use the host connection string
+ if (!EntityHelper.IsMultiTenant())
+ {
+ using (CurrentTenant.Change(null))
+ {
+ return _dbContextProvider.GetDbContext();
+ }
+ }
+
+ return _dbContextProvider.GetDbContext();
+ }
+
protected virtual Task GetDbContextAsync()
{
+ // Multi-tenancy unaware entities should always use the host connection string
+ if (!EntityHelper.IsMultiTenant())
+ {
+ using (CurrentTenant.Change(null))
+ {
+ return _dbContextProvider.GetDbContextAsync();
+ }
+ }
+
return _dbContextProvider.GetDbContextAsync();
}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextOptionsFactory.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextOptionsFactory.cs
index 0147de12fb..c0603ec6f1 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextOptionsFactory.cs
+++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextOptionsFactory.cs
@@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Data;
+using Volo.Abp.MultiTenancy;
namespace Volo.Abp.EntityFrameworkCore.DependencyInjection
{
@@ -86,16 +87,34 @@ namespace Volo.Abp.EntityFrameworkCore.DependencyInjection
}
var connectionStringName = ConnectionStringNameAttribute.GetConnStringName();
-
- //Use DefaultConnectionStringResolver.Resolve when we remove IConnectionStringResolver.Resolve
-#pragma warning disable 618
- var connectionString = serviceProvider.GetRequiredService().Resolve(connectionStringName);
-#pragma warning restore 618
+ var connectionString = ResolveConnectionString(serviceProvider, connectionStringName);
return new DbContextCreationContext(
connectionStringName,
connectionString
);
}
+
+ private static string ResolveConnectionString(
+ IServiceProvider serviceProvider,
+ string connectionStringName)
+ {
+ // Use DefaultConnectionStringResolver.Resolve when we remove IConnectionStringResolver.Resolve
+#pragma warning disable 618
+ var connectionStringResolver = serviceProvider.GetRequiredService();
+ var currentTenant = serviceProvider.GetRequiredService();
+
+ // Multi-tenancy unaware contexts should always use the host connection string
+ if (typeof(TDbContext).IsDefined(typeof(IgnoreMultiTenancyAttribute), false))
+ {
+ using (currentTenant.Change(null))
+ {
+ return connectionStringResolver.Resolve(connectionStringName);
+ }
+ }
+
+ return connectionStringResolver.Resolve(connectionStringName);
+#pragma warning restore 618
+ }
}
}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreTransactionApi.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreTransactionApi.cs
index 99622dda96..ce9afacef1 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreTransactionApi.cs
+++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreTransactionApi.cs
@@ -5,6 +5,7 @@ using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Volo.Abp.EntityFrameworkCore;
+using Volo.Abp.Threading;
namespace Volo.Abp.Uow.EntityFrameworkCore
{
@@ -14,22 +15,22 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
public IEfCoreDbContext StarterDbContext { get; }
public List AttendedDbContexts { get; }
- public EfCoreTransactionApi(IDbContextTransaction dbContextTransaction, IEfCoreDbContext starterDbContext)
+ protected ICancellationTokenProvider CancellationTokenProvider { get; }
+
+ public EfCoreTransactionApi(
+ IDbContextTransaction dbContextTransaction,
+ IEfCoreDbContext starterDbContext,
+ ICancellationTokenProvider cancellationTokenProvider)
{
DbContextTransaction = dbContextTransaction;
StarterDbContext = starterDbContext;
+ CancellationTokenProvider = cancellationTokenProvider;
AttendedDbContexts = new List();
}
- public Task CommitAsync()
- {
- Commit();
- return Task.CompletedTask;
- }
-
- protected void Commit()
+ public async Task CommitAsync()
{
- DbContextTransaction.Commit();
+ await DbContextTransaction.CommitAsync(CancellationTokenProvider.Token);
foreach (var dbContext in AttendedDbContexts)
{
@@ -38,7 +39,7 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
continue; //Relational databases use the shared transaction
}
- dbContext.Database.CommitTransaction();
+ await dbContext.Database.CommitTransactionAsync(CancellationTokenProvider.Token);
}
}
@@ -47,15 +48,19 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
DbContextTransaction.Dispose();
}
- public void Rollback()
+ public async Task RollbackAsync(CancellationToken cancellationToken)
{
- DbContextTransaction.Rollback();
- }
+ await DbContextTransaction.RollbackAsync(CancellationTokenProvider.FallbackToProvider(cancellationToken));
- public Task RollbackAsync(CancellationToken cancellationToken)
- {
- DbContextTransaction.Rollback();
- return Task.CompletedTask;
+ foreach (var dbContext in AttendedDbContexts)
+ {
+ if (dbContext.As().HasRelationalTransactionManager())
+ {
+ continue; //Relational databases use the shared transaction
+ }
+
+ await dbContext.Database.RollbackTransactionAsync(CancellationTokenProvider.FallbackToProvider(cancellationToken));
+ }
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs
index 564a3ef8ad..89cc69fb74 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs
+++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs
@@ -9,6 +9,7 @@ using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.DependencyInjection;
+using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading;
namespace Volo.Abp.Uow.EntityFrameworkCore
@@ -23,15 +24,18 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IConnectionStringResolver _connectionStringResolver;
private readonly ICancellationTokenProvider _cancellationTokenProvider;
+ private readonly ICurrentTenant _currentTenant;
public UnitOfWorkDbContextProvider(
IUnitOfWorkManager unitOfWorkManager,
IConnectionStringResolver connectionStringResolver,
- ICancellationTokenProvider cancellationTokenProvider)
+ ICancellationTokenProvider cancellationTokenProvider,
+ ICurrentTenant currentTenant)
{
_unitOfWorkManager = unitOfWorkManager;
_connectionStringResolver = connectionStringResolver;
_cancellationTokenProvider = cancellationTokenProvider;
+ _currentTenant = currentTenant;
Logger = NullLogger>.Instance;
}
@@ -57,7 +61,7 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
}
var connectionStringName = ConnectionStringNameAttribute.GetConnStringName();
- var connectionString = _connectionStringResolver.Resolve(connectionStringName);
+ var connectionString = ResolveConnectionString(connectionStringName);
var dbContextKey = $"{typeof(TDbContext).FullName}_{connectionString}";
@@ -79,7 +83,7 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
}
var connectionStringName = ConnectionStringNameAttribute.GetConnStringName();
- var connectionString = await _connectionStringResolver.ResolveAsync(connectionStringName);
+ var connectionString = await ResolveConnectionStringAsync(connectionStringName);
var dbContextKey = $"{typeof(TDbContext).FullName}_{connectionString}";
@@ -168,7 +172,8 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
transactionApiKey,
new EfCoreTransactionApi(
dbtransaction,
- dbContext
+ dbContext,
+ _cancellationTokenProvider
)
);
@@ -186,7 +191,10 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
}
else
{
- dbContext.Database.BeginTransaction(); //TODO: Why not using the new created transaction?
+ /* No need to store the returning IDbContextTransaction for non-relational databases
+ * since EfCoreTransactionApi will handle the commit/rollback over the DbContext instance.
+ */
+ dbContext.Database.BeginTransaction();
}
activeTransaction.AttendedDbContexts.Add(dbContext);
@@ -212,7 +220,8 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
transactionApiKey,
new EfCoreTransactionApi(
dbTransaction,
- dbContext
+ dbContext,
+ _cancellationTokenProvider
)
);
@@ -230,7 +239,10 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
}
else
{
- await dbContext.Database.BeginTransactionAsync(GetCancellationToken()); //TODO: Why not using the new created transaction?
+ /* No need to store the returning IDbContextTransaction for non-relational databases
+ * since EfCoreTransactionApi will handle the commit/rollback over the DbContext instance.
+ */
+ await dbContext.Database.BeginTransactionAsync(GetCancellationToken());
}
activeTransaction.AttendedDbContexts.Add(dbContext);
@@ -239,6 +251,35 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
}
}
+ private async Task ResolveConnectionStringAsync(string connectionStringName)
+ {
+ // Multi-tenancy unaware contexts should always use the host connection string
+ if (typeof(TDbContext).IsDefined(typeof(IgnoreMultiTenancyAttribute), false))
+ {
+ using (_currentTenant.Change(null))
+ {
+ return await _connectionStringResolver.ResolveAsync(connectionStringName);
+ }
+ }
+
+ return await _connectionStringResolver.ResolveAsync(connectionStringName);
+ }
+
+ [Obsolete("Use ResolveConnectionStringAsync method.")]
+ private string ResolveConnectionString(string connectionStringName)
+ {
+ // Multi-tenancy unaware contexts should always use the host connection string
+ if (typeof(TDbContext).IsDefined(typeof(IgnoreMultiTenancyAttribute), false))
+ {
+ using (_currentTenant.Change(null))
+ {
+ return _connectionStringResolver.Resolve(connectionStringName);
+ }
+ }
+
+ return _connectionStringResolver.Resolve(connectionStringName);
+ }
+
protected virtual CancellationToken GetCancellationToken(CancellationToken preferredValue = default)
{
return _cancellationTokenProvider.FallbackToProvider(preferredValue);
diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Content/ReferencedRemoteStreamContent.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Content/ReferencedRemoteStreamContent.cs
deleted file mode 100644
index b99cec8a51..0000000000
--- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Content/ReferencedRemoteStreamContent.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.IO;
-using Volo.Abp.Content;
-
-namespace Volo.Abp.Http.Client.Content
-{
- internal class ReferencedRemoteStreamContent : RemoteStreamContent
- {
- private readonly object[] _references;
-
- public ReferencedRemoteStreamContent(Stream stream, params object[] references)
- : base(stream)
- {
- this._references = references;
- }
- }
-}
diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiDescriptionFinder.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiDescriptionFinder.cs
index 9142118b97..7e90bd4fe7 100644
--- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiDescriptionFinder.cs
+++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiDescriptionFinder.cs
@@ -1,24 +1,38 @@
using System;
+using System.Globalization;
using System.Linq;
using System.Net.Http;
+using System.Net.Http.Headers;
using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks;
+using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Modeling;
+using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading;
+using Volo.Abp.Tracing;
namespace Volo.Abp.Http.Client.DynamicProxying
{
public class ApiDescriptionFinder : IApiDescriptionFinder, ITransientDependency
{
public ICancellationTokenProvider CancellationTokenProvider { get; set; }
-
protected IApiDescriptionCache Cache { get; }
-
- public ApiDescriptionFinder(IApiDescriptionCache cache)
+ protected AbpCorrelationIdOptions AbpCorrelationIdOptions { get; }
+ protected ICorrelationIdProvider CorrelationIdProvider { get; }
+ protected ICurrentTenant CurrentTenant { get; }
+
+ public ApiDescriptionFinder(
+ IApiDescriptionCache cache,
+ IOptions abpCorrelationIdOptions,
+ ICorrelationIdProvider correlationIdProvider,
+ ICurrentTenant currentTenant)
{
Cache = cache;
+ AbpCorrelationIdOptions = abpCorrelationIdOptions.Value;
+ CorrelationIdProvider = correlationIdProvider;
+ CurrentTenant = currentTenant;
CancellationTokenProvider = NullCancellationTokenProvider.Instance;
}
@@ -71,10 +85,19 @@ namespace Volo.Abp.Http.Client.DynamicProxying
return await Cache.GetAsync(baseUrl, () => GetApiDescriptionFromServerAsync(client, baseUrl));
}
- protected virtual async Task GetApiDescriptionFromServerAsync(HttpClient client, string baseUrl)
+ protected virtual async Task GetApiDescriptionFromServerAsync(
+ HttpClient client,
+ string baseUrl)
{
- var response = await client.GetAsync(
- baseUrl.EnsureEndsWith('/') + "api/abp/api-definition",
+ var requestMessage = new HttpRequestMessage(
+ HttpMethod.Get,
+ baseUrl.EnsureEndsWith('/') + "api/abp/api-definition"
+ );
+
+ AddHeaders(requestMessage);
+
+ var response = await client.SendAsync(
+ requestMessage,
CancellationTokenProvider.Token
);
@@ -93,6 +116,30 @@ namespace Volo.Abp.Http.Client.DynamicProxying
return (ApplicationApiDescriptionModel)result;
}
+ protected virtual void AddHeaders(HttpRequestMessage requestMessage)
+ {
+ //CorrelationId
+ requestMessage.Headers.Add(AbpCorrelationIdOptions.HttpHeaderName, CorrelationIdProvider.Get());
+
+ //TenantId
+ if (CurrentTenant.Id.HasValue)
+ {
+ //TODO: Use AbpAspNetCoreMultiTenancyOptions to get the key
+ requestMessage.Headers.Add(TenantResolverConsts.DefaultTenantKey, CurrentTenant.Id.Value.ToString());
+ }
+
+ //Culture
+ //TODO: Is that the way we want? Couldn't send the culture (not ui culture)
+ var currentCulture = CultureInfo.CurrentUICulture.Name ?? CultureInfo.CurrentCulture.Name;
+ if (!currentCulture.IsNullOrEmpty())
+ {
+ requestMessage.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(currentCulture));
+ }
+
+ //X-Requested-With
+ requestMessage.Headers.Add("X-Requested-With", "XMLHttpRequest");
+ }
+
protected virtual bool TypeMatches(MethodParameterApiDescriptionModel actionParameter, ParameterInfo methodParameter)
{
return NormalizeTypeName(actionParameter.TypeAsString) ==
diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs
index 7eb4e5ad78..136c9e42ef 100644
--- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs
+++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs
@@ -14,7 +14,6 @@ using Volo.Abp.Content;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
using Volo.Abp.Http.Client.Authentication;
-using Volo.Abp.Http.Client.Content;
using Volo.Abp.Http.Modeling;
using Volo.Abp.Http.ProxyScripting.Generators;
using Volo.Abp.Json;
@@ -112,7 +111,10 @@ namespace Volo.Abp.Http.Client.DynamicProxying
/* returning a class that holds a reference to response
* content just to be sure that GC does not dispose of
* it before we finish doing our work with the stream */
- return (T)((object)new ReferencedRemoteStreamContent(await responseContent.ReadAsStreamAsync(), responseContent));
+ return (T)(object)new RemoteStreamContent(await responseContent.ReadAsStreamAsync())
+ {
+ ContentType = responseContent.Headers.ContentType?.ToString()
+ };
}
var stringContent = await responseContent.ReadAsStringAsync();
@@ -136,7 +138,13 @@ namespace Volo.Abp.Http.Client.DynamicProxying
var client = HttpClientFactory.Create(clientConfig.RemoteServiceName);
- var action = await ApiDescriptionFinder.FindActionAsync(client, remoteServiceConfig.BaseUrl, typeof(TService), invocation.Method);
+ var action = await ApiDescriptionFinder.FindActionAsync(
+ client,
+ remoteServiceConfig.BaseUrl,
+ typeof(TService),
+ invocation.Method
+ );
+
var apiVersion = GetApiVersionInfo(action);
var url = remoteServiceConfig.BaseUrl.EnsureEndsWith('/') + UrlBuilder.GenerateUrlWithParameters(action, invocation.ArgumentsDictionary, apiVersion);
@@ -156,9 +164,11 @@ namespace Volo.Abp.Http.Client.DynamicProxying
)
);
- var response = await client.SendAsync(requestMessage,
+ var response = await client.SendAsync(
+ requestMessage,
HttpCompletionOption.ResponseHeadersRead /*this will buffer only the headers, the content will be used as a stream*/,
- GetCancellationToken());
+ GetCancellationToken()
+ );
if (!response.IsSuccessStatusCode)
{
@@ -196,7 +206,11 @@ namespace Volo.Abp.Http.Client.DynamicProxying
return action.SupportedVersions.Last(); //TODO: Ensure to get the latest version!
}
- protected virtual void AddHeaders(IAbpMethodInvocation invocation, ActionApiDescriptionModel action, HttpRequestMessage requestMessage, ApiVersionInfo apiVersion)
+ protected virtual void AddHeaders(
+ IAbpMethodInvocation invocation,
+ ActionApiDescriptionModel action,
+ HttpRequestMessage requestMessage,
+ ApiVersionInfo apiVersion)
{
//API Version
if (!apiVersion.Version.IsNullOrEmpty())
diff --git a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/UnitOfWorkMemoryDatabaseProvider.cs b/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/UnitOfWorkMemoryDatabaseProvider.cs
index c2c5a1df71..9772bac8a0 100644
--- a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/UnitOfWorkMemoryDatabaseProvider.cs
+++ b/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/UnitOfWorkMemoryDatabaseProvider.cs
@@ -3,6 +3,7 @@ using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.Domain.Repositories.MemoryDb;
using Volo.Abp.MemoryDb;
+using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Uow.MemoryDb
{
@@ -14,17 +15,20 @@ namespace Volo.Abp.Uow.MemoryDb
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IConnectionStringResolver _connectionStringResolver;
private readonly MemoryDatabaseManager _memoryDatabaseManager;
+ private readonly ICurrentTenant _currentTenant;
public UnitOfWorkMemoryDatabaseProvider(
IUnitOfWorkManager unitOfWorkManager,
IConnectionStringResolver connectionStringResolver,
TMemoryDbContext dbContext,
- MemoryDatabaseManager memoryDatabaseManager)
+ MemoryDatabaseManager memoryDatabaseManager,
+ ICurrentTenant currentTenant)
{
_unitOfWorkManager = unitOfWorkManager;
_connectionStringResolver = connectionStringResolver;
DbContext = dbContext;
_memoryDatabaseManager = memoryDatabaseManager;
+ _currentTenant = currentTenant;
}
public Task GetDbContextAsync()
@@ -72,5 +76,34 @@ namespace Volo.Abp.Uow.MemoryDb
return ((MemoryDbDatabaseApi)databaseApi).Database;
}
+
+ private async Task ResolveConnectionStringAsync()
+ {
+ // Multi-tenancy unaware contexts should always use the host connection string
+ if (typeof(TMemoryDbContext).IsDefined(typeof(IgnoreMultiTenancyAttribute), false))
+ {
+ using (_currentTenant.Change(null))
+ {
+ return await _connectionStringResolver.ResolveAsync();
+ }
+ }
+
+ return await _connectionStringResolver.ResolveAsync();
+ }
+
+ [Obsolete("Use ResolveConnectionStringAsync method.")]
+ private string ResolveConnectionString()
+ {
+ // Multi-tenancy unaware contexts should always use the host connection string
+ if (typeof(TMemoryDbContext).IsDefined(typeof(IgnoreMultiTenancyAttribute), false))
+ {
+ using (_currentTenant.Change(null))
+ {
+ return _connectionStringResolver.Resolve();
+ }
+ }
+
+ return _connectionStringResolver.Resolve();
+ }
}
}
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepository.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepository.cs
index 960222679f..12e5987777 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepository.cs
+++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepository.cs
@@ -24,6 +24,8 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
IMongoQueryable GetMongoQueryable();
Task> GetMongoQueryableAsync(CancellationToken cancellationToken = default);
+
+ Task> GetAggregateAsync(CancellationToken cancellationToken = default);
}
public interface IMongoDbRepository : IMongoDbRepository, IRepository
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
index b252c48999..fc520bce81 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
+++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
@@ -16,6 +16,7 @@ using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Guids;
using Volo.Abp.MongoDB;
+using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Domain.Repositories.MongoDB
{
@@ -51,10 +52,34 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
}
[Obsolete("Use GetDbContextAsync method.")]
- protected virtual TMongoDbContext DbContext => DbContextProvider.GetDbContext();
+ protected virtual TMongoDbContext DbContext => GetDbContext();
+
+ [Obsolete("Use GetDbContextAsync method.")]
+ private TMongoDbContext GetDbContext()
+ {
+ // Multi-tenancy unaware entities should always use the host connection string
+ if (!EntityHelper.IsMultiTenant())
+ {
+ using (CurrentTenant.Change(null))
+ {
+ return DbContextProvider.GetDbContext();
+ }
+ }
+
+ return DbContextProvider.GetDbContext();
+ }
protected Task GetDbContextAsync(CancellationToken cancellationToken = default)
{
+ // Multi-tenancy unaware entities should always use the host connection string
+ if (!EntityHelper.IsMultiTenant())
+ {
+ using (CurrentTenant.Change(null))
+ {
+ return DbContextProvider.GetDbContextAsync(GetCancellationToken(cancellationToken));
+ }
+ }
+
return DbContextProvider.GetDbContextAsync(GetCancellationToken(cancellationToken));
}
@@ -314,16 +339,26 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
}
public override async Task DeleteManyAsync(
- IEnumerable entities,
- bool autoSave = false,
- CancellationToken cancellationToken = default)
+ IEnumerable entities,
+ bool autoSave = false,
+ CancellationToken cancellationToken = default)
{
- var entityArray = entities.ToArray();
+ var softDeletedEntities = new List();
+ var hardDeletedEntities = new List();
- foreach (var entity in entityArray)
+ foreach (var entity in entities)
{
await ApplyAbpConceptsForDeletedEntityAsync(entity);
SetNewConcurrencyStamp(entity);
+
+ if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)) && !IsHardDeleted(entity))
+ {
+ softDeletedEntities.Add(entity);
+ }
+ else
+ {
+ hardDeletedEntities.Add(entity);
+ }
}
var dbContext = await GetDbContextAsync(GetCancellationToken(cancellationToken));
@@ -331,54 +366,57 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
if (BulkOperationProvider != null)
{
- await BulkOperationProvider.DeleteManyAsync(this, entityArray, dbContext.SessionHandle, autoSave, cancellationToken);
+ await BulkOperationProvider.DeleteManyAsync(this, entities.ToArray(), dbContext.SessionHandle, autoSave, cancellationToken);
return;
}
- var entitiesCount = entityArray.Count();
-
- if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
+ if (softDeletedEntities.Count > 0)
{
UpdateResult updateResult;
+ var softDeleteEntitiesCount = softDeletedEntities.Count;
+
if (dbContext.SessionHandle != null)
{
updateResult = await collection.UpdateManyAsync(
dbContext.SessionHandle,
- CreateEntitiesFilter(entityArray),
+ CreateEntitiesFilter(softDeletedEntities),
Builders.Update.Set(x => ((ISoftDelete)x).IsDeleted, true)
);
}
else
{
updateResult = await collection.UpdateManyAsync(
- CreateEntitiesFilter(entityArray),
+ CreateEntitiesFilter(softDeletedEntities),
Builders.Update.Set(x => ((ISoftDelete)x).IsDeleted, true)
);
}
- if (updateResult.MatchedCount < entitiesCount)
+ if (updateResult.MatchedCount < softDeleteEntitiesCount)
{
ThrowOptimisticConcurrencyException();
}
}
- else
+
+ if (hardDeletedEntities.Count > 0)
{
DeleteResult deleteResult;
+ var hardDeletedEntitiesCount = hardDeletedEntities.Count;
+
if (dbContext.SessionHandle != null)
{
deleteResult = await collection.DeleteManyAsync(
dbContext.SessionHandle,
- CreateEntitiesFilter(entityArray)
+ CreateEntitiesFilter(hardDeletedEntities)
);
}
else
{
deleteResult = await collection.DeleteManyAsync(
- CreateEntitiesFilter(entityArray)
+ CreateEntitiesFilter(hardDeletedEntities)
);
}
- if (deleteResult.DeletedCount < entitiesCount)
+ if (deleteResult.DeletedCount < hardDeletedEntitiesCount)
{
ThrowOptimisticConcurrencyException();
}
@@ -473,6 +511,17 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
);
}
+ public async Task> GetAggregateAsync(CancellationToken cancellationToken = default)
+ {
+ var dbContext = await GetDbContextAsync(cancellationToken);
+ var collection = await GetCollectionAsync(cancellationToken);
+
+ return ApplyDataFilters(
+ dbContext.SessionHandle != null
+ ? collection.Aggregate(dbContext.SessionHandle)
+ : collection.Aggregate());
+ }
+
protected virtual bool IsHardDeleted(TEntity entity)
{
var hardDeletedEntities = UnitOfWorkManager?.Current?.Items.GetOrDefault(UnitOfWorkItemNames.HardDeletedEntities) as HashSet;
@@ -621,6 +670,22 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
throw new AbpDbConcurrencyException("Database operation expected to affect 1 row but actually affected 0 row. Data may have been modified or deleted since entities were loaded. This exception has been thrown on optimistic concurrency check.");
}
+ protected virtual IAggregateFluent ApplyDataFilters(IAggregateFluent aggregate)
+ {
+ if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)) && DataFilter.IsEnabled())
+ {
+ aggregate = aggregate.Match(e => ((ISoftDelete)e).IsDeleted == false);
+ }
+
+ if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity)) && DataFilter.IsEnabled())
+ {
+ var tenantId = CurrentTenant.Id;
+ aggregate = aggregate.Match(e => ((IMultiTenant)e).TenantId == tenantId);
+ }
+
+ return aggregate;
+ }
+
[Obsolete("This method will be removed in future versions.")]
public QueryableExecutionModel GetExecutionModel()
{
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs
index 90605f416e..bcbdc00d9e 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs
+++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
@@ -16,10 +17,10 @@ namespace Volo.Abp.Domain.Repositories
return repository.ToMongoDbRepository().Database;
}
- public static Task GetDatabaseAsync(this IBasicRepository repository)
+ public static Task GetDatabaseAsync(this IBasicRepository repository, CancellationToken cancellationToken = default)
where TEntity : class, IEntity
{
- return repository.ToMongoDbRepository().GetDatabaseAsync();
+ return repository.ToMongoDbRepository().GetDatabaseAsync(cancellationToken);
}
[Obsolete("Use GetCollectionAsync method.")]
@@ -29,10 +30,10 @@ namespace Volo.Abp.Domain.Repositories
return repository.ToMongoDbRepository().Collection;
}
- public static Task> GetCollectionAsync(this IBasicRepository repository)
+ public static Task> GetCollectionAsync(this IBasicRepository repository, CancellationToken cancellationToken = default)
where TEntity : class, IEntity
{
- return repository.ToMongoDbRepository().GetCollectionAsync();
+ return repository.ToMongoDbRepository().GetCollectionAsync(cancellationToken);
}
[Obsolete("Use GetMongoQueryableAsync method.")]
@@ -42,10 +43,16 @@ namespace Volo.Abp.Domain.Repositories
return repository.ToMongoDbRepository().GetMongoQueryable();
}
- public static Task> GetMongoQueryableAsync(this IBasicRepository repository)
+ public static Task> GetMongoQueryableAsync(this IBasicRepository repository, CancellationToken cancellationToken = default)
where TEntity : class, IEntity
{
- return repository.ToMongoDbRepository().GetMongoQueryableAsync();
+ return repository.ToMongoDbRepository().GetMongoQueryableAsync(cancellationToken);
+ }
+
+ public static Task> GetAggregateAsync(this IBasicRepository repository, CancellationToken cancellationToken = default)
+ where TEntity : class, IEntity
+ {
+ return repository.ToMongoDbRepository().GetAggregateAsync(cancellationToken);
}
public static IMongoDbRepository ToMongoDbRepository(this IBasicRepository repository)
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbTransactionApi.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbTransactionApi.cs
index 6c3ab76ee5..f376c2f804 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbTransactionApi.cs
+++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbTransactionApi.cs
@@ -1,7 +1,7 @@
-using System.Collections.Generic;
-using System.Threading;
+using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
+using Volo.Abp.Threading;
namespace Volo.Abp.Uow.MongoDB
{
@@ -9,19 +9,19 @@ namespace Volo.Abp.Uow.MongoDB
{
public IClientSessionHandle SessionHandle { get; }
- public MongoDbTransactionApi(IClientSessionHandle sessionHandle)
+ protected ICancellationTokenProvider CancellationTokenProvider { get; }
+
+ public MongoDbTransactionApi(
+ IClientSessionHandle sessionHandle,
+ ICancellationTokenProvider cancellationTokenProvider)
{
SessionHandle = sessionHandle;
+ CancellationTokenProvider = cancellationTokenProvider;
}
public async Task CommitAsync()
{
- await SessionHandle.CommitTransactionAsync();
- }
-
- protected void Commit()
- {
- SessionHandle.CommitTransaction();
+ await SessionHandle.CommitTransactionAsync(CancellationTokenProvider.Token);
}
public void Dispose()
@@ -29,14 +29,11 @@ namespace Volo.Abp.Uow.MongoDB
SessionHandle.Dispose();
}
- public void Rollback()
- {
- SessionHandle.AbortTransaction();
- }
-
public async Task RollbackAsync(CancellationToken cancellationToken)
{
- await SessionHandle.AbortTransactionAsync(cancellationToken);
+ await SessionHandle.AbortTransactionAsync(
+ CancellationTokenProvider.FallbackToProvider(cancellationToken)
+ );
}
}
}
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs
index 2b279f9c37..684593fb7f 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs
+++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs
@@ -8,6 +8,7 @@ using MongoDB.Bson;
using MongoDB.Driver;
using Volo.Abp.Data;
using Volo.Abp.MongoDB;
+using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading;
namespace Volo.Abp.Uow.MongoDB
@@ -20,15 +21,18 @@ namespace Volo.Abp.Uow.MongoDB
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IConnectionStringResolver _connectionStringResolver;
private readonly ICancellationTokenProvider _cancellationTokenProvider;
+ private readonly ICurrentTenant _currentTenant;
public UnitOfWorkMongoDbContextProvider(
IUnitOfWorkManager unitOfWorkManager,
IConnectionStringResolver connectionStringResolver,
- ICancellationTokenProvider cancellationTokenProvider)
+ ICancellationTokenProvider cancellationTokenProvider,
+ ICurrentTenant currentTenant)
{
_unitOfWorkManager = unitOfWorkManager;
_connectionStringResolver = connectionStringResolver;
_cancellationTokenProvider = cancellationTokenProvider;
+ _currentTenant = currentTenant;
Logger = NullLogger>.Instance;
}
@@ -54,7 +58,7 @@ namespace Volo.Abp.Uow.MongoDB
$"A {nameof(IMongoDatabase)} instance can only be created inside a unit of work!");
}
- var connectionString = _connectionStringResolver.Resolve();
+ var connectionString = ResolveConnectionString();
var dbContextKey = $"{typeof(TMongoDbContext).FullName}_{connectionString}";
var mongoUrl = new MongoUrl(connectionString);
@@ -81,7 +85,7 @@ namespace Volo.Abp.Uow.MongoDB
$"A {nameof(IMongoDatabase)} instance can only be created inside a unit of work!");
}
- var connectionString = await _connectionStringResolver.ResolveAsync();
+ var connectionString = await ResolveConnectionStringAsync();
var dbContextKey = $"{typeof(TMongoDbContext).FullName}_{connectionString}";
var mongoUrl = new MongoUrl(connectionString);
@@ -178,7 +182,10 @@ namespace Volo.Abp.Uow.MongoDB
unitOfWork.AddTransactionApi(
transactionApiKey,
- new MongoDbTransactionApi(session)
+ new MongoDbTransactionApi(
+ session,
+ _cancellationTokenProvider
+ )
);
dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, session);
@@ -215,7 +222,10 @@ namespace Volo.Abp.Uow.MongoDB
unitOfWork.AddTransactionApi(
transactionApiKey,
- new MongoDbTransactionApi(session)
+ new MongoDbTransactionApi(
+ session,
+ _cancellationTokenProvider
+ )
);
dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, session);
@@ -228,6 +238,35 @@ namespace Volo.Abp.Uow.MongoDB
return dbContext;
}
+ private async Task ResolveConnectionStringAsync()
+ {
+ // Multi-tenancy unaware contexts should always use the host connection string
+ if (typeof(TMongoDbContext).IsDefined(typeof(IgnoreMultiTenancyAttribute), false))
+ {
+ using (_currentTenant.Change(null))
+ {
+ return await _connectionStringResolver.ResolveAsync();
+ }
+ }
+
+ return await _connectionStringResolver.ResolveAsync();
+ }
+
+ [Obsolete("Use ResolveConnectionStringAsync method.")]
+ private string ResolveConnectionString()
+ {
+ // Multi-tenancy unaware contexts should always use the host connection string
+ if (typeof(TMongoDbContext).IsDefined(typeof(IgnoreMultiTenancyAttribute), false))
+ {
+ using (_currentTenant.Change(null))
+ {
+ return _connectionStringResolver.Resolve();
+ }
+ }
+
+ return _connectionStringResolver.Resolve();
+ }
+
protected virtual CancellationToken GetCancellationToken(CancellationToken preferredValue = default)
{
return _cancellationTokenProvider.FallbackToProvider(preferredValue);
diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ISupportsRollback.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ISupportsRollback.cs
index 4c211d652d..2286a386b8 100644
--- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ISupportsRollback.cs
+++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ISupportsRollback.cs
@@ -5,8 +5,6 @@ namespace Volo.Abp.Uow
{
public interface ISupportsRollback
{
- void Rollback();
-
Task RollbackAsync(CancellationToken cancellationToken);
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs
index 955fa6b449..878c03d629 100644
--- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs
+++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs
@@ -262,27 +262,6 @@ namespace Volo.Abp.Uow
}
}
- protected virtual void RollbackAll()
- {
- foreach (var databaseApi in GetAllActiveDatabaseApis())
- {
- try
- {
- (databaseApi as ISupportsRollback)?.Rollback();
- }
- catch { }
- }
-
- foreach (var transactionApi in GetAllActiveTransactionApis())
- {
- try
- {
- (transactionApi as ISupportsRollback)?.Rollback();
- }
- catch { }
- }
- }
-
protected virtual async Task RollbackAllAsync(CancellationToken cancellationToken)
{
foreach (var databaseApi in GetAllActiveDatabaseApis())
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController.cs
new file mode 100644
index 0000000000..15491f9b21
--- /dev/null
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController.cs
@@ -0,0 +1,36 @@
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Shouldly;
+using Volo.Abp.Content;
+
+namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
+{
+ [Route("api/remote-stream-content-test")]
+ public class RemoteStreamContentTestController : AbpController
+ {
+ [HttpGet]
+ [Route("Download")]
+ public async Task DownloadAsync()
+ {
+ var memoryStream = new MemoryStream();
+ await memoryStream.WriteAsync(Encoding.UTF8.GetBytes("DownloadAsync"));
+
+ return new RemoteStreamContent(memoryStream)
+ {
+ ContentType = "application/rtf"
+ };
+ }
+
+ [HttpPost]
+ [Route("Upload")]
+ public async Task UploadAsync([FromBody]IRemoteStreamContent streamContent)
+ {
+ using (var reader = new StreamReader(streamContent.GetStream()))
+ {
+ return await reader.ReadToEndAsync() + ":" + streamContent.ContentType;
+ }
+ }
+ }
+}
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController_Tests.cs
new file mode 100644
index 0000000000..3d49a5b3ff
--- /dev/null
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController_Tests.cs
@@ -0,0 +1,37 @@
+using System.IO;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using Shouldly;
+using Xunit;
+
+namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
+{
+ public class RemoteStreamContentTestController_Tests : AspNetCoreMvcTestBase
+ {
+ [Fact]
+ public async Task DownloadAsync()
+ {
+ var result = await GetResponseAsync("/api/remote-stream-content-test/download");
+ result.Content.Headers.ContentType?.ToString().ShouldBe("application/rtf");
+ (await result.Content.ReadAsStringAsync()).ShouldBe("DownloadAsync");
+ }
+
+ [Fact]
+ public async Task UploadAsync()
+ {
+ using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/remote-stream-content-test/upload"))
+ {
+ var memoryStream = new MemoryStream();
+ await memoryStream.WriteAsync(Encoding.UTF8.GetBytes("UploadAsync"));
+ memoryStream.Position = 0;
+ requestMessage.Content = new StreamContent(memoryStream);
+ requestMessage.Content.Headers.Add("Content-Type", "application/rtf");
+
+ var response = await Client.SendAsync(requestMessage);
+
+ (await response.Content.ReadAsStringAsync()).ShouldBe("UploadAsync:application/rtf");
+ }
+ }
+ }
+}
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json
index 9812ddc326..994844bec9 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json
@@ -3,7 +3,7 @@
"name": "asp.net",
"private": true,
"dependencies": {
- "@abp/aspnetcore.mvc.ui.theme.shared": "^4.2.0-rc.2",
+ "@abp/aspnetcore.mvc.ui.theme.shared": "^4.2.0",
"highlight.js": "^9.13.1"
},
"devDependencies": {}
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock
index 2a08d4af29..a50932965e 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock
@@ -2,30 +2,30 @@
# yarn lockfile v1
-"@abp/aspnetcore.mvc.ui.theme.shared@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0-rc.2.tgz#9ff3af53b667e747c06d3f067a0f68a938ac72a8"
- integrity sha512-qsJ6UaUxyOJOHxsqVjlUGhCvQUnbXgGzLvFPJZYLpnWm6ZvE1KAgJnQHL46YSllCDT0meVqHt9byjOCRJUMm9Q==
- dependencies:
- "@abp/aspnetcore.mvc.ui" "~4.2.0-rc.2"
- "@abp/bootstrap" "~4.2.0-rc.2"
- "@abp/bootstrap-datepicker" "~4.2.0-rc.2"
- "@abp/datatables.net-bs4" "~4.2.0-rc.2"
- "@abp/font-awesome" "~4.2.0-rc.2"
- "@abp/jquery-form" "~4.2.0-rc.2"
- "@abp/jquery-validation-unobtrusive" "~4.2.0-rc.2"
- "@abp/lodash" "~4.2.0-rc.2"
- "@abp/luxon" "~4.2.0-rc.2"
- "@abp/malihu-custom-scrollbar-plugin" "~4.2.0-rc.2"
- "@abp/select2" "~4.2.0-rc.2"
- "@abp/sweetalert" "~4.2.0-rc.2"
- "@abp/timeago" "~4.2.0-rc.2"
- "@abp/toastr" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0-rc.2.tgz#726f45c7ff12e69e970fb89b4adfb15502a11576"
- integrity sha512-EzTYQ8XzXIprfK95LyYc1Ci3to3dNlBOSzkkYfYDXkSR5/SyBKckCTd5FL4c7yrs+qBoJMxKWDyWz+pmf6PIJA==
+"@abp/aspnetcore.mvc.ui.theme.shared@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0.tgz#a72b5e1cefa27e658b7f072a8c2c1b4ee12baef8"
+ integrity sha512-bgWwBBJA/74kFGWh7O+lzb+inV5LOlYOpDoCNAL0XgQTrutrPNHwsk5ZnGVfhSYrBgk47HGVZDwsqKMCTRn1ig==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui" "~4.2.0"
+ "@abp/bootstrap" "~4.2.0"
+ "@abp/bootstrap-datepicker" "~4.2.0"
+ "@abp/datatables.net-bs4" "~4.2.0"
+ "@abp/font-awesome" "~4.2.0"
+ "@abp/jquery-form" "~4.2.0"
+ "@abp/jquery-validation-unobtrusive" "~4.2.0"
+ "@abp/lodash" "~4.2.0"
+ "@abp/luxon" "~4.2.0"
+ "@abp/malihu-custom-scrollbar-plugin" "~4.2.0"
+ "@abp/select2" "~4.2.0"
+ "@abp/sweetalert" "~4.2.0"
+ "@abp/timeago" "~4.2.0"
+ "@abp/toastr" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0.tgz#9c090f64a33d31962936d8d53b345afeaa9f2ba3"
+ integrity sha512-Qt3MUZ41vuvnIVEAYxyOm1mflvFwwvKYsEjFBbePBnwaYL7udooiIFxTEm4FBh3EQJOi+8T84rnXqiIXj4Pi8A==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@@ -36,145 +36,145 @@
micromatch "^4.0.2"
path "^0.12.7"
-"@abp/bootstrap-datepicker@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0-rc.2.tgz#f2a6d013321c98f8c9a7533087360fce9a5fd074"
- integrity sha512-n3gLYLL7hHX83gurN5iRkpairrw0oAyg+Bc6SeIbNAdorun9wBJn7IlmvXxGPn1xK5iDKktRSeWJ885fMgkuWg==
+"@abp/bootstrap-datepicker@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0.tgz#92abebe044a91b94b8a3b85560b501120a0fa500"
+ integrity sha512-bhEa/+zGVX00vkXGrbKI/hcl9o5Xgqwb27by9ZQqxk9Go4lwsEP/7lrXM49Cg8XZTT3L0/lYclneEMDrqGafaQ==
dependencies:
bootstrap-datepicker "^1.9.0"
-"@abp/bootstrap@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0-rc.2.tgz#49250657f667f7553f3c2149fda43f7535de989b"
- integrity sha512-WYdyDQzgFlltxqdYINAMVWjXiiDAx780fTJEd3YKLSzxmVGBfoW4cfFzw8vr/G/EMYrgAPQtrIS+BRlFAJXXGQ==
+"@abp/bootstrap@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0.tgz#c7ce82ead40bf0d62a318f67f180663ec76aa53c"
+ integrity sha512-E1gEX0ct67KFjKiZB6eQcIYJ3TS/pF1S4CxknBVCd77Zs03bHI+eEgBNlwcYriVBbQo+vheUQAaACbi+e2mm3Q==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
bootstrap "^4.5.0"
bootstrap-v4-rtl "4.4.1-2"
-"@abp/core@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0-rc.2.tgz#dc18c3b8f294563ba62c000c026f5ceb86030456"
- integrity sha512-YJz4xUwb/mv/Xi/WuPz2SF/LD22P/UJ+psb+35ezOeuj020IAdaunk8LdrU5TfaZqNe5WpGszKMA+jO9ydNuqA==
+"@abp/core@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0.tgz#20da3d1bab30e80d8864915fdd67e99db729be71"
+ integrity sha512-Cfa6Ck+Tr7isVpNxo9qT9eKByLadDErA+QVjeps7qYq9ztIpIz/7Yl85tHYEH0YPO9y2zcSOvxjy5SCBXlph5Q==
dependencies:
- "@abp/utils" "^4.2.0-rc.2"
+ "@abp/utils" "^4.2.0"
-"@abp/datatables.net-bs4@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0-rc.2.tgz#0d14886aa756ca707dd365b423b40d84c658268e"
- integrity sha512-kX+NrGkisy7IMi+xL69dPaPOYNLBZ4Vp7xCvJqNhdc5Sh6Rn1P0bLvxFKG065mBMfgW8tyFNnN3c5WzwcRFSmg==
+"@abp/datatables.net-bs4@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0.tgz#b5cb47235079a4063c5ff8ce78e65596fa587709"
+ integrity sha512-N4hp2xCst1qavt07Nf+zXlvbZfeSah64VuMjsZgaimHMlDjxg6zVsTHLgLfzwfPV/eOBrGiecPEuvfEeaqcw4A==
dependencies:
- "@abp/datatables.net" "~4.2.0-rc.2"
+ "@abp/datatables.net" "~4.2.0"
datatables.net-bs4 "^1.10.21"
-"@abp/datatables.net@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0-rc.2.tgz#a82ac16c1644a92d01ba63bf57e0d3784eb00f2f"
- integrity sha512-bEQ6QSUN65lJ8fK8wOVE16cayDI64EgyVb3qZAzWUncxPyLLa5s5zlDjcQ98D3An+x3tG2CdmEEWjlAgWdaf1g==
+"@abp/datatables.net@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0.tgz#2e0273c3212e5a62fc8b4138e4570fb27143f701"
+ integrity sha512-33ZkaorkVkPQ7HNtDjyIvcVbvAdFm8V+gFN+xMQZhA10wMlMGrKzVJjriv4NhNpPjtB4/owhOv6wobiuWBrGiA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
datatables.net "^1.10.21"
-"@abp/font-awesome@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0-rc.2.tgz#6c72ef7ae00beda565e9836c8214ccf074ea7e4b"
- integrity sha512-bEQPGyVsKV7aQtVwG4UIcG+DMneBD7jcjX3eFqjOlGhQq3ODbNld5IPXHO+JnHDLt5NOzrePQLUzPhsvCIwhGA==
+"@abp/font-awesome@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0.tgz#a637d164634b0df862e4ea620736afae282c71c9"
+ integrity sha512-P8OXp+XIZj6l7cNJ5+7Lpl8iixI/bHGSPkATggaOYZ2EWoNR3B/8pj7p44weP2bCAvUEvaxk214BKlpAslo8eQ==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
"@fortawesome/fontawesome-free" "^5.13.0"
-"@abp/jquery-form@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0-rc.2.tgz#a4726794f78cf69dd75c0adda3dca3ed623f02d8"
- integrity sha512-rOGXYTTiQUD2HWTabh0+Ot6LX4PEObd3DW3ikBHZSnfen7W0OgnLdqNaunHYSEV3UUgCAZHaX0wQd4SM0pRMLg==
+"@abp/jquery-form@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0.tgz#12b88a79a69f7d3b15aed8c7ca3ff5bc9f526f22"
+ integrity sha512-lxvXhA4kg002gmDTWgoE6TcQWDe6kBcpV4KBB7aK/6LjK3noeT29SPX0kvKxjoUKyM5TqT2Hx7rg4jgtICjFFA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-form "^4.3.0"
-"@abp/jquery-validation-unobtrusive@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0-rc.2.tgz#5dee22e1bcbd44bd8e2584d37d79e8313cf615ec"
- integrity sha512-xk56Otr6PG/bED2yJuPo0OhwcgS4FQQXySgPD9e7mlZQcjxZ4LvmRU/btoNoxSHKYUBLKRfEOYOqRTxJhrH0eA==
+"@abp/jquery-validation-unobtrusive@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0.tgz#05bcd303ec1e22b85389d03a8941eb898bac354f"
+ integrity sha512-mtvUcoTD5XSurMFI5cybgWzFI9bn35vU1PvH5NJxJitjJ7sg9gjtLf9WOIddIy4FdqmprhbG2YnR32GITOwFhg==
dependencies:
- "@abp/jquery-validation" "~4.2.0-rc.2"
+ "@abp/jquery-validation" "~4.2.0"
jquery-validation-unobtrusive "^3.2.11"
-"@abp/jquery-validation@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0-rc.2.tgz#594b9132d1eafebed60be10d219bc9e8b15f18b6"
- integrity sha512-LkNI3X7gpYYkI3DnCTZ1KIV6ykKMqw6pLZhFvTZz7GliZWE1jHtFos4U6lWe2XnMjnFeVeY6rPFM/1LaamfCKg==
+"@abp/jquery-validation@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0.tgz#a09d7cf2abf8ccf0c59f27eadacb030fb2067bbe"
+ integrity sha512-/nvJrs1pt3LJX+SgH3FtDPfCDrcl4M0LDxjV7hf0Y1jtyhvWOQiyJMb8FKzMweTTEOd0pHG/GvOKd90STabSiw==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-validation "^1.19.2"
-"@abp/jquery@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0-rc.2.tgz#146589cbf4397be727d38798d557f3879ae51057"
- integrity sha512-yTYk5rRG3qnRKnA/pSXZNH/+KJcJ2Wo5BUtt3G8oKAe+no0Au1BoCV9j7JNiSnLXkFVWFuRwEZCh+cp6ngACng==
+"@abp/jquery@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0.tgz#0a24488198ca6c9b84273fa028b853ee9f94f3a7"
+ integrity sha512-6a42Iy7knhgzvQUvCHenrVnPDKhsOyqgZkPxs9pa9x/wNapSch+jLM7u1ezKAFj/Ai4w9yG/yqP+4YE8seZDZw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
jquery "~3.5.1"
-"@abp/lodash@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0-rc.2.tgz#f0a238991c288f439e2751938a39d434dd7883e7"
- integrity sha512-En9gZD8TDY8ZvZqHVsv3cP2EsRdPRsGD0ncUYOvlNG/sc+MZpRmZ+xOLws1wXS83IxGAxzPdCFEu0biJlyOyxg==
+"@abp/lodash@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0.tgz#74dfac7d70f1563df2b78c5ebd0b2450e11c4c42"
+ integrity sha512-5hpjxWZJPvjMIY7FCCw/v/B+JzJbB/yuoioRzcU4vrisY9uRq54vVYcX7hH1DldsJFPTuXY3Id1WBflHA5I9Aw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
lodash "^4.17.15"
-"@abp/luxon@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0-rc.2.tgz#ace30caacf6abcce1559b65046ea55e47e1cb8a2"
- integrity sha512-ivhOadlaeBh6Pi3S5Bo0pb4EPCEjMFL5N5tZXGGieZt7EnF+4uiXbKJVErXNCDtX1jhJT/3HGqmdxa+WynUE0A==
+"@abp/luxon@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0.tgz#9cd02faa02cda1315f3e23ae204991ef47d6ae7c"
+ integrity sha512-dwtv2kqWCDyQADA1Os0aIy6Au2PhBtN6q9kukLWCvYmQZI23OKuEBMSngbJVTqEPfz0LV6CWbsWCUC3okAs46A==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
luxon "^1.24.1"
-"@abp/malihu-custom-scrollbar-plugin@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0-rc.2.tgz#483668c09e13b0ebcea16320a16f8517fcdd53ee"
- integrity sha512-IYOwJcWyJkn/gdp4VkEYCv2Gi5+Boxe7pE7hA49gxgllHiFV0ABDFrRg4h8MbyJd80iwvVPo8t8ouvn4Snm+gQ==
+"@abp/malihu-custom-scrollbar-plugin@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0.tgz#2f8538df5567a2cf227998e4e2fb9a44b6e814eb"
+ integrity sha512-3D5REdR7yw2sRRfm3Oi+qlhDABLrKvfU/l7JcCJy+vrBvadx3e3pTdTLXsGptypPN3x/Qr400LgwIrrgyefN8g==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
malihu-custom-scrollbar-plugin "^3.1.5"
-"@abp/select2@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0-rc.2.tgz#d11e808dac90e09e14025b6ba6dabed683a9b1fb"
- integrity sha512-fENomkoAML+NQWvZ/ecjvqnXtvrzJKyChwj9Ul12c+Noi6boeuFDbhi/OG6qCrSzDnNBrehHVXBLFxT9sIL0OA==
+"@abp/select2@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0.tgz#eb05d22b1390c037911ba25e5ca0f2ed508a93b1"
+ integrity sha512-VlNoa9+F1/kGmaEI2wbL/cRNeAEpp0UdLpbadAnsmpUIODxCULCWS556Q4Y6Ff4CzYtzkYz2qaJ8T8pn+3EOcA==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
select2 "^4.0.13"
-"@abp/sweetalert@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0-rc.2.tgz#2359eeb9e4b34c4cbb3aaed11136ea3d280bd677"
- integrity sha512-oQPj2vKPNAOvBECgJFdDwvJ8nwQ54ZPsAW1XS3XSkFz3YwWn4Xt9eZK6vecHloYckSckrFtsN/DSQI8ao/uIFg==
+"@abp/sweetalert@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0.tgz#b1daf641f27f0c8c2e246d364d6285c133faf773"
+ integrity sha512-AarV/L031xNB1gk/OYEUxkKZmls7zTwovS2t3ZrmwXXoav7nBCSPjEf1ByR2yhZRU/Yo1SNY/CNQQ4dgyf7Xng==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
sweetalert "^2.1.2"
-"@abp/timeago@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0-rc.2.tgz#d243acff635978068ec579c83a34d0680616c5ef"
- integrity sha512-TF1dt9ro3BQnfVetDzbOkedSIncSwvPfnHKMY1xcLG2h0c6ke2PjDQ+4QJrtigggT4vfgmQtRrs/zJxjzWS7qw==
+"@abp/timeago@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0.tgz#9b15c496b7e63df93921d41de9e9eaf35a8dccbe"
+ integrity sha512-hyuLVGluHxtWEhR0VakPx5UCbyPcfq4lECEgHhI62PvH0xcSNNZ3bp1QnBTd3se/HAYvwA5sCwJY0YXQgUF2UQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
timeago "^1.6.7"
-"@abp/toastr@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0-rc.2.tgz#4e76f4b7068f92b267b725ad597b8315e6b615bc"
- integrity sha512-UJVuQWc7py54JC35RrH+MwAZsOoOhejxX+3aonz8Io2rgFFj0YwK5U+vItRNM3iabSqTcIExcSD3XL2TmQyVzg==
+"@abp/toastr@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0.tgz#400e2f28b19c72b131ca32aa188ff5151d035752"
+ integrity sha512-tuGZd3kXqj1t/Y1xN8sOUH1KxiArYKD7xkhuajoOS65Ex5ad8mHPuzCtu8Pv+KL8TVFys9x3U3Tg24DQ6ASjhQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
toastr "^2.1.4"
-"@abp/utils@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0-rc.2.tgz#43c27d421da8e58a5d74c0a2df8742efa827c842"
- integrity sha512-6gSLTP9s88aFjxm+fU2iZMzv5Eoe5/va2PHTAoQJA4BaP/SpFRGts3cT4HYWPfAbmzZVZ+tvjuYd3P6d3FCAhw==
+"@abp/utils@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0.tgz#073330e3e3f6ee61892f50260e48dbe1b05df35e"
+ integrity sha512-75qR3SdiAa75wqleAx9sUMXLj4m9duuBo5+2sVv7Y29GcEyKUPvm8B1s6tksvSGA0e3vnFTHeVEc10eD1xKHSQ==
dependencies:
just-compare "^1.3.0"
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json
index a87af271a2..cc12cde188 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json
@@ -3,8 +3,8 @@
"name": "asp.net",
"private": true,
"dependencies": {
- "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.0-rc.2",
- "@abp/prismjs": "^4.2.0-rc.2"
+ "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.0",
+ "@abp/prismjs": "^4.2.0"
},
"devDependencies": {}
}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock
index 1c363e7ca2..c3d415ce3b 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock
@@ -2,37 +2,37 @@
# yarn lockfile v1
-"@abp/aspnetcore.mvc.ui.theme.basic@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-4.2.0-rc.2.tgz#f4625e18fd3704d432913e9de59c7183770ea485"
- integrity sha512-wwOFcrICyhgAcBq7zgdIkYQ8Mov0g1iYrjoRZRiUzBYG4wkcAO9POM9asE6uvY5sD/hd0cRoXSZOcNKUt0J1SA==
- dependencies:
- "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui.theme.shared@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0-rc.2.tgz#9ff3af53b667e747c06d3f067a0f68a938ac72a8"
- integrity sha512-qsJ6UaUxyOJOHxsqVjlUGhCvQUnbXgGzLvFPJZYLpnWm6ZvE1KAgJnQHL46YSllCDT0meVqHt9byjOCRJUMm9Q==
- dependencies:
- "@abp/aspnetcore.mvc.ui" "~4.2.0-rc.2"
- "@abp/bootstrap" "~4.2.0-rc.2"
- "@abp/bootstrap-datepicker" "~4.2.0-rc.2"
- "@abp/datatables.net-bs4" "~4.2.0-rc.2"
- "@abp/font-awesome" "~4.2.0-rc.2"
- "@abp/jquery-form" "~4.2.0-rc.2"
- "@abp/jquery-validation-unobtrusive" "~4.2.0-rc.2"
- "@abp/lodash" "~4.2.0-rc.2"
- "@abp/luxon" "~4.2.0-rc.2"
- "@abp/malihu-custom-scrollbar-plugin" "~4.2.0-rc.2"
- "@abp/select2" "~4.2.0-rc.2"
- "@abp/sweetalert" "~4.2.0-rc.2"
- "@abp/timeago" "~4.2.0-rc.2"
- "@abp/toastr" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0-rc.2.tgz#726f45c7ff12e69e970fb89b4adfb15502a11576"
- integrity sha512-EzTYQ8XzXIprfK95LyYc1Ci3to3dNlBOSzkkYfYDXkSR5/SyBKckCTd5FL4c7yrs+qBoJMxKWDyWz+pmf6PIJA==
+"@abp/aspnetcore.mvc.ui.theme.basic@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-4.2.0.tgz#01d6aab8a31fd6ea828b753805f1ba9a9165975f"
+ integrity sha512-d+7YubPbuBRY8tjqBxS4I1gyxekjg8Z0X9QaDrf/SGQBoWpIdbG09AekNdddKNkimWcPg4UgUytahPuX9f17ZA==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui.theme.shared@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0.tgz#a72b5e1cefa27e658b7f072a8c2c1b4ee12baef8"
+ integrity sha512-bgWwBBJA/74kFGWh7O+lzb+inV5LOlYOpDoCNAL0XgQTrutrPNHwsk5ZnGVfhSYrBgk47HGVZDwsqKMCTRn1ig==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui" "~4.2.0"
+ "@abp/bootstrap" "~4.2.0"
+ "@abp/bootstrap-datepicker" "~4.2.0"
+ "@abp/datatables.net-bs4" "~4.2.0"
+ "@abp/font-awesome" "~4.2.0"
+ "@abp/jquery-form" "~4.2.0"
+ "@abp/jquery-validation-unobtrusive" "~4.2.0"
+ "@abp/lodash" "~4.2.0"
+ "@abp/luxon" "~4.2.0"
+ "@abp/malihu-custom-scrollbar-plugin" "~4.2.0"
+ "@abp/select2" "~4.2.0"
+ "@abp/sweetalert" "~4.2.0"
+ "@abp/timeago" "~4.2.0"
+ "@abp/toastr" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0.tgz#9c090f64a33d31962936d8d53b345afeaa9f2ba3"
+ integrity sha512-Qt3MUZ41vuvnIVEAYxyOm1mflvFwwvKYsEjFBbePBnwaYL7udooiIFxTEm4FBh3EQJOi+8T84rnXqiIXj4Pi8A==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@@ -43,162 +43,162 @@
micromatch "^4.0.2"
path "^0.12.7"
-"@abp/bootstrap-datepicker@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0-rc.2.tgz#f2a6d013321c98f8c9a7533087360fce9a5fd074"
- integrity sha512-n3gLYLL7hHX83gurN5iRkpairrw0oAyg+Bc6SeIbNAdorun9wBJn7IlmvXxGPn1xK5iDKktRSeWJ885fMgkuWg==
+"@abp/bootstrap-datepicker@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0.tgz#92abebe044a91b94b8a3b85560b501120a0fa500"
+ integrity sha512-bhEa/+zGVX00vkXGrbKI/hcl9o5Xgqwb27by9ZQqxk9Go4lwsEP/7lrXM49Cg8XZTT3L0/lYclneEMDrqGafaQ==
dependencies:
bootstrap-datepicker "^1.9.0"
-"@abp/bootstrap@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0-rc.2.tgz#49250657f667f7553f3c2149fda43f7535de989b"
- integrity sha512-WYdyDQzgFlltxqdYINAMVWjXiiDAx780fTJEd3YKLSzxmVGBfoW4cfFzw8vr/G/EMYrgAPQtrIS+BRlFAJXXGQ==
+"@abp/bootstrap@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0.tgz#c7ce82ead40bf0d62a318f67f180663ec76aa53c"
+ integrity sha512-E1gEX0ct67KFjKiZB6eQcIYJ3TS/pF1S4CxknBVCd77Zs03bHI+eEgBNlwcYriVBbQo+vheUQAaACbi+e2mm3Q==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
bootstrap "^4.5.0"
bootstrap-v4-rtl "4.4.1-2"
-"@abp/clipboard@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-4.2.0-rc.2.tgz#0cda5f6f3624e68e1ec7290517364d02f2b60e42"
- integrity sha512-wF/d8Xuq+ORUkiWgDorM7rxueiygtELaZKlRDYzmQRnwJN4vS1q/4/UtPaLSlcGhHxWuxu2XSWQtzcphfBjFWA==
+"@abp/clipboard@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-4.2.0.tgz#860220df1d57ef64e864401d56cb5cf7068d5861"
+ integrity sha512-yBgMDhpqPEHp9N9//Ur1BEIOicFIoKBut75PMz9XPOttLyqCmqHYEPj/jgAkUzLd5O+fJM9TE3yGNM7YdRbRPg==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
clipboard "^2.0.6"
-"@abp/core@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0-rc.2.tgz#dc18c3b8f294563ba62c000c026f5ceb86030456"
- integrity sha512-YJz4xUwb/mv/Xi/WuPz2SF/LD22P/UJ+psb+35ezOeuj020IAdaunk8LdrU5TfaZqNe5WpGszKMA+jO9ydNuqA==
+"@abp/core@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0.tgz#20da3d1bab30e80d8864915fdd67e99db729be71"
+ integrity sha512-Cfa6Ck+Tr7isVpNxo9qT9eKByLadDErA+QVjeps7qYq9ztIpIz/7Yl85tHYEH0YPO9y2zcSOvxjy5SCBXlph5Q==
dependencies:
- "@abp/utils" "^4.2.0-rc.2"
+ "@abp/utils" "^4.2.0"
-"@abp/datatables.net-bs4@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0-rc.2.tgz#0d14886aa756ca707dd365b423b40d84c658268e"
- integrity sha512-kX+NrGkisy7IMi+xL69dPaPOYNLBZ4Vp7xCvJqNhdc5Sh6Rn1P0bLvxFKG065mBMfgW8tyFNnN3c5WzwcRFSmg==
+"@abp/datatables.net-bs4@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0.tgz#b5cb47235079a4063c5ff8ce78e65596fa587709"
+ integrity sha512-N4hp2xCst1qavt07Nf+zXlvbZfeSah64VuMjsZgaimHMlDjxg6zVsTHLgLfzwfPV/eOBrGiecPEuvfEeaqcw4A==
dependencies:
- "@abp/datatables.net" "~4.2.0-rc.2"
+ "@abp/datatables.net" "~4.2.0"
datatables.net-bs4 "^1.10.21"
-"@abp/datatables.net@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0-rc.2.tgz#a82ac16c1644a92d01ba63bf57e0d3784eb00f2f"
- integrity sha512-bEQ6QSUN65lJ8fK8wOVE16cayDI64EgyVb3qZAzWUncxPyLLa5s5zlDjcQ98D3An+x3tG2CdmEEWjlAgWdaf1g==
+"@abp/datatables.net@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0.tgz#2e0273c3212e5a62fc8b4138e4570fb27143f701"
+ integrity sha512-33ZkaorkVkPQ7HNtDjyIvcVbvAdFm8V+gFN+xMQZhA10wMlMGrKzVJjriv4NhNpPjtB4/owhOv6wobiuWBrGiA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
datatables.net "^1.10.21"
-"@abp/font-awesome@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0-rc.2.tgz#6c72ef7ae00beda565e9836c8214ccf074ea7e4b"
- integrity sha512-bEQPGyVsKV7aQtVwG4UIcG+DMneBD7jcjX3eFqjOlGhQq3ODbNld5IPXHO+JnHDLt5NOzrePQLUzPhsvCIwhGA==
+"@abp/font-awesome@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0.tgz#a637d164634b0df862e4ea620736afae282c71c9"
+ integrity sha512-P8OXp+XIZj6l7cNJ5+7Lpl8iixI/bHGSPkATggaOYZ2EWoNR3B/8pj7p44weP2bCAvUEvaxk214BKlpAslo8eQ==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
"@fortawesome/fontawesome-free" "^5.13.0"
-"@abp/jquery-form@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0-rc.2.tgz#a4726794f78cf69dd75c0adda3dca3ed623f02d8"
- integrity sha512-rOGXYTTiQUD2HWTabh0+Ot6LX4PEObd3DW3ikBHZSnfen7W0OgnLdqNaunHYSEV3UUgCAZHaX0wQd4SM0pRMLg==
+"@abp/jquery-form@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0.tgz#12b88a79a69f7d3b15aed8c7ca3ff5bc9f526f22"
+ integrity sha512-lxvXhA4kg002gmDTWgoE6TcQWDe6kBcpV4KBB7aK/6LjK3noeT29SPX0kvKxjoUKyM5TqT2Hx7rg4jgtICjFFA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-form "^4.3.0"
-"@abp/jquery-validation-unobtrusive@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0-rc.2.tgz#5dee22e1bcbd44bd8e2584d37d79e8313cf615ec"
- integrity sha512-xk56Otr6PG/bED2yJuPo0OhwcgS4FQQXySgPD9e7mlZQcjxZ4LvmRU/btoNoxSHKYUBLKRfEOYOqRTxJhrH0eA==
+"@abp/jquery-validation-unobtrusive@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0.tgz#05bcd303ec1e22b85389d03a8941eb898bac354f"
+ integrity sha512-mtvUcoTD5XSurMFI5cybgWzFI9bn35vU1PvH5NJxJitjJ7sg9gjtLf9WOIddIy4FdqmprhbG2YnR32GITOwFhg==
dependencies:
- "@abp/jquery-validation" "~4.2.0-rc.2"
+ "@abp/jquery-validation" "~4.2.0"
jquery-validation-unobtrusive "^3.2.11"
-"@abp/jquery-validation@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0-rc.2.tgz#594b9132d1eafebed60be10d219bc9e8b15f18b6"
- integrity sha512-LkNI3X7gpYYkI3DnCTZ1KIV6ykKMqw6pLZhFvTZz7GliZWE1jHtFos4U6lWe2XnMjnFeVeY6rPFM/1LaamfCKg==
+"@abp/jquery-validation@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0.tgz#a09d7cf2abf8ccf0c59f27eadacb030fb2067bbe"
+ integrity sha512-/nvJrs1pt3LJX+SgH3FtDPfCDrcl4M0LDxjV7hf0Y1jtyhvWOQiyJMb8FKzMweTTEOd0pHG/GvOKd90STabSiw==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-validation "^1.19.2"
-"@abp/jquery@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0-rc.2.tgz#146589cbf4397be727d38798d557f3879ae51057"
- integrity sha512-yTYk5rRG3qnRKnA/pSXZNH/+KJcJ2Wo5BUtt3G8oKAe+no0Au1BoCV9j7JNiSnLXkFVWFuRwEZCh+cp6ngACng==
+"@abp/jquery@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0.tgz#0a24488198ca6c9b84273fa028b853ee9f94f3a7"
+ integrity sha512-6a42Iy7knhgzvQUvCHenrVnPDKhsOyqgZkPxs9pa9x/wNapSch+jLM7u1ezKAFj/Ai4w9yG/yqP+4YE8seZDZw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
jquery "~3.5.1"
-"@abp/lodash@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0-rc.2.tgz#f0a238991c288f439e2751938a39d434dd7883e7"
- integrity sha512-En9gZD8TDY8ZvZqHVsv3cP2EsRdPRsGD0ncUYOvlNG/sc+MZpRmZ+xOLws1wXS83IxGAxzPdCFEu0biJlyOyxg==
+"@abp/lodash@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0.tgz#74dfac7d70f1563df2b78c5ebd0b2450e11c4c42"
+ integrity sha512-5hpjxWZJPvjMIY7FCCw/v/B+JzJbB/yuoioRzcU4vrisY9uRq54vVYcX7hH1DldsJFPTuXY3Id1WBflHA5I9Aw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
lodash "^4.17.15"
-"@abp/luxon@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0-rc.2.tgz#ace30caacf6abcce1559b65046ea55e47e1cb8a2"
- integrity sha512-ivhOadlaeBh6Pi3S5Bo0pb4EPCEjMFL5N5tZXGGieZt7EnF+4uiXbKJVErXNCDtX1jhJT/3HGqmdxa+WynUE0A==
+"@abp/luxon@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0.tgz#9cd02faa02cda1315f3e23ae204991ef47d6ae7c"
+ integrity sha512-dwtv2kqWCDyQADA1Os0aIy6Au2PhBtN6q9kukLWCvYmQZI23OKuEBMSngbJVTqEPfz0LV6CWbsWCUC3okAs46A==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
luxon "^1.24.1"
-"@abp/malihu-custom-scrollbar-plugin@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0-rc.2.tgz#483668c09e13b0ebcea16320a16f8517fcdd53ee"
- integrity sha512-IYOwJcWyJkn/gdp4VkEYCv2Gi5+Boxe7pE7hA49gxgllHiFV0ABDFrRg4h8MbyJd80iwvVPo8t8ouvn4Snm+gQ==
+"@abp/malihu-custom-scrollbar-plugin@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0.tgz#2f8538df5567a2cf227998e4e2fb9a44b6e814eb"
+ integrity sha512-3D5REdR7yw2sRRfm3Oi+qlhDABLrKvfU/l7JcCJy+vrBvadx3e3pTdTLXsGptypPN3x/Qr400LgwIrrgyefN8g==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
malihu-custom-scrollbar-plugin "^3.1.5"
-"@abp/prismjs@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-4.2.0-rc.2.tgz#6fe8f0063f4d674ddf309725acf65225ee3b1b1e"
- integrity sha512-pvqGp5FmcDPVKBsPsPbJsbdLRK1i9RJGawYZUSwzyNOdjckf+jWviyFCN/xwt8gx5eHB2eY/VO957yX0y0ti2A==
+"@abp/prismjs@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-4.2.0.tgz#8cedfac538d225930c3654f0d94cad0102faa2f4"
+ integrity sha512-f4duxGD47p2TDMNiiBcvvjOG1hjhSbAoXyq306RrbP0CBUVTdjzzVhCPPnr5+nMoG55VlRBqh92zkax5kdgwQg==
dependencies:
- "@abp/clipboard" "~4.2.0-rc.2"
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/clipboard" "~4.2.0"
+ "@abp/core" "~4.2.0"
prismjs "^1.20.0"
-"@abp/select2@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0-rc.2.tgz#d11e808dac90e09e14025b6ba6dabed683a9b1fb"
- integrity sha512-fENomkoAML+NQWvZ/ecjvqnXtvrzJKyChwj9Ul12c+Noi6boeuFDbhi/OG6qCrSzDnNBrehHVXBLFxT9sIL0OA==
+"@abp/select2@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0.tgz#eb05d22b1390c037911ba25e5ca0f2ed508a93b1"
+ integrity sha512-VlNoa9+F1/kGmaEI2wbL/cRNeAEpp0UdLpbadAnsmpUIODxCULCWS556Q4Y6Ff4CzYtzkYz2qaJ8T8pn+3EOcA==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
select2 "^4.0.13"
-"@abp/sweetalert@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0-rc.2.tgz#2359eeb9e4b34c4cbb3aaed11136ea3d280bd677"
- integrity sha512-oQPj2vKPNAOvBECgJFdDwvJ8nwQ54ZPsAW1XS3XSkFz3YwWn4Xt9eZK6vecHloYckSckrFtsN/DSQI8ao/uIFg==
+"@abp/sweetalert@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0.tgz#b1daf641f27f0c8c2e246d364d6285c133faf773"
+ integrity sha512-AarV/L031xNB1gk/OYEUxkKZmls7zTwovS2t3ZrmwXXoav7nBCSPjEf1ByR2yhZRU/Yo1SNY/CNQQ4dgyf7Xng==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
sweetalert "^2.1.2"
-"@abp/timeago@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0-rc.2.tgz#d243acff635978068ec579c83a34d0680616c5ef"
- integrity sha512-TF1dt9ro3BQnfVetDzbOkedSIncSwvPfnHKMY1xcLG2h0c6ke2PjDQ+4QJrtigggT4vfgmQtRrs/zJxjzWS7qw==
+"@abp/timeago@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0.tgz#9b15c496b7e63df93921d41de9e9eaf35a8dccbe"
+ integrity sha512-hyuLVGluHxtWEhR0VakPx5UCbyPcfq4lECEgHhI62PvH0xcSNNZ3bp1QnBTd3se/HAYvwA5sCwJY0YXQgUF2UQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
timeago "^1.6.7"
-"@abp/toastr@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0-rc.2.tgz#4e76f4b7068f92b267b725ad597b8315e6b615bc"
- integrity sha512-UJVuQWc7py54JC35RrH+MwAZsOoOhejxX+3aonz8Io2rgFFj0YwK5U+vItRNM3iabSqTcIExcSD3XL2TmQyVzg==
+"@abp/toastr@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0.tgz#400e2f28b19c72b131ca32aa188ff5151d035752"
+ integrity sha512-tuGZd3kXqj1t/Y1xN8sOUH1KxiArYKD7xkhuajoOS65Ex5ad8mHPuzCtu8Pv+KL8TVFys9x3U3Tg24DQ6ASjhQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
toastr "^2.1.4"
-"@abp/utils@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0-rc.2.tgz#43c27d421da8e58a5d74c0a2df8742efa827c842"
- integrity sha512-6gSLTP9s88aFjxm+fU2iZMzv5Eoe5/va2PHTAoQJA4BaP/SpFRGts3cT4HYWPfAbmzZVZ+tvjuYd3P6d3FCAhw==
+"@abp/utils@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0.tgz#073330e3e3f6ee61892f50260e48dbe1b05df35e"
+ integrity sha512-75qR3SdiAa75wqleAx9sUMXLj4m9duuBo5+2sVv7Y29GcEyKUPvm8B1s6tksvSGA0e3vnFTHeVEc10eD1xKHSQ==
dependencies:
just-compare "^1.3.0"
diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs
index e53e3cabbf..c2fc5ea4b3 100644
--- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs
+++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs
@@ -1,11 +1,14 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
+using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute.Extensions;
using Shouldly;
using Volo.Abp.Application.Dtos;
+using Volo.Abp.Content;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Http.Client;
using Volo.Abp.TestApp.Application;
@@ -168,5 +171,31 @@ namespace Volo.Abp.Http.DynamicProxying
result.Inner1.Value2.ShouldBe("value two");
result.Inner1.Inner2.Value3.ShouldBe("value three");
}
+
+ [Fact]
+ public async Task DownloadAsync()
+ {
+ var result = await _peopleAppService.DownloadAsync();
+
+ result.ContentType.ShouldBe("application/rtf");
+ using (var reader = new StreamReader(result.GetStream()))
+ {
+ var str = await reader.ReadToEndAsync();
+ str.ShouldBe("DownloadAsync");
+ }
+ }
+
+ [Fact]
+ public async Task UploadAsync()
+ {
+ var memoryStream = new MemoryStream();
+ await memoryStream.WriteAsync(Encoding.UTF8.GetBytes("UploadAsync"));
+ memoryStream.Position = 0;
+ var result = await _peopleAppService.UploadAsync(new RemoteStreamContent(memoryStream)
+ {
+ ContentType = "application/rtf"
+ });
+ result.ShouldBe("UploadAsync:application/rtf");
+ }
}
}
diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleAppService.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleAppService.cs
index a34cd19ebb..2344cb7c9b 100644
--- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleAppService.cs
+++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleAppService.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
+using Volo.Abp.Content;
using Volo.Abp.TestApp.Application.Dto;
namespace Volo.Abp.TestApp.Application
@@ -20,5 +21,9 @@ namespace Volo.Abp.TestApp.Application
Task GetWithAuthorized();
Task GetWithComplexType(GetWithComplexTypeInput input);
+
+ Task DownloadAsync();
+
+ Task UploadAsync(IRemoteStreamContent streamContent);
}
}
diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs
index cff72c7869..788304900d 100644
--- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs
+++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs
@@ -1,12 +1,15 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
+using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.TestApp.Domain;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Application.Services;
+using Volo.Abp.Content;
using Volo.Abp.TestApp.Application.Dto;
namespace Volo.Abp.TestApp.Application
@@ -64,5 +67,24 @@ namespace Volo.Abp.TestApp.Application
{
return Task.FromResult(input);
}
+
+ public async Task DownloadAsync()
+ {
+ var memoryStream = new MemoryStream();
+ await memoryStream.WriteAsync(Encoding.UTF8.GetBytes("DownloadAsync"));
+
+ return new RemoteStreamContent(memoryStream)
+ {
+ ContentType = "application/rtf"
+ };
+ }
+
+ public async Task UploadAsync(IRemoteStreamContent streamContent)
+ {
+ using (var reader = new StreamReader(streamContent.GetStream()))
+ {
+ return await reader.ReadToEndAsync() + ":" + streamContent.ContentType;
+ }
+ }
}
}
diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HardDelete_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HardDelete_Tests.cs
index 3d9b324da8..e31b64f6e4 100644
--- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HardDelete_Tests.cs
+++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HardDelete_Tests.cs
@@ -1,7 +1,9 @@
using Shouldly;
using System;
+using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Data;
+using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Modularity;
using Volo.Abp.TestApp.Domain;
@@ -119,5 +121,40 @@ namespace Volo.Abp.TestApp.Testing
john.ShouldBeNull();
}
}
+
+ [Fact]
+ public async Task Should_HardDelete_WithDeleteMany()
+ {
+ var persons = await PersonRepository.GetListAsync();
+
+ await WithUnitOfWorkAsync(async () =>
+ {
+ var hardDeleteEntities = (HashSet)UnitOfWorkManager.Current.Items.GetOrAdd(
+ UnitOfWorkItemNames.HardDeletedEntities,
+ () => new HashSet()
+ );
+ hardDeleteEntities.UnionWith(persons);
+ await PersonRepository.DeleteManyAsync(persons);
+ });
+
+ var personsCount = await PersonRepository.GetCountAsync();
+
+ personsCount.ShouldBe(0);
+ }
+
+ [Fact]
+ public async Task Should_HardDelete_WithDeleteMany_WithPredicate()
+ {
+ await WithUnitOfWorkAsync(async () =>
+ {
+ await PersonRepository.HardDeleteAsync(x => x.Id == TestDataBuilder.UserDouglasId);
+
+ await PersonRepository.DeleteManyAsync(new[] { TestDataBuilder.UserDouglasId });
+ });
+
+ var douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId);
+
+ douglas.ShouldBeNull();
+ }
}
}
diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs
index ad0e0d20c2..cd7e22b9a2 100644
--- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs
+++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs
@@ -44,9 +44,10 @@ namespace Volo.Abp.AuditLogging
Task> GetAverageExecutionDurationPerDayAsync(
DateTime startDate,
- DateTime endDate);
+ DateTime endDate,
+ CancellationToken cancellationToken = default);
- Task GetEntityChange(Guid entityChangeId);
+ Task GetEntityChange(Guid entityChangeId, CancellationToken cancellationToken = default);
Task> GetEntityChangeListAsync(
string sorting = null,
@@ -70,8 +71,8 @@ namespace Volo.Abp.AuditLogging
string entityTypeFullName = null,
CancellationToken cancellationToken = default);
- Task GetEntityChangeWithUsernameAsync(Guid entityChangeId);
+ Task GetEntityChangeWithUsernameAsync(Guid entityChangeId, CancellationToken cancellationToken = default);
- Task> GetEntityChangesWithUsernameAsync(string entityId, string entityTypeFullName);
+ Task> GetEntityChangesWithUsernameAsync(string entityId, string entityTypeFullName, CancellationToken cancellationToken = default);
}
}
diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs
index edb1f3f599..acd1912925 100644
--- a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs
+++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs
@@ -125,14 +125,17 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
.WhereIf(minExecutionDuration != null && minExecutionDuration.Value > 0, auditLog => auditLog.ExecutionDuration >= minExecutionDuration);
}
- public virtual async Task> GetAverageExecutionDurationPerDayAsync(DateTime startDate, DateTime endDate)
+ public virtual async Task> GetAverageExecutionDurationPerDayAsync(
+ DateTime startDate,
+ DateTime endDate,
+ CancellationToken cancellationToken = default)
{
var result = await (await GetDbSetAsync()).AsNoTracking()
.Where(a => a.ExecutionTime < endDate.AddDays(1) && a.ExecutionTime > startDate)
.OrderBy(t => t.ExecutionTime)
.GroupBy(t => new { t.ExecutionTime.Date })
.Select(g => new { Day = g.Min(t => t.ExecutionTime), avgExecutionTime = g.Average(t => t.ExecutionDuration) })
- .ToListAsync();
+ .ToListAsync(GetCancellationToken(cancellationToken));
return result.ToDictionary(element => element.Day.ClearTime(), element => element.avgExecutionTime);
}
@@ -148,14 +151,16 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
return (await GetQueryableAsync()).IncludeDetails();
}
- public virtual async Task GetEntityChange(Guid entityChangeId)
+ public virtual async Task GetEntityChange(
+ Guid entityChangeId,
+ CancellationToken cancellationToken = default)
{
var entityChange = await (await GetDbContextAsync()).Set()
.AsNoTracking()
.IncludeDetails()
.Where(x => x.Id == entityChangeId)
.OrderBy(x => x.Id)
- .FirstOrDefaultAsync();
+ .FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
if (entityChange == null)
{
@@ -201,10 +206,12 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
return totalCount;
}
- public virtual async Task GetEntityChangeWithUsernameAsync(Guid entityChangeId)
+ public virtual async Task GetEntityChangeWithUsernameAsync(
+ Guid entityChangeId,
+ CancellationToken cancellationToken = default)
{
var auditLog = await (await GetDbSetAsync()).AsNoTracking().IncludeDetails()
- .Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId)).FirstAsync();
+ .Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId)).FirstAsync(GetCancellationToken(cancellationToken));
return new EntityChangeWithUsername()
{
@@ -213,7 +220,10 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
};
}
- public virtual async Task> GetEntityChangesWithUsernameAsync(string entityId, string entityTypeFullName)
+ public virtual async Task> GetEntityChangesWithUsernameAsync(
+ string entityId,
+ string entityTypeFullName,
+ CancellationToken cancellationToken = default)
{
var dbContext = await GetDbContextAsync();
@@ -225,7 +235,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
return await (from e in query
join auditLog in dbContext.AuditLogs on e.AuditLogId equals auditLog.Id
select new EntityChangeWithUsername {EntityChange = e, UserName = auditLog.UserName})
- .OrderByDescending(x => x.EntityChange.ChangeTime).ToListAsync();
+ .OrderByDescending(x => x.EntityChange.ChangeTime).ToListAsync(GetCancellationToken(cancellationToken));
}
protected virtual async Task> GetEntityChangeListQueryAsync(
diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs
index 788b6995bb..e0ce5990b7 100644
--- a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs
+++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs
@@ -52,7 +52,8 @@ namespace Volo.Abp.AuditLogging.MongoDB
minDuration,
hasException,
httpStatusCode,
- includeDetails
+ includeDetails,
+ cancellationToken
);
return await query.OrderBy(sorting ?? "executionTime desc").As>()
@@ -85,7 +86,8 @@ namespace Volo.Abp.AuditLogging.MongoDB
maxDuration,
minDuration,
hasException,
- httpStatusCode
+ httpStatusCode,
+ cancellationToken: cancellationToken
);
var count = await query.As>()
@@ -106,9 +108,10 @@ namespace Volo.Abp.AuditLogging.MongoDB
int? minDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
- bool includeDetails = false)
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
{
- return (await GetMongoQueryableAsync())
+ return (await GetMongoQueryableAsync(cancellationToken))
.WhereIf(startTime.HasValue, auditLog => auditLog.ExecutionTime >= startTime)
.WhereIf(endTime.HasValue, auditLog => auditLog.ExecutionTime <= endTime)
.WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions != "")
@@ -124,9 +127,12 @@ namespace Volo.Abp.AuditLogging.MongoDB
}
- public virtual async Task> GetAverageExecutionDurationPerDayAsync(DateTime startDate, DateTime endDate)
+ public virtual async Task> GetAverageExecutionDurationPerDayAsync(
+ DateTime startDate,
+ DateTime endDate,
+ CancellationToken cancellationToken = default)
{
- var result = await (await GetMongoQueryableAsync())
+ var result = await (await GetMongoQueryableAsync(cancellationToken))
.Where(a => a.ExecutionTime < endDate.AddDays(1) && a.ExecutionTime > startDate)
.OrderBy(t => t.ExecutionTime)
.GroupBy(t => new
@@ -136,17 +142,19 @@ namespace Volo.Abp.AuditLogging.MongoDB
t.ExecutionTime.Day
})
.Select(g => new { Day = g.Min(t => t.ExecutionTime), avgExecutionTime = g.Average(t => t.ExecutionDuration) })
- .ToListAsync();
+ .ToListAsync(GetCancellationToken(cancellationToken));
return result.ToDictionary(element => element.Day.ClearTime(), element => element.avgExecutionTime);
}
- public virtual async Task GetEntityChange(Guid entityChangeId)
+ public virtual async Task GetEntityChange(
+ Guid entityChangeId,
+ CancellationToken cancellationToken = default)
{
- var entityChange = (await (await GetMongoQueryableAsync())
+ var entityChange = (await (await GetMongoQueryableAsync(cancellationToken))
.Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId))
.OrderBy(x => x.Id)
- .FirstAsync()).EntityChanges.FirstOrDefault(x => x.Id == entityChangeId);
+ .FirstAsync(GetCancellationToken(cancellationToken))).EntityChanges.FirstOrDefault(x => x.Id == entityChangeId);
if (entityChange == null)
{
@@ -169,7 +177,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
- var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
+ var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, cancellationToken);
return await query
.OrderBy(sorting ?? "changeTime desc")
@@ -187,18 +195,20 @@ namespace Volo.Abp.AuditLogging.MongoDB
string entityTypeFullName = null,
CancellationToken cancellationToken = default)
{
- var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
+ var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, cancellationToken);
var count = await query.As>().LongCountAsync(GetCancellationToken(cancellationToken));
return count;
}
- public virtual async Task GetEntityChangeWithUsernameAsync(Guid entityChangeId)
+ public virtual async Task GetEntityChangeWithUsernameAsync(
+ Guid entityChangeId,
+ CancellationToken cancellationToken = default)
{
- var auditLog = (await (await GetMongoQueryableAsync())
+ var auditLog = await (await GetMongoQueryableAsync(cancellationToken))
.Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId))
- .FirstAsync());
+ .FirstAsync(GetCancellationToken(cancellationToken));
return new EntityChangeWithUsername()
{
@@ -207,13 +217,16 @@ namespace Volo.Abp.AuditLogging.MongoDB
};
}
- public virtual async Task> GetEntityChangesWithUsernameAsync(string entityId, string entityTypeFullName)
+ public virtual async Task> GetEntityChangesWithUsernameAsync(
+ string entityId,
+ string entityTypeFullName,
+ CancellationToken cancellationToken = default)
{
- var auditLogs = await (await GetMongoQueryableAsync())
+ var auditLogs = await (await GetMongoQueryableAsync(cancellationToken))
.Where(x => x.EntityChanges.Any(y => y.EntityId == entityId && y.EntityTypeFullName == entityTypeFullName))
.As>()
.OrderByDescending(x => x.ExecutionTime)
- .ToListAsync();
+ .ToListAsync(GetCancellationToken(cancellationToken));
var entityChanges = auditLogs.SelectMany(x => x.EntityChanges).ToList();
@@ -229,9 +242,10 @@ namespace Volo.Abp.AuditLogging.MongoDB
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
- string entityTypeFullName = null)
+ string entityTypeFullName = null,
+ CancellationToken cancellationToken = default)
{
- return (await GetMongoQueryableAsync())
+ return (await GetMongoQueryableAsync(cancellationToken))
.SelectMany(x => x.EntityChanges)
.WhereIf(auditLogId.HasValue, e => e.Id == auditLogId)
.WhereIf(startTime.HasValue, e => e.ChangeTime >= startTime)
diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo/Abp/BackgroundJobs/IBackgroundJobRepository.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo/Abp/BackgroundJobs/IBackgroundJobRepository.cs
index e12aeff70a..0fdf15de4b 100644
--- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo/Abp/BackgroundJobs/IBackgroundJobRepository.cs
+++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo/Abp/BackgroundJobs/IBackgroundJobRepository.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
@@ -7,6 +8,6 @@ namespace Volo.Abp.BackgroundJobs
{
public interface IBackgroundJobRepository : IBasicRepository
{
- Task> GetWaitingListAsync(int maxResultCount);
+ Task> GetWaitingListAsync(int maxResultCount, CancellationToken cancellationToken = default);
}
-}
\ No newline at end of file
+}
diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsDbContext.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsDbContext.cs
index d879803677..e49fa3fe55 100644
--- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsDbContext.cs
+++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsDbContext.cs
@@ -1,15 +1,17 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
+using Volo.Abp.MultiTenancy;
namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore
{
+ [IgnoreMultiTenancy]
[ConnectionStringName(BackgroundJobsDbProperties.ConnectionStringName)]
public class BackgroundJobsDbContext : AbpDbContext, IBackgroundJobsDbContext
{
public DbSet BackgroundJobs { get; set; }
- public BackgroundJobsDbContext(DbContextOptions options)
+ public BackgroundJobsDbContext(DbContextOptions options)
: base(options)
{
@@ -22,4 +24,4 @@ namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore
builder.ConfigureBackgroundJobs();
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsDbContextModelCreatingExtensions.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsDbContextModelCreatingExtensions.cs
index 0d16130fb5..0e36a661f6 100644
--- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsDbContextModelCreatingExtensions.cs
+++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsDbContextModelCreatingExtensions.cs
@@ -12,13 +12,18 @@ namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore
{
Check.NotNull(builder, nameof(builder));
+ if (builder.IsTenantOnlyDatabase())
+ {
+ return;
+ }
+
var options = new BackgroundJobsModelBuilderConfigurationOptions(
BackgroundJobsDbProperties.DbTablePrefix,
BackgroundJobsDbProperties.DbSchema
);
optionsAction?.Invoke(options);
-
+
builder.Entity(b =>
{
b.ToTable(options.TablePrefix + "BackgroundJobs", options.Schema);
@@ -32,9 +37,9 @@ namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore
b.Property(x => x.LastTryTime);
b.Property(x => x.IsAbandoned).HasDefaultValue(false);
b.Property(x => x.Priority).HasDefaultValue(BackgroundJobPriority.Normal);
-
+
b.HasIndex(x => new { x.IsAbandoned, x.NextTryTime });
});
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/EfCoreBackgroundJobRepository.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/EfCoreBackgroundJobRepository.cs
index 1971faf380..3ae5d2a409 100644
--- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/EfCoreBackgroundJobRepository.cs
+++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/EfCoreBackgroundJobRepository.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
@@ -21,9 +22,11 @@ namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore
Clock = clock;
}
- public virtual async Task> GetWaitingListAsync(int maxResultCount)
+ public virtual async Task> GetWaitingListAsync(
+ int maxResultCount,
+ CancellationToken cancellationToken = default)
{
- return await (await GetWaitingListQueryAsync(maxResultCount)).ToListAsync();
+ return await (await GetWaitingListQueryAsync(maxResultCount)).ToListAsync(GetCancellationToken(cancellationToken));
}
protected virtual async Task> GetWaitingListQueryAsync(int maxResultCount)
diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/IBackgroundJobsDbContext.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/IBackgroundJobsDbContext.cs
index cc70b6543a..46701b863e 100644
--- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/IBackgroundJobsDbContext.cs
+++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/IBackgroundJobsDbContext.cs
@@ -1,12 +1,14 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
+using Volo.Abp.MultiTenancy;
namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore
{
+ [IgnoreMultiTenancy]
[ConnectionStringName(BackgroundJobsDbProperties.ConnectionStringName)]
public interface IBackgroundJobsDbContext : IEfCoreDbContext
{
DbSet BackgroundJobs { get; }
}
-}
\ No newline at end of file
+}
diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/BackgroundJobsMongoDbContext.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/BackgroundJobsMongoDbContext.cs
index 745903cae7..13a058bc33 100644
--- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/BackgroundJobsMongoDbContext.cs
+++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/BackgroundJobsMongoDbContext.cs
@@ -1,9 +1,11 @@
using MongoDB.Driver;
using Volo.Abp.Data;
using Volo.Abp.MongoDB;
+using Volo.Abp.MultiTenancy;
namespace Volo.Abp.BackgroundJobs.MongoDB
{
+ [IgnoreMultiTenancy]
[ConnectionStringName(BackgroundJobsDbProperties.ConnectionStringName)]
public class BackgroundJobsMongoDbContext : AbpMongoDbContext, IBackgroundJobsMongoDbContext
{
@@ -16,4 +18,4 @@ namespace Volo.Abp.BackgroundJobs.MongoDB
modelBuilder.ConfigureBackgroundJobs();
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/IBackgroundJobsMongoDbContext.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/IBackgroundJobsMongoDbContext.cs
index 8e2d11869d..254d22d63c 100644
--- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/IBackgroundJobsMongoDbContext.cs
+++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/IBackgroundJobsMongoDbContext.cs
@@ -1,9 +1,11 @@
using MongoDB.Driver;
using Volo.Abp.Data;
using Volo.Abp.MongoDB;
+using Volo.Abp.MultiTenancy;
namespace Volo.Abp.BackgroundJobs.MongoDB
{
+ [IgnoreMultiTenancy]
[ConnectionStringName(BackgroundJobsDbProperties.ConnectionStringName)]
public interface IBackgroundJobsMongoDbContext : IAbpMongoDbContext
{
diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/MongoBackgroundJobRepository.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/MongoBackgroundJobRepository.cs
index 258c9310e2..56d0bfaff1 100644
--- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/MongoBackgroundJobRepository.cs
+++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/MongoBackgroundJobRepository.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
@@ -21,15 +22,17 @@ namespace Volo.Abp.BackgroundJobs.MongoDB
Clock = clock;
}
- public virtual async Task> GetWaitingListAsync(int maxResultCount)
+ public virtual async Task> GetWaitingListAsync(
+ int maxResultCount,
+ CancellationToken cancellationToken = default)
{
- return await (await GetWaitingListQuery(maxResultCount)).ToListAsync();
+ return await (await GetWaitingListQuery(maxResultCount)).ToListAsync(GetCancellationToken(cancellationToken));
}
- protected virtual async Task> GetWaitingListQuery(int maxResultCount)
+ protected virtual async Task> GetWaitingListQuery(int maxResultCount, CancellationToken cancellationToken = default)
{
var now = Clock.Now;
- return (await GetMongoQueryableAsync())
+ return (await GetMongoQueryableAsync(cancellationToken))
.Where(t => !t.IsAbandoned && t.NextTryTime <= now)
.OrderByDescending(t => t.Priority)
.ThenBy(t => t.TryCount)
diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/DatabaseBlobContainer.cs b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/DatabaseBlobContainer.cs
index 4342d9092c..df912b84e5 100644
--- a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/DatabaseBlobContainer.cs
+++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/DatabaseBlobContainer.cs
@@ -5,17 +5,17 @@ using Volo.Abp.MultiTenancy;
namespace Volo.Abp.BlobStoring.Database
{
- public class DatabaseBlobContainer : AggregateRoot, IMultiTenant //TODO: Rename to BlobContainer
+ public class DatabaseBlobContainer : AggregateRoot, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual string Name { get; protected set; }
- public DatabaseBlobContainer(Guid id, [NotNull] string name, Guid? tenantId = null)
+ public DatabaseBlobContainer(Guid id, [NotNull] string name, Guid? tenantId = null)
: base(id)
{
Name = Check.NotNullOrWhiteSpace(name, nameof(name), DatabaseContainerConsts.MaxNameLength);
TenantId = tenantId;
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/blogging/app/Volo.BloggingTestApp/package.json b/modules/blogging/app/Volo.BloggingTestApp/package.json
index 1a97b62da3..dd0661267d 100644
--- a/modules/blogging/app/Volo.BloggingTestApp/package.json
+++ b/modules/blogging/app/Volo.BloggingTestApp/package.json
@@ -3,7 +3,7 @@
"name": "volo.blogtestapp",
"private": true,
"dependencies": {
- "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.0-rc.2",
- "@abp/blogging": "^4.2.0-rc.2"
+ "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.0",
+ "@abp/blogging": "^4.2.0"
}
}
\ No newline at end of file
diff --git a/modules/blogging/app/Volo.BloggingTestApp/yarn.lock b/modules/blogging/app/Volo.BloggingTestApp/yarn.lock
index 6f7c1a81f7..21cabeb03f 100644
--- a/modules/blogging/app/Volo.BloggingTestApp/yarn.lock
+++ b/modules/blogging/app/Volo.BloggingTestApp/yarn.lock
@@ -2,37 +2,37 @@
# yarn lockfile v1
-"@abp/aspnetcore.mvc.ui.theme.basic@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-4.2.0-rc.2.tgz#f4625e18fd3704d432913e9de59c7183770ea485"
- integrity sha512-wwOFcrICyhgAcBq7zgdIkYQ8Mov0g1iYrjoRZRiUzBYG4wkcAO9POM9asE6uvY5sD/hd0cRoXSZOcNKUt0J1SA==
- dependencies:
- "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui.theme.shared@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0-rc.2.tgz#9ff3af53b667e747c06d3f067a0f68a938ac72a8"
- integrity sha512-qsJ6UaUxyOJOHxsqVjlUGhCvQUnbXgGzLvFPJZYLpnWm6ZvE1KAgJnQHL46YSllCDT0meVqHt9byjOCRJUMm9Q==
- dependencies:
- "@abp/aspnetcore.mvc.ui" "~4.2.0-rc.2"
- "@abp/bootstrap" "~4.2.0-rc.2"
- "@abp/bootstrap-datepicker" "~4.2.0-rc.2"
- "@abp/datatables.net-bs4" "~4.2.0-rc.2"
- "@abp/font-awesome" "~4.2.0-rc.2"
- "@abp/jquery-form" "~4.2.0-rc.2"
- "@abp/jquery-validation-unobtrusive" "~4.2.0-rc.2"
- "@abp/lodash" "~4.2.0-rc.2"
- "@abp/luxon" "~4.2.0-rc.2"
- "@abp/malihu-custom-scrollbar-plugin" "~4.2.0-rc.2"
- "@abp/select2" "~4.2.0-rc.2"
- "@abp/sweetalert" "~4.2.0-rc.2"
- "@abp/timeago" "~4.2.0-rc.2"
- "@abp/toastr" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0-rc.2.tgz#726f45c7ff12e69e970fb89b4adfb15502a11576"
- integrity sha512-EzTYQ8XzXIprfK95LyYc1Ci3to3dNlBOSzkkYfYDXkSR5/SyBKckCTd5FL4c7yrs+qBoJMxKWDyWz+pmf6PIJA==
+"@abp/aspnetcore.mvc.ui.theme.basic@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-4.2.0.tgz#01d6aab8a31fd6ea828b753805f1ba9a9165975f"
+ integrity sha512-d+7YubPbuBRY8tjqBxS4I1gyxekjg8Z0X9QaDrf/SGQBoWpIdbG09AekNdddKNkimWcPg4UgUytahPuX9f17ZA==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui.theme.shared@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0.tgz#a72b5e1cefa27e658b7f072a8c2c1b4ee12baef8"
+ integrity sha512-bgWwBBJA/74kFGWh7O+lzb+inV5LOlYOpDoCNAL0XgQTrutrPNHwsk5ZnGVfhSYrBgk47HGVZDwsqKMCTRn1ig==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui" "~4.2.0"
+ "@abp/bootstrap" "~4.2.0"
+ "@abp/bootstrap-datepicker" "~4.2.0"
+ "@abp/datatables.net-bs4" "~4.2.0"
+ "@abp/font-awesome" "~4.2.0"
+ "@abp/jquery-form" "~4.2.0"
+ "@abp/jquery-validation-unobtrusive" "~4.2.0"
+ "@abp/lodash" "~4.2.0"
+ "@abp/luxon" "~4.2.0"
+ "@abp/malihu-custom-scrollbar-plugin" "~4.2.0"
+ "@abp/select2" "~4.2.0"
+ "@abp/sweetalert" "~4.2.0"
+ "@abp/timeago" "~4.2.0"
+ "@abp/toastr" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0.tgz#9c090f64a33d31962936d8d53b345afeaa9f2ba3"
+ integrity sha512-Qt3MUZ41vuvnIVEAYxyOm1mflvFwwvKYsEjFBbePBnwaYL7udooiIFxTEm4FBh3EQJOi+8T84rnXqiIXj4Pi8A==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@@ -43,214 +43,214 @@
micromatch "^4.0.2"
path "^0.12.7"
-"@abp/blogging@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/blogging/-/blogging-4.2.0-rc.2.tgz#ba757ce0dc244dad0e5a807b3d4540320cfa79c4"
- integrity sha512-iWksm+5YJDryVdh1VZwnBaRy6fsJzeZBdeM3fCFQIYaKHF6orYfVUeLXuLXFVjDfuV8alhlo7rI5ANG6dsI0bw==
+"@abp/blogging@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/blogging/-/blogging-4.2.0.tgz#5eaef63ea06f86cca8ca2727624cdc224566b473"
+ integrity sha512-rSJ0mSGInIDQcFUDGVVlWjXEF8T81BQ0u41vuURm3f06MBcK3TficQbl0Xnvx0Pc9Cbs4mFNd3UiZcsGp4MeMg==
dependencies:
- "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0-rc.2"
- "@abp/owl.carousel" "~4.2.0-rc.2"
- "@abp/prismjs" "~4.2.0-rc.2"
- "@abp/tui-editor" "~4.2.0-rc.2"
+ "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0"
+ "@abp/owl.carousel" "~4.2.0"
+ "@abp/prismjs" "~4.2.0"
+ "@abp/tui-editor" "~4.2.0"
-"@abp/bootstrap-datepicker@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0-rc.2.tgz#f2a6d013321c98f8c9a7533087360fce9a5fd074"
- integrity sha512-n3gLYLL7hHX83gurN5iRkpairrw0oAyg+Bc6SeIbNAdorun9wBJn7IlmvXxGPn1xK5iDKktRSeWJ885fMgkuWg==
+"@abp/bootstrap-datepicker@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0.tgz#92abebe044a91b94b8a3b85560b501120a0fa500"
+ integrity sha512-bhEa/+zGVX00vkXGrbKI/hcl9o5Xgqwb27by9ZQqxk9Go4lwsEP/7lrXM49Cg8XZTT3L0/lYclneEMDrqGafaQ==
dependencies:
bootstrap-datepicker "^1.9.0"
-"@abp/bootstrap@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0-rc.2.tgz#49250657f667f7553f3c2149fda43f7535de989b"
- integrity sha512-WYdyDQzgFlltxqdYINAMVWjXiiDAx780fTJEd3YKLSzxmVGBfoW4cfFzw8vr/G/EMYrgAPQtrIS+BRlFAJXXGQ==
+"@abp/bootstrap@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0.tgz#c7ce82ead40bf0d62a318f67f180663ec76aa53c"
+ integrity sha512-E1gEX0ct67KFjKiZB6eQcIYJ3TS/pF1S4CxknBVCd77Zs03bHI+eEgBNlwcYriVBbQo+vheUQAaACbi+e2mm3Q==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
bootstrap "^4.5.0"
bootstrap-v4-rtl "4.4.1-2"
-"@abp/clipboard@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-4.2.0-rc.2.tgz#0cda5f6f3624e68e1ec7290517364d02f2b60e42"
- integrity sha512-wF/d8Xuq+ORUkiWgDorM7rxueiygtELaZKlRDYzmQRnwJN4vS1q/4/UtPaLSlcGhHxWuxu2XSWQtzcphfBjFWA==
+"@abp/clipboard@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-4.2.0.tgz#860220df1d57ef64e864401d56cb5cf7068d5861"
+ integrity sha512-yBgMDhpqPEHp9N9//Ur1BEIOicFIoKBut75PMz9XPOttLyqCmqHYEPj/jgAkUzLd5O+fJM9TE3yGNM7YdRbRPg==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
clipboard "^2.0.6"
-"@abp/codemirror@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/codemirror/-/codemirror-4.2.0-rc.2.tgz#70086f33b73c75a4e0e8e5552b812b1e466d4a3f"
- integrity sha512-FM3lCG6e3Xxy9AyfVbOvVBysH4rnIYyG/IOHxqW3h6Twz2pWi+s5vA4dXnbb/+ODeFwD72+eJ5F6yRKXWamrmA==
+"@abp/codemirror@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/codemirror/-/codemirror-4.2.0.tgz#4dac96e8bd908c0a77d1d2ca488cc08c30a123dc"
+ integrity sha512-urWA355XeP56NpPLDoByc7btjCSQY66jLe2G1/x/3zznChdFqEdWkql5nbLgsnfiPb0CaIntoWCKeqSnEz08kQ==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
codemirror "^5.54.0"
-"@abp/core@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0-rc.2.tgz#dc18c3b8f294563ba62c000c026f5ceb86030456"
- integrity sha512-YJz4xUwb/mv/Xi/WuPz2SF/LD22P/UJ+psb+35ezOeuj020IAdaunk8LdrU5TfaZqNe5WpGszKMA+jO9ydNuqA==
+"@abp/core@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0.tgz#20da3d1bab30e80d8864915fdd67e99db729be71"
+ integrity sha512-Cfa6Ck+Tr7isVpNxo9qT9eKByLadDErA+QVjeps7qYq9ztIpIz/7Yl85tHYEH0YPO9y2zcSOvxjy5SCBXlph5Q==
dependencies:
- "@abp/utils" "^4.2.0-rc.2"
+ "@abp/utils" "^4.2.0"
-"@abp/datatables.net-bs4@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0-rc.2.tgz#0d14886aa756ca707dd365b423b40d84c658268e"
- integrity sha512-kX+NrGkisy7IMi+xL69dPaPOYNLBZ4Vp7xCvJqNhdc5Sh6Rn1P0bLvxFKG065mBMfgW8tyFNnN3c5WzwcRFSmg==
+"@abp/datatables.net-bs4@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0.tgz#b5cb47235079a4063c5ff8ce78e65596fa587709"
+ integrity sha512-N4hp2xCst1qavt07Nf+zXlvbZfeSah64VuMjsZgaimHMlDjxg6zVsTHLgLfzwfPV/eOBrGiecPEuvfEeaqcw4A==
dependencies:
- "@abp/datatables.net" "~4.2.0-rc.2"
+ "@abp/datatables.net" "~4.2.0"
datatables.net-bs4 "^1.10.21"
-"@abp/datatables.net@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0-rc.2.tgz#a82ac16c1644a92d01ba63bf57e0d3784eb00f2f"
- integrity sha512-bEQ6QSUN65lJ8fK8wOVE16cayDI64EgyVb3qZAzWUncxPyLLa5s5zlDjcQ98D3An+x3tG2CdmEEWjlAgWdaf1g==
+"@abp/datatables.net@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0.tgz#2e0273c3212e5a62fc8b4138e4570fb27143f701"
+ integrity sha512-33ZkaorkVkPQ7HNtDjyIvcVbvAdFm8V+gFN+xMQZhA10wMlMGrKzVJjriv4NhNpPjtB4/owhOv6wobiuWBrGiA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
datatables.net "^1.10.21"
-"@abp/font-awesome@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0-rc.2.tgz#6c72ef7ae00beda565e9836c8214ccf074ea7e4b"
- integrity sha512-bEQPGyVsKV7aQtVwG4UIcG+DMneBD7jcjX3eFqjOlGhQq3ODbNld5IPXHO+JnHDLt5NOzrePQLUzPhsvCIwhGA==
+"@abp/font-awesome@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0.tgz#a637d164634b0df862e4ea620736afae282c71c9"
+ integrity sha512-P8OXp+XIZj6l7cNJ5+7Lpl8iixI/bHGSPkATggaOYZ2EWoNR3B/8pj7p44weP2bCAvUEvaxk214BKlpAslo8eQ==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
"@fortawesome/fontawesome-free" "^5.13.0"
-"@abp/highlight.js@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-4.2.0-rc.2.tgz#c7e99394868863265b20328c2189d14d0630501d"
- integrity sha512-bBjAPSHRGHz7xhtpC4oy3L/QV6mJuHx3LRxyd5wwhuyWsuv9qzo4GoHQsgR6gK9ANI9LGbVp+91vFaXjsNGj2A==
+"@abp/highlight.js@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-4.2.0.tgz#92b1885fcfe4e94a4eaa3b7deffe9b62b4767692"
+ integrity sha512-C6gOvrp/pexbxgcd8rwN3McI4CVPWgE4JwgGrVw/VOuNF5eB4Bvy1ELI9bQNiLnoGNHhdUJD5a7nCNOMW4L9cA==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
-"@abp/jquery-form@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0-rc.2.tgz#a4726794f78cf69dd75c0adda3dca3ed623f02d8"
- integrity sha512-rOGXYTTiQUD2HWTabh0+Ot6LX4PEObd3DW3ikBHZSnfen7W0OgnLdqNaunHYSEV3UUgCAZHaX0wQd4SM0pRMLg==
+"@abp/jquery-form@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0.tgz#12b88a79a69f7d3b15aed8c7ca3ff5bc9f526f22"
+ integrity sha512-lxvXhA4kg002gmDTWgoE6TcQWDe6kBcpV4KBB7aK/6LjK3noeT29SPX0kvKxjoUKyM5TqT2Hx7rg4jgtICjFFA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-form "^4.3.0"
-"@abp/jquery-validation-unobtrusive@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0-rc.2.tgz#5dee22e1bcbd44bd8e2584d37d79e8313cf615ec"
- integrity sha512-xk56Otr6PG/bED2yJuPo0OhwcgS4FQQXySgPD9e7mlZQcjxZ4LvmRU/btoNoxSHKYUBLKRfEOYOqRTxJhrH0eA==
+"@abp/jquery-validation-unobtrusive@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0.tgz#05bcd303ec1e22b85389d03a8941eb898bac354f"
+ integrity sha512-mtvUcoTD5XSurMFI5cybgWzFI9bn35vU1PvH5NJxJitjJ7sg9gjtLf9WOIddIy4FdqmprhbG2YnR32GITOwFhg==
dependencies:
- "@abp/jquery-validation" "~4.2.0-rc.2"
+ "@abp/jquery-validation" "~4.2.0"
jquery-validation-unobtrusive "^3.2.11"
-"@abp/jquery-validation@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0-rc.2.tgz#594b9132d1eafebed60be10d219bc9e8b15f18b6"
- integrity sha512-LkNI3X7gpYYkI3DnCTZ1KIV6ykKMqw6pLZhFvTZz7GliZWE1jHtFos4U6lWe2XnMjnFeVeY6rPFM/1LaamfCKg==
+"@abp/jquery-validation@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0.tgz#a09d7cf2abf8ccf0c59f27eadacb030fb2067bbe"
+ integrity sha512-/nvJrs1pt3LJX+SgH3FtDPfCDrcl4M0LDxjV7hf0Y1jtyhvWOQiyJMb8FKzMweTTEOd0pHG/GvOKd90STabSiw==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-validation "^1.19.2"
-"@abp/jquery@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0-rc.2.tgz#146589cbf4397be727d38798d557f3879ae51057"
- integrity sha512-yTYk5rRG3qnRKnA/pSXZNH/+KJcJ2Wo5BUtt3G8oKAe+no0Au1BoCV9j7JNiSnLXkFVWFuRwEZCh+cp6ngACng==
+"@abp/jquery@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0.tgz#0a24488198ca6c9b84273fa028b853ee9f94f3a7"
+ integrity sha512-6a42Iy7knhgzvQUvCHenrVnPDKhsOyqgZkPxs9pa9x/wNapSch+jLM7u1ezKAFj/Ai4w9yG/yqP+4YE8seZDZw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
jquery "~3.5.1"
-"@abp/lodash@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0-rc.2.tgz#f0a238991c288f439e2751938a39d434dd7883e7"
- integrity sha512-En9gZD8TDY8ZvZqHVsv3cP2EsRdPRsGD0ncUYOvlNG/sc+MZpRmZ+xOLws1wXS83IxGAxzPdCFEu0biJlyOyxg==
+"@abp/lodash@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0.tgz#74dfac7d70f1563df2b78c5ebd0b2450e11c4c42"
+ integrity sha512-5hpjxWZJPvjMIY7FCCw/v/B+JzJbB/yuoioRzcU4vrisY9uRq54vVYcX7hH1DldsJFPTuXY3Id1WBflHA5I9Aw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
lodash "^4.17.15"
-"@abp/luxon@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0-rc.2.tgz#ace30caacf6abcce1559b65046ea55e47e1cb8a2"
- integrity sha512-ivhOadlaeBh6Pi3S5Bo0pb4EPCEjMFL5N5tZXGGieZt7EnF+4uiXbKJVErXNCDtX1jhJT/3HGqmdxa+WynUE0A==
+"@abp/luxon@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0.tgz#9cd02faa02cda1315f3e23ae204991ef47d6ae7c"
+ integrity sha512-dwtv2kqWCDyQADA1Os0aIy6Au2PhBtN6q9kukLWCvYmQZI23OKuEBMSngbJVTqEPfz0LV6CWbsWCUC3okAs46A==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
luxon "^1.24.1"
-"@abp/malihu-custom-scrollbar-plugin@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0-rc.2.tgz#483668c09e13b0ebcea16320a16f8517fcdd53ee"
- integrity sha512-IYOwJcWyJkn/gdp4VkEYCv2Gi5+Boxe7pE7hA49gxgllHiFV0ABDFrRg4h8MbyJd80iwvVPo8t8ouvn4Snm+gQ==
+"@abp/malihu-custom-scrollbar-plugin@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0.tgz#2f8538df5567a2cf227998e4e2fb9a44b6e814eb"
+ integrity sha512-3D5REdR7yw2sRRfm3Oi+qlhDABLrKvfU/l7JcCJy+vrBvadx3e3pTdTLXsGptypPN3x/Qr400LgwIrrgyefN8g==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
malihu-custom-scrollbar-plugin "^3.1.5"
-"@abp/markdown-it@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/markdown-it/-/markdown-it-4.2.0-rc.2.tgz#b3b983e2b0a4f6ff99223b2cd7982144c1683226"
- integrity sha512-jiBUx6bzbBfjDry6kEdZsKYylkixzPHeNuJ8AsMsF1FqJ6LIgsuWeRbT+bToHd25AZ1ZxTnqYM5efKXia0N4/w==
+"@abp/markdown-it@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/markdown-it/-/markdown-it-4.2.0.tgz#e04514da16f9fdbfe3cab2933a60aa9193784a0b"
+ integrity sha512-If9AH2QwXExsZdFH5Orfo9giSrGMr9HviNM9cxDnHPwID5MJFrc7zxalqNwXcArtjGxLB+QaAfxEACIvLfLp/g==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
markdown-it "^11.0.0"
-"@abp/owl.carousel@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/owl.carousel/-/owl.carousel-4.2.0-rc.2.tgz#c5cdf1f53e539b891f1fe265091570e71bdf83c0"
- integrity sha512-hl8XtVB0II/piGeXLS0e50oKYWT8YDw5QsL9/DnvJnneigrFoAFnVR0siavgr+C6jY3XqQR8aCpxByi82PvUDQ==
+"@abp/owl.carousel@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/owl.carousel/-/owl.carousel-4.2.0.tgz#1e02b137dc05529feca196568b87dd691a3d273a"
+ integrity sha512-T44Mvi7VlkDuv31WzoDLoskEF1jJ2KK/0UKtsg2ECauOfS1iQA1weoRx+ITK4Vg6RWayZxyQatVt1+6jz+0LcA==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
owl.carousel "^2.3.4"
-"@abp/prismjs@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-4.2.0-rc.2.tgz#6fe8f0063f4d674ddf309725acf65225ee3b1b1e"
- integrity sha512-pvqGp5FmcDPVKBsPsPbJsbdLRK1i9RJGawYZUSwzyNOdjckf+jWviyFCN/xwt8gx5eHB2eY/VO957yX0y0ti2A==
+"@abp/prismjs@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-4.2.0.tgz#8cedfac538d225930c3654f0d94cad0102faa2f4"
+ integrity sha512-f4duxGD47p2TDMNiiBcvvjOG1hjhSbAoXyq306RrbP0CBUVTdjzzVhCPPnr5+nMoG55VlRBqh92zkax5kdgwQg==
dependencies:
- "@abp/clipboard" "~4.2.0-rc.2"
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/clipboard" "~4.2.0"
+ "@abp/core" "~4.2.0"
prismjs "^1.20.0"
-"@abp/select2@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0-rc.2.tgz#d11e808dac90e09e14025b6ba6dabed683a9b1fb"
- integrity sha512-fENomkoAML+NQWvZ/ecjvqnXtvrzJKyChwj9Ul12c+Noi6boeuFDbhi/OG6qCrSzDnNBrehHVXBLFxT9sIL0OA==
+"@abp/select2@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0.tgz#eb05d22b1390c037911ba25e5ca0f2ed508a93b1"
+ integrity sha512-VlNoa9+F1/kGmaEI2wbL/cRNeAEpp0UdLpbadAnsmpUIODxCULCWS556Q4Y6Ff4CzYtzkYz2qaJ8T8pn+3EOcA==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
select2 "^4.0.13"
-"@abp/sweetalert@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0-rc.2.tgz#2359eeb9e4b34c4cbb3aaed11136ea3d280bd677"
- integrity sha512-oQPj2vKPNAOvBECgJFdDwvJ8nwQ54ZPsAW1XS3XSkFz3YwWn4Xt9eZK6vecHloYckSckrFtsN/DSQI8ao/uIFg==
+"@abp/sweetalert@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0.tgz#b1daf641f27f0c8c2e246d364d6285c133faf773"
+ integrity sha512-AarV/L031xNB1gk/OYEUxkKZmls7zTwovS2t3ZrmwXXoav7nBCSPjEf1ByR2yhZRU/Yo1SNY/CNQQ4dgyf7Xng==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
sweetalert "^2.1.2"
-"@abp/timeago@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0-rc.2.tgz#d243acff635978068ec579c83a34d0680616c5ef"
- integrity sha512-TF1dt9ro3BQnfVetDzbOkedSIncSwvPfnHKMY1xcLG2h0c6ke2PjDQ+4QJrtigggT4vfgmQtRrs/zJxjzWS7qw==
+"@abp/timeago@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0.tgz#9b15c496b7e63df93921d41de9e9eaf35a8dccbe"
+ integrity sha512-hyuLVGluHxtWEhR0VakPx5UCbyPcfq4lECEgHhI62PvH0xcSNNZ3bp1QnBTd3se/HAYvwA5sCwJY0YXQgUF2UQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
timeago "^1.6.7"
-"@abp/toastr@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0-rc.2.tgz#4e76f4b7068f92b267b725ad597b8315e6b615bc"
- integrity sha512-UJVuQWc7py54JC35RrH+MwAZsOoOhejxX+3aonz8Io2rgFFj0YwK5U+vItRNM3iabSqTcIExcSD3XL2TmQyVzg==
+"@abp/toastr@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0.tgz#400e2f28b19c72b131ca32aa188ff5151d035752"
+ integrity sha512-tuGZd3kXqj1t/Y1xN8sOUH1KxiArYKD7xkhuajoOS65Ex5ad8mHPuzCtu8Pv+KL8TVFys9x3U3Tg24DQ6ASjhQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
toastr "^2.1.4"
-"@abp/tui-editor@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-4.2.0-rc.2.tgz#25e97dd47ccbd8a22ac47a9d46fd1d0f9a2f762a"
- integrity sha512-7giF6IFxYOPfoDPJupEXeFKSzf7iB14RUIA6h7+8AXw7OfIeobpdZq3qCpRRgS4UiP1eemaegeT6s42maL498Q==
+"@abp/tui-editor@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-4.2.0.tgz#893be49c6de9af515afab424bd3720796034190f"
+ integrity sha512-UN6CY5FGbqaYlRJoa8rLENibpMnB19XkhJReq05Bej6b/aCBiZCi7GAilgWPEghqublAObgdmeOe11NJlMrQ5Q==
dependencies:
- "@abp/codemirror" "~4.2.0-rc.2"
- "@abp/highlight.js" "~4.2.0-rc.2"
- "@abp/jquery" "~4.2.0-rc.2"
- "@abp/markdown-it" "~4.2.0-rc.2"
+ "@abp/codemirror" "~4.2.0"
+ "@abp/highlight.js" "~4.2.0"
+ "@abp/jquery" "~4.2.0"
+ "@abp/markdown-it" "~4.2.0"
tui-editor "^1.4.10"
-"@abp/utils@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0-rc.2.tgz#43c27d421da8e58a5d74c0a2df8742efa827c842"
- integrity sha512-6gSLTP9s88aFjxm+fU2iZMzv5Eoe5/va2PHTAoQJA4BaP/SpFRGts3cT4HYWPfAbmzZVZ+tvjuYd3P6d3FCAhw==
+"@abp/utils@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0.tgz#073330e3e3f6ee61892f50260e48dbe1b05df35e"
+ integrity sha512-75qR3SdiAa75wqleAx9sUMXLj4m9duuBo5+2sVv7Y29GcEyKUPvm8B1s6tksvSGA0e3vnFTHeVEc10eD1xKHSQ==
dependencies:
just-compare "^1.3.0"
diff --git a/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Blogs/IBlogRepository.cs b/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Blogs/IBlogRepository.cs
index ade8d1be0e..37dbf85ddd 100644
--- a/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Blogs/IBlogRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Blogs/IBlogRepository.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
@@ -6,6 +7,6 @@ namespace Volo.Blogging.Blogs
{
public interface IBlogRepository : IBasicRepository
{
- Task FindByShortNameAsync(string shortName);
+ Task FindByShortNameAsync(string shortName, CancellationToken cancellationToken = default);
}
}
diff --git a/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Comments/ICommentRepository.cs b/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Comments/ICommentRepository.cs
index 88ff91d516..65144cf5c2 100644
--- a/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Comments/ICommentRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Comments/ICommentRepository.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
@@ -7,14 +8,12 @@ namespace Volo.Blogging.Comments
{
public interface ICommentRepository : IBasicRepository
{
- Task> GetListOfPostAsync(
- Guid postId
- );
+ Task> GetListOfPostAsync(Guid postId, CancellationToken cancellationToken = default);
- Task GetCommentCountOfPostAsync(Guid postId);
+ Task GetCommentCountOfPostAsync(Guid postId, CancellationToken cancellationToken = default);
- Task> GetRepliesOfComment(Guid id);
+ Task> GetRepliesOfComment(Guid id, CancellationToken cancellationToken = default);
- Task DeleteOfPost(Guid id);
+ Task DeleteOfPost(Guid id, CancellationToken cancellationToken = default);
}
}
diff --git a/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Posts/IPostRepository.cs b/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Posts/IPostRepository.cs
index 9a49590015..b5446515bf 100644
--- a/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Posts/IPostRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Posts/IPostRepository.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
@@ -7,12 +8,12 @@ namespace Volo.Blogging.Posts
{
public interface IPostRepository : IBasicRepository
{
- Task> GetPostsByBlogId(Guid id);
+ Task> GetPostsByBlogId(Guid id, CancellationToken cancellationToken = default);
- Task IsPostUrlInUseAsync(Guid blogId, string url, Guid? excludingPostId = null);
+ Task IsPostUrlInUseAsync(Guid blogId, string url, Guid? excludingPostId = null, CancellationToken cancellationToken = default);
- Task GetPostByUrl(Guid blogId, string url);
+ Task GetPostByUrl(Guid blogId, string url, CancellationToken cancellationToken = default);
- Task> GetOrderedList(Guid blogId,bool descending = false);
+ Task> GetOrderedList(Guid blogId,bool descending = false, CancellationToken cancellationToken = default);
}
}
diff --git a/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Tagging/ITagRepository.cs b/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Tagging/ITagRepository.cs
index 8c076c49d7..12aa0031ed 100644
--- a/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Tagging/ITagRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Tagging/ITagRepository.cs
@@ -8,13 +8,13 @@ namespace Volo.Blogging.Tagging
{
public interface ITagRepository : IBasicRepository
{
- Task> GetListAsync(Guid blogId);
+ Task> GetListAsync(Guid blogId, CancellationToken cancellationToken = default);
- Task GetByNameAsync(Guid blogId, string name);
+ Task GetByNameAsync(Guid blogId, string name, CancellationToken cancellationToken = default);
- Task FindByNameAsync(Guid blogId, string name);
+ Task FindByNameAsync(Guid blogId, string name, CancellationToken cancellationToken = default);
- Task> GetListAsync(IEnumerable ids);
+ Task> GetListAsync(IEnumerable ids, CancellationToken cancellationToken = default);
Task DecreaseUsageCountOfTagsAsync(List id, CancellationToken cancellationToken = default);
}
diff --git a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Blogs/EfCoreBlogRepository.cs b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Blogs/EfCoreBlogRepository.cs
index 564d45dc7a..d5397a66f0 100644
--- a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Blogs/EfCoreBlogRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Blogs/EfCoreBlogRepository.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
@@ -15,9 +16,9 @@ namespace Volo.Blogging.Blogs
}
- public async Task FindByShortNameAsync(string shortName)
+ public async Task FindByShortNameAsync(string shortName, CancellationToken cancellationToken = default)
{
- return await (await GetDbSetAsync()).FirstOrDefaultAsync(p => p.ShortName == shortName);
+ return await (await GetDbSetAsync()).FirstOrDefaultAsync(p => p.ShortName == shortName, GetCancellationToken(cancellationToken));
}
}
}
diff --git a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Comments/EfCoreCommentRepository.cs b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Comments/EfCoreCommentRepository.cs
index 6c28b521aa..801ef07825 100644
--- a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Comments/EfCoreCommentRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Comments/EfCoreCommentRepository.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
@@ -16,29 +17,29 @@ namespace Volo.Blogging.Comments
{
}
- public async Task> GetListOfPostAsync(Guid postId)
+ public async Task> GetListOfPostAsync(Guid postId, CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
.Where(a => a.PostId == postId)
.OrderBy(a => a.CreationTime)
- .ToListAsync();
+ .ToListAsync(GetCancellationToken(cancellationToken));
}
- public async Task GetCommentCountOfPostAsync(Guid postId)
+ public async Task GetCommentCountOfPostAsync(Guid postId, CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
- .CountAsync(a => a.PostId == postId);
+ .CountAsync(a => a.PostId == postId, GetCancellationToken(cancellationToken));
}
- public async Task> GetRepliesOfComment(Guid id)
+ public async Task> GetRepliesOfComment(Guid id, CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
- .Where(a => a.RepliedCommentId == id).ToListAsync();
+ .Where(a => a.RepliedCommentId == id).ToListAsync(GetCancellationToken(cancellationToken));
}
- public async Task DeleteOfPost(Guid id)
+ public async Task DeleteOfPost(Guid id, CancellationToken cancellationToken = default)
{
- var recordsToDelete = (await GetDbSetAsync()).Where(pt => pt.PostId == id);
+ var recordsToDelete = await (await GetDbSetAsync()).Where(pt => pt.PostId == id).ToListAsync(GetCancellationToken(cancellationToken));
(await GetDbSetAsync()).RemoveRange(recordsToDelete);
}
}
diff --git a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContext.cs b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContext.cs
index 4ab71a0222..85c34aa996 100644
--- a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContext.cs
+++ b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContext.cs
@@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
+using Volo.Abp.MultiTenancy;
using Volo.Blogging.Blogs;
using Volo.Blogging.Comments;
using Volo.Blogging.Posts;
@@ -9,6 +10,7 @@ using Volo.Blogging.Users;
namespace Volo.Blogging.EntityFrameworkCore
{
+ [IgnoreMultiTenancy]
[ConnectionStringName(BloggingDbProperties.ConnectionStringName)]
public class BloggingDbContext : AbpDbContext, IBloggingDbContext
{
@@ -23,7 +25,7 @@ namespace Volo.Blogging.EntityFrameworkCore
public DbSet PostTags { get; set; }
public DbSet Comments { get; set; }
-
+
public BloggingDbContext(DbContextOptions options)
: base(options)
{
@@ -37,4 +39,4 @@ namespace Volo.Blogging.EntityFrameworkCore
builder.ConfigureBlogging();
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContextModelBuilderExtensions.cs b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContextModelBuilderExtensions.cs
index a5e909d8a4..9c54d0a3a0 100644
--- a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContextModelBuilderExtensions.cs
+++ b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContextModelBuilderExtensions.cs
@@ -20,6 +20,11 @@ namespace Volo.Blogging.EntityFrameworkCore
{
Check.NotNull(builder, nameof(builder));
+ if (builder.IsTenantOnlyDatabase())
+ {
+ return;
+ }
+
var options = new BloggingModelBuilderConfigurationOptions(
BloggingDbProperties.DbTablePrefix,
BloggingDbProperties.DbSchema
diff --git a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/IBloggingDbContext.cs b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/IBloggingDbContext.cs
index dcdb6c78e1..ecb7c282d4 100644
--- a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/IBloggingDbContext.cs
+++ b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/IBloggingDbContext.cs
@@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
+using Volo.Abp.MultiTenancy;
using Volo.Blogging.Blogs;
using Volo.Blogging.Comments;
using Volo.Blogging.Posts;
@@ -9,6 +10,7 @@ using Volo.Blogging.Users;
namespace Volo.Blogging.EntityFrameworkCore
{
+ [IgnoreMultiTenancy]
[ConnectionStringName(BloggingDbProperties.ConnectionStringName)]
public interface IBloggingDbContext : IEfCoreDbContext
{
@@ -24,4 +26,4 @@ namespace Volo.Blogging.EntityFrameworkCore
DbSet Tags { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Posts/EfCorePostRepository.cs b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Posts/EfCorePostRepository.cs
index a5a84fd340..a676816dee 100644
--- a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Posts/EfCorePostRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Posts/EfCorePostRepository.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Entities;
@@ -18,12 +19,12 @@ namespace Volo.Blogging.Posts
}
- public async Task> GetPostsByBlogId(Guid id)
+ public async Task> GetPostsByBlogId(Guid id, CancellationToken cancellationToken = default)
{
- return await (await GetDbSetAsync()).Where(p => p.BlogId == id).OrderByDescending(p=>p.CreationTime).ToListAsync();
+ return await (await GetDbSetAsync()).Where(p => p.BlogId == id).OrderByDescending(p=>p.CreationTime).ToListAsync(GetCancellationToken(cancellationToken));
}
- public async Task IsPostUrlInUseAsync(Guid blogId, string url, Guid? excludingPostId = null)
+ public async Task IsPostUrlInUseAsync(Guid blogId, string url, Guid? excludingPostId = null, CancellationToken cancellationToken = default)
{
var query = (await GetDbSetAsync()).Where(p => blogId == p.BlogId && p.Url == url);
@@ -32,12 +33,12 @@ namespace Volo.Blogging.Posts
query = query.Where(p => excludingPostId != p.Id);
}
- return await query.AnyAsync();
+ return await query.AnyAsync(GetCancellationToken(cancellationToken));
}
- public async Task GetPostByUrl(Guid blogId, string url)
+ public async Task GetPostByUrl(Guid blogId, string url, CancellationToken cancellationToken = default)
{
- var post = await (await GetDbSetAsync()).FirstOrDefaultAsync(p => p.BlogId == blogId && p.Url == url);
+ var post = await (await GetDbSetAsync()).FirstOrDefaultAsync(p => p.BlogId == blogId && p.Url == url, GetCancellationToken(cancellationToken));
if (post == null)
{
@@ -47,15 +48,15 @@ namespace Volo.Blogging.Posts
return post;
}
- public async Task> GetOrderedList(Guid blogId,bool descending = false)
+ public async Task> GetOrderedList(Guid blogId,bool descending = false, CancellationToken cancellationToken = default)
{
if (!descending)
{
- return await (await GetDbSetAsync()).Where(x=>x.BlogId==blogId).OrderByDescending(x => x.CreationTime).ToListAsync();
+ return await (await GetDbSetAsync()).Where(x=>x.BlogId==blogId).OrderByDescending(x => x.CreationTime).ToListAsync(GetCancellationToken(cancellationToken));
}
else
{
- return await (await GetDbSetAsync()).Where(x => x.BlogId == blogId).OrderBy(x => x.CreationTime).ToListAsync();
+ return await (await GetDbSetAsync()).Where(x => x.BlogId == blogId).OrderBy(x => x.CreationTime).ToListAsync(GetCancellationToken(cancellationToken));
}
}
diff --git a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Tagging/EfCoreTagRepository.cs b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Tagging/EfCoreTagRepository.cs
index a92ae780da..0a33207374 100644
--- a/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Tagging/EfCoreTagRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Tagging/EfCoreTagRepository.cs
@@ -17,24 +17,24 @@ namespace Volo.Blogging.Tagging
{
}
- public async Task> GetListAsync(Guid blogId)
+ public async Task> GetListAsync(Guid blogId, CancellationToken cancellationToken = default)
{
- return await (await GetDbSetAsync()).Where(t=>t.BlogId == blogId).ToListAsync();
+ return await (await GetDbSetAsync()).Where(t=>t.BlogId == blogId).ToListAsync(GetCancellationToken(cancellationToken));
}
- public async Task GetByNameAsync(Guid blogId, string name)
+ public async Task GetByNameAsync(Guid blogId, string name, CancellationToken cancellationToken = default)
{
- return await (await GetDbSetAsync()).FirstAsync(t=> t.BlogId == blogId && t.Name == name);
+ return await (await GetDbSetAsync()).FirstAsync(t=> t.BlogId == blogId && t.Name == name, GetCancellationToken(cancellationToken));
}
- public async Task FindByNameAsync(Guid blogId, string name)
+ public async Task FindByNameAsync(Guid blogId, string name, CancellationToken cancellationToken = default)
{
- return await (await GetDbSetAsync()).FirstOrDefaultAsync(t => t.BlogId == blogId && t.Name == name);
+ return await (await GetDbSetAsync()).FirstOrDefaultAsync(t => t.BlogId == blogId && t.Name == name, GetCancellationToken(cancellationToken));
}
- public async Task> GetListAsync(IEnumerable ids)
+ public async Task> GetListAsync(IEnumerable ids, CancellationToken cancellationToken = default)
{
- return await (await GetDbSetAsync()).Where(t => ids.Contains(t.Id)).ToListAsync();
+ return await (await GetDbSetAsync()).Where(t => ids.Contains(t.Id)).ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task DecreaseUsageCountOfTagsAsync(List ids, CancellationToken cancellationToken = default)
diff --git a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Blogs/MongoBlogRepository.cs b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Blogs/MongoBlogRepository.cs
index 6025dfe3ca..2577b8d3a0 100644
--- a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Blogs/MongoBlogRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Blogs/MongoBlogRepository.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver.Linq;
using Volo.Abp.Domain.Repositories.MongoDB;
@@ -13,9 +14,9 @@ namespace Volo.Blogging.Blogs
{
}
- public async Task FindByShortNameAsync(string shortName)
+ public async Task FindByShortNameAsync(string shortName, CancellationToken cancellationToken = default)
{
- return await (await GetMongoQueryableAsync()).FirstOrDefaultAsync(p => p.ShortName == shortName);
+ return await (await GetMongoQueryableAsync(cancellationToken)).FirstOrDefaultAsync(p => p.ShortName == shortName, GetCancellationToken(cancellationToken));
}
}
}
diff --git a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Comments/MongoCommentRepository.cs b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Comments/MongoCommentRepository.cs
index bbbe60345b..689e44abbd 100644
--- a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Comments/MongoCommentRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Comments/MongoCommentRepository.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
@@ -15,33 +16,33 @@ namespace Volo.Blogging.Comments
{
}
- public async Task> GetListOfPostAsync(Guid postId)
+ public async Task> GetListOfPostAsync(Guid postId, CancellationToken cancellationToken = default)
{
- return await (await GetMongoQueryableAsync())
+ return await (await GetMongoQueryableAsync(cancellationToken))
.Where(a => a.PostId == postId)
.OrderBy(a => a.CreationTime)
- .ToListAsync();
+ .ToListAsync(GetCancellationToken(cancellationToken));
}
- public async Task GetCommentCountOfPostAsync(Guid postId)
+ public async Task GetCommentCountOfPostAsync(Guid postId, CancellationToken cancellationToken = default)
{
- return await (await GetMongoQueryableAsync())
- .CountAsync(a => a.PostId == postId);
+ return await (await GetMongoQueryableAsync(cancellationToken))
+ .CountAsync(a => a.PostId == postId, GetCancellationToken(cancellationToken));
}
- public async Task> GetRepliesOfComment(Guid id)
+ public async Task> GetRepliesOfComment(Guid id, CancellationToken cancellationToken = default)
{
- return await (await GetMongoQueryableAsync())
- .Where(a => a.RepliedCommentId == id).ToListAsync();
+ return await (await GetMongoQueryableAsync(cancellationToken))
+ .Where(a => a.RepliedCommentId == id).ToListAsync(GetCancellationToken(cancellationToken));
}
- public async Task DeleteOfPost(Guid id)
+ public async Task DeleteOfPost(Guid id, CancellationToken cancellationToken = default)
{
- var recordsToDelete = (await GetMongoQueryableAsync()).Where(pt => pt.PostId == id);
+ var recordsToDelete = (await GetMongoQueryableAsync(cancellationToken)).Where(pt => pt.PostId == id);
foreach (var record in recordsToDelete)
{
- await DeleteAsync(record);
+ await DeleteAsync(record, cancellationToken: GetCancellationToken(cancellationToken));
}
}
}
diff --git a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/MongoDB/BloggingMongoDbContext.cs b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/MongoDB/BloggingMongoDbContext.cs
index fa265b3e67..1f20ff1744 100644
--- a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/MongoDB/BloggingMongoDbContext.cs
+++ b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/MongoDB/BloggingMongoDbContext.cs
@@ -1,6 +1,7 @@
using MongoDB.Driver;
using Volo.Abp.Data;
using Volo.Abp.MongoDB;
+using Volo.Abp.MultiTenancy;
using Volo.Blogging.Blogs;
using Volo.Blogging.Comments;
using Volo.Blogging.Posts;
@@ -8,6 +9,7 @@ using Volo.Blogging.Users;
namespace Volo.Blogging.MongoDB
{
+ [IgnoreMultiTenancy]
[ConnectionStringName(BloggingDbProperties.ConnectionStringName)]
public class BloggingMongoDbContext : AbpMongoDbContext, IBloggingMongoDbContext
{
diff --git a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/MongoDB/IBloggingMongoDbContext.cs b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/MongoDB/IBloggingMongoDbContext.cs
index 8366e87d74..1dbf5eee92 100644
--- a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/MongoDB/IBloggingMongoDbContext.cs
+++ b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/MongoDB/IBloggingMongoDbContext.cs
@@ -1,6 +1,7 @@
using MongoDB.Driver;
using Volo.Abp.Data;
using Volo.Abp.MongoDB;
+using Volo.Abp.MultiTenancy;
using Volo.Blogging.Blogs;
using Volo.Blogging.Comments;
using Volo.Blogging.Posts;
@@ -8,6 +9,7 @@ using Volo.Blogging.Users;
namespace Volo.Blogging.MongoDB
{
+ [IgnoreMultiTenancy]
[ConnectionStringName(BloggingDbProperties.ConnectionStringName)]
public interface IBloggingMongoDbContext : IAbpMongoDbContext
{
@@ -22,4 +24,4 @@ namespace Volo.Blogging.MongoDB
IMongoCollection Comments { get; }
}
-}
\ No newline at end of file
+}
diff --git a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Posts/MongoPostRepository.cs b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Posts/MongoPostRepository.cs
index 27f4ad4348..a2d79c9466 100644
--- a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Posts/MongoPostRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Posts/MongoPostRepository.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
@@ -16,27 +17,27 @@ namespace Volo.Blogging.Posts
{
}
- public async Task> GetPostsByBlogId(Guid id)
+ public async Task> GetPostsByBlogId(Guid id, CancellationToken cancellationToken = default)
{
- return await (await GetMongoQueryableAsync()).Where(p => p.BlogId == id).OrderByDescending(p => p.CreationTime).ToListAsync();
+ return await (await GetMongoQueryableAsync(cancellationToken)).Where(p => p.BlogId == id).OrderByDescending(p => p.CreationTime).ToListAsync(GetCancellationToken(cancellationToken));
}
- public async Task IsPostUrlInUseAsync(Guid blogId, string url, Guid? excludingPostId = null)
+ public async Task IsPostUrlInUseAsync(Guid blogId, string url, Guid? excludingPostId = null, CancellationToken cancellationToken = default)
{
- var query = (await GetMongoQueryableAsync()).Where(p => blogId == p.BlogId && p.Url == url);
+ var query = (await GetMongoQueryableAsync(cancellationToken)).Where(p => blogId == p.BlogId && p.Url == url);
if (excludingPostId != null)
{
query = query.Where(p => excludingPostId != p.Id);
}
- return await query.AnyAsync();
+ return await query.AnyAsync(GetCancellationToken(cancellationToken));
}
- public async Task GetPostByUrl(Guid blogId, string url)
+ public async Task GetPostByUrl(Guid blogId, string url, CancellationToken cancellationToken = default)
{
- var post = await (await GetMongoQueryableAsync()).FirstOrDefaultAsync(p => p.BlogId == blogId && p.Url == url);
+ var post = await (await GetMongoQueryableAsync(cancellationToken)).FirstOrDefaultAsync(p => p.BlogId == blogId && p.Url == url, GetCancellationToken(cancellationToken));
if (post == null)
{
@@ -46,16 +47,16 @@ namespace Volo.Blogging.Posts
return post;
}
- public async Task> GetOrderedList(Guid blogId, bool @descending = false)
+ public async Task> GetOrderedList(Guid blogId, bool @descending = false, CancellationToken cancellationToken = default)
{
- var query = (await GetMongoQueryableAsync()).Where(x => x.BlogId == blogId);
+ var query = (await GetMongoQueryableAsync(cancellationToken)).Where(x => x.BlogId == blogId);
if (!descending)
{
- return await query.OrderBy(x => x.CreationTime).ToListAsync();
+ return await query.OrderBy(x => x.CreationTime).ToListAsync(GetCancellationToken(cancellationToken));
}
- return await query.OrderByDescending(x => x.CreationTime).ToListAsync();
+ return await query.OrderByDescending(x => x.CreationTime).ToListAsync(GetCancellationToken(cancellationToken));
}
}
}
diff --git a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Tagging/MongoTagRepository.cs b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Tagging/MongoTagRepository.cs
index f0024b37d7..2030d47f2d 100644
--- a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Tagging/MongoTagRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Tagging/MongoTagRepository.cs
@@ -18,29 +18,29 @@ namespace Volo.Blogging.Tagging
{
}
- public async Task> GetListAsync(Guid blogId)
+ public async Task> GetListAsync(Guid blogId, CancellationToken cancellationToken = default)
{
- return await (await GetMongoQueryableAsync()).Where(t => t.BlogId == blogId).ToListAsync();
+ return await (await GetMongoQueryableAsync(cancellationToken)).Where(t => t.BlogId == blogId).ToListAsync(GetCancellationToken(cancellationToken));
}
- public async Task GetByNameAsync(Guid blogId, string name)
+ public async Task GetByNameAsync(Guid blogId, string name, CancellationToken cancellationToken = default)
{
- return await (await GetMongoQueryableAsync()).Where(t => t.BlogId == blogId && t.Name == name).FirstAsync();
+ return await (await GetMongoQueryableAsync(cancellationToken)).Where(t => t.BlogId == blogId && t.Name == name).FirstAsync(GetCancellationToken(cancellationToken));
}
- public async Task FindByNameAsync(Guid blogId, string name)
+ public async Task FindByNameAsync(Guid blogId, string name, CancellationToken cancellationToken = default)
{
- return await (await GetMongoQueryableAsync()).Where(t => t.BlogId == blogId && t.Name == name).FirstOrDefaultAsync();
+ return await (await GetMongoQueryableAsync(cancellationToken)).Where(t => t.BlogId == blogId && t.Name == name).FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
}
- public async Task> GetListAsync(IEnumerable ids)
+ public async Task> GetListAsync(IEnumerable ids, CancellationToken cancellationToken = default)
{
- return await (await GetMongoQueryableAsync()).Where(t => ids.Contains(t.Id)).ToListAsync();
+ return await (await GetMongoQueryableAsync(cancellationToken)).Where(t => ids.Contains(t.Id)).ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task DecreaseUsageCountOfTagsAsync(List ids, CancellationToken cancellationToken = default)
{
- var tags = await (await GetMongoQueryableAsync())
+ var tags = await (await GetMongoQueryableAsync(cancellationToken))
.Where(t => ids.Contains(t.Id))
.ToListAsync(GetCancellationToken(cancellationToken));
diff --git a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Users/MongoBlogUserRepository.cs b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Users/MongoBlogUserRepository.cs
index fdcf4d0097..5523af8394 100644
--- a/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Users/MongoBlogUserRepository.cs
+++ b/modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Users/MongoBlogUserRepository.cs
@@ -15,7 +15,7 @@ namespace Volo.Blogging.Users
{
}
- public async Task> GetUsersAsync(int maxCount, string filter, CancellationToken cancellationToken)
+ public async Task> GetUsersAsync(int maxCount, string filter, CancellationToken cancellationToken = default)
{
var query = await GetMongoQueryableAsync(cancellationToken);
@@ -24,7 +24,7 @@ namespace Volo.Blogging.Users
query = query.Where(x => x.UserName.Contains(filter));
}
- return await query.Take(maxCount).ToListAsync(cancellationToken);
+ return await query.Take(maxCount).ToListAsync(GetCancellationToken(cancellationToken));
}
}
}
diff --git a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json
index 9fd2034ecb..0a602e5e82 100644
--- a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json
+++ b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json
@@ -3,6 +3,6 @@
"name": "client-simulation-web",
"private": true,
"dependencies": {
- "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.0-rc.2"
+ "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.0"
}
}
\ No newline at end of file
diff --git a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock
index 8edfb8fa10..7b70feb736 100644
--- a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock
+++ b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock
@@ -2,37 +2,37 @@
# yarn lockfile v1
-"@abp/aspnetcore.mvc.ui.theme.basic@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-4.2.0-rc.2.tgz#f4625e18fd3704d432913e9de59c7183770ea485"
- integrity sha512-wwOFcrICyhgAcBq7zgdIkYQ8Mov0g1iYrjoRZRiUzBYG4wkcAO9POM9asE6uvY5sD/hd0cRoXSZOcNKUt0J1SA==
- dependencies:
- "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui.theme.shared@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0-rc.2.tgz#9ff3af53b667e747c06d3f067a0f68a938ac72a8"
- integrity sha512-qsJ6UaUxyOJOHxsqVjlUGhCvQUnbXgGzLvFPJZYLpnWm6ZvE1KAgJnQHL46YSllCDT0meVqHt9byjOCRJUMm9Q==
- dependencies:
- "@abp/aspnetcore.mvc.ui" "~4.2.0-rc.2"
- "@abp/bootstrap" "~4.2.0-rc.2"
- "@abp/bootstrap-datepicker" "~4.2.0-rc.2"
- "@abp/datatables.net-bs4" "~4.2.0-rc.2"
- "@abp/font-awesome" "~4.2.0-rc.2"
- "@abp/jquery-form" "~4.2.0-rc.2"
- "@abp/jquery-validation-unobtrusive" "~4.2.0-rc.2"
- "@abp/lodash" "~4.2.0-rc.2"
- "@abp/luxon" "~4.2.0-rc.2"
- "@abp/malihu-custom-scrollbar-plugin" "~4.2.0-rc.2"
- "@abp/select2" "~4.2.0-rc.2"
- "@abp/sweetalert" "~4.2.0-rc.2"
- "@abp/timeago" "~4.2.0-rc.2"
- "@abp/toastr" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0-rc.2.tgz#726f45c7ff12e69e970fb89b4adfb15502a11576"
- integrity sha512-EzTYQ8XzXIprfK95LyYc1Ci3to3dNlBOSzkkYfYDXkSR5/SyBKckCTd5FL4c7yrs+qBoJMxKWDyWz+pmf6PIJA==
+"@abp/aspnetcore.mvc.ui.theme.basic@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-4.2.0.tgz#01d6aab8a31fd6ea828b753805f1ba9a9165975f"
+ integrity sha512-d+7YubPbuBRY8tjqBxS4I1gyxekjg8Z0X9QaDrf/SGQBoWpIdbG09AekNdddKNkimWcPg4UgUytahPuX9f17ZA==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui.theme.shared@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0.tgz#a72b5e1cefa27e658b7f072a8c2c1b4ee12baef8"
+ integrity sha512-bgWwBBJA/74kFGWh7O+lzb+inV5LOlYOpDoCNAL0XgQTrutrPNHwsk5ZnGVfhSYrBgk47HGVZDwsqKMCTRn1ig==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui" "~4.2.0"
+ "@abp/bootstrap" "~4.2.0"
+ "@abp/bootstrap-datepicker" "~4.2.0"
+ "@abp/datatables.net-bs4" "~4.2.0"
+ "@abp/font-awesome" "~4.2.0"
+ "@abp/jquery-form" "~4.2.0"
+ "@abp/jquery-validation-unobtrusive" "~4.2.0"
+ "@abp/lodash" "~4.2.0"
+ "@abp/luxon" "~4.2.0"
+ "@abp/malihu-custom-scrollbar-plugin" "~4.2.0"
+ "@abp/select2" "~4.2.0"
+ "@abp/sweetalert" "~4.2.0"
+ "@abp/timeago" "~4.2.0"
+ "@abp/toastr" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0.tgz#9c090f64a33d31962936d8d53b345afeaa9f2ba3"
+ integrity sha512-Qt3MUZ41vuvnIVEAYxyOm1mflvFwwvKYsEjFBbePBnwaYL7udooiIFxTEm4FBh3EQJOi+8T84rnXqiIXj4Pi8A==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@@ -43,145 +43,145 @@
micromatch "^4.0.2"
path "^0.12.7"
-"@abp/bootstrap-datepicker@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0-rc.2.tgz#f2a6d013321c98f8c9a7533087360fce9a5fd074"
- integrity sha512-n3gLYLL7hHX83gurN5iRkpairrw0oAyg+Bc6SeIbNAdorun9wBJn7IlmvXxGPn1xK5iDKktRSeWJ885fMgkuWg==
+"@abp/bootstrap-datepicker@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0.tgz#92abebe044a91b94b8a3b85560b501120a0fa500"
+ integrity sha512-bhEa/+zGVX00vkXGrbKI/hcl9o5Xgqwb27by9ZQqxk9Go4lwsEP/7lrXM49Cg8XZTT3L0/lYclneEMDrqGafaQ==
dependencies:
bootstrap-datepicker "^1.9.0"
-"@abp/bootstrap@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0-rc.2.tgz#49250657f667f7553f3c2149fda43f7535de989b"
- integrity sha512-WYdyDQzgFlltxqdYINAMVWjXiiDAx780fTJEd3YKLSzxmVGBfoW4cfFzw8vr/G/EMYrgAPQtrIS+BRlFAJXXGQ==
+"@abp/bootstrap@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0.tgz#c7ce82ead40bf0d62a318f67f180663ec76aa53c"
+ integrity sha512-E1gEX0ct67KFjKiZB6eQcIYJ3TS/pF1S4CxknBVCd77Zs03bHI+eEgBNlwcYriVBbQo+vheUQAaACbi+e2mm3Q==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
bootstrap "^4.5.0"
bootstrap-v4-rtl "4.4.1-2"
-"@abp/core@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0-rc.2.tgz#dc18c3b8f294563ba62c000c026f5ceb86030456"
- integrity sha512-YJz4xUwb/mv/Xi/WuPz2SF/LD22P/UJ+psb+35ezOeuj020IAdaunk8LdrU5TfaZqNe5WpGszKMA+jO9ydNuqA==
+"@abp/core@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0.tgz#20da3d1bab30e80d8864915fdd67e99db729be71"
+ integrity sha512-Cfa6Ck+Tr7isVpNxo9qT9eKByLadDErA+QVjeps7qYq9ztIpIz/7Yl85tHYEH0YPO9y2zcSOvxjy5SCBXlph5Q==
dependencies:
- "@abp/utils" "^4.2.0-rc.2"
+ "@abp/utils" "^4.2.0"
-"@abp/datatables.net-bs4@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0-rc.2.tgz#0d14886aa756ca707dd365b423b40d84c658268e"
- integrity sha512-kX+NrGkisy7IMi+xL69dPaPOYNLBZ4Vp7xCvJqNhdc5Sh6Rn1P0bLvxFKG065mBMfgW8tyFNnN3c5WzwcRFSmg==
+"@abp/datatables.net-bs4@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0.tgz#b5cb47235079a4063c5ff8ce78e65596fa587709"
+ integrity sha512-N4hp2xCst1qavt07Nf+zXlvbZfeSah64VuMjsZgaimHMlDjxg6zVsTHLgLfzwfPV/eOBrGiecPEuvfEeaqcw4A==
dependencies:
- "@abp/datatables.net" "~4.2.0-rc.2"
+ "@abp/datatables.net" "~4.2.0"
datatables.net-bs4 "^1.10.21"
-"@abp/datatables.net@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0-rc.2.tgz#a82ac16c1644a92d01ba63bf57e0d3784eb00f2f"
- integrity sha512-bEQ6QSUN65lJ8fK8wOVE16cayDI64EgyVb3qZAzWUncxPyLLa5s5zlDjcQ98D3An+x3tG2CdmEEWjlAgWdaf1g==
+"@abp/datatables.net@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0.tgz#2e0273c3212e5a62fc8b4138e4570fb27143f701"
+ integrity sha512-33ZkaorkVkPQ7HNtDjyIvcVbvAdFm8V+gFN+xMQZhA10wMlMGrKzVJjriv4NhNpPjtB4/owhOv6wobiuWBrGiA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
datatables.net "^1.10.21"
-"@abp/font-awesome@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0-rc.2.tgz#6c72ef7ae00beda565e9836c8214ccf074ea7e4b"
- integrity sha512-bEQPGyVsKV7aQtVwG4UIcG+DMneBD7jcjX3eFqjOlGhQq3ODbNld5IPXHO+JnHDLt5NOzrePQLUzPhsvCIwhGA==
+"@abp/font-awesome@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0.tgz#a637d164634b0df862e4ea620736afae282c71c9"
+ integrity sha512-P8OXp+XIZj6l7cNJ5+7Lpl8iixI/bHGSPkATggaOYZ2EWoNR3B/8pj7p44weP2bCAvUEvaxk214BKlpAslo8eQ==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
"@fortawesome/fontawesome-free" "^5.13.0"
-"@abp/jquery-form@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0-rc.2.tgz#a4726794f78cf69dd75c0adda3dca3ed623f02d8"
- integrity sha512-rOGXYTTiQUD2HWTabh0+Ot6LX4PEObd3DW3ikBHZSnfen7W0OgnLdqNaunHYSEV3UUgCAZHaX0wQd4SM0pRMLg==
+"@abp/jquery-form@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0.tgz#12b88a79a69f7d3b15aed8c7ca3ff5bc9f526f22"
+ integrity sha512-lxvXhA4kg002gmDTWgoE6TcQWDe6kBcpV4KBB7aK/6LjK3noeT29SPX0kvKxjoUKyM5TqT2Hx7rg4jgtICjFFA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-form "^4.3.0"
-"@abp/jquery-validation-unobtrusive@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0-rc.2.tgz#5dee22e1bcbd44bd8e2584d37d79e8313cf615ec"
- integrity sha512-xk56Otr6PG/bED2yJuPo0OhwcgS4FQQXySgPD9e7mlZQcjxZ4LvmRU/btoNoxSHKYUBLKRfEOYOqRTxJhrH0eA==
+"@abp/jquery-validation-unobtrusive@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0.tgz#05bcd303ec1e22b85389d03a8941eb898bac354f"
+ integrity sha512-mtvUcoTD5XSurMFI5cybgWzFI9bn35vU1PvH5NJxJitjJ7sg9gjtLf9WOIddIy4FdqmprhbG2YnR32GITOwFhg==
dependencies:
- "@abp/jquery-validation" "~4.2.0-rc.2"
+ "@abp/jquery-validation" "~4.2.0"
jquery-validation-unobtrusive "^3.2.11"
-"@abp/jquery-validation@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0-rc.2.tgz#594b9132d1eafebed60be10d219bc9e8b15f18b6"
- integrity sha512-LkNI3X7gpYYkI3DnCTZ1KIV6ykKMqw6pLZhFvTZz7GliZWE1jHtFos4U6lWe2XnMjnFeVeY6rPFM/1LaamfCKg==
+"@abp/jquery-validation@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0.tgz#a09d7cf2abf8ccf0c59f27eadacb030fb2067bbe"
+ integrity sha512-/nvJrs1pt3LJX+SgH3FtDPfCDrcl4M0LDxjV7hf0Y1jtyhvWOQiyJMb8FKzMweTTEOd0pHG/GvOKd90STabSiw==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-validation "^1.19.2"
-"@abp/jquery@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0-rc.2.tgz#146589cbf4397be727d38798d557f3879ae51057"
- integrity sha512-yTYk5rRG3qnRKnA/pSXZNH/+KJcJ2Wo5BUtt3G8oKAe+no0Au1BoCV9j7JNiSnLXkFVWFuRwEZCh+cp6ngACng==
+"@abp/jquery@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0.tgz#0a24488198ca6c9b84273fa028b853ee9f94f3a7"
+ integrity sha512-6a42Iy7knhgzvQUvCHenrVnPDKhsOyqgZkPxs9pa9x/wNapSch+jLM7u1ezKAFj/Ai4w9yG/yqP+4YE8seZDZw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
jquery "~3.5.1"
-"@abp/lodash@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0-rc.2.tgz#f0a238991c288f439e2751938a39d434dd7883e7"
- integrity sha512-En9gZD8TDY8ZvZqHVsv3cP2EsRdPRsGD0ncUYOvlNG/sc+MZpRmZ+xOLws1wXS83IxGAxzPdCFEu0biJlyOyxg==
+"@abp/lodash@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0.tgz#74dfac7d70f1563df2b78c5ebd0b2450e11c4c42"
+ integrity sha512-5hpjxWZJPvjMIY7FCCw/v/B+JzJbB/yuoioRzcU4vrisY9uRq54vVYcX7hH1DldsJFPTuXY3Id1WBflHA5I9Aw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
lodash "^4.17.15"
-"@abp/luxon@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0-rc.2.tgz#ace30caacf6abcce1559b65046ea55e47e1cb8a2"
- integrity sha512-ivhOadlaeBh6Pi3S5Bo0pb4EPCEjMFL5N5tZXGGieZt7EnF+4uiXbKJVErXNCDtX1jhJT/3HGqmdxa+WynUE0A==
+"@abp/luxon@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0.tgz#9cd02faa02cda1315f3e23ae204991ef47d6ae7c"
+ integrity sha512-dwtv2kqWCDyQADA1Os0aIy6Au2PhBtN6q9kukLWCvYmQZI23OKuEBMSngbJVTqEPfz0LV6CWbsWCUC3okAs46A==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
luxon "^1.24.1"
-"@abp/malihu-custom-scrollbar-plugin@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0-rc.2.tgz#483668c09e13b0ebcea16320a16f8517fcdd53ee"
- integrity sha512-IYOwJcWyJkn/gdp4VkEYCv2Gi5+Boxe7pE7hA49gxgllHiFV0ABDFrRg4h8MbyJd80iwvVPo8t8ouvn4Snm+gQ==
+"@abp/malihu-custom-scrollbar-plugin@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0.tgz#2f8538df5567a2cf227998e4e2fb9a44b6e814eb"
+ integrity sha512-3D5REdR7yw2sRRfm3Oi+qlhDABLrKvfU/l7JcCJy+vrBvadx3e3pTdTLXsGptypPN3x/Qr400LgwIrrgyefN8g==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
malihu-custom-scrollbar-plugin "^3.1.5"
-"@abp/select2@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0-rc.2.tgz#d11e808dac90e09e14025b6ba6dabed683a9b1fb"
- integrity sha512-fENomkoAML+NQWvZ/ecjvqnXtvrzJKyChwj9Ul12c+Noi6boeuFDbhi/OG6qCrSzDnNBrehHVXBLFxT9sIL0OA==
+"@abp/select2@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0.tgz#eb05d22b1390c037911ba25e5ca0f2ed508a93b1"
+ integrity sha512-VlNoa9+F1/kGmaEI2wbL/cRNeAEpp0UdLpbadAnsmpUIODxCULCWS556Q4Y6Ff4CzYtzkYz2qaJ8T8pn+3EOcA==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
select2 "^4.0.13"
-"@abp/sweetalert@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0-rc.2.tgz#2359eeb9e4b34c4cbb3aaed11136ea3d280bd677"
- integrity sha512-oQPj2vKPNAOvBECgJFdDwvJ8nwQ54ZPsAW1XS3XSkFz3YwWn4Xt9eZK6vecHloYckSckrFtsN/DSQI8ao/uIFg==
+"@abp/sweetalert@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0.tgz#b1daf641f27f0c8c2e246d364d6285c133faf773"
+ integrity sha512-AarV/L031xNB1gk/OYEUxkKZmls7zTwovS2t3ZrmwXXoav7nBCSPjEf1ByR2yhZRU/Yo1SNY/CNQQ4dgyf7Xng==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
sweetalert "^2.1.2"
-"@abp/timeago@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0-rc.2.tgz#d243acff635978068ec579c83a34d0680616c5ef"
- integrity sha512-TF1dt9ro3BQnfVetDzbOkedSIncSwvPfnHKMY1xcLG2h0c6ke2PjDQ+4QJrtigggT4vfgmQtRrs/zJxjzWS7qw==
+"@abp/timeago@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0.tgz#9b15c496b7e63df93921d41de9e9eaf35a8dccbe"
+ integrity sha512-hyuLVGluHxtWEhR0VakPx5UCbyPcfq4lECEgHhI62PvH0xcSNNZ3bp1QnBTd3se/HAYvwA5sCwJY0YXQgUF2UQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
timeago "^1.6.7"
-"@abp/toastr@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0-rc.2.tgz#4e76f4b7068f92b267b725ad597b8315e6b615bc"
- integrity sha512-UJVuQWc7py54JC35RrH+MwAZsOoOhejxX+3aonz8Io2rgFFj0YwK5U+vItRNM3iabSqTcIExcSD3XL2TmQyVzg==
+"@abp/toastr@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0.tgz#400e2f28b19c72b131ca32aa188ff5151d035752"
+ integrity sha512-tuGZd3kXqj1t/Y1xN8sOUH1KxiArYKD7xkhuajoOS65Ex5ad8mHPuzCtu8Pv+KL8TVFys9x3U3Tg24DQ6ASjhQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
toastr "^2.1.4"
-"@abp/utils@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0-rc.2.tgz#43c27d421da8e58a5d74c0a2df8742efa827c842"
- integrity sha512-6gSLTP9s88aFjxm+fU2iZMzv5Eoe5/va2PHTAoQJA4BaP/SpFRGts3cT4HYWPfAbmzZVZ+tvjuYd3P6d3FCAhw==
+"@abp/utils@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0.tgz#073330e3e3f6ee61892f50260e48dbe1b05df35e"
+ integrity sha512-75qR3SdiAa75wqleAx9sUMXLj4m9duuBo5+2sVv7Y29GcEyKUPvm8B1s6tksvSGA0e3vnFTHeVEc10eD1xKHSQ==
dependencies:
just-compare "^1.3.0"
diff --git a/modules/cms-kit/angular/package.json b/modules/cms-kit/angular/package.json
index f0c70ee363..1fcaa68498 100644
--- a/modules/cms-kit/angular/package.json
+++ b/modules/cms-kit/angular/package.json
@@ -16,10 +16,10 @@
"private": true,
"dependencies": {
"@abp/ng.account": "~3.3.2",
- "@abp/ng.identity": "~4.2.0-rc.2",
- "@abp/ng.setting-management": "~4.2.0-rc.2",
- "@abp/ng.tenant-management": "~4.2.0-rc.2",
- "@abp/ng.theme.basic": "~4.2.0-rc.2",
+ "@abp/ng.identity": "~4.2.0",
+ "@abp/ng.setting-management": "~4.2.0",
+ "@abp/ng.tenant-management": "~4.2.0",
+ "@abp/ng.theme.basic": "~4.2.0",
"@angular/animations": "~10.0.0",
"@angular/common": "~10.0.0",
"@angular/compiler": "~10.0.0",
diff --git a/modules/cms-kit/angular/projects/cms-kit/package.json b/modules/cms-kit/angular/projects/cms-kit/package.json
index a8e4549b0a..04018e4360 100644
--- a/modules/cms-kit/angular/projects/cms-kit/package.json
+++ b/modules/cms-kit/angular/projects/cms-kit/package.json
@@ -4,8 +4,8 @@
"peerDependencies": {
"@angular/common": "^9.1.11",
"@angular/core": "^9.1.11",
- "@abp/ng.core": ">=4.2.0-rc.2",
- "@abp/ng.theme.shared": ">=4.2.0-rc.2"
+ "@abp/ng.core": ">=4.2.0",
+ "@abp/ng.theme.shared": ">=4.2.0"
},
"dependencies": {
"tslib": "^2.0.0"
diff --git a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json
index 214c743fe8..1d3fc57a43 100644
--- a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json
+++ b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json
@@ -3,6 +3,6 @@
"name": "my-app-identityserver",
"private": true,
"dependencies": {
- "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.0-rc.2"
+ "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.0"
}
}
\ No newline at end of file
diff --git a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock
index 0118c5f1a3..2fc3f25822 100644
--- a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock
+++ b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock
@@ -2,37 +2,37 @@
# yarn lockfile v1
-"@abp/aspnetcore.mvc.ui.theme.basic@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-4.2.0-rc.2.tgz#f4625e18fd3704d432913e9de59c7183770ea485"
- integrity sha512-wwOFcrICyhgAcBq7zgdIkYQ8Mov0g1iYrjoRZRiUzBYG4wkcAO9POM9asE6uvY5sD/hd0cRoXSZOcNKUt0J1SA==
- dependencies:
- "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui.theme.shared@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0-rc.2.tgz#9ff3af53b667e747c06d3f067a0f68a938ac72a8"
- integrity sha512-qsJ6UaUxyOJOHxsqVjlUGhCvQUnbXgGzLvFPJZYLpnWm6ZvE1KAgJnQHL46YSllCDT0meVqHt9byjOCRJUMm9Q==
- dependencies:
- "@abp/aspnetcore.mvc.ui" "~4.2.0-rc.2"
- "@abp/bootstrap" "~4.2.0-rc.2"
- "@abp/bootstrap-datepicker" "~4.2.0-rc.2"
- "@abp/datatables.net-bs4" "~4.2.0-rc.2"
- "@abp/font-awesome" "~4.2.0-rc.2"
- "@abp/jquery-form" "~4.2.0-rc.2"
- "@abp/jquery-validation-unobtrusive" "~4.2.0-rc.2"
- "@abp/lodash" "~4.2.0-rc.2"
- "@abp/luxon" "~4.2.0-rc.2"
- "@abp/malihu-custom-scrollbar-plugin" "~4.2.0-rc.2"
- "@abp/select2" "~4.2.0-rc.2"
- "@abp/sweetalert" "~4.2.0-rc.2"
- "@abp/timeago" "~4.2.0-rc.2"
- "@abp/toastr" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0-rc.2.tgz#726f45c7ff12e69e970fb89b4adfb15502a11576"
- integrity sha512-EzTYQ8XzXIprfK95LyYc1Ci3to3dNlBOSzkkYfYDXkSR5/SyBKckCTd5FL4c7yrs+qBoJMxKWDyWz+pmf6PIJA==
+"@abp/aspnetcore.mvc.ui.theme.basic@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-4.2.0.tgz#01d6aab8a31fd6ea828b753805f1ba9a9165975f"
+ integrity sha512-d+7YubPbuBRY8tjqBxS4I1gyxekjg8Z0X9QaDrf/SGQBoWpIdbG09AekNdddKNkimWcPg4UgUytahPuX9f17ZA==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui.theme.shared@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0.tgz#a72b5e1cefa27e658b7f072a8c2c1b4ee12baef8"
+ integrity sha512-bgWwBBJA/74kFGWh7O+lzb+inV5LOlYOpDoCNAL0XgQTrutrPNHwsk5ZnGVfhSYrBgk47HGVZDwsqKMCTRn1ig==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui" "~4.2.0"
+ "@abp/bootstrap" "~4.2.0"
+ "@abp/bootstrap-datepicker" "~4.2.0"
+ "@abp/datatables.net-bs4" "~4.2.0"
+ "@abp/font-awesome" "~4.2.0"
+ "@abp/jquery-form" "~4.2.0"
+ "@abp/jquery-validation-unobtrusive" "~4.2.0"
+ "@abp/lodash" "~4.2.0"
+ "@abp/luxon" "~4.2.0"
+ "@abp/malihu-custom-scrollbar-plugin" "~4.2.0"
+ "@abp/select2" "~4.2.0"
+ "@abp/sweetalert" "~4.2.0"
+ "@abp/timeago" "~4.2.0"
+ "@abp/toastr" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0.tgz#9c090f64a33d31962936d8d53b345afeaa9f2ba3"
+ integrity sha512-Qt3MUZ41vuvnIVEAYxyOm1mflvFwwvKYsEjFBbePBnwaYL7udooiIFxTEm4FBh3EQJOi+8T84rnXqiIXj4Pi8A==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@@ -43,145 +43,145 @@
micromatch "^4.0.2"
path "^0.12.7"
-"@abp/bootstrap-datepicker@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0-rc.2.tgz#f2a6d013321c98f8c9a7533087360fce9a5fd074"
- integrity sha512-n3gLYLL7hHX83gurN5iRkpairrw0oAyg+Bc6SeIbNAdorun9wBJn7IlmvXxGPn1xK5iDKktRSeWJ885fMgkuWg==
+"@abp/bootstrap-datepicker@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0.tgz#92abebe044a91b94b8a3b85560b501120a0fa500"
+ integrity sha512-bhEa/+zGVX00vkXGrbKI/hcl9o5Xgqwb27by9ZQqxk9Go4lwsEP/7lrXM49Cg8XZTT3L0/lYclneEMDrqGafaQ==
dependencies:
bootstrap-datepicker "^1.9.0"
-"@abp/bootstrap@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0-rc.2.tgz#49250657f667f7553f3c2149fda43f7535de989b"
- integrity sha512-WYdyDQzgFlltxqdYINAMVWjXiiDAx780fTJEd3YKLSzxmVGBfoW4cfFzw8vr/G/EMYrgAPQtrIS+BRlFAJXXGQ==
+"@abp/bootstrap@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0.tgz#c7ce82ead40bf0d62a318f67f180663ec76aa53c"
+ integrity sha512-E1gEX0ct67KFjKiZB6eQcIYJ3TS/pF1S4CxknBVCd77Zs03bHI+eEgBNlwcYriVBbQo+vheUQAaACbi+e2mm3Q==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
bootstrap "^4.5.0"
bootstrap-v4-rtl "4.4.1-2"
-"@abp/core@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0-rc.2.tgz#dc18c3b8f294563ba62c000c026f5ceb86030456"
- integrity sha512-YJz4xUwb/mv/Xi/WuPz2SF/LD22P/UJ+psb+35ezOeuj020IAdaunk8LdrU5TfaZqNe5WpGszKMA+jO9ydNuqA==
+"@abp/core@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0.tgz#20da3d1bab30e80d8864915fdd67e99db729be71"
+ integrity sha512-Cfa6Ck+Tr7isVpNxo9qT9eKByLadDErA+QVjeps7qYq9ztIpIz/7Yl85tHYEH0YPO9y2zcSOvxjy5SCBXlph5Q==
dependencies:
- "@abp/utils" "^4.2.0-rc.2"
+ "@abp/utils" "^4.2.0"
-"@abp/datatables.net-bs4@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0-rc.2.tgz#0d14886aa756ca707dd365b423b40d84c658268e"
- integrity sha512-kX+NrGkisy7IMi+xL69dPaPOYNLBZ4Vp7xCvJqNhdc5Sh6Rn1P0bLvxFKG065mBMfgW8tyFNnN3c5WzwcRFSmg==
+"@abp/datatables.net-bs4@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0.tgz#b5cb47235079a4063c5ff8ce78e65596fa587709"
+ integrity sha512-N4hp2xCst1qavt07Nf+zXlvbZfeSah64VuMjsZgaimHMlDjxg6zVsTHLgLfzwfPV/eOBrGiecPEuvfEeaqcw4A==
dependencies:
- "@abp/datatables.net" "~4.2.0-rc.2"
+ "@abp/datatables.net" "~4.2.0"
datatables.net-bs4 "^1.10.21"
-"@abp/datatables.net@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0-rc.2.tgz#a82ac16c1644a92d01ba63bf57e0d3784eb00f2f"
- integrity sha512-bEQ6QSUN65lJ8fK8wOVE16cayDI64EgyVb3qZAzWUncxPyLLa5s5zlDjcQ98D3An+x3tG2CdmEEWjlAgWdaf1g==
+"@abp/datatables.net@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0.tgz#2e0273c3212e5a62fc8b4138e4570fb27143f701"
+ integrity sha512-33ZkaorkVkPQ7HNtDjyIvcVbvAdFm8V+gFN+xMQZhA10wMlMGrKzVJjriv4NhNpPjtB4/owhOv6wobiuWBrGiA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
datatables.net "^1.10.21"
-"@abp/font-awesome@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0-rc.2.tgz#6c72ef7ae00beda565e9836c8214ccf074ea7e4b"
- integrity sha512-bEQPGyVsKV7aQtVwG4UIcG+DMneBD7jcjX3eFqjOlGhQq3ODbNld5IPXHO+JnHDLt5NOzrePQLUzPhsvCIwhGA==
+"@abp/font-awesome@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0.tgz#a637d164634b0df862e4ea620736afae282c71c9"
+ integrity sha512-P8OXp+XIZj6l7cNJ5+7Lpl8iixI/bHGSPkATggaOYZ2EWoNR3B/8pj7p44weP2bCAvUEvaxk214BKlpAslo8eQ==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
"@fortawesome/fontawesome-free" "^5.13.0"
-"@abp/jquery-form@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0-rc.2.tgz#a4726794f78cf69dd75c0adda3dca3ed623f02d8"
- integrity sha512-rOGXYTTiQUD2HWTabh0+Ot6LX4PEObd3DW3ikBHZSnfen7W0OgnLdqNaunHYSEV3UUgCAZHaX0wQd4SM0pRMLg==
+"@abp/jquery-form@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0.tgz#12b88a79a69f7d3b15aed8c7ca3ff5bc9f526f22"
+ integrity sha512-lxvXhA4kg002gmDTWgoE6TcQWDe6kBcpV4KBB7aK/6LjK3noeT29SPX0kvKxjoUKyM5TqT2Hx7rg4jgtICjFFA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-form "^4.3.0"
-"@abp/jquery-validation-unobtrusive@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0-rc.2.tgz#5dee22e1bcbd44bd8e2584d37d79e8313cf615ec"
- integrity sha512-xk56Otr6PG/bED2yJuPo0OhwcgS4FQQXySgPD9e7mlZQcjxZ4LvmRU/btoNoxSHKYUBLKRfEOYOqRTxJhrH0eA==
+"@abp/jquery-validation-unobtrusive@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0.tgz#05bcd303ec1e22b85389d03a8941eb898bac354f"
+ integrity sha512-mtvUcoTD5XSurMFI5cybgWzFI9bn35vU1PvH5NJxJitjJ7sg9gjtLf9WOIddIy4FdqmprhbG2YnR32GITOwFhg==
dependencies:
- "@abp/jquery-validation" "~4.2.0-rc.2"
+ "@abp/jquery-validation" "~4.2.0"
jquery-validation-unobtrusive "^3.2.11"
-"@abp/jquery-validation@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0-rc.2.tgz#594b9132d1eafebed60be10d219bc9e8b15f18b6"
- integrity sha512-LkNI3X7gpYYkI3DnCTZ1KIV6ykKMqw6pLZhFvTZz7GliZWE1jHtFos4U6lWe2XnMjnFeVeY6rPFM/1LaamfCKg==
+"@abp/jquery-validation@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0.tgz#a09d7cf2abf8ccf0c59f27eadacb030fb2067bbe"
+ integrity sha512-/nvJrs1pt3LJX+SgH3FtDPfCDrcl4M0LDxjV7hf0Y1jtyhvWOQiyJMb8FKzMweTTEOd0pHG/GvOKd90STabSiw==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-validation "^1.19.2"
-"@abp/jquery@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0-rc.2.tgz#146589cbf4397be727d38798d557f3879ae51057"
- integrity sha512-yTYk5rRG3qnRKnA/pSXZNH/+KJcJ2Wo5BUtt3G8oKAe+no0Au1BoCV9j7JNiSnLXkFVWFuRwEZCh+cp6ngACng==
+"@abp/jquery@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0.tgz#0a24488198ca6c9b84273fa028b853ee9f94f3a7"
+ integrity sha512-6a42Iy7knhgzvQUvCHenrVnPDKhsOyqgZkPxs9pa9x/wNapSch+jLM7u1ezKAFj/Ai4w9yG/yqP+4YE8seZDZw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
jquery "~3.5.1"
-"@abp/lodash@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0-rc.2.tgz#f0a238991c288f439e2751938a39d434dd7883e7"
- integrity sha512-En9gZD8TDY8ZvZqHVsv3cP2EsRdPRsGD0ncUYOvlNG/sc+MZpRmZ+xOLws1wXS83IxGAxzPdCFEu0biJlyOyxg==
+"@abp/lodash@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0.tgz#74dfac7d70f1563df2b78c5ebd0b2450e11c4c42"
+ integrity sha512-5hpjxWZJPvjMIY7FCCw/v/B+JzJbB/yuoioRzcU4vrisY9uRq54vVYcX7hH1DldsJFPTuXY3Id1WBflHA5I9Aw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
lodash "^4.17.15"
-"@abp/luxon@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0-rc.2.tgz#ace30caacf6abcce1559b65046ea55e47e1cb8a2"
- integrity sha512-ivhOadlaeBh6Pi3S5Bo0pb4EPCEjMFL5N5tZXGGieZt7EnF+4uiXbKJVErXNCDtX1jhJT/3HGqmdxa+WynUE0A==
+"@abp/luxon@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0.tgz#9cd02faa02cda1315f3e23ae204991ef47d6ae7c"
+ integrity sha512-dwtv2kqWCDyQADA1Os0aIy6Au2PhBtN6q9kukLWCvYmQZI23OKuEBMSngbJVTqEPfz0LV6CWbsWCUC3okAs46A==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
luxon "^1.24.1"
-"@abp/malihu-custom-scrollbar-plugin@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0-rc.2.tgz#483668c09e13b0ebcea16320a16f8517fcdd53ee"
- integrity sha512-IYOwJcWyJkn/gdp4VkEYCv2Gi5+Boxe7pE7hA49gxgllHiFV0ABDFrRg4h8MbyJd80iwvVPo8t8ouvn4Snm+gQ==
+"@abp/malihu-custom-scrollbar-plugin@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0.tgz#2f8538df5567a2cf227998e4e2fb9a44b6e814eb"
+ integrity sha512-3D5REdR7yw2sRRfm3Oi+qlhDABLrKvfU/l7JcCJy+vrBvadx3e3pTdTLXsGptypPN3x/Qr400LgwIrrgyefN8g==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
malihu-custom-scrollbar-plugin "^3.1.5"
-"@abp/select2@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0-rc.2.tgz#d11e808dac90e09e14025b6ba6dabed683a9b1fb"
- integrity sha512-fENomkoAML+NQWvZ/ecjvqnXtvrzJKyChwj9Ul12c+Noi6boeuFDbhi/OG6qCrSzDnNBrehHVXBLFxT9sIL0OA==
+"@abp/select2@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0.tgz#eb05d22b1390c037911ba25e5ca0f2ed508a93b1"
+ integrity sha512-VlNoa9+F1/kGmaEI2wbL/cRNeAEpp0UdLpbadAnsmpUIODxCULCWS556Q4Y6Ff4CzYtzkYz2qaJ8T8pn+3EOcA==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
select2 "^4.0.13"
-"@abp/sweetalert@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0-rc.2.tgz#2359eeb9e4b34c4cbb3aaed11136ea3d280bd677"
- integrity sha512-oQPj2vKPNAOvBECgJFdDwvJ8nwQ54ZPsAW1XS3XSkFz3YwWn4Xt9eZK6vecHloYckSckrFtsN/DSQI8ao/uIFg==
+"@abp/sweetalert@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0.tgz#b1daf641f27f0c8c2e246d364d6285c133faf773"
+ integrity sha512-AarV/L031xNB1gk/OYEUxkKZmls7zTwovS2t3ZrmwXXoav7nBCSPjEf1ByR2yhZRU/Yo1SNY/CNQQ4dgyf7Xng==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
sweetalert "^2.1.2"
-"@abp/timeago@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0-rc.2.tgz#d243acff635978068ec579c83a34d0680616c5ef"
- integrity sha512-TF1dt9ro3BQnfVetDzbOkedSIncSwvPfnHKMY1xcLG2h0c6ke2PjDQ+4QJrtigggT4vfgmQtRrs/zJxjzWS7qw==
+"@abp/timeago@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0.tgz#9b15c496b7e63df93921d41de9e9eaf35a8dccbe"
+ integrity sha512-hyuLVGluHxtWEhR0VakPx5UCbyPcfq4lECEgHhI62PvH0xcSNNZ3bp1QnBTd3se/HAYvwA5sCwJY0YXQgUF2UQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
timeago "^1.6.7"
-"@abp/toastr@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0-rc.2.tgz#4e76f4b7068f92b267b725ad597b8315e6b615bc"
- integrity sha512-UJVuQWc7py54JC35RrH+MwAZsOoOhejxX+3aonz8Io2rgFFj0YwK5U+vItRNM3iabSqTcIExcSD3XL2TmQyVzg==
+"@abp/toastr@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0.tgz#400e2f28b19c72b131ca32aa188ff5151d035752"
+ integrity sha512-tuGZd3kXqj1t/Y1xN8sOUH1KxiArYKD7xkhuajoOS65Ex5ad8mHPuzCtu8Pv+KL8TVFys9x3U3Tg24DQ6ASjhQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
toastr "^2.1.4"
-"@abp/utils@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0-rc.2.tgz#43c27d421da8e58a5d74c0a2df8742efa827c842"
- integrity sha512-6gSLTP9s88aFjxm+fU2iZMzv5Eoe5/va2PHTAoQJA4BaP/SpFRGts3cT4HYWPfAbmzZVZ+tvjuYd3P6d3FCAhw==
+"@abp/utils@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0.tgz#073330e3e3f6ee61892f50260e48dbe1b05df35e"
+ integrity sha512-75qR3SdiAa75wqleAx9sUMXLj4m9duuBo5+2sVv7Y29GcEyKUPvm8B1s6tksvSGA0e3vnFTHeVEc10eD1xKHSQ==
dependencies:
just-compare "^1.3.0"
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json b/modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json
index 807eaccef0..010901f2f3 100644
--- a/modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json
@@ -3,6 +3,6 @@
"name": "my-app",
"private": true,
"dependencies": {
- "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.0-rc.2"
+ "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.0"
}
}
\ No newline at end of file
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock
index 0aff599aef..69cec15c38 100644
--- a/modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock
@@ -2,37 +2,37 @@
# yarn lockfile v1
-"@abp/aspnetcore.mvc.ui.theme.basic@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-4.2.0-rc.2.tgz#f4625e18fd3704d432913e9de59c7183770ea485"
- integrity sha512-wwOFcrICyhgAcBq7zgdIkYQ8Mov0g1iYrjoRZRiUzBYG4wkcAO9POM9asE6uvY5sD/hd0cRoXSZOcNKUt0J1SA==
- dependencies:
- "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui.theme.shared@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0-rc.2.tgz#9ff3af53b667e747c06d3f067a0f68a938ac72a8"
- integrity sha512-qsJ6UaUxyOJOHxsqVjlUGhCvQUnbXgGzLvFPJZYLpnWm6ZvE1KAgJnQHL46YSllCDT0meVqHt9byjOCRJUMm9Q==
- dependencies:
- "@abp/aspnetcore.mvc.ui" "~4.2.0-rc.2"
- "@abp/bootstrap" "~4.2.0-rc.2"
- "@abp/bootstrap-datepicker" "~4.2.0-rc.2"
- "@abp/datatables.net-bs4" "~4.2.0-rc.2"
- "@abp/font-awesome" "~4.2.0-rc.2"
- "@abp/jquery-form" "~4.2.0-rc.2"
- "@abp/jquery-validation-unobtrusive" "~4.2.0-rc.2"
- "@abp/lodash" "~4.2.0-rc.2"
- "@abp/luxon" "~4.2.0-rc.2"
- "@abp/malihu-custom-scrollbar-plugin" "~4.2.0-rc.2"
- "@abp/select2" "~4.2.0-rc.2"
- "@abp/sweetalert" "~4.2.0-rc.2"
- "@abp/timeago" "~4.2.0-rc.2"
- "@abp/toastr" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0-rc.2.tgz#726f45c7ff12e69e970fb89b4adfb15502a11576"
- integrity sha512-EzTYQ8XzXIprfK95LyYc1Ci3to3dNlBOSzkkYfYDXkSR5/SyBKckCTd5FL4c7yrs+qBoJMxKWDyWz+pmf6PIJA==
+"@abp/aspnetcore.mvc.ui.theme.basic@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-4.2.0.tgz#01d6aab8a31fd6ea828b753805f1ba9a9165975f"
+ integrity sha512-d+7YubPbuBRY8tjqBxS4I1gyxekjg8Z0X9QaDrf/SGQBoWpIdbG09AekNdddKNkimWcPg4UgUytahPuX9f17ZA==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui.theme.shared@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0.tgz#a72b5e1cefa27e658b7f072a8c2c1b4ee12baef8"
+ integrity sha512-bgWwBBJA/74kFGWh7O+lzb+inV5LOlYOpDoCNAL0XgQTrutrPNHwsk5ZnGVfhSYrBgk47HGVZDwsqKMCTRn1ig==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui" "~4.2.0"
+ "@abp/bootstrap" "~4.2.0"
+ "@abp/bootstrap-datepicker" "~4.2.0"
+ "@abp/datatables.net-bs4" "~4.2.0"
+ "@abp/font-awesome" "~4.2.0"
+ "@abp/jquery-form" "~4.2.0"
+ "@abp/jquery-validation-unobtrusive" "~4.2.0"
+ "@abp/lodash" "~4.2.0"
+ "@abp/luxon" "~4.2.0"
+ "@abp/malihu-custom-scrollbar-plugin" "~4.2.0"
+ "@abp/select2" "~4.2.0"
+ "@abp/sweetalert" "~4.2.0"
+ "@abp/timeago" "~4.2.0"
+ "@abp/toastr" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0.tgz#9c090f64a33d31962936d8d53b345afeaa9f2ba3"
+ integrity sha512-Qt3MUZ41vuvnIVEAYxyOm1mflvFwwvKYsEjFBbePBnwaYL7udooiIFxTEm4FBh3EQJOi+8T84rnXqiIXj4Pi8A==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@@ -43,145 +43,145 @@
micromatch "^4.0.2"
path "^0.12.7"
-"@abp/bootstrap-datepicker@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0-rc.2.tgz#f2a6d013321c98f8c9a7533087360fce9a5fd074"
- integrity sha512-n3gLYLL7hHX83gurN5iRkpairrw0oAyg+Bc6SeIbNAdorun9wBJn7IlmvXxGPn1xK5iDKktRSeWJ885fMgkuWg==
+"@abp/bootstrap-datepicker@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0.tgz#92abebe044a91b94b8a3b85560b501120a0fa500"
+ integrity sha512-bhEa/+zGVX00vkXGrbKI/hcl9o5Xgqwb27by9ZQqxk9Go4lwsEP/7lrXM49Cg8XZTT3L0/lYclneEMDrqGafaQ==
dependencies:
bootstrap-datepicker "^1.9.0"
-"@abp/bootstrap@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0-rc.2.tgz#49250657f667f7553f3c2149fda43f7535de989b"
- integrity sha512-WYdyDQzgFlltxqdYINAMVWjXiiDAx780fTJEd3YKLSzxmVGBfoW4cfFzw8vr/G/EMYrgAPQtrIS+BRlFAJXXGQ==
+"@abp/bootstrap@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0.tgz#c7ce82ead40bf0d62a318f67f180663ec76aa53c"
+ integrity sha512-E1gEX0ct67KFjKiZB6eQcIYJ3TS/pF1S4CxknBVCd77Zs03bHI+eEgBNlwcYriVBbQo+vheUQAaACbi+e2mm3Q==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
bootstrap "^4.5.0"
bootstrap-v4-rtl "4.4.1-2"
-"@abp/core@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0-rc.2.tgz#dc18c3b8f294563ba62c000c026f5ceb86030456"
- integrity sha512-YJz4xUwb/mv/Xi/WuPz2SF/LD22P/UJ+psb+35ezOeuj020IAdaunk8LdrU5TfaZqNe5WpGszKMA+jO9ydNuqA==
+"@abp/core@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0.tgz#20da3d1bab30e80d8864915fdd67e99db729be71"
+ integrity sha512-Cfa6Ck+Tr7isVpNxo9qT9eKByLadDErA+QVjeps7qYq9ztIpIz/7Yl85tHYEH0YPO9y2zcSOvxjy5SCBXlph5Q==
dependencies:
- "@abp/utils" "^4.2.0-rc.2"
+ "@abp/utils" "^4.2.0"
-"@abp/datatables.net-bs4@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0-rc.2.tgz#0d14886aa756ca707dd365b423b40d84c658268e"
- integrity sha512-kX+NrGkisy7IMi+xL69dPaPOYNLBZ4Vp7xCvJqNhdc5Sh6Rn1P0bLvxFKG065mBMfgW8tyFNnN3c5WzwcRFSmg==
+"@abp/datatables.net-bs4@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0.tgz#b5cb47235079a4063c5ff8ce78e65596fa587709"
+ integrity sha512-N4hp2xCst1qavt07Nf+zXlvbZfeSah64VuMjsZgaimHMlDjxg6zVsTHLgLfzwfPV/eOBrGiecPEuvfEeaqcw4A==
dependencies:
- "@abp/datatables.net" "~4.2.0-rc.2"
+ "@abp/datatables.net" "~4.2.0"
datatables.net-bs4 "^1.10.21"
-"@abp/datatables.net@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0-rc.2.tgz#a82ac16c1644a92d01ba63bf57e0d3784eb00f2f"
- integrity sha512-bEQ6QSUN65lJ8fK8wOVE16cayDI64EgyVb3qZAzWUncxPyLLa5s5zlDjcQ98D3An+x3tG2CdmEEWjlAgWdaf1g==
+"@abp/datatables.net@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0.tgz#2e0273c3212e5a62fc8b4138e4570fb27143f701"
+ integrity sha512-33ZkaorkVkPQ7HNtDjyIvcVbvAdFm8V+gFN+xMQZhA10wMlMGrKzVJjriv4NhNpPjtB4/owhOv6wobiuWBrGiA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
datatables.net "^1.10.21"
-"@abp/font-awesome@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0-rc.2.tgz#6c72ef7ae00beda565e9836c8214ccf074ea7e4b"
- integrity sha512-bEQPGyVsKV7aQtVwG4UIcG+DMneBD7jcjX3eFqjOlGhQq3ODbNld5IPXHO+JnHDLt5NOzrePQLUzPhsvCIwhGA==
+"@abp/font-awesome@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0.tgz#a637d164634b0df862e4ea620736afae282c71c9"
+ integrity sha512-P8OXp+XIZj6l7cNJ5+7Lpl8iixI/bHGSPkATggaOYZ2EWoNR3B/8pj7p44weP2bCAvUEvaxk214BKlpAslo8eQ==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
"@fortawesome/fontawesome-free" "^5.13.0"
-"@abp/jquery-form@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0-rc.2.tgz#a4726794f78cf69dd75c0adda3dca3ed623f02d8"
- integrity sha512-rOGXYTTiQUD2HWTabh0+Ot6LX4PEObd3DW3ikBHZSnfen7W0OgnLdqNaunHYSEV3UUgCAZHaX0wQd4SM0pRMLg==
+"@abp/jquery-form@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0.tgz#12b88a79a69f7d3b15aed8c7ca3ff5bc9f526f22"
+ integrity sha512-lxvXhA4kg002gmDTWgoE6TcQWDe6kBcpV4KBB7aK/6LjK3noeT29SPX0kvKxjoUKyM5TqT2Hx7rg4jgtICjFFA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-form "^4.3.0"
-"@abp/jquery-validation-unobtrusive@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0-rc.2.tgz#5dee22e1bcbd44bd8e2584d37d79e8313cf615ec"
- integrity sha512-xk56Otr6PG/bED2yJuPo0OhwcgS4FQQXySgPD9e7mlZQcjxZ4LvmRU/btoNoxSHKYUBLKRfEOYOqRTxJhrH0eA==
+"@abp/jquery-validation-unobtrusive@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0.tgz#05bcd303ec1e22b85389d03a8941eb898bac354f"
+ integrity sha512-mtvUcoTD5XSurMFI5cybgWzFI9bn35vU1PvH5NJxJitjJ7sg9gjtLf9WOIddIy4FdqmprhbG2YnR32GITOwFhg==
dependencies:
- "@abp/jquery-validation" "~4.2.0-rc.2"
+ "@abp/jquery-validation" "~4.2.0"
jquery-validation-unobtrusive "^3.2.11"
-"@abp/jquery-validation@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0-rc.2.tgz#594b9132d1eafebed60be10d219bc9e8b15f18b6"
- integrity sha512-LkNI3X7gpYYkI3DnCTZ1KIV6ykKMqw6pLZhFvTZz7GliZWE1jHtFos4U6lWe2XnMjnFeVeY6rPFM/1LaamfCKg==
+"@abp/jquery-validation@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0.tgz#a09d7cf2abf8ccf0c59f27eadacb030fb2067bbe"
+ integrity sha512-/nvJrs1pt3LJX+SgH3FtDPfCDrcl4M0LDxjV7hf0Y1jtyhvWOQiyJMb8FKzMweTTEOd0pHG/GvOKd90STabSiw==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-validation "^1.19.2"
-"@abp/jquery@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0-rc.2.tgz#146589cbf4397be727d38798d557f3879ae51057"
- integrity sha512-yTYk5rRG3qnRKnA/pSXZNH/+KJcJ2Wo5BUtt3G8oKAe+no0Au1BoCV9j7JNiSnLXkFVWFuRwEZCh+cp6ngACng==
+"@abp/jquery@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0.tgz#0a24488198ca6c9b84273fa028b853ee9f94f3a7"
+ integrity sha512-6a42Iy7knhgzvQUvCHenrVnPDKhsOyqgZkPxs9pa9x/wNapSch+jLM7u1ezKAFj/Ai4w9yG/yqP+4YE8seZDZw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
jquery "~3.5.1"
-"@abp/lodash@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0-rc.2.tgz#f0a238991c288f439e2751938a39d434dd7883e7"
- integrity sha512-En9gZD8TDY8ZvZqHVsv3cP2EsRdPRsGD0ncUYOvlNG/sc+MZpRmZ+xOLws1wXS83IxGAxzPdCFEu0biJlyOyxg==
+"@abp/lodash@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0.tgz#74dfac7d70f1563df2b78c5ebd0b2450e11c4c42"
+ integrity sha512-5hpjxWZJPvjMIY7FCCw/v/B+JzJbB/yuoioRzcU4vrisY9uRq54vVYcX7hH1DldsJFPTuXY3Id1WBflHA5I9Aw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
lodash "^4.17.15"
-"@abp/luxon@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0-rc.2.tgz#ace30caacf6abcce1559b65046ea55e47e1cb8a2"
- integrity sha512-ivhOadlaeBh6Pi3S5Bo0pb4EPCEjMFL5N5tZXGGieZt7EnF+4uiXbKJVErXNCDtX1jhJT/3HGqmdxa+WynUE0A==
+"@abp/luxon@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0.tgz#9cd02faa02cda1315f3e23ae204991ef47d6ae7c"
+ integrity sha512-dwtv2kqWCDyQADA1Os0aIy6Au2PhBtN6q9kukLWCvYmQZI23OKuEBMSngbJVTqEPfz0LV6CWbsWCUC3okAs46A==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
luxon "^1.24.1"
-"@abp/malihu-custom-scrollbar-plugin@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0-rc.2.tgz#483668c09e13b0ebcea16320a16f8517fcdd53ee"
- integrity sha512-IYOwJcWyJkn/gdp4VkEYCv2Gi5+Boxe7pE7hA49gxgllHiFV0ABDFrRg4h8MbyJd80iwvVPo8t8ouvn4Snm+gQ==
+"@abp/malihu-custom-scrollbar-plugin@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0.tgz#2f8538df5567a2cf227998e4e2fb9a44b6e814eb"
+ integrity sha512-3D5REdR7yw2sRRfm3Oi+qlhDABLrKvfU/l7JcCJy+vrBvadx3e3pTdTLXsGptypPN3x/Qr400LgwIrrgyefN8g==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
malihu-custom-scrollbar-plugin "^3.1.5"
-"@abp/select2@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0-rc.2.tgz#d11e808dac90e09e14025b6ba6dabed683a9b1fb"
- integrity sha512-fENomkoAML+NQWvZ/ecjvqnXtvrzJKyChwj9Ul12c+Noi6boeuFDbhi/OG6qCrSzDnNBrehHVXBLFxT9sIL0OA==
+"@abp/select2@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0.tgz#eb05d22b1390c037911ba25e5ca0f2ed508a93b1"
+ integrity sha512-VlNoa9+F1/kGmaEI2wbL/cRNeAEpp0UdLpbadAnsmpUIODxCULCWS556Q4Y6Ff4CzYtzkYz2qaJ8T8pn+3EOcA==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
select2 "^4.0.13"
-"@abp/sweetalert@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0-rc.2.tgz#2359eeb9e4b34c4cbb3aaed11136ea3d280bd677"
- integrity sha512-oQPj2vKPNAOvBECgJFdDwvJ8nwQ54ZPsAW1XS3XSkFz3YwWn4Xt9eZK6vecHloYckSckrFtsN/DSQI8ao/uIFg==
+"@abp/sweetalert@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0.tgz#b1daf641f27f0c8c2e246d364d6285c133faf773"
+ integrity sha512-AarV/L031xNB1gk/OYEUxkKZmls7zTwovS2t3ZrmwXXoav7nBCSPjEf1ByR2yhZRU/Yo1SNY/CNQQ4dgyf7Xng==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
sweetalert "^2.1.2"
-"@abp/timeago@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0-rc.2.tgz#d243acff635978068ec579c83a34d0680616c5ef"
- integrity sha512-TF1dt9ro3BQnfVetDzbOkedSIncSwvPfnHKMY1xcLG2h0c6ke2PjDQ+4QJrtigggT4vfgmQtRrs/zJxjzWS7qw==
+"@abp/timeago@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0.tgz#9b15c496b7e63df93921d41de9e9eaf35a8dccbe"
+ integrity sha512-hyuLVGluHxtWEhR0VakPx5UCbyPcfq4lECEgHhI62PvH0xcSNNZ3bp1QnBTd3se/HAYvwA5sCwJY0YXQgUF2UQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
timeago "^1.6.7"
-"@abp/toastr@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0-rc.2.tgz#4e76f4b7068f92b267b725ad597b8315e6b615bc"
- integrity sha512-UJVuQWc7py54JC35RrH+MwAZsOoOhejxX+3aonz8Io2rgFFj0YwK5U+vItRNM3iabSqTcIExcSD3XL2TmQyVzg==
+"@abp/toastr@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0.tgz#400e2f28b19c72b131ca32aa188ff5151d035752"
+ integrity sha512-tuGZd3kXqj1t/Y1xN8sOUH1KxiArYKD7xkhuajoOS65Ex5ad8mHPuzCtu8Pv+KL8TVFys9x3U3Tg24DQ6ASjhQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
toastr "^2.1.4"
-"@abp/utils@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0-rc.2.tgz#43c27d421da8e58a5d74c0a2df8742efa827c842"
- integrity sha512-6gSLTP9s88aFjxm+fU2iZMzv5Eoe5/va2PHTAoQJA4BaP/SpFRGts3cT4HYWPfAbmzZVZ+tvjuYd3P6d3FCAhw==
+"@abp/utils@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0.tgz#073330e3e3f6ee61892f50260e48dbe1b05df35e"
+ integrity sha512-75qR3SdiAa75wqleAx9sUMXLj4m9duuBo5+2sVv7Y29GcEyKUPvm8B1s6tksvSGA0e3vnFTHeVEc10eD1xKHSQ==
dependencies:
just-compare "^1.3.0"
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json
index bbb4ac8f0d..1c93432838 100644
--- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json
@@ -3,7 +3,7 @@
"name": "my-app",
"private": true,
"dependencies": {
- "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.0-rc.2",
- "@abp/cms-kit": "4.2.0-rc.2"
+ "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.0",
+ "@abp/cms-kit": "4.2.0"
}
}
\ No newline at end of file
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock
index 9a99b12cc0..4bcd9f8297 100644
--- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock
@@ -2,37 +2,37 @@
# yarn lockfile v1
-"@abp/aspnetcore.mvc.ui.theme.basic@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-4.2.0-rc.2.tgz#f4625e18fd3704d432913e9de59c7183770ea485"
- integrity sha512-wwOFcrICyhgAcBq7zgdIkYQ8Mov0g1iYrjoRZRiUzBYG4wkcAO9POM9asE6uvY5sD/hd0cRoXSZOcNKUt0J1SA==
- dependencies:
- "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui.theme.shared@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0-rc.2.tgz#9ff3af53b667e747c06d3f067a0f68a938ac72a8"
- integrity sha512-qsJ6UaUxyOJOHxsqVjlUGhCvQUnbXgGzLvFPJZYLpnWm6ZvE1KAgJnQHL46YSllCDT0meVqHt9byjOCRJUMm9Q==
- dependencies:
- "@abp/aspnetcore.mvc.ui" "~4.2.0-rc.2"
- "@abp/bootstrap" "~4.2.0-rc.2"
- "@abp/bootstrap-datepicker" "~4.2.0-rc.2"
- "@abp/datatables.net-bs4" "~4.2.0-rc.2"
- "@abp/font-awesome" "~4.2.0-rc.2"
- "@abp/jquery-form" "~4.2.0-rc.2"
- "@abp/jquery-validation-unobtrusive" "~4.2.0-rc.2"
- "@abp/lodash" "~4.2.0-rc.2"
- "@abp/luxon" "~4.2.0-rc.2"
- "@abp/malihu-custom-scrollbar-plugin" "~4.2.0-rc.2"
- "@abp/select2" "~4.2.0-rc.2"
- "@abp/sweetalert" "~4.2.0-rc.2"
- "@abp/timeago" "~4.2.0-rc.2"
- "@abp/toastr" "~4.2.0-rc.2"
-
-"@abp/aspnetcore.mvc.ui@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0-rc.2.tgz#726f45c7ff12e69e970fb89b4adfb15502a11576"
- integrity sha512-EzTYQ8XzXIprfK95LyYc1Ci3to3dNlBOSzkkYfYDXkSR5/SyBKckCTd5FL4c7yrs+qBoJMxKWDyWz+pmf6PIJA==
+"@abp/aspnetcore.mvc.ui.theme.basic@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-4.2.0.tgz#01d6aab8a31fd6ea828b753805f1ba9a9165975f"
+ integrity sha512-d+7YubPbuBRY8tjqBxS4I1gyxekjg8Z0X9QaDrf/SGQBoWpIdbG09AekNdddKNkimWcPg4UgUytahPuX9f17ZA==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui.theme.shared" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui.theme.shared@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-4.2.0.tgz#a72b5e1cefa27e658b7f072a8c2c1b4ee12baef8"
+ integrity sha512-bgWwBBJA/74kFGWh7O+lzb+inV5LOlYOpDoCNAL0XgQTrutrPNHwsk5ZnGVfhSYrBgk47HGVZDwsqKMCTRn1ig==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui" "~4.2.0"
+ "@abp/bootstrap" "~4.2.0"
+ "@abp/bootstrap-datepicker" "~4.2.0"
+ "@abp/datatables.net-bs4" "~4.2.0"
+ "@abp/font-awesome" "~4.2.0"
+ "@abp/jquery-form" "~4.2.0"
+ "@abp/jquery-validation-unobtrusive" "~4.2.0"
+ "@abp/lodash" "~4.2.0"
+ "@abp/luxon" "~4.2.0"
+ "@abp/malihu-custom-scrollbar-plugin" "~4.2.0"
+ "@abp/select2" "~4.2.0"
+ "@abp/sweetalert" "~4.2.0"
+ "@abp/timeago" "~4.2.0"
+ "@abp/toastr" "~4.2.0"
+
+"@abp/aspnetcore.mvc.ui@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-4.2.0.tgz#9c090f64a33d31962936d8d53b345afeaa9f2ba3"
+ integrity sha512-Qt3MUZ41vuvnIVEAYxyOm1mflvFwwvKYsEjFBbePBnwaYL7udooiIFxTEm4FBh3EQJOi+8T84rnXqiIXj4Pi8A==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@@ -43,160 +43,160 @@
micromatch "^4.0.2"
path "^0.12.7"
-"@abp/bootstrap-datepicker@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0-rc.2.tgz#f2a6d013321c98f8c9a7533087360fce9a5fd074"
- integrity sha512-n3gLYLL7hHX83gurN5iRkpairrw0oAyg+Bc6SeIbNAdorun9wBJn7IlmvXxGPn1xK5iDKktRSeWJ885fMgkuWg==
+"@abp/bootstrap-datepicker@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-4.2.0.tgz#92abebe044a91b94b8a3b85560b501120a0fa500"
+ integrity sha512-bhEa/+zGVX00vkXGrbKI/hcl9o5Xgqwb27by9ZQqxk9Go4lwsEP/7lrXM49Cg8XZTT3L0/lYclneEMDrqGafaQ==
dependencies:
bootstrap-datepicker "^1.9.0"
-"@abp/bootstrap@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0-rc.2.tgz#49250657f667f7553f3c2149fda43f7535de989b"
- integrity sha512-WYdyDQzgFlltxqdYINAMVWjXiiDAx780fTJEd3YKLSzxmVGBfoW4cfFzw8vr/G/EMYrgAPQtrIS+BRlFAJXXGQ==
+"@abp/bootstrap@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-4.2.0.tgz#c7ce82ead40bf0d62a318f67f180663ec76aa53c"
+ integrity sha512-E1gEX0ct67KFjKiZB6eQcIYJ3TS/pF1S4CxknBVCd77Zs03bHI+eEgBNlwcYriVBbQo+vheUQAaACbi+e2mm3Q==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
bootstrap "^4.5.0"
bootstrap-v4-rtl "4.4.1-2"
-"@abp/cms-kit@4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/cms-kit/-/cms-kit-4.2.0-rc.2.tgz#0acd23315d4fe51b594739a11f9f28df25f53355"
- integrity sha512-f1sCyqfdz91IGRvSKaFtAENfA7+spP2KwsmySMtgD4skj+9U2k28rluodI0YamxsplM+eaWCeG3h6Y84UJSk2w==
+"@abp/cms-kit@4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/cms-kit/-/cms-kit-4.2.0.tgz#cfca768d3d7f95251c224a2737e8a78038635e68"
+ integrity sha512-CbO3FLmdRHJVFE5tqqj2EKgfDkhFFDXu5H7nyAtwk9zi1yV8pGvNFTQVJfzgZ7g0r5KaKTMRL3rFvSixWTF4jg==
dependencies:
- "@abp/star-rating-svg" "~4.2.0-rc.2"
+ "@abp/star-rating-svg" "~4.2.0"
-"@abp/core@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0-rc.2.tgz#dc18c3b8f294563ba62c000c026f5ceb86030456"
- integrity sha512-YJz4xUwb/mv/Xi/WuPz2SF/LD22P/UJ+psb+35ezOeuj020IAdaunk8LdrU5TfaZqNe5WpGszKMA+jO9ydNuqA==
+"@abp/core@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/core/-/core-4.2.0.tgz#20da3d1bab30e80d8864915fdd67e99db729be71"
+ integrity sha512-Cfa6Ck+Tr7isVpNxo9qT9eKByLadDErA+QVjeps7qYq9ztIpIz/7Yl85tHYEH0YPO9y2zcSOvxjy5SCBXlph5Q==
dependencies:
- "@abp/utils" "^4.2.0-rc.2"
+ "@abp/utils" "^4.2.0"
-"@abp/datatables.net-bs4@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0-rc.2.tgz#0d14886aa756ca707dd365b423b40d84c658268e"
- integrity sha512-kX+NrGkisy7IMi+xL69dPaPOYNLBZ4Vp7xCvJqNhdc5Sh6Rn1P0bLvxFKG065mBMfgW8tyFNnN3c5WzwcRFSmg==
+"@abp/datatables.net-bs4@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-4.2.0.tgz#b5cb47235079a4063c5ff8ce78e65596fa587709"
+ integrity sha512-N4hp2xCst1qavt07Nf+zXlvbZfeSah64VuMjsZgaimHMlDjxg6zVsTHLgLfzwfPV/eOBrGiecPEuvfEeaqcw4A==
dependencies:
- "@abp/datatables.net" "~4.2.0-rc.2"
+ "@abp/datatables.net" "~4.2.0"
datatables.net-bs4 "^1.10.21"
-"@abp/datatables.net@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0-rc.2.tgz#a82ac16c1644a92d01ba63bf57e0d3784eb00f2f"
- integrity sha512-bEQ6QSUN65lJ8fK8wOVE16cayDI64EgyVb3qZAzWUncxPyLLa5s5zlDjcQ98D3An+x3tG2CdmEEWjlAgWdaf1g==
+"@abp/datatables.net@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-4.2.0.tgz#2e0273c3212e5a62fc8b4138e4570fb27143f701"
+ integrity sha512-33ZkaorkVkPQ7HNtDjyIvcVbvAdFm8V+gFN+xMQZhA10wMlMGrKzVJjriv4NhNpPjtB4/owhOv6wobiuWBrGiA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
datatables.net "^1.10.21"
-"@abp/font-awesome@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0-rc.2.tgz#6c72ef7ae00beda565e9836c8214ccf074ea7e4b"
- integrity sha512-bEQPGyVsKV7aQtVwG4UIcG+DMneBD7jcjX3eFqjOlGhQq3ODbNld5IPXHO+JnHDLt5NOzrePQLUzPhsvCIwhGA==
+"@abp/font-awesome@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-4.2.0.tgz#a637d164634b0df862e4ea620736afae282c71c9"
+ integrity sha512-P8OXp+XIZj6l7cNJ5+7Lpl8iixI/bHGSPkATggaOYZ2EWoNR3B/8pj7p44weP2bCAvUEvaxk214BKlpAslo8eQ==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
"@fortawesome/fontawesome-free" "^5.13.0"
-"@abp/jquery-form@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0-rc.2.tgz#a4726794f78cf69dd75c0adda3dca3ed623f02d8"
- integrity sha512-rOGXYTTiQUD2HWTabh0+Ot6LX4PEObd3DW3ikBHZSnfen7W0OgnLdqNaunHYSEV3UUgCAZHaX0wQd4SM0pRMLg==
+"@abp/jquery-form@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-4.2.0.tgz#12b88a79a69f7d3b15aed8c7ca3ff5bc9f526f22"
+ integrity sha512-lxvXhA4kg002gmDTWgoE6TcQWDe6kBcpV4KBB7aK/6LjK3noeT29SPX0kvKxjoUKyM5TqT2Hx7rg4jgtICjFFA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-form "^4.3.0"
-"@abp/jquery-validation-unobtrusive@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0-rc.2.tgz#5dee22e1bcbd44bd8e2584d37d79e8313cf615ec"
- integrity sha512-xk56Otr6PG/bED2yJuPo0OhwcgS4FQQXySgPD9e7mlZQcjxZ4LvmRU/btoNoxSHKYUBLKRfEOYOqRTxJhrH0eA==
+"@abp/jquery-validation-unobtrusive@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.2.0.tgz#05bcd303ec1e22b85389d03a8941eb898bac354f"
+ integrity sha512-mtvUcoTD5XSurMFI5cybgWzFI9bn35vU1PvH5NJxJitjJ7sg9gjtLf9WOIddIy4FdqmprhbG2YnR32GITOwFhg==
dependencies:
- "@abp/jquery-validation" "~4.2.0-rc.2"
+ "@abp/jquery-validation" "~4.2.0"
jquery-validation-unobtrusive "^3.2.11"
-"@abp/jquery-validation@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0-rc.2.tgz#594b9132d1eafebed60be10d219bc9e8b15f18b6"
- integrity sha512-LkNI3X7gpYYkI3DnCTZ1KIV6ykKMqw6pLZhFvTZz7GliZWE1jHtFos4U6lWe2XnMjnFeVeY6rPFM/1LaamfCKg==
+"@abp/jquery-validation@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-4.2.0.tgz#a09d7cf2abf8ccf0c59f27eadacb030fb2067bbe"
+ integrity sha512-/nvJrs1pt3LJX+SgH3FtDPfCDrcl4M0LDxjV7hf0Y1jtyhvWOQiyJMb8FKzMweTTEOd0pHG/GvOKd90STabSiw==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
jquery-validation "^1.19.2"
-"@abp/jquery@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0-rc.2.tgz#146589cbf4397be727d38798d557f3879ae51057"
- integrity sha512-yTYk5rRG3qnRKnA/pSXZNH/+KJcJ2Wo5BUtt3G8oKAe+no0Au1BoCV9j7JNiSnLXkFVWFuRwEZCh+cp6ngACng==
+"@abp/jquery@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-4.2.0.tgz#0a24488198ca6c9b84273fa028b853ee9f94f3a7"
+ integrity sha512-6a42Iy7knhgzvQUvCHenrVnPDKhsOyqgZkPxs9pa9x/wNapSch+jLM7u1ezKAFj/Ai4w9yG/yqP+4YE8seZDZw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
jquery "~3.5.1"
-"@abp/lodash@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0-rc.2.tgz#f0a238991c288f439e2751938a39d434dd7883e7"
- integrity sha512-En9gZD8TDY8ZvZqHVsv3cP2EsRdPRsGD0ncUYOvlNG/sc+MZpRmZ+xOLws1wXS83IxGAxzPdCFEu0biJlyOyxg==
+"@abp/lodash@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-4.2.0.tgz#74dfac7d70f1563df2b78c5ebd0b2450e11c4c42"
+ integrity sha512-5hpjxWZJPvjMIY7FCCw/v/B+JzJbB/yuoioRzcU4vrisY9uRq54vVYcX7hH1DldsJFPTuXY3Id1WBflHA5I9Aw==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
lodash "^4.17.15"
-"@abp/luxon@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0-rc.2.tgz#ace30caacf6abcce1559b65046ea55e47e1cb8a2"
- integrity sha512-ivhOadlaeBh6Pi3S5Bo0pb4EPCEjMFL5N5tZXGGieZt7EnF+4uiXbKJVErXNCDtX1jhJT/3HGqmdxa+WynUE0A==
+"@abp/luxon@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-4.2.0.tgz#9cd02faa02cda1315f3e23ae204991ef47d6ae7c"
+ integrity sha512-dwtv2kqWCDyQADA1Os0aIy6Au2PhBtN6q9kukLWCvYmQZI23OKuEBMSngbJVTqEPfz0LV6CWbsWCUC3okAs46A==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
luxon "^1.24.1"
-"@abp/malihu-custom-scrollbar-plugin@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0-rc.2.tgz#483668c09e13b0ebcea16320a16f8517fcdd53ee"
- integrity sha512-IYOwJcWyJkn/gdp4VkEYCv2Gi5+Boxe7pE7hA49gxgllHiFV0ABDFrRg4h8MbyJd80iwvVPo8t8ouvn4Snm+gQ==
+"@abp/malihu-custom-scrollbar-plugin@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-4.2.0.tgz#2f8538df5567a2cf227998e4e2fb9a44b6e814eb"
+ integrity sha512-3D5REdR7yw2sRRfm3Oi+qlhDABLrKvfU/l7JcCJy+vrBvadx3e3pTdTLXsGptypPN3x/Qr400LgwIrrgyefN8g==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
malihu-custom-scrollbar-plugin "^3.1.5"
-"@abp/select2@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0-rc.2.tgz#d11e808dac90e09e14025b6ba6dabed683a9b1fb"
- integrity sha512-fENomkoAML+NQWvZ/ecjvqnXtvrzJKyChwj9Ul12c+Noi6boeuFDbhi/OG6qCrSzDnNBrehHVXBLFxT9sIL0OA==
+"@abp/select2@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-4.2.0.tgz#eb05d22b1390c037911ba25e5ca0f2ed508a93b1"
+ integrity sha512-VlNoa9+F1/kGmaEI2wbL/cRNeAEpp0UdLpbadAnsmpUIODxCULCWS556Q4Y6Ff4CzYtzkYz2qaJ8T8pn+3EOcA==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
select2 "^4.0.13"
-"@abp/star-rating-svg@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/star-rating-svg/-/star-rating-svg-4.2.0-rc.2.tgz#8060bf0c8b17858562c9346cc7413c6f0b219020"
- integrity sha512-M/39KVFLeJGvfwdMiVw+qCc5HNixyHEWNjX7Dv0Coc7Av1aGWsFvEN3njnnKzMpSXAS+s3yQlMyXfTP+7YBBug==
+"@abp/star-rating-svg@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/star-rating-svg/-/star-rating-svg-4.2.0.tgz#19d8ce9dacd92d573ff462aa194fdfa341a39ecc"
+ integrity sha512-jzcdwR1iz63OQaEgXBescuTntg+8DDAhDmDRMss6fO2ou1qlGLqs7mvb/al4z2FvxdDAqaoY8h9c1jKp7+yzuA==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
star-rating-svg "^3.5.0"
-"@abp/sweetalert@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0-rc.2.tgz#2359eeb9e4b34c4cbb3aaed11136ea3d280bd677"
- integrity sha512-oQPj2vKPNAOvBECgJFdDwvJ8nwQ54ZPsAW1XS3XSkFz3YwWn4Xt9eZK6vecHloYckSckrFtsN/DSQI8ao/uIFg==
+"@abp/sweetalert@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-4.2.0.tgz#b1daf641f27f0c8c2e246d364d6285c133faf773"
+ integrity sha512-AarV/L031xNB1gk/OYEUxkKZmls7zTwovS2t3ZrmwXXoav7nBCSPjEf1ByR2yhZRU/Yo1SNY/CNQQ4dgyf7Xng==
dependencies:
- "@abp/core" "~4.2.0-rc.2"
+ "@abp/core" "~4.2.0"
sweetalert "^2.1.2"
-"@abp/timeago@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0-rc.2.tgz#d243acff635978068ec579c83a34d0680616c5ef"
- integrity sha512-TF1dt9ro3BQnfVetDzbOkedSIncSwvPfnHKMY1xcLG2h0c6ke2PjDQ+4QJrtigggT4vfgmQtRrs/zJxjzWS7qw==
+"@abp/timeago@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-4.2.0.tgz#9b15c496b7e63df93921d41de9e9eaf35a8dccbe"
+ integrity sha512-hyuLVGluHxtWEhR0VakPx5UCbyPcfq4lECEgHhI62PvH0xcSNNZ3bp1QnBTd3se/HAYvwA5sCwJY0YXQgUF2UQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
timeago "^1.6.7"
-"@abp/toastr@~4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0-rc.2.tgz#4e76f4b7068f92b267b725ad597b8315e6b615bc"
- integrity sha512-UJVuQWc7py54JC35RrH+MwAZsOoOhejxX+3aonz8Io2rgFFj0YwK5U+vItRNM3iabSqTcIExcSD3XL2TmQyVzg==
+"@abp/toastr@~4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-4.2.0.tgz#400e2f28b19c72b131ca32aa188ff5151d035752"
+ integrity sha512-tuGZd3kXqj1t/Y1xN8sOUH1KxiArYKD7xkhuajoOS65Ex5ad8mHPuzCtu8Pv+KL8TVFys9x3U3Tg24DQ6ASjhQ==
dependencies:
- "@abp/jquery" "~4.2.0-rc.2"
+ "@abp/jquery" "~4.2.0"
toastr "^2.1.4"
-"@abp/utils@^4.2.0-rc.2":
- version "4.2.0-rc.2"
- resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0-rc.2.tgz#43c27d421da8e58a5d74c0a2df8742efa827c842"
- integrity sha512-6gSLTP9s88aFjxm+fU2iZMzv5Eoe5/va2PHTAoQJA4BaP/SpFRGts3cT4HYWPfAbmzZVZ+tvjuYd3P6d3FCAhw==
+"@abp/utils@^4.2.0":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.2.0.tgz#073330e3e3f6ee61892f50260e48dbe1b05df35e"
+ integrity sha512-75qR3SdiAa75wqleAx9sUMXLj4m9duuBo5+2sVv7Y29GcEyKUPvm8B1s6tksvSGA0e3vnFTHeVEc10eD1xKHSQ==
dependencies:
just-compare "^1.3.0"
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/IContentAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/IContentAdminAppService.cs
index e910d42c2f..52bd07aa86 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/IContentAdminAppService.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/IContentAdminAppService.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.CmsKit.Admin.Contents;
@@ -13,5 +14,6 @@ namespace Volo.CmsKit.Admin.Contents
ContentCreateDto,
ContentUpdateDto>
{
+ Task GetAsync(string entityType, string entityId);
}
}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageDto.cs
index e8750ce07b..3aebb76b51 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageDto.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageDto.cs
@@ -3,7 +3,7 @@ using Volo.Abp.Application.Dtos;
namespace Volo.CmsKit.Admin.Pages
{
- public class PageDto : EntityDto
+ public class PageDto : AuditedEntityDto
{
public string Title { get; set; }
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/EntityTagCreateDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/EntityTagCreateDto.cs
new file mode 100644
index 0000000000..92e83fecf4
--- /dev/null
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/EntityTagCreateDto.cs
@@ -0,0 +1,16 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Volo.CmsKit.Admin.Tags
+{
+ public class EntityTagCreateDto
+ {
+ [Required]
+ public string TagName { get; set; }
+
+ [Required]
+ public string EntityType { get; set; }
+
+ [Required]
+ public string EntityId { get; set; }
+ }
+}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/EntityTagRemoveDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/EntityTagRemoveDto.cs
new file mode 100644
index 0000000000..411d4c7157
--- /dev/null
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/EntityTagRemoveDto.cs
@@ -0,0 +1,17 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace Volo.CmsKit.Admin.Tags
+{
+ public class EntityTagRemoveDto
+ {
+ [Required]
+ public Guid TagId { get; set; }
+
+ [Required]
+ public string EntityType { get; set; }
+
+ [Required]
+ public string EntityId { get; set; }
+ }
+}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/IEntityTagAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/IEntityTagAdminAppService.cs
new file mode 100644
index 0000000000..aece4d5c00
--- /dev/null
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/IEntityTagAdminAppService.cs
@@ -0,0 +1,11 @@
+using System.Threading.Tasks;
+
+namespace Volo.CmsKit.Admin.Tags
+{
+ public interface IEntityTagAdminAppService
+ {
+ Task AddTagToEntityAsync(EntityTagCreateDto input);
+
+ Task RemoveTagFromEntityAsync(EntityTagRemoveDto input);
+ }
+}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/ITagAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/ITagAdminAppService.cs
index e677a54c28..a5ae9d85d4 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/ITagAdminAppService.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/ITagAdminAppService.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.CmsKit.Tags;
@@ -6,5 +8,6 @@ namespace Volo.CmsKit.Admin.Tags
{
public interface ITagAdminAppService : ICrudAppService
{
+ Task> GetTagDefinitionsAsync();
}
}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/TagDefinitionDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/TagDefinitionDto.cs
new file mode 100644
index 0000000000..0fdfe04b00
--- /dev/null
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/TagDefinitionDto.cs
@@ -0,0 +1,18 @@
+namespace Volo.CmsKit.Admin.Tags
+{
+ public class TagDefinitionDto
+ {
+ public TagDefinitionDto()
+ {
+ }
+ public TagDefinitionDto(string entityType, string displayName)
+ {
+ EntityType = entityType;
+ DisplayName = displayName;
+ }
+
+ public string EntityType { get; set; }
+
+ public string DisplayName { get; set; }
+ }
+}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs
index e682e80d30..46afe04213 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs
@@ -3,8 +3,10 @@ using Volo.CmsKit.Admin.Blogs;
using Volo.CmsKit.Admin.Contents;
using Volo.CmsKit.Admin.Pages;
using Volo.CmsKit.Blogs;
+using Volo.CmsKit.Admin.Tags;
using Volo.CmsKit.Contents;
using Volo.CmsKit.Pages;
+using Volo.CmsKit.Tags;
namespace Volo.CmsKit.Admin
{
@@ -24,6 +26,8 @@ namespace Volo.CmsKit.Admin
CreateMap(MemberList.Destination)
.ReverseMap();
+
+ CreateMap(MemberList.Destination);
}
}
}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs
index 8903acfb33..8ec8559e34 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs
@@ -1,6 +1,8 @@
-using Microsoft.AspNetCore.Authorization;
+using JetBrains.Annotations;
+using Microsoft.AspNetCore.Authorization;
using System;
using System.Threading.Tasks;
+using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.CmsKit.Contents;
@@ -30,13 +32,13 @@ namespace Volo.CmsKit.Admin.Contents
IContentRepository contentRepository) : base(repository)
{
ContentManager = contentManager;
+ ContentRepository = contentRepository;
GetListPolicyName = CmsKitAdminPermissions.Contents.Default;
GetPolicyName = CmsKitAdminPermissions.Contents.Default;
CreatePolicyName = CmsKitAdminPermissions.Contents.Create;
UpdatePolicyName = CmsKitAdminPermissions.Contents.Update;
DeletePolicyName = CmsKitAdminPermissions.Contents.Delete;
- ContentRepository = contentRepository;
}
[Authorize(CmsKitAdminPermissions.Contents.Create)]
@@ -53,5 +55,17 @@ namespace Volo.CmsKit.Admin.Contents
return MapToGetOutputDto(entity);
}
+
+ public async Task GetAsync(
+ [NotNull] string entityType,
+ [NotNull] string entityId)
+ {
+ Check.NotNullOrWhiteSpace(entityType, nameof(entityType));
+ Check.NotNullOrWhiteSpace(entityId, nameof(entityId));
+
+ var content = await ContentRepository.GetAsync(entityType, entityId, CurrentTenant?.Id);
+
+ return ObjectMapper.Map(content);
+ }
}
}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs
index 6223ed9c2e..3db45dac95 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs
@@ -24,7 +24,6 @@ namespace Volo.CmsKit.Admin.Pages
public virtual async Task GetAsync(Guid id)
{
var page = await PageRepository.GetAsync(id);
-
return ObjectMapper.Map(page);
}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs
new file mode 100644
index 0000000000..1ef6a8bdf9
--- /dev/null
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Threading.Tasks;
+using Volo.CmsKit.Admin.Tags;
+using Volo.CmsKit.Tags;
+
+namespace Volo.CmsKit.Admin.Application.Volo.CmsKit.Admin.Tags
+{
+ public class EntityTagAdminAppService : CmsKitAdminAppServiceBase, IEntityTagAdminAppService
+ {
+ protected ITagDefinitionStore _tagDefinitionStore;
+ protected IEntityTagManager _entityTagManager;
+ protected ITagManager _tagManager;
+
+ public EntityTagAdminAppService(
+ ITagDefinitionStore tagDefinitionStore,
+ IEntityTagManager entityTagManager,
+ ITagManager tagManager)
+ {
+ _tagDefinitionStore = tagDefinitionStore;
+ _entityTagManager = entityTagManager;
+ _tagManager = tagManager;
+ }
+
+ public async Task AddTagToEntityAsync(EntityTagCreateDto input)
+ {
+ var definition = await _tagDefinitionStore.GetTagEntityTypeDefinitionsAsync(input.EntityType);
+
+ await CheckPolicyAsync(definition.CreatePolicy);
+
+ var tag = await _tagManager.GetOrAddAsync(input.EntityType, input.TagName, CurrentTenant?.Id);
+
+ await _entityTagManager.AddTagToEntityAsync(
+ tag.Id,
+ input.EntityType,
+ input.EntityId,
+ CurrentTenant?.Id);
+ }
+
+ public async Task RemoveTagFromEntityAsync(EntityTagRemoveDto input)
+ {
+ var definition = await _tagDefinitionStore.GetTagEntityTypeDefinitionsAsync(input.EntityType);
+
+ await CheckPolicyAsync(definition.DeletePolicy);
+
+ await _entityTagManager.RemoveTagFromEntityAsync(
+ input.TagId,
+ input.EntityType,
+ input.EntityId,
+ CurrentTenant?.Id);
+ }
+ }
+}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/TagAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/TagAdminAppService.cs
index cda45c23de..eccdaf82c0 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/TagAdminAppService.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/TagAdminAppService.cs
@@ -1,12 +1,11 @@
using Microsoft.AspNetCore.Authorization;
+using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
-using Volo.CmsKit.Admin.Tags;
using Volo.CmsKit.Permissions;
using Volo.CmsKit.Tags;
@@ -25,11 +24,15 @@ namespace Volo.CmsKit.Admin.Tags
{
protected ITagManager TagManager { get; }
+ protected IStringLocalizerFactory StringLocalizerFactory { get; }
+
public TagAdminAppService(
IRepository repository,
- ITagManager tagManager) : base(repository)
+ ITagManager tagManager,
+ IStringLocalizerFactory stringLocalizerFactory) : base(repository)
{
TagManager = tagManager;
+ StringLocalizerFactory = stringLocalizerFactory;
GetListPolicyName = CmsKitAdminPermissions.Tags.Default;
GetPolicyName = CmsKitAdminPermissions.Tags.Default;
@@ -68,5 +71,17 @@ namespace Volo.CmsKit.Admin.Tags
x.Name.ToLower().Contains(input.Filter) ||
x.EntityType.ToLower().Contains(input.Filter));
}
+
+ public async Task> GetTagDefinitionsAsync()
+ {
+ var definitions = await TagManager.GetTagDefinitionsAsync();
+
+ return definitions
+ .Select(s =>
+ new TagDefinitionDto(
+ s.EntityType,
+ s.DisplayName?.Localize(StringLocalizerFactory) ?? s.EntityType))
+ .ToList();
+ }
}
}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Contents/ContentAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Contents/ContentAdminController.cs
index f519109022..4e3a56a8e2 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Contents/ContentAdminController.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Contents/ContentAdminController.cs
@@ -59,5 +59,13 @@ namespace Volo.CmsKit.Admin.Contents
{
return ContentAdminAppService.UpdateAsync(id, input);
}
+
+ [HttpGet]
+ [Route("{entityType}/{entityId}")]
+ [Authorize(CmsKitAdminPermissions.Contents.Default)]
+ public Task GetAsync(string entityType, string entityId)
+ {
+ return ContentAdminAppService.GetAsync(entityType, entityId);
+ }
}
}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/TagAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/TagAdminController.cs
index cc755fa63f..afc9a83fc8 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/TagAdminController.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/TagAdminController.cs
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
+using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
@@ -60,5 +61,10 @@ namespace Volo.CmsKit.Admin.Tags
{
return TagAdminAppService.UpdateAsync(id, input);
}
+
+ public Task> GetTagDefinitionsAsync()
+ {
+ return TagAdminAppService.GetTagDefinitionsAsync();
+ }
}
}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs
index 4edf42dcf8..fa31692bfe 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs
@@ -2,10 +2,14 @@
{
public static class CmsKitErrorCodes
{
- public const string TagAlreadyExist = "CmsKit:0001";
-
+ public static class Tags
+ {
+ public const string TagAlreadyExist = "CmsKit:Tag:0001";
+ public const string EntityNotTaggable = "CmsKit:Tag:0002";
+ }
+
public const string ContentAlreadyExist = "CmsKit:0002";
-
+
public static class Pages
{
public const string UrlAlreadyExist = "CmsKit:Page:0001";
diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/GlobalCmsKitFeatures.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/GlobalCmsKitFeatures.cs
index 5a7adc34b2..f6293fc659 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/GlobalCmsKitFeatures.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/GlobalCmsKitFeatures.cs
@@ -28,6 +28,7 @@ namespace Volo.CmsKit.GlobalFeatures
AddFeature(new TagsFeature(this));
AddFeature(new ContentsFeature(this));
AddFeature(new PagesFeature(this));
+ AddFeature(new BlogsFeature(this));
}
}
}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json
index 7ed510da10..00eccab1be 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json
+++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json
@@ -2,6 +2,7 @@
"culture": "en",
"texts": {
"CmsKit:0002": "Content already exists!",
+ "CmsKit:0003": "The entity {0} is not taggable.",
"CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display.",
"Comments": "Comments",
"Delete": "Delete",
diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json
index 40494fbb39..1ebb0c126b 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json
+++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json
@@ -2,6 +2,7 @@
"culture": "tr",
"texts": {
"CmsKit:0002": "İçerik zaten mevcut!",
+ "CmsKit:0003": "{0} ögesi etiketlenebilir değil.",
"CommentAuthorizationExceptionMessage": "Bu yorumları görebilmek için yetki gerekir.",
"Comments": "Yorumlar",
"Delete": "Sil",
diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs
index c16734c377..cb189571f7 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs
@@ -1,8 +1,15 @@
using Volo.Abp.BlobStoring;
+using Microsoft.Extensions.Options;
using Volo.Abp.Domain;
+using Volo.Abp.GlobalFeatures;
+using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Users;
+using Volo.CmsKit.GlobalFeatures;
+using Volo.CmsKit.Localization;
+using Volo.CmsKit.Pages;
using Volo.CmsKit.Reactions;
+using Volo.CmsKit.Tags;
namespace Volo.CmsKit
{
@@ -30,7 +37,18 @@ namespace Volo.CmsKit
options.Reactions.AddOrReplace(StandardReactions.HeartBroken);
options.Reactions.AddOrReplace(StandardReactions.Rocket);
options.Reactions.AddOrReplace(StandardReactions.Pray);
+
});
+
+ if (GlobalFeatureManager.Instance.IsEnabled())
+ {
+ // TODO: Configure TagEntityTypes here...
+ }
+ }
+
+ private static LocalizableString L(string name)
+ {
+ return LocalizableString.Create(name);
}
}
-}
+}
\ No newline at end of file
diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitOptions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitOptions.cs
index cc69f715ce..8075895184 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitOptions.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitOptions.cs
@@ -1,16 +1,12 @@
using JetBrains.Annotations;
using Volo.CmsKit.Reactions;
+using Volo.CmsKit.Tags;
namespace Volo.CmsKit
{
public class CmsKitOptions
{
[NotNull]
- public ReactionDefinitionDictionary Reactions { get; }
-
- public CmsKitOptions()
- {
- Reactions = new ReactionDefinitionDictionary();
- }
+ public ReactionDefinitionDictionary Reactions { get; } = new ReactionDefinitionDictionary();
}
}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/PolicySpecifiedDefinition.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/PolicySpecifiedDefinition.cs
new file mode 100644
index 0000000000..6105beab97
--- /dev/null
+++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/PolicySpecifiedDefinition.cs
@@ -0,0 +1,32 @@
+using JetBrains.Annotations;
+using Volo.Abp;
+using Volo.Abp.Localization;
+
+namespace Volo.CmsKit.Domain.Volo.CmsKit
+{
+ public abstract class PolicySpecifiedDefinition
+ {
+ protected PolicySpecifiedDefinition()
+ {
+ }
+
+ public PolicySpecifiedDefinition(
+ [CanBeNull] string createPolicy = null,
+ [CanBeNull] string updatePolicy = null,
+ [CanBeNull] string deletePolicy = null)
+ {
+ CreatePolicy = createPolicy;
+ DeletePolicy = deletePolicy;
+ UpdatePolicy = updatePolicy;
+ }
+
+ [CanBeNull]
+ public virtual string CreatePolicy { get; set; }
+
+ [CanBeNull]
+ public virtual string UpdatePolicy { get; set; }
+
+ [CanBeNull]
+ public virtual string DeletePolicy { get; set; }
+ }
+}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/CmsKitTagOptions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/CmsKitTagOptions.cs
new file mode 100644
index 0000000000..8f9b073d6b
--- /dev/null
+++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/CmsKitTagOptions.cs
@@ -0,0 +1,11 @@
+using JetBrains.Annotations;
+using Volo.CmsKit.Tags;
+
+namespace Volo.CmsKit.Tags
+{
+ public class CmsKitTagOptions
+ {
+ [NotNull]
+ public TagEntityTypeDefinitionDictionary EntityTypes { get; } = new TagEntityTypeDefinitionDictionary();
+ }
+}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/DefaultTagDefinitionStore.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/DefaultTagDefinitionStore.cs
new file mode 100644
index 0000000000..5a79bea25a
--- /dev/null
+++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/DefaultTagDefinitionStore.cs
@@ -0,0 +1,58 @@
+using JetBrains.Annotations;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.CmsKit.Tags
+{
+ public class DefaultTagDefinitionStore : ITagDefinitionStore, ITransientDependency
+ {
+ private readonly CmsKitTagOptions options;
+
+ public DefaultTagDefinitionStore(IOptions