diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml new file mode 100644 index 0000000000..f897615f4b --- /dev/null +++ b/.github/workflows/spellcheck.yml @@ -0,0 +1,29 @@ +name: Documentation Checks + +on: + push: + branches: + - dev + paths: + # This ensures the check will only be run when something changes in the docs content + - "docs/en/**/*" + pull_request: + branches: + - dev + paths: + - "docs/en/**/*" +jobs: + spellcheck: + name: "Docs: Spellcheck (En)" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + name: Check out the code + - uses: actions/setup-node@v1 + name: Setup node + with: + node-version: "16" + - run: npm install -g cspell + name: Install cSpell + - run: cspell --config ./cSpell.json "docs/en/**/*.md" --no-progress # Update for path to the markdown files + name: Run cSpell diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/en.json index eebaf72246..f34bbd49c2 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/en.json @@ -11,6 +11,7 @@ "CommercialSupportWebSite": "Commercial support web site", "CommunityWebSite": "ABP community web site", "ManageAccount": "My Account | ABP.IO", - "ManageYourProfile": "Manage your profile" + "ManageYourProfile": "Manage your profile", + "ReturnToApplication": "Return to application" } -} \ No newline at end of file +} diff --git a/cSpell.json b/cSpell.json new file mode 100644 index 0000000000..dd74bfb264 --- /dev/null +++ b/cSpell.json @@ -0,0 +1,151 @@ +{ + "version": "0.2", + "language": "en", + "words": [ + "ABP's", + "abpframework", + "Antiforgery", + "appsettings", + "aspnet", + "aspnetcore", + "Autofac", + "automagically", + "Blazor", + "CQRS", + "crossfade", + "Dapr", + "Datagrid's", + "Datatable", + "datepicker", + "dismissable", + "dockerized", + "entrypoints", + "findability", + "hoverable", + "Iddict", + "IntelliCode", + "Keysize", + "Linq", + "Microservices", + "middlewares", + "Minifier", + "multitenancy", + "multitenant", + "Navs", + "Newtonsoft", + "Npgsql", + "oidc", + "overridable", + "Parameterless", + "Passwordless", + "PKCE", + "preconfigured", + "proxying", + "redirections", + "scrollbars", + "signin", + "Templating", + "textboxes", + "toolset", + "unsubscription", + "Xunit" + ], + "ignoreWords": [ + "Aliyun", + "Allibone", + "Blazorise", + "Boutwell", + "Cmskit", + "connectionstrings", + "Devart", + "Formik", + "Halil", + "Hanselman", + "hikalkan", + "Ibrahim", + "İbrahim", + "Kalkan", + "Kirti", + "Kommunity", + "Kulkarni", + "Luxon", + "malihu", + "Malik", + "Masis", + "Minio", + "NGXS", + "NSWAG", + "Scriban", + "Serilog", + "Shoudly", + "Shouldly", + "Sweetalert", + "Syncfusion", + "Telerik", + "Timeago", + "Toastr", + "Volo", + "Volosoft", + "Xeevis" + ], + "patterns": [ + { + "name": "Markdown links", + "pattern": "\\((.*)\\)", + "description": "" + }, + { + "name": "Markdown code blocks", + "pattern": "/^(\\s*`{3,}).*[\\s\\S]*?^\\1/gmx", + "description": "Taken from the cSpell example at https://cspell.org/configuration/patterns/#verbose-regular-expressions" + }, + { + "name": "Inline code blocks", + "pattern": "\\`([^\\`\\r\\n]+?)\\`", + "description": "https://stackoverflow.com/questions/41274241/how-to-capture-inline-markdown-code-but-not-a-markdown-code-fence-with-regex" + }, + { + "name": "Link contents", + "pattern": "\\", + "description": "" + }, + { + "name": "Snippet references", + "pattern": "-- snippet:(.*)", + "description": "" + }, + { + "name": "Snippet references 2", + "pattern": "\\<\\[sample:(.*)", + "description": "another kind of snippet reference" + }, + { + "name": "Multi-line code blocks", + "pattern": "/^\\s*```[\\s\\S]*?^\\s*```/gm" + }, + { + "name": "HTML Tags", + "pattern": "<[^>]*>", + "description": "Reference: https://stackoverflow.com/questions/11229831/regular-expression-to-remove-html-tags-from-a-string" + }, + { + "name": "Markdown Image", + "pattern": "!\\[(.*)\\]\\((.*)\\)" + } + ], + "ignoreRegExpList": [ + "Markdown links", + "Markdown code blocks", + "Inline code blocks", + "Link contents", + "Snippet references", + "Snippet references 2", + "Multi-line code blocks", + "HTML Tags", + "Markdown Image" + ], + "ignorePaths": [ + "**/*Release/Post.md", + "**/*Preview/POST.md" + ] +} diff --git a/docs/en/Blob-Storing-Aws.md b/docs/en/Blob-Storing-Aws.md index 5b77431e84..c69024db28 100644 --- a/docs/en/Blob-Storing-Aws.md +++ b/docs/en/Blob-Storing-Aws.md @@ -59,7 +59,7 @@ Configure(options => * **ProfilesLocation** (string): The path to the aws credentials file to look at. * **Region** (string): The system name of the service. * **Policy** (string): An IAM policy in JSON format that you want to use as an inline session policy. -* **DurationSeconds** (int): Validity period(s) of a temporary access certificate,minimum is 900 and the maximum is 3600. **note**: Using subaccounts operated OSS,if the value is 0. +* **DurationSeconds** (int): Validity period(s) of a temporary access certificate,minimum is 900 and the maximum is 3600. **note**: Using sub-accounts operated OSS,if the value is 0. * **ContainerName** (string): You can specify the container name in Aws. If this is not specified, it uses the name of the BLOB container defined with the `BlobContainerName` attribute (see the [BLOB storing document](Blob-Storing.md)). Please note that Aws has some **rules for naming containers**. A container name must be a valid DNS name, conforming to the [following naming rules](https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html): * Bucket names must be between **3** and **63** characters long. * Bucket names can consist only of **lowercase** letters, numbers, dots (.), and hyphens (-). diff --git a/docs/en/Blog-Posts/2022-01-11 v5_1_Release_Stable/POST.md b/docs/en/Blog-Posts/2022-01-11 v5_1_Release_Stable/POST.md index 4fe7bd39b9..8620b4f7d2 100644 --- a/docs/en/Blog-Posts/2022-01-11 v5_1_Release_Stable/POST.md +++ b/docs/en/Blog-Posts/2022-01-11 v5_1_Release_Stable/POST.md @@ -107,7 +107,7 @@ Here are some other notable changes that come with this release: * Developers should control `EnableLegacyTimestampBehavior` when using PostgreSQL. [#11371](https://github.com/abpframework/abp/pull/11371) [#65](https://github.com/abpframework/eShopOnAbp/pull/65) -All issues & PRs in [5.1 milesone](https://github.com/abpframework/abp/milestone/60?closed=1). +All issues & PRs in [5.1 milestone](https://github.com/abpframework/abp/milestone/60?closed=1). ### About ABP Commercial diff --git a/docs/en/Community-Articles/2020-04-19-Customize-the-SignIn-Manager/POST.md b/docs/en/Community-Articles/2020-04-19-Customize-the-SignIn-Manager/POST.md index 9ae426624f..1694232f29 100644 --- a/docs/en/Community-Articles/2020-04-19-Customize-the-SignIn-Manager/POST.md +++ b/docs/en/Community-Articles/2020-04-19-Customize-the-SignIn-Manager/POST.md @@ -8,7 +8,7 @@ This document explains how to customize the SignIn Manager for your own applicat ## Create a CustomSignInManager -Create a new class inheriting the [SignInMager](https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs) of Microsoft Identity package. +Create a new class inheriting the [SignInManager](https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs) of Microsoft Identity package. ````csharp public class CustomSignInManager : Microsoft.AspNetCore.Identity.SignInManager diff --git a/docs/en/Community-Articles/2020-04-27-Use-Azure-Active-Directory-Authentication-for-MVC-Razor-Page-Applications/POST.md b/docs/en/Community-Articles/2020-04-27-Use-Azure-Active-Directory-Authentication-for-MVC-Razor-Page-Applications/POST.md index b2c307bcb3..e6c6774341 100644 --- a/docs/en/Community-Articles/2020-04-27-Use-Azure-Active-Directory-Authentication-for-MVC-Razor-Page-Applications/POST.md +++ b/docs/en/Community-Articles/2020-04-27-Use-Azure-Active-Directory-Authentication-for-MVC-Razor-Page-Applications/POST.md @@ -12,7 +12,7 @@ Two different **alternative approaches** for AzureAD integration will be demonst > There is **no difference** in functionality between these approaches. AddAzureAD is an abstracted way of OpenIdConnection ([source](https://github.com/dotnet/aspnetcore/blob/c56aa320c32ee5429d60647782c91d53ac765865/src/Azure/AzureAD/Authentication.AzureAD.UI/src/AzureADAuthenticationBuilderExtensions.cs#L122)) with predefined cookie settings. > -> However there are key differences in integration to ABP applications because of default configurated signin schemes which will be explained below. +> However there are key differences in integration to ABP applications because of default configured signin schemes which will be explained below. ## 1. AddOpenIdConnect @@ -211,7 +211,7 @@ You can find the source code of the completed example [here](https://github.com/ to your openid configuration. -* Help! I keep getting ***AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application*** error! +* Help! I keep getting `AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application` error! * If you set your **CallbackPath** in appsettings as: diff --git a/docs/en/Community-Articles/2020-05-29-Real-Time-Messaging-In-A-Distributed-Architecture-Using-Abp-Framework-SingalR-RabbitMQ/POST.md b/docs/en/Community-Articles/2020-05-29-Real-Time-Messaging-In-A-Distributed-Architecture-Using-Abp-Framework-SingalR-RabbitMQ/POST.md index eea0eaae46..0d09112681 100644 --- a/docs/en/Community-Articles/2020-05-29-Real-Time-Messaging-In-A-Distributed-Architecture-Using-Abp-Framework-SingalR-RabbitMQ/POST.md +++ b/docs/en/Community-Articles/2020-05-29-Real-Time-Messaging-In-A-Distributed-Architecture-Using-Abp-Framework-SingalR-RabbitMQ/POST.md @@ -1,4 +1,4 @@ -# Real Time Messaging In A Distributed Architecture Using Abp Framework, SingalR & RabbitMQ +# Real Time Messaging In A Distributed Architecture Using Abp Framework, SignalR & RabbitMQ In this article, we will build a basic real time messaging application in a distributed architecture. We will use [Abp Framework](https://abp.io) for infrastructure and tiered startup template, [SignalR](https://dotnet.microsoft.com/apps/aspnet/signalr) for real time server-client communication and [RabbitMQ](https://www.rabbitmq.com/) as the distributed event bus. diff --git a/docs/en/Community-Articles/2020-07-21-File-Upload-Download-With-BLOB-Storage-System-in-ASPNET-Core-ABP-Framework/POST.md b/docs/en/Community-Articles/2020-07-21-File-Upload-Download-With-BLOB-Storage-System-in-ASPNET-Core-ABP-Framework/POST.md index 560e15e288..a6fb03d6c4 100644 --- a/docs/en/Community-Articles/2020-07-21-File-Upload-Download-With-BLOB-Storage-System-in-ASPNET-Core-ABP-Framework/POST.md +++ b/docs/en/Community-Articles/2020-07-21-File-Upload-Download-With-BLOB-Storage-System-in-ASPNET-Core-ABP-Framework/POST.md @@ -46,11 +46,11 @@ Open a command prompt (terminal) in the folder containing your solution (.sln) f `abp add-module Volo.Abp.BlobStoring.Database` -This action will add the module depencies and also module migration. After this action, run `FileActionsDemo.DbMigrator` to update the database. +This action will add the module dependencies and also module migration. After this action, run `FileActionsDemo.DbMigrator` to update the database. -### Setting up Blob Storaging +### Setting up Blob Storage -BLOB Strorage system works with `Containers`. Before the using blob storage, we need to create our blob container. +BLOB Storage system works with `Containers`. Before the using blob storage, we need to create our blob container. Create a class that name `MyFileContainer` at the `FileActionsDemo.Domain` project. diff --git a/docs/en/Community-Articles/2020-09-16-How-to-Setup-Azure-Active-Directory-and-Integrate-Abp-Angular-Application/POST.md b/docs/en/Community-Articles/2020-09-16-How-to-Setup-Azure-Active-Directory-and-Integrate-Abp-Angular-Application/POST.md index c82365efee..1b56d1f2b7 100644 --- a/docs/en/Community-Articles/2020-09-16-How-to-Setup-Azure-Active-Directory-and-Integrate-Abp-Angular-Application/POST.md +++ b/docs/en/Community-Articles/2020-09-16-How-to-Setup-Azure-Active-Directory-and-Integrate-Abp-Angular-Application/POST.md @@ -107,7 +107,7 @@ Next time you hit login, you should be seeing login screen enabled Azure AD like * But I don't want my users to see default login screen. I want my users to login **only** from AzureAD. - * You can **mimic** this behaviour by customizing the login page and instantly trigger Azure AD provider click. For more info, you can check [this article](https://community.abp.io/articles/how-to-customize-the-login-page-for-mvc-razor-page-applications-9a40f3cd). + * You can **mimic** this behavior by customizing the login page and instantly trigger Azure AD provider click. For more info, you can check [this article](https://community.abp.io/articles/how-to-customize-the-login-page-for-mvc-razor-page-applications-9a40f3cd). # May 2021 Update diff --git a/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md b/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md index a53fec2e48..12154dc538 100644 --- a/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md +++ b/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md @@ -85,7 +85,7 @@ Add [Microsoft.SignalR](https://www.npmjs.com/package/@microsoft/signalr) JavaSc You can install the latest version (3.1.13 will be old) ``` "@microsoft/signalr": "^3.1.13" -```` +``` ![Add SignalR package](signalr-package.jpg) @@ -93,7 +93,7 @@ You can install the latest version (3.1.13 will be old) We added SignalR to the `package.json` but it comes into your `node_modules` folder. We need to copy the related files to `wwwroot/libs` folder. To do this copy the content of the following file to your `abp.resourcemappings.js` file. It's in your root directory of Web folder. After you do this, go to your web directory and run `abp install-libs` command. By doing this, it'll copy the related files into your `wwwroot/libs` folder. -[abp.resourcemappings.js](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-abp-resourcemapping-js) +[`abp.resourcemappings.js`](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-abp-resourcemapping-js) ![Resource mappings](resource-mappings.jpg) diff --git a/docs/en/Community-Articles/2022-02-22-Integrating-MAUI-Client-via-using-OpenID-Connect/README.md b/docs/en/Community-Articles/2022-02-22-Integrating-MAUI-Client-via-using-OpenID-Connect/README.md index 0d86c98a1d..fa6ecdcc96 100644 --- a/docs/en/Community-Articles/2022-02-22-Integrating-MAUI-Client-via-using-OpenID-Connect/README.md +++ b/docs/en/Community-Articles/2022-02-22-Integrating-MAUI-Client-via-using-OpenID-Connect/README.md @@ -595,7 +595,7 @@ In this step we have to store access token & refresh token for future requests. ## Recap -The purpose of this arcitle is connecting to ABP backend with access token and it's working properly. +The purpose of this article is connecting to ABP backend with access token and it's working properly. -I'm planning to integrate HttpApi.Client library of backend project instead of making requests manually as a second part of this article. I'll get inspired by [hikalkan/maui-abp-playing](https://github.com/hikalkan/maui-abp-playing) repo to achive that. +I'm planning to integrate HttpApi.Client library of backend project instead of making requests manually as a second part of this article. I'll get inspired by [hikalkan/maui-abp-playing](https://github.com/hikalkan/maui-abp-playing) repo to achieve that. diff --git a/docs/en/Community-Articles/2022-10-27-Dotnet7-Upgrade/Upgrade-Your-Existing-Projects-to-Dotnet7.md b/docs/en/Community-Articles/2022-10-27-Dotnet7-Upgrade/Upgrade-Your-Existing-Projects-to-Dotnet7.md new file mode 100644 index 0000000000..1fcdd78cd5 --- /dev/null +++ b/docs/en/Community-Articles/2022-10-27-Dotnet7-Upgrade/Upgrade-Your-Existing-Projects-to-Dotnet7.md @@ -0,0 +1,265 @@ +# Upgrade Your Existing Projects to .NET7 + +A new .NET version has come. As open-source contributors, we are tracking the latest libraries and adopting them to our existing projects. In this sense, we completed our .NET 7 upgrade in our repositories for ABP Framework and ABP Commercial. In this article, I'll share the experiences we faced while upgrading to the new .NET version 👉 .NET 7. + +When I wrote this article, the latest .NET version was `7.0.0-rc.2`. So some of the version statements I wrote below must be changed due to the stable version release. + + + +**To see the latest and greatest stuff, let's see how to upgrade our existing projects to .NET 7!** + + + +## Install .NET7 SDK + +If you are on your development computer, then you need to install the .NET7 SDK `7.x.x`. For the production servers, you need to install the .NET 7 runtimes. Download link for the .NET7 SDK and runtimes is: + +* https://dotnet.microsoft.com/en-us/download/dotnet/7.0 + + + +## Update Your *.csproj Files + +First, you need to update all your `*.csproj` files to support .NET7. Find and replace all your `*` in the `*.csproj` files to support .NET 7: + +```xml +net7.0 +``` + +We already did this in ABP Framework, see this commit as an example [github.com/abpframework/abp/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.csproj](https://github.com/abpframework/abp/blob/dev/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/MyCompanyName.MyProjectName.Mvc.csproj#L4). + + + +### Microsoft Package Updates + +You must be using Microsoft packages as well; then you need to update them to the latest .NET 7 version. +At the time, I wrote this article, the latest version was `7.0.0-rc.2.22476.2`, so I'll update them to this version including minor version changes. + +Here's the list of all package reference updates I did: + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + + + +--- + + + +## Entity Framework Core Updates + +If you use EF Core as your data access library, you should update your `dotnet-ef` CLI tool. Here's the terminal command to update it: + +```bash +dotnet tool update dotnet-ef --global --prerelease +``` + +We already did the the EF Core package reference update in the *Microsoft Package Updates* section. + + + +### Breaking Change: OrderBy + +This release makes a breaking change in an EF Core query running behavior. We faced this issue in some of our queries that were missing `OrderBy` statement. It throws an exception and does not run the query. Here's the explanation of a EF Core team member for this issue: [github.com/dotnet/efcore/issues/21202#issuecomment-913206415](https://github.com/dotnet/efcore/issues/21202#issuecomment-913206415). + +The following exception is being thrown: + +> InvalidOperationException: The query uses 'Skip' without specifying ordering and uses split query mode. This generates incorrect results. Either provide ordering or run query in single query mode using AsSingleQuery(). See https://go.microsoft.com/fwlink/?linkid=2196526 for more information + +If you don't want to add `OrderBy` statement to solve the issue, you can also use `AsSingleQuery()`. + +![AsSingleQuery](https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2022-10-27-Dotnet7-Upgrade/./as-single-query.jpg) + + + +### EF Core - SQL Client Connection String Update + +With this version, the behavior of the SQL connection has been changed. There is a keyword in the SQL connection string called `TrustServerCertificate`. This keyword indicates whether the channel will be encrypted while bypassing walking the certificate chain to validate trust. + +> When `TrustServerCertificate` is set to `True`, the transport layer will use SSL to encrypt the channel and bypass walking the certificate chain to validate trust. If `TrustServerCertificate` is set to `true` and encryption is turned on, the encryption level specified on the server will be used even if `Encrypt` is set to `false`. The connection will fail otherwise. + + + +After the .NET7 update, it just started to throw the following exception: + +> A connection was successfully established with the server, but then an error occurred during the login process. + + + +We fixed this problem by adding the `TrustServerCertificate=true` to your connection string. Here's an example connection string that supports, + +````sql +Server=localhost; Database=MyProjectName; Trusted_Connection=True; TrustServerCertificate=True +```` + +See our commit for this fix: + +* [github.com/abpframework/abp/commit/96f17e67918eb87edd2baf876d4a7598281fe608](https://github.com/abpframework/abp/commit/96f17e67918eb87edd2baf876d4a7598281fe608) + +Related docs: + +* [learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-7.0/breaking-changes#encrypt-true](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-7.0/breaking-changes#encrypt-true) +* [stackoverflow.com/questions/34430550/a-connection-was-successfully-established-with-the-server-but-then-an-error-occ](https://stackoverflow.com/questions/34430550/a-connection-was-successfully-established-with-the-server-but-then-an-error-occ) + + + +--- + + + +## Blazor Update + +Ensure that you have updated your Blazor project's csproj to support .NET7: + +```xml +net7.0 +``` + +### Install Blazor Workloads + +#### .NET Web Assembly build tools + +If you have a Blazor-WASM project, install the workloads by running the following in a command shell: + +```bash +dotnet workload install wasm-tools +``` + + **OR** you can update your workloads by running the following command in your Blazor project directory: + +```bash +dotnet workload restore +``` + + + +--- + + + +## .NET MAUI Update + +Ensure that you have updated your Blazor project's csproj to support .NET7: + +```xml +net7.0-android;net7.0-ios;net7.0-maccatalyst +$(TargetFrameworks);net7.0-windows10.0.19041.0 +``` + + + +### Install MAUI Workloads + +If you have .NET MAUI project, then you also need to update your `TargetFramework` as below: + +If you have a .NET MAUI project, after installing the .NET 7 SDK, install the latest workloads with the following command: + +```bash +dotnet workload install maui +``` + + **OR** run the following command in your existing .NET MAUI project directory + +```bash +dotnet workload restore +``` + + + +Further information, check out https://github.com/dotnet/maui/wiki/.NET-7-and-.NET-MAUI + +--- + + + +#### Dotnet Maui Check Tool + +Alternatively, there's a 3rd party tool for .NET MAUI to install the required workloads. This tool installs the missing SDK packs. You can reach the tool's repository at [github.com/Redth/dotnet-maui-check](https://github.com/Redth/dotnet-maui-check). + +Installation: + +```bash +dotnet tool install -g Redth.Net.Maui.Check +``` + +Run: + +```bash +maui-check +``` + + + +--- + + + +## Docker Image Update + +If you are using Docker to automate the deployment of applications, you also need to update your images. We were using `aspnet:6.0.0-bullseye-slim` base and after the .NET 7 update, we started using `aspnet:7.0-bullseye-slim` in our Docker files. + +``` +FROM mcr.microsoft.com/dotnet/aspnet:7.0-bullseye-slim AS base +``` + +For this update, you can check out the following commit as an example: + +* [github.com/abpframework/abp/commit/2d07b9bd00152bef4658c48ff9b2cbee5788d308](https://github.com/abpframework/abp/commit/2d07b9bd00152bef4658c48ff9b2cbee5788d308) + + + +## ABP Framework .NET 7 Update + +In [ABP Framework repository](https://github.com/abpframework/abp), we pdated all our dependencies from .NET 6 to .NET 7. +Not all the changes are here, but you can check out the following PR of the .NET 7 update: + +* [github.com/abpframework/abp/pull/13626/files](https://github.com/abpframework/abp/pull/13626/files) + + +... + +Happy coding with .NET 7 🤗 + +... diff --git a/docs/en/Community-Articles/2022-10-27-Dotnet7-Upgrade/as-single-query.jpg b/docs/en/Community-Articles/2022-10-27-Dotnet7-Upgrade/as-single-query.jpg new file mode 100644 index 0000000000..38e3bde39e Binary files /dev/null and b/docs/en/Community-Articles/2022-10-27-Dotnet7-Upgrade/as-single-query.jpg differ diff --git a/docs/en/Community-Articles/2022-10-27-Dotnet7-Upgrade/cover-image.jpg b/docs/en/Community-Articles/2022-10-27-Dotnet7-Upgrade/cover-image.jpg new file mode 100644 index 0000000000..3218fe8f0d Binary files /dev/null and b/docs/en/Community-Articles/2022-10-27-Dotnet7-Upgrade/cover-image.jpg differ diff --git a/docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md b/docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md index 637a87624b..9b3225a989 100644 --- a/docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md +++ b/docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md @@ -11,7 +11,7 @@ - Abp CLI https://docs.abp.io/en/abp/latest/cli - A code editor -Note: This arcticle prepare Windows OS. You may change the path type of your OS. an Example +Note: This article prepare Windows OS. You may change the path type of your OS. an Example Windows: `templates\app\aspnet-core\src\MyCompanyName.MyProjectName.DbMigrator\appsettings.json` @@ -22,11 +22,15 @@ Unix: `templates/app/aspnet-core/src/MyCompanyName.MyProjectName.DbMigrator/apps You need to install SQL Server and Redis. You can install these programs without docker, but my example uses docker containers. Your computer should have Docker Engine. Then open the terminal en execute the commands one by one. For the Sql Server +```cmd docker run -v sqlvolume:/var/opt/mssql -e 'ACCEPT_EULA=Y' -e "SA_PASSWORD=yourpassword" -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-CU3-ubuntu-18.04 +``` For the Redis +```cmd docker run -p 6379:6379 -d redis +``` Then we are ready to download and execute the code. diff --git a/docs/en/Dependency-Injection.md b/docs/en/Dependency-Injection.md index a0ad342c4c..bfce8a71bf 100644 --- a/docs/en/Dependency-Injection.md +++ b/docs/en/Dependency-Injection.md @@ -6,7 +6,7 @@ ABP's Dependency Injection system is developed based on Microsoft's [dependency ## Modularity -Since ABP is a modular framework, every module defines it's own services and registers via dependency injection in it's own seperate [module class](Module-Development-Basics.md). Example: +Since ABP is a modular framework, every module defines it's own services and registers via dependency injection in it's own separate [module class](Module-Development-Basics.md). Example: ````C# public class BlogModule : AbpModule diff --git a/docs/en/Distributed-Event-Bus-Rebus-Integration.md b/docs/en/Distributed-Event-Bus-Rebus-Integration.md index 7499c1d837..39fb35ede9 100644 --- a/docs/en/Distributed-Event-Bus-Rebus-Integration.md +++ b/docs/en/Distributed-Event-Bus-Rebus-Integration.md @@ -18,7 +18,7 @@ You can configure using the standard [configuration system](Configuration.md), l ### The Options Classes -`AbpRebusEventBusOptions` classe can be used to configure the event bus options for the Rebus. +`AbpRebusEventBusOptions` class can be used to configure the event bus options for the Rebus. You can configure this options inside the `PreConfigureServices` of your [module](Module-Development-Basics.md). diff --git a/docs/en/Entity-Framework-Core-Oracle.md b/docs/en/Entity-Framework-Core-Oracle.md index 6e7686c6b0..161f1abf45 100644 --- a/docs/en/Entity-Framework-Core-Oracle.md +++ b/docs/en/Entity-Framework-Core-Oracle.md @@ -6,7 +6,7 @@ This document explains how to switch to the **Oracle** database provider for **[ ABP Framework provides integrations for two different Oracle packages. See one of the following documents based on your provider decision: -* **[Volo.Abp.EntityFrameworkCore.Oracle](Entity-Framework-Core-Oracle-Official.md)** package uses the official & free oracle driver. -* **[Volo.Abp.EntityFrameworkCore.Oracle.Devart](Entity-Framework-Core-Oracle-Devart.md)** package uses the commercial (paid) driver of [Devart](https://www.devart.com/) company. +* **[`Volo.Abp.EntityFrameworkCore.Oracle`](Entity-Framework-Core-Oracle-Official.md)** package uses the official & free oracle driver. +* **[`Volo.Abp.EntityFrameworkCore.Oracle.Devart`](Entity-Framework-Core-Oracle-Devart.md)** package uses the commercial (paid) driver of [Devart](https://www.devart.com/) company. > You can choose one of the package you want. If you don't know the differences of the packages, please search for it. ABP Framework only provides integrations it doesn't provide support for such 3rd-party libraries. diff --git a/docs/en/JSON.md b/docs/en/JSON.md index 29e93007af..283690c2e1 100644 --- a/docs/en/JSON.md +++ b/docs/en/JSON.md @@ -4,7 +4,7 @@ The ABP Framework provides an abstraction to work with JSON. Having such an abst * You can write library independent code. Therefore, you can change the underlying library with the minimum effort and code change. * You can use the predefined converters defined in the ABP without worrying about the underlying library's internal details. -> The JSON serialization system is implemented with the [Volo.Abp.Json](https://www.nuget.org/packages/Volo.Abp.Json) NuGet package. Most of the time, you don't need to manually [install it](https://abp.io/package-detail/Volo.Abp.Json) since it comes pre-installed with the [application startup template](Startup-Templates/Application.md). +> The JSON serialization system is implemented with the [Volo.Abp.Json](https://www.nuget.org/packages/Volo.Abp.Json) NuGet package([Volo.Abp.Json.SystemTextJson](https://www.nuget.org/packages/Volo.Abp.Json.SystemTextJson) is the default implementation). Most of the time, you don't need to manually [install it](https://abp.io/package-detail/Volo.Abp.Json) since it comes pre-installed with the [application startup template](Startup-Templates/Application.md). ## IJsonSerializer @@ -45,16 +45,24 @@ public class ProductManager `AbpJsonOptions` type provides options for the JSON operations in the ABP Framework. Properties: -* **DefaultDateTimeFormat(`string`)**: Default `DateTime` format. -* **UseHybridSerializer(`bool`)**: True by default. Boolean field indicating whether the ABP Framework uses the hybrid approach or not. If the field is true, it will try to use `System.Json.Text` to handle JSON if it can otherwise use the `Newtonsoft.Json.` -* **Providers(`ITypeList`)**: List of JSON serializer providers implementing the `IJsonSerializerProvider` interface. You can create and add custom serializers to the list, and the ABP Framework uses them automatically. When the `Serialize` or `Deserialize` method is called on the `IJsonSerializer` interface, the ABP Framework calls the `CanHandle` methods of the given providers in reverse order and uses the first provider that returns `true` to do the JSON operation. +* **InputDateTimeFormats(`List`)**: Formats of input JSON date, Empty string means default format. You can provide multiple formats to parse the date. +* **OutputDateTimeFormat(`string`)**: Format of output json date, Null or empty string means default format. + +## System Text Json ### AbpSystemTextJsonSerializerOptions -`AbpSystemTextJsonSerializerOptions` provides options for `System.Text.Json` usage. +- **JsonSerializerOptions(`System.Text.Json.JsonSerializerOptions`)**: Global options for System.Text.Json library operations. See [here](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions) for reference. -Properties: +### AbpSystemTextJsonSerializerModifiersOptions -- **JsonSerializerOptions(`System.Text.Json.JsonSerializerOptions`)**: Global options for System.Text.Json library operations. See [here](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions) for reference. -- **UnsupportedTypes(`ITypeList`)**: List of the unsupported types. You can add types of the unsupported types to the list and, the hybrid JSON serializer automatically uses the `Newtonsoft.Json` library instead of `System.Text.Json`. +- **Modifiers(`List>`)**: Configure `Modifiers` of `DefaultJsonTypeInfoResolver`. See [here](https://devblogs.microsoft.com/dotnet/announcing-dotnet-7-preview-6/#json-contract-customization) for reference. + + +## Newtonsoft + +Add [Volo.Abp.Json.Newtonsoft](https://www.nuget.org/packages/Volo.Abp.Json.Newtonsoft) packge and depends on `AbpJsonNewtonsoftModule` to replace the `System Text Json`. + +#### AbpNewtonsoftJsonSerializerOptions +- **JsonSerializerSettings(`Newtonsoft.Json.JsonSerializerSettings`)**: Global options for Newtonsoft library operations. See [here](https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonSerializerSettings.htm) for reference. diff --git a/docs/en/Migration-Guides/Abp-4_0-Blazor.md b/docs/en/Migration-Guides/Abp-4_0-Blazor.md index 90a9bc2e53..7f00d6de75 100644 --- a/docs/en/Migration-Guides/Abp-4_0-Blazor.md +++ b/docs/en/Migration-Guides/Abp-4_0-Blazor.md @@ -9,7 +9,7 @@ These changes are required to manually applied in your own solution. It would be * Add `true` to the `PropertyGroup` section of your project (`.csproj`) file. * Update the `Blazorise.*` packages to the latest version (to the latest RC for the ABP 4.0 preview). -### wwwroot/index.html +### `wwwroot/index.html` There are some changes made in the index.html file; diff --git a/docs/en/Migration-Guides/Abp-5_2.md b/docs/en/Migration-Guides/Abp-5_2.md index d0cbf80aad..aeb79e22a6 100644 --- a/docs/en/Migration-Guides/Abp-5_2.md +++ b/docs/en/Migration-Guides/Abp-5_2.md @@ -15,7 +15,7 @@ We've upgraded to Blazorise 1.0 stable version. So there is some breaking change Also You can review that pull request [#11649 - Blazorise 1.0 Migration](https://github.com/abpframework/abp/pull/11649) -- `NumericEdit` is now made around the native `input type="number"` so a lot of its formating features are moved to the new `NumericPicker` component. Replace NumericEdit with NumericPicker. +- `NumericEdit` is now made around the native `input type="number"` so a lot of its formatting features are moved to the new `NumericPicker` component. Replace NumericEdit with NumericPicker. - Rename `DecimalsSeparator` to `DecimalSeparator` on the `DataGridColumn` and `NumericPicker`. - Rename `MaxMessageSize` to `MaxChunkSize`. - Remove `Fullscreen` parameter on `` and replace it with `Size="ModalSize.Fullscreen"` parameter. diff --git a/docs/en/Migration-Guides/Abp-7_0.md b/docs/en/Migration-Guides/Abp-7_0.md new file mode 100644 index 0000000000..b4c4d14b02 --- /dev/null +++ b/docs/en/Migration-Guides/Abp-7_0.md @@ -0,0 +1,36 @@ +# ABP Version 7.0 Migration Guide + +This document is a guide for upgrading ABP v6.0 solutions to ABP v7.0. There is a change in this version that may affect your applications, please read it carefully and apply the necessary changes to your application. + +## Hybrid JSON was removed. + +Since [System.Text.Json](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/overview) library supports more custom features in NET 7, ABP no longer need the hybrid Json feature. + +### Previous Behavior + +There is a `Volo.Abp.Json` package which contains the `AbpJsonModule` module. +`Serialization/deserialization` features of [System.Text.Json](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/overview) and [Nettonsoft](https://www.newtonsoft.com/json/help/html/SerializingJSON.htm) are implemented in this module. + +We use [System.Text.Json](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/overview) first, More custom cases can be handled with [Nettonsoft](https://www.newtonsoft.com/json/help/html/SerializingJSON.htm) by configuring `UnsupportedTypes` of `AbpSystemTextJsonSerializerOptions`. + +### New Behavior + +We created `Volo.Abp.Json.SystemTextJson` and `Volo.Abp.Json.Newtonsoft` as separate packages, which means you can only use one of them in your project. The default is to use `SystemTextJson`. If you want `Newtonsoft`, please also use `Volo.Abp.AspNetCore.Mvc.NewtonsoftJson` in your web project. + +* Volo.Abp.Json.Abstractions +* Volo.Abp.Json.Newtonsoft +* Volo.Abp.Json.SystemTextJson +* Volo.Abp.Json (Depends on `Volo.Abp.Json.SystemTextJson` by default to prevent breaking) +* Volo.Abp.AspNetCore.Mvc.NewtonsoftJson + +The `AbpJsonOptions` now has only two properties, which are + +* `InputDateTimeFormats(List)`: Formats of input JSON date, Empty string means default format. You can provide multiple formats to parse the date. +* `OutputDateTimeFormat(string)`: Format of output json date, Null or empty string means default format. + +Please remove all `UnsupportedTypes` add custom `Modifiers` to control serialization/deserialization behavior. + +Check the docs to see the more info: https://github.com/abpframework/abp/blob/dev/docs/en/JSON.md#configuration + +Check the docs to see how to customize a JSON contract: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/custom-contracts + diff --git a/docs/en/Migration-Guides/IdentityServer_To_OpenIddict.md b/docs/en/Migration-Guides/IdentityServer_To_OpenIddict.md index a4baa79d9f..d60493be7a 100644 --- a/docs/en/Migration-Guides/IdentityServer_To_OpenIddict.md +++ b/docs/en/Migration-Guides/IdentityServer_To_OpenIddict.md @@ -72,7 +72,7 @@ private void ConfigureAuthentication(ServiceConfigurationContext context) ## Source code of samples and module -* [Open source tiered & separate auth server application migrate Identity Server to OpenIddct](https://github.com/abpframework/abp-samples/tree/master/Ids2OpenId) -* [Commercial tiered & separate auth server application migrate Identity Server to OpenIddct](https://abp.io/Account/Login?returnUrl=/api/download/samples/Ids2OpenId) +* [Open source tiered & separate auth server application migrate Identity Server to OpenIddict](https://github.com/abpframework/abp-samples/tree/master/Ids2OpenId) +* [Commercial tiered & separate auth server application migrate Identity Server to OpenIddict](https://abp.io/Account/Login?returnUrl=/api/download/samples/Ids2OpenId) * [OpenIddict module document](https://docs.abp.io/en/abp/6.0/Modules/OpenIddict) * [OpenIddict module source code](https://github.com/abpframework/abp/tree/rel-6.0/modules/openiddict) diff --git a/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md b/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md index ba6b264758..2638895843 100644 --- a/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md +++ b/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md @@ -19,62 +19,68 @@ Use the `abp update` command to update your existing application. See [Upgrading ### Domain.Shared Layer - In **MyApplication.Domain.Shared.csproj** replace **project reference**: - ```csharp - - ``` + +```csharp + +``` + with - ```csharp - - ``` + +```csharp + +``` - In **MyApplicationDomainSharedModule.cs** replace usings and **module dependencies:** - ```csharp - using Volo.Abp.IdentityServer; - ... - typeof(AbpIdentityServerDomainSharedModule) - ``` +```csharp +using Volo.Abp.IdentityServer; +... +typeof(AbpIdentityServerDomainSharedModule) +``` + with - ```csharp - using Volo.Abp.OpenIddict; - ... - typeof(AbpOpenIddictDomainSharedModule) + +```csharp +using Volo.Abp.OpenIddict; +... +typeof(AbpOpenIddictDomainSharedModule) +``` ### Domain Layer - In **MyApplication.Domain.csproj** replace **project references**: - ```csharp - - - ``` +```csharp + + +``` with - ```csharp - - - ``` +```csharp + + +``` - In **MyApplicationDomainModule.cs** replace usings and **module dependencies**: - ```csharp - using Volo.Abp.IdentityServer; - using Volo.Abp.PermissionManagement.IdentityServer; - ... - typeof(AbpIdentityServerDomainModule), - typeof(AbpPermissionManagementDomainIdentityServerModule), - ``` +```csharp +using Volo.Abp.IdentityServer; +using Volo.Abp.PermissionManagement.IdentityServer; +... +typeof(AbpIdentityServerDomainModule), +typeof(AbpPermissionManagementDomainIdentityServerModule), +``` with - ```csharp - using Volo.Abp.OpenIddict; - using Volo.Abp.PermissionManagement.OpenIddict; - ... - typeof(AbpOpenIddictDomainModule), - typeof(AbpPermissionManagementDomainOpenIddictModule), - ``` +```csharp +using Volo.Abp.OpenIddict; +using Volo.Abp.PermissionManagement.OpenIddict; +... +typeof(AbpOpenIddictDomainModule), +typeof(AbpPermissionManagementDomainOpenIddictModule), +``` #### OpenIddictDataSeedContributor @@ -101,19 +107,19 @@ If you are using MongoDB, skip this step and check the *MongoDB* layer section. - In **MyApplicationEntityFrameworkCoreModule.cs** replace usings and **module dependencies**: - ```csharp - using Volo.Abp.IdentityServer.EntityFrameworkCore; - ... - typeof(AbpIdentityServerEntityFrameworkCoreModule), - ``` +```csharp +using Volo.Abp.IdentityServer.EntityFrameworkCore; +... +typeof(AbpIdentityServerEntityFrameworkCoreModule), +``` with - ```csharp - using Volo.Abp.OpenIddict.EntityFrameworkCore; - ... - typeof(AbpOpenIddictEntityFrameworkCoreModule), - ``` +```csharp +using Volo.Abp.OpenIddict.EntityFrameworkCore; +... +typeof(AbpOpenIddictEntityFrameworkCoreModule), +``` - In **MyApplicationDbContext.cs** replace usings and **fluent api configurations**: @@ -165,19 +171,19 @@ If you are using EntityFrameworkCore, skip this step and check the *EntityFramew - In **MyApplicationMongoDbModule.cs** replace usings and **module dependencies**: - ```csharp - using Volo.Abp.IdentityServer.MongoDB; - ... - typeof(AbpIdentityServerMongoDbModule), - ``` +```csharp +using Volo.Abp.IdentityServer.MongoDB; +... +typeof(AbpIdentityServerMongoDbModule), +``` with - ```csharp - using Volo.Abp.OpenIddict.MongoDB; - ... - typeof(AbpOpenIddictMongoDbModule), - ``` +```csharp +using Volo.Abp.OpenIddict.MongoDB; +... +typeof(AbpOpenIddictMongoDbModule), +``` ### DbMigrator Project @@ -251,7 +257,7 @@ for creating the host builder. ## Source code of samples and module -* [Open source tiered & separate auth server application migrate Identity Server to OpenIddct](https://github.com/abpframework/abp-samples/tree/master/Ids2OpenId) +* [Open source tiered & separate auth server application migrate Identity Server to OpenIddict](https://github.com/abpframework/abp-samples/tree/master/Ids2OpenId) * [OpenIddict module document](https://docs.abp.io/en/abp/6.0/Modules/OpenIddict) * [OpenIddict module source code](https://github.com/abpframework/abp/tree/rel-6.0/modules/openiddict) diff --git a/docs/en/Module-Entity-Extensions.md b/docs/en/Module-Entity-Extensions.md index 7ee1d8840e..1a3c318c6b 100644 --- a/docs/en/Module-Entity-Extensions.md +++ b/docs/en/Module-Entity-Extensions.md @@ -6,7 +6,7 @@ Module entity extension system is a **high level** extension system that allows ## Quick Example -Open the *YourProjectNameModuleExtensionConfigurator* class inside the `Domain.Shared` project of your solution and change the `ConfigureExtraProperties`method as shown below to add a `SocialSecurityNumber` property to the `IdentityUser` entity of the [Identity Module](Modules/Identity.md). +Open the `YourProjectNameModuleExtensionConfigurator` class inside the `Domain.Shared` project of your solution and change the `ConfigureExtraProperties`method as shown below to add a `SocialSecurityNumber` property to the `IdentityUser` entity of the [Identity Module](Modules/Identity.md). ````csharp public static void ConfigureExtraProperties() diff --git a/docs/en/Modules/Cms-Kit/Dynamic-Widget.md b/docs/en/Modules/Cms-Kit/Dynamic-Widget.md index 88c0be6750..4ca764b7ea 100644 --- a/docs/en/Modules/Cms-Kit/Dynamic-Widget.md +++ b/docs/en/Modules/Cms-Kit/Dynamic-Widget.md @@ -3,7 +3,7 @@ CMS kit provides a dynamic [widget](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Widgets) used to render the components previously developed by the software in the content of the pages and blog posts. Its means, that in static content you can use dynamic content. We will mention how you can do it. You have two choices to define the widget in the system: Writing and UI. ### Adding the widget -Firstly we will show how to use the widget system via writing manually in the page and blogpost contents. +Firstly we will show how to use the widget system via writing manually in the page and blog post contents. Let's define the view component diff --git a/docs/en/Modules/Cms-Kit/Index.md b/docs/en/Modules/Cms-Kit/Index.md index b8cbe89d20..5b7f3b5366 100644 --- a/docs/en/Modules/Cms-Kit/Index.md +++ b/docs/en/Modules/Cms-Kit/Index.md @@ -22,7 +22,7 @@ All features are individually usable. If you disable a feature, it completely di ## Pre Requirements - This module depends on [BlobStoring](../../Blob-Storing.md) module for keeping media content. -> Make sure `BlobStoring` module is installed and at leats one provider is configured properly. For more information, check the [documentation](../../Blob-Storing.md). +> Make sure `BlobStoring` module is installed and at least one provider is configured properly. For more information, check the [documentation](../../Blob-Storing.md). - CMS Kit uses [distributed cache](../../Caching.md) for responding faster. > Using a distributed cache, such as [Redis](../../Redis-Cache.md), is highly recommended for data consistency in distributed/clustered deployments. diff --git a/docs/en/Redis-Cache.md b/docs/en/Redis-Cache.md index 9fe8efdb27..aa756e1a2e 100644 --- a/docs/en/Redis-Cache.md +++ b/docs/en/Redis-Cache.md @@ -4,7 +4,7 @@ ABP Framework [Caching System](Caching.md) extends the [ASP.NET Core distributed However, ABP provides an **integration package** for Redis Cache: [Volo.Abp.Caching.StackExchangeRedis](https://www.nuget.org/packages/Volo.Abp.Caching.StackExchangeRedis). There are two reasons for using this package, instead of the standard [Microsoft.Extensions.Caching.StackExchangeRedis](https://www.nuget.org/packages/Microsoft.Extensions.Caching.StackExchangeRedis/) package. -1. It implements `SetManyAsync` and `GetManyAsync` methods. These are not standard methods of the Microsoft Caching library, but added by the ABP Framework [Caching](Caching.md) system. They **significiantly increases the performance** when you need to set/get multiple cache items with a single method call. +1. It implements `SetManyAsync` and `GetManyAsync` methods. These are not standard methods of the Microsoft Caching library, but added by the ABP Framework [Caching](Caching.md) system. They **significantly increases the performance** when you need to set/get multiple cache items with a single method call. 2. It **simplifies** the Redis cache **configuration** (will be explained below). > Volo.Abp.Caching.StackExchangeRedis is already uses the Microsoft.Extensions.Caching.StackExchangeRedis package, but extends and improves it. diff --git a/docs/en/SignalR-Integration.md b/docs/en/SignalR-Integration.md index 35f109b8e6..d532067911 100644 --- a/docs/en/SignalR-Integration.md +++ b/docs/en/SignalR-Integration.md @@ -235,4 +235,4 @@ Refer to the Microsoft's documentation to [host and scale](https://docs.microsof ## See Also - [Microsoft SignalR documentation](https://docs.microsoft.com/en-us/aspnet/core/signalr/introduction) -- [Real-Time Messaging In A Distributed Architecture Using ABP, SingalR & RabbitMQ](https://volosoft.com/blog/RealTime-Messaging-Distributed-Architecture-Abp-SingalR-RabbitMQ) +- [Real-Time Messaging In A Distributed Architecture Using ABP, SignalR & RabbitMQ](https://volosoft.com/blog/RealTime-Messaging-Distributed-Architecture-Abp-SingalR-RabbitMQ) diff --git a/docs/en/Specifications.md b/docs/en/Specifications.md index a9aeb2b050..2ef9c4496e 100644 --- a/docs/en/Specifications.md +++ b/docs/en/Specifications.md @@ -246,7 +246,7 @@ So, what's the point of a specification? Why and when should we consider to use Some benefits of using specifications: -- **Reusabe**: Imagine that you need the Premium Customer filter in many places in your code base. If you go with expressions and do not create a specification, what happens if you later change the "Premium Customer" definition? Say you want to change the minimum balance from $100,000 to $250,000 and add another condition to be a customer older than 3 years. If you'd used a specification, you just change a single class. If you repeated (copy/pasted) the same expression everywhere, you need to change all of them. +- **Reusable**: Imagine that you need the Premium Customer filter in many places in your code base. If you go with expressions and do not create a specification, what happens if you later change the "Premium Customer" definition? Say you want to change the minimum balance from $100,000 to $250,000 and add another condition to be a customer older than 3 years. If you'd used a specification, you just change a single class. If you repeated (copy/pasted) the same expression everywhere, you need to change all of them. - **Composable**: You can combine multiple specifications to create new specifications. This is another type of reusability. - **Named**: `PremiumCustomerSpecification` better explains the intent rather than a complex expression. So, if you have an expression that is meaningful in your business, consider using specifications. - **Testable**: A specification is a separately (and easily) testable object. diff --git a/docs/en/Startup-Templates/Index.md b/docs/en/Startup-Templates/Index.md index 76c0488031..e30f2729e2 100644 --- a/docs/en/Startup-Templates/Index.md +++ b/docs/en/Startup-Templates/Index.md @@ -2,9 +2,9 @@ While you can start with an empty project and add needed packages manually, startup templates make easy and comfortable to start a new solution with the ABP framework. Click the name from the list below to see the documentation of the related startup template: -* [**app**](Application.md): Application template. -* [**app-nolayers**](Application-Single-Layer.md): Application (single layer) template. -* [**module**](Module.md): Module/service template. -* [**console**](Console.md): Console template. -* [**WPF**](WPF.md): WPF template. -* [**MAUI**](MAUI.md): MAUI template. +* [**`app`**](Application.md): Application template. +* [**`app-nolayers`**](Application-Single-Layer.md): Application (single layer) template. +* [**`module`**](Module.md): Module/service template. +* [**`console`**](Console.md): Console template. +* [**`WPF`**](WPF.md): WPF template. +* [**`MAUI`**](MAUI.md): MAUI template. diff --git a/docs/en/Themes/LeptonXLite/Angular.md b/docs/en/Themes/LeptonXLite/Angular.md index 4079281f99..950cd20c8b 100644 --- a/docs/en/Themes/LeptonXLite/Angular.md +++ b/docs/en/Themes/LeptonXLite/Angular.md @@ -1,7 +1,8 @@ # LeptonX Lite Angular UI + LeptonX Lite has implementation for the ABP Framework Angular Client. It's a simplified variation of the [LeptonX Theme](https://x.leptontheme.com/). -> If you are looking for a professional, enterprise ready theme, you can check the [LeptonX Theme](https://x.leptontheme.com/), which is a part of [ABP Commercial](https://commercial.abp.io/). +> If you are looking for a professional, enterprise ready theme, you can check the [LeptonX Theme](https://x.leptontheme.com/), which is a part of [ABP Commercial](https://commercial.abp.io/). > See the [Theming document](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Theming) to learn about themes. @@ -11,28 +12,27 @@ This theme is **already installed** when you create a new solution using the sta To add `LeptonX-lite` into your project, -* Install `@abp/ng.theme.lepton-x` +- Install `@abp/ng.theme.lepton-x` `yarn add @abp/ng.theme.lepton-x@preview` -* Install `bootstrap-icons` +- Install `bootstrap-icons` `yarn add bootstrap-icons` +- Then, we need to edit the styles array in `angular.json` to replace the existing style with the new one. -* Then, we need to edit the styles array in `angular.json` to replace the existing style with the new one. - -Add the following style +Add the following style ```json "node_modules/bootstrap-icons/font/bootstrap-icons.css", ``` -* Finally, remove `ThemeBasicModule` from `app.module.ts`, and import the related modules in `app.module.ts` +- Finally, remove `ThemeBasicModule` from `app.module.ts`, and import the related modules in `app.module.ts` ```js -import { ThemeLeptonXModule } from '@abp/ng.theme.lepton-x'; -import { SideMenuLayoutModule } from '@abp/ng.theme.lepton-x/layouts'; +import { ThemeLeptonXModule } from "@abp/ng.theme.lepton-x"; +import { SideMenuLayoutModule } from "@abp/ng.theme.lepton-x/layouts"; @NgModule({ imports: [ @@ -51,7 +51,7 @@ export class AppModule {} Note: If you employ [Resource Owner Password Flow](https://docs.abp.io/en/abp/latest/UI/Angular/Authorization#resource-owner-password-flow) for authorization, you should import the following module as well: ```js -import { AccountLayoutModule } from '@abp/ng.theme.lepton-x/account'; +import { AccountLayoutModule } from "@abp/ng.theme.lepton-x/account"; @NgModule({ // ... @@ -69,15 +69,15 @@ To change the logos and brand color of `LeptonX`, simply add the following CSS t ```css :root { - --lpx-logo: url('/assets/images/logo.png'); - --lpx-logo-icon: url('/assets/images/logo-icon.png'); + --lpx-logo: url("/assets/images/logo.png"); + --lpx-logo-icon: url("/assets/images/logo-icon.png"); --lpx-brand: #edae53; } ``` - `--lpx-logo` is used to place the logo in the menu. -- `--lpx-logo-icon` is a square icon used when the menu is collapsed. -- `--lpx-brand` is a color used throughout the application, especially on active elements. +- `--lpx-logo-icon` is a square icon used when the menu is collapsed. +- `--lpx-brand` is a color used throughout the application, especially on active elements. ### Server Side @@ -85,22 +85,18 @@ In order to migrate to LeptonX on your server side projects (Host and/or AuthSer ## Customization - ### Layouts -The Angular version of LeptonX Lite provides **layout components** for your **user interface** on [ABP Framework Theming](https://docs.abp.io/en/abp/latest/UI/Angular/Theming). You can use layouts to **organize your user interface**. You can replace the **layout components** and some parts of the **layout components** with the [ABP replaceable component system](https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement). - +The Angular version of LeptonX Lite provides **layout components** for your **user interface** on [ABP Framework Theming](https://docs.abp.io/en/abp/latest/UI/Angular/Theming). You can use the layouts to **organize your user interface**. You can replace the **layout components** and some parts of the **layout components** with the [ABP replaceable component system](https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement). The main responsibility of a theme is to **provide** the layouts. There are **three pre-defined layouts that must be implemented by all the themes:** -* **ApplicationLayoutComponent:** The **default** layout which is used by the **main** application pages. - -* **AccountLayoutComponent:** Mostly used by the **account module** for **login**, **register**, **forgot password**... pages. - -* **EmptyLayoutComponent:** The **Minimal** layout that **has no layout components** at all. +- **ApplicationLayoutComponent:** The **default** layout which is used by the **main** application pages. +- **AccountLayoutComponent:** Mostly used by the **account module** for **login**, **register**, **forgot password**... pages. +- **EmptyLayoutComponent:** The **Minimal** layout that **has no layout components** at all. + +The **Layout components** and all the replacable components are predefined in `eThemeLeptonXComponents` as enum. - The **Layout components** and all the replacable components are predefined in `eThemeLeptonXComponents` as enum. - ### How to replace a component ```js @@ -122,8 +118,8 @@ export class AppComponent { } } ``` -See the [Component Replacement](https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement) documentation for more information on how to replace components. +See the [Component Replacement](https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement) documentation for more information on how to replace components. ### Brand Component @@ -131,16 +127,14 @@ The **brand component** is a simple component that can be used to display your b ```js ///... - this.replaceableComponents.add({ - component: YourNewLogoComponent, - key: eThemeLeptonXComponents.Logo, - }); +this.replaceableComponents.add({ + component: YourNewLogoComponent, + key: eThemeLeptonXComponents.Logo, +}); ///... ``` -![Brand component](../../images/leptonxlite-brand-component.png) - - +![Brand component](../../images/leptonxlite-brand-component.png) ## Breadcrumb Component @@ -148,14 +142,14 @@ On websites that have a lot of pages, **breadcrumb navigation** can greatly **en ```js ///... - this.replaceableComponents.add({ - component: YourNewSidebarComponent, - key: eThemeLeptonXComponents.Breadcrumb, - }); +this.replaceableComponents.add({ + component: YourNewSidebarComponent, + key: eThemeLeptonXComponents.Breadcrumb, +}); ///... ``` -![Breadcrumb component](../../images/leptonxlite-breadcrumb-component.png) +![Breadcrumb component](../../images/leptonxlite-breadcrumb-component.png) ## Sidebar Menu Component @@ -163,54 +157,61 @@ Sidebar menus have been used as a **directory for Related Pages** to a **Service ```js ///... - this.replaceableComponents.add({ - component: YourNewSidebarComponent, - key: eThemeLeptonXComponents.Sidebar, - }); +this.replaceableComponents.add({ + component: YourNewSidebarComponent, + key: eThemeLeptonXComponents.Sidebar, +}); ///... ``` -![Sidebar menu component](../../images/leptonxlite-sidebar-menu-component.png) + +![Sidebar menu component](../../images/leptonxlite-sidebar-menu-component.png) ## Page Alerts Component Provides contextual **feedback messages** for typical user actions with a handful of **available** and **flexible** **alert messages**. Alerts are available for any length of text, as well as an **optional dismiss button**. -![Page alerts component](../../images/leptonxlite-page-alerts-component.png) +![Page alerts component](../../images/leptonxlite-page-alerts-component.png) + ```js ///... - this.replaceableComponents.add({ - component: YourNewPageAlertContainerComponent, - key: eThemeLeptonXComponents.PageAlertContainer, - }); +this.replaceableComponents.add({ + component: YourNewPageAlertContainerComponent, + key: eThemeLeptonXComponents.PageAlertContainer, +}); ///... ``` + ## Toolbar Component + ![Breadcrumb component](../../images/leptonxlite-toolbar-component.png) Toolbar items are used to add **extra functionality to the toolbar**. The toolbar is a **horizontal bar** that **contains** a group of **toolbar items**. + ```js ///... - this.replaceableComponents.add({ - component: YourNewNavItemsComponent, - key: eThemeLeptonXComponents.NavItems, - }); +this.replaceableComponents.add({ + component: YourNewNavItemsComponent, + key: eThemeLeptonXComponents.NavItems, +}); ///... ``` ## Toolbar Items + There are two parts to the toolbar. The first is Language-Switch. The second is the User-Profile element. You can swap out each of these parts individually. ## Language Switch Component -Think about a **multi-lingual** website and the first thing that could **hit your mind** is **the language switch component**. A **navigation bar** is a **great place** to **embed a language switch**. By embedding the language switch in the navigation bar of your website, you would **make it simpler** for users to **find it** and **easily** switch the **language** **without trying to locate it across the website.** +Think about a **multi-lingual** website and the first thing that could **hit your mind** is **the language switch component**. A **navigation bar** is a **great place** to **embed a language switch**. By embedding the language switch in the navigation bar of your website, you would **make it simpler** for users to **find it** and **easily** switch the **language** **without trying to locate it across the website.** + +![Language switch component](../../images/leptonxlite-language-switch-component.png) -![Language switch component](../../images/leptonxlite-language-switch-component.png) ```js ///... - this.replaceableComponents.add({ - component: YourNewLanguagesComponent, - key: eThemeLeptonXComponents.Languages, - }); +this.replaceableComponents.add({ + component: YourNewLanguagesComponent, + key: eThemeLeptonXComponents.Languages, +}); ///... ``` @@ -219,33 +220,84 @@ Think about a **multi-lingual** website and the first thing that could **hit you The **User Menu** is the **menu** that **drops down** when you **click your name** or **profile picture** in the **upper right corner** of your page (**in the toolbar**). It drops down options such as **Settings**, **Logout**, etc. ![User menu component](../../images/leptonxlite-user-menu-component.png) + ```js ///... - this.replaceableComponents.add({ - component: YourNewCurrentUserComponent, - key: eThemeLeptonXComponents.CurrentUser, - }); +this.replaceableComponents.add({ + component: YourNewCurrentUserComponent, + key: eThemeLeptonXComponents.CurrentUser, +}); ///... ``` + Note: The language selection component in the Volo app is not replaceable. It is part of the settings menu. ## Mobile Navbar Component + The **mobile navbar component** is used to display the **navbar menu on mobile devices**. The mobile navbar component is a **dropdown menu** that contains language selection and user menu. -![Mobile user menu component](../../images/leptonxlite-mobile-user-menu-component.png) +![Mobile user menu component](../../images/leptonxlite-mobile-user-menu-component.png) + ```js ///... - this.replaceableComponents.add({ - component: YourNewMobileNavbarComponent, - key: eThemeLeptonXComponents.MobileNavbar, - }); +this.replaceableComponents.add({ + component: YourNewMobileNavbarComponent, + key: eThemeLeptonXComponents.MobileNavbar, +}); ///... ``` + ## Mobile Navbar Items. -There are two parts of the mobile navbar. The mobile navbar has Language-Switch and User-Profile. You can swap out each of these parts individually. + +There are two parts of the mobile navbar. The mobile navbar has Language-Switch and User-Profile. You can swap out each of these parts individually. The Mobile language-Selection component key is `eThemeLeptonXComponents.MobileLanguageSelection`. The Mobile User-Profile component key is `eThemeLeptonXComponents.MobileUserProfile`. +## Footer Component + +![Angular Footer Component](../../images/angular-footer.png) + +The Footer is the section of content at the very bottom of the site. This section of the content can be modified. +Inject **FooterLinksService** and use the **setFooterInfo** method of **FooterLinksService** +to assign path or link and description. +**descUrl** and **footerLinks** are nullable. Constant **footerLinks** are on the right side of footer. + + +```js +///... + +const footerLinks = [ + { + link: "/components/bootstrap/badge", + text: "Manage Your Profile", + }, + { + link: "/components/bootstrap/border", + text: "My Security Logs", + }, +]; + +const footerInfo: FooterNav = { + desc: "Home", + descUrl: "/components/home", + footerLinks: footerLinks, +}; + +this.footerLinksService.setFooterInfo(footerInfo); + +///... +``` +If you want to change the footer component, the key is `eThemeLeptonXComponents.Footer` + +```js +///... +this.replaceableComponents.add({ + component: YourNewFooterComponent, + key: eThemeLeptonXComponents.Footer, +}); +///... +``` + diff --git a/docs/en/UI/Angular/Chart-Component.md b/docs/en/UI/Angular/Chart-Component.md index a1cea80b52..d165261e18 100644 --- a/docs/en/UI/Angular/Chart-Component.md +++ b/docs/en/UI/Angular/Chart-Component.md @@ -231,8 +231,8 @@ See the [`chart.js` samples](https://www.chartjs.org/docs/latest/samples) for mo | `[type]` | Type of the chart. | `string` | null | | `[data]` | Chart data to display | `any` | null | | `[options]` | Chart options to customize | `any` | null | -| `[plugins]` | Chart plugins to customize behaviour | `any` | null | -| `[width]` | Witdh of the chart | `string` | null | +| `[plugins]` | Chart plugins to customize behavior | `any` | null | +| `[width]` | Width of the chart | `string` | null | | `[height]` | Height of the chart | `string` | null | | `[responsive]` | Whether the chart is responsive | `boolean` | true | | `(dataSelect)` | A callback that executes when an element on the chart is clicked | `EventEmitter` | - | diff --git a/docs/en/UI/Angular/DateTime-Format-Pipe.md b/docs/en/UI/Angular/DateTime-Format-Pipe.md index 4841ffe665..662bed1c9c 100644 --- a/docs/en/UI/Angular/DateTime-Format-Pipe.md +++ b/docs/en/UI/Angular/DateTime-Format-Pipe.md @@ -1,3 +1,4 @@ +{%{ # DateTime Format Pipes You can format date by Date pipe of angular. @@ -5,7 +6,7 @@ You can format date by Date pipe of angular. Example ```html - {{today | date 'dd/mm/yy'}} +{{today | date 'dd/mm/yy'}} ``` ShortDate, ShortTime and ShortDateTime format data like angular's data pipe but easier. Also the pipes get format from config service by culture. @@ -13,17 +14,18 @@ ShortDate, ShortTime and ShortDateTime format data like angular's data pipe but # ShortDate Pipe ```html - {{today | shortDatePipe }} +{{today | shortDatePipe }} ``` # ShortTime Pipe ```html - {{today | shortTimePipe }} +{{today | shortTimePipe }} ``` # ShortDateTime Pipe ```html - {{today | shortDateTimePipe }} +{{today | shortDateTimePipe }} ``` +}%} diff --git a/docs/en/UI/Angular/Dynamic-Form-Extensions.md b/docs/en/UI/Angular/Dynamic-Form-Extensions.md index 1764b0cad7..f576dcafdc 100644 --- a/docs/en/UI/Angular/Dynamic-Form-Extensions.md +++ b/docs/en/UI/Angular/Dynamic-Form-Extensions.md @@ -7,7 +7,7 @@ Form prop extension system allows you to add a new field to the create and/or ed Form Prop Extension Example: 'Date of Birth' Field -You can validate the field, perform visibility checks, and do more. You will also have access to the current entity when creating a contibutor for an edit form. +You can validate the field, perform visibility checks, and do more. You will also have access to the current entity when creating a contributor for an edit form. ## How to Set Up diff --git a/docs/en/UI/Angular/Loading-Strategy.md b/docs/en/UI/Angular/Loading-Strategy.md index 5322d13eda..a222233088 100644 --- a/docs/en/UI/Angular/Loading-Strategy.md +++ b/docs/en/UI/Angular/Loading-Strategy.md @@ -102,7 +102,7 @@ Sets given paremeters and `crossorigin="anonymous"` as attributes of created `` element and places it at the **beginning** of `` tag in the document. +Sets given parameters and `crossorigin="anonymous"` as attributes of created `