(options =>
+ {
+ options.EntityTypes.Add(new CommentEntityTypeDefinition("Comment"));
+ options.IsRecaptchaEnabled = true;
+ });
+```
+
+Here, we simply defining what should be the entity-type name of our comment and also enable the reCaptcha for the comment system. After this configuration, now we can open the `Index.cshtml` file in the `*.Web` project and invoke the `CommentingViewComponent` as below:
+
+```html
+@page
+@using Microsoft.AspNetCore.Mvc.Localization
+@using SentimentAnalysisDemo.Localization
+@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting
+@model SentimentAnalysisDemo.Web.Pages.IndexModel
+
+
+
Comments:
+
+ @await Component.InvokeAsync(typeof(CommentingViewComponent), new
+ {
+ entityType = "Comment",
+ entityId = "SentimentAnalysisDemo",
+ isReadOnly = false
+ })
+
+
+```
+
+After adding the related component, now you can run the web project and see the comment component if you want.
+
+### Applying Sentiment Analysis (Creating the Spam Detection Service)
+
+By default, CMS Kit's Comment Feature does not provide a spam detection system. In this demo application, we will override the `CommentPublicAppService`'s `CreateAsync` and `UpdateAsync` methods and then will add the spam detection control whenever a new comment has been submitted or an existing one is being updated.
+
+To override the `CommentPublicAppService` and extend its use-case implementations, create a `MyCommentAppService` class and update its content as below:
+
+```csharp
+using System;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Options;
+using SentimentAnalysisDemo.ML;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.EventBus.Distributed;
+using Volo.CmsKit.Comments;
+using Volo.CmsKit.Public.Comments;
+using Volo.CmsKit.Users;
+
+namespace SentimentAnalysisDemo.Volo.CmsKit.Public.Comments;
+
+[Dependency(ReplaceServices = true)]
+[ExposeServices(typeof(ICommentPublicAppService), typeof(CommentPublicAppService), typeof(MyCommentAppService))]
+public class MyCommentAppService : CommentPublicAppService
+{
+ protected ISpamDetector SpamDetector { get; }
+
+ public MyCommentAppService(
+ ICommentRepository commentRepository,
+ ICmsUserLookupService cmsUserLookupService,
+ IDistributedEventBus distributedEventBus,
+ CommentManager commentManager,
+ IOptionsSnapshot cmsCommentOptions,
+ ISpamDetector spamDetector
+ )
+ : base(commentRepository, cmsUserLookupService, distributedEventBus, commentManager, cmsCommentOptions)
+ {
+ SpamDetector = spamDetector;
+ }
+
+ public override async Task CreateAsync(string entityType, string entityId, CreateCommentInput input)
+ {
+ //Check message: spam or ham.
+ await SpamDetector.CheckAsync(input.Text);
+
+ return await base.CreateAsync(entityType, entityId, input);
+ }
+
+ public override async Task UpdateAsync(Guid id, UpdateCommentInput input)
+ {
+ //Check message: spam or ham.
+ await SpamDetector.CheckAsync(input.Text);
+
+ return await base.UpdateAsync(id, input);
+ }
+}
+```
+
+Here, we simply just inject the `ISpamDetector` service, which we will create in a minute, and use its `CheckAsync` method to make a spam check before the comment is created or updated.
+
+Now, we can create the `ISpamDetector` service in the `*.Application.Contracts` project as follows:
+
+```csharp
+using System.Threading.Tasks;
+
+namespace SentimentAnalysisDemo.ML;
+
+public interface ISpamDetector
+{
+ Task CheckAsync(string text);
+}
+```
+
+Then, we can create the `SpamDetector` and implement the `ISpamDetector` interface (in the `*.Application` project):
+
+```csharp
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using Microsoft.ML;
+using SentimentAnalysisDemo.ML.Model;
+using Volo.Abp;
+using Volo.Abp.DependencyInjection;
+
+namespace SentimentAnalysisDemo.ML;
+
+public class SpamDetector : ISpamDetector, ITransientDependency
+{
+ public async Task CheckAsync(string text)
+ {
+ //check if the text contains a spam content or not...
+
+ }
+}
+```
+
+The `CheckAsync` method is where we need to make the sentiment analysis and detect if the comment contains spam content or not. If it's spam, then we should throw a [UserFriendlyException](https://docs.abp.io/en/abp/latest/Exception-Handling#user-friendly-exception) and notify the user that the comment should be updated and should not contain any spam content.
+
+#### Spam Detection
+
+Before, making the spam check, we should have a dataset to train a machine-learning model and add `Microsoft.ML` package into our project. For that purpose, I searched in [Kaggle](https://www.kaggle.com/) for spam datasets, found the **Spam-Mail-Detection-Dataset** from Kaggle, and downloaded the csv file to use in my application. Therefore, [you should also download the dataset from the link and put it under the **/ML/Data/spam_data.csv** directory of the `*.Web` project](https://github.com/EngincanV/SentimentAnalysisDemo/blob/master/src/SentimentAnalysisDemo.Web/ML/Data/spam_data.csv).
+
+Here is what our dataset looks like (**0 -> not spam / 1 -> spam**):
+
+| Category | Message |
+|----------|---------|
+| 0 | Is that seriously how you spell his name? |
+| 1 | Free entry in 2 a wkly comp to win FA Cup final tkts 21st May 2005. Text FA to 87121 to receive entry question(std txt rate)T&C's apply 08452810075over18's |
+| . | . |
+| . | . |
+| . | . |
+
+> **Note:** This dataset is not ready-to use in a real-world solution. It's for mail spam detection but for the simplicity of the sample, it's not important and can be used for development purposes.
+
+After, downloading the dataset and putting it in the directory of **/ML/Data**, now we can add the `Microsoft.ML` package into our `*.Application` project:
+
+```bash
+dotnet add package Microsoft.ML
+```
+
+Finally, we can implement the `CheckAsync` method and use sentiment analysis to make spam checks as follows:
+
+```csharp
+
+ public async Task CheckAsync(string text)
+ {
+ var dataPath = Path.Combine(Environment.CurrentDirectory, "ML", "Data", "spam_data.csv");
+
+ var mlContext = new MLContext();
+
+ //Step 1: Load Data 👇
+ IDataView dataView = mlContext.Data.LoadFromTextFile(dataPath, hasHeader: true, separatorChar: ',');
+
+ //Step 2: Split data to train-test data 👇
+ DataOperationsCatalog.TrainTestData trainTestSplit = mlContext.Data.TrainTestSplit(dataView, testFraction: 0.2);
+ IDataView trainingData = trainTestSplit.TrainSet; //80% of the data.
+ IDataView testData = trainTestSplit.TestSet; //20% of the data.
+
+ //Step 3: Common data process configuration with pipeline data transformations + choose and set the training algorithm 👇
+ var estimator = mlContext.Transforms.Text.FeaturizeText(outputColumnName: "Features", inputColumnName: nameof(SentimentAnalyzeInput.Message))
+ .Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(labelColumnName: "Label", featureColumnName: "Features"));
+
+ //Step 4: Train the model 👇
+ ITransformer model = estimator.Fit(trainingData);
+
+ //Step 5: Predict 👇
+ var sentimentAnalyzeInput = new SentimentAnalyzeInput
+ {
+ Message = text
+ };
+
+ var predictionEngine = mlContext.Model.CreatePredictionEngine(model);
+ var result = predictionEngine.Predict(sentimentAnalyzeInput);
+ if (IsSpam(result))
+ {
+ throw new UserFriendlyException("Spam detected! Please update the message!");
+ }
+ }
+
+ private static bool IsSpam(SentimentAnalyzeResult result)
+ {
+ //1 -> spam / 0 -> ham (for 'Prediction' column)
+ return result is { Prediction: true, Probability: >= 0.5f };
+ }
+
+```
+
+Here, we have done the following things:
+
+1. **First, we loaded the data**: For that reason, we created a `MLContext` object, which is a main class for all ML.NET operations. Then, we used its `LoadFromTextFile` method and specified the dataset path in our application. Also, we mapped the dataset columns to the `SentimentAnalyzeInput` class, which we will create later on.
+2. **For the second step, we split the data as training and testing data**: To be able to train a machine learning model and then evaluate its accuracy, we should not use all the data for training purposes, instead, we should split the data as training and testing data and after training the model, compare the training data accuracy with the testing data.
+3. **For the third step, we should make data transformation, convert the text-based data into numeric vectors and then choose a training algorithm**: After splitting the data for training and testing purposes, now we can apply some data transformations for the *Message* column in our dataset. Because, as you would see, messages are text-based inputs and machine-learning algorithms work best with the numeric vectors. So, we are making data transformations and representing the data as numeric values. Then, we can apply `BinaryClassification` with the **SdcaLogicticRegression** algorithm to our training data.
+4. **Train the model**: Since we make the data transformations and chose the correct algorithm for our model, now we can train the model.
+5. **Predict the sample data**: Finally, we can pass a comment to this method and make spam check and either approve our reject the comment according to the predicted result. (To make predictions, we need to create a **PredictionEngine** and get the final results in the output class that we specified, `SentimentAnalyzeResult` in our example)
+
+Let's create the `SentimentAnalyzeInput` and `SentimentAnalyzeResult` classes as follows.
+
+**SentimentAnalyzeInput.cs:**
+
+```csharp
+using Microsoft.ML.Data;
+
+namespace SentimentAnalysisDemo.ML.Model;
+
+public class SentimentAnalyzeInput
+{
+ [LoadColumn(0), ColumnName("Label")]
+ public bool Category { get; set; }
+
+ [LoadColumn(1), ColumnName("Message")]
+ public string Message { get; set; }
+}
+```
+
+**SentimentAnalyzeResult.cs:**
+
+```csharp
+using Microsoft.ML.Data;
+
+namespace SentimentAnalysisDemo.ML.Model;
+
+public class SentimentAnalyzeResult
+{
+ [ColumnName("PredictedLabel")]
+ public bool Prediction { get; set; }
+
+ public float Probability { get; set; }
+
+ public float Score { get; set; }
+}
+```
+
+Then, finally we can run the application to see the final results:
+
+
+
+## Conclusion
+
+In this article, I briefly explain what sentiment analysis is, created a sample ABP-based application, integrated the CMS Kit Module and finally, applied sentiment analysis to make spam checks whenever a new comment has been submitted or updated. You can get the source code of the demo from [https://github.com/EngincanV/SentimentAnalysisDemo](https://github.com/EngincanV/SentimentAnalysisDemo)
+
+Thanks for reading :)
\ No newline at end of file
diff --git a/docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/cover-image.png b/docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/cover-image.png
new file mode 100644
index 0000000000..7091f1a6b5
Binary files /dev/null and b/docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/cover-image.png differ
diff --git a/docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/demo.gif b/docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/demo.gif
new file mode 100644
index 0000000000..5a373ba110
Binary files /dev/null and b/docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/demo.gif differ
diff --git a/docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/sentiment-analysis-steps.png b/docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/sentiment-analysis-steps.png
new file mode 100644
index 0000000000..4222b4c97c
Binary files /dev/null and b/docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/sentiment-analysis-steps.png differ
diff --git a/docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/sentiment-analysis.png b/docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/sentiment-analysis.png
new file mode 100644
index 0000000000..9597476dca
Binary files /dev/null and b/docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/sentiment-analysis.png differ
diff --git a/docs/en/cli/index.md b/docs/en/cli/index.md
index b9dc63b59c..17ca5b0ac6 100644
--- a/docs/en/cli/index.md
+++ b/docs/en/cli/index.md
@@ -1,19 +1,19 @@
# ABP CLI
-ABP CLI (Command Line Interface) is a command line tool to perform some common operations for ABP based solutions.
+ABP CLI (Command Line Interface) is a command line tool to perform some common operations for ABP based solutions or ABP Studio features.
## Installation
ABP CLI is a [dotnet global tool](https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools). Install it using a command line window:
````bash
-dotnet tool install -g Volo.Abp.Cli
+dotnet tool install -g Volo.Abp.Studio.Cli
````
To update an existing installation:
````bash
-dotnet tool update -g Volo.Abp.Cli
+dotnet tool update -g Volo.Abp.Studio.Cli
````
## Global Options
@@ -29,13 +29,24 @@ Here, is the list of all available commands before explaining their details:
* **`help`**: Shows help on the usage of the ABP CLI.
* **`cli`**: Update or remove ABP CLI.
* **`new`**: Generates a new solution based on the ABP [startup templates](../solution-templates).
+* **`new-module`**: Generates a new module based on the given template.
+* **`new-package`**: Generates a new package based on the given template.
* **`update`**: Automatically updates all ABP related NuGet and NPM packages in a solution.
* **`clean`**: Deletes all `BIN` and `OBJ` folders in the current folder.
* **`add-package`**: Adds an ABP package to a project.
-* **`add-module`**: Adds a [multi-package application module](../modules) to a solution.
+* **`add-package-ref`**: Adds package to given project.
+* **`install-module`**: Adds a [multi-package application module](../modules) to a given module.
+* **`install-local-module`**: Installs a local module to given module.
* **`list-modules`**: Lists names of open-source application modules.
* **`list-templates`**: Lists the names of available templates to create a solution.
* **`get-source`**: Downloads the source code of a module.
+* **`add-source-code`**: Downloads the source code and replaces package references with project references.
+* **`init-solution`**: Creates ABP Studio configuration files for a given solution.
+* **`kube-connect`**: Connects to kubernetes environment.
+* **`kube-intercept`**: Intercepts a service running in Kubernetes environment.
+* **`list-module-sources`**: Lists the remote module sources.
+* **`add-module-source`**: Adds a remote module source.
+* **`delete-module-source`**: Deletes a remote module source.
* **`generate-proxy`**: Generates client side proxies to use HTTP API endpoints.
* **`remove-proxy`**: Removes previously generated client side proxies.
* **`switch-to-preview`**: Switches to the latest preview version of the ABP.
@@ -110,8 +121,10 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md
#### Options
-* `--template` or `-t`: Specifies the template name. Default template name is `app`, which generates a web application. Available templates:
- * **`app`** (default): [Application template](../solution-templates/layered-web-application). Additional options:
+* `--template` or `-t`: Specifies the template name. Default template name is `app`, which generates a application solution. Available templates:
+ * **`empty`**: Empty solution template.
+
+ * **`app`**: Application template. Additional options:
* `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks:
* `mvc`: ASP.NET Core MVC. There are some additional options for this template:
* `--tiered`: Creates a tiered solution where Web and Http API layers are physically separated. If not specified, it creates a layered solution which is less complex and suitable for most scenarios.
@@ -123,54 +136,160 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md
* `--pwa`: Specifies the project as Progressive Web Application.
* `blazor-server`: Blazor Server UI. There are some additional options for this template:
* `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project.
- * `none`: Without UI. No front-end layer will be created. There are some additional options for this template:
+ * `maui-blazor`: Blazor Maui UI. There are some additional options for this template:
+ * `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project.
+ * `no-ui`: Without UI. No front-end layer will be created. There are some additional options for this template:
* `--separate-auth-server`: The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side.
- * `--mobile` or `-m`: Specifies the mobile application framework. If not specified, no mobile application will be created. Available options:
+ * `--mobile` or `-m`: Specifies the mobile application framework. Default value is `react-native`. Available frameworks:
+ * `none`: Without any mobile application.
* `react-native`: React Native.
* `maui`: MAUI. This mobile option is only available for ABP.
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
- * `--theme`: Specifes the theme. Default theme is `leptonx-lite`. Available themes:
- * `leptonx-lite`: [LeptonX Lite Theme](../ui-themes/lepton-x-lite/asp-net-core.md).
- * `basic`: [Basic Theme](../framework/ui/mvc-razor-pages/basic-theme.md).
- * **`module`**: [Module template](../solution-templates/application-module). Additional options:
- * `--no-ui`: Specifies to not include the UI. This makes possible to create service-only modules (a.k.a. microservices - without UI).
- * **`console`**: [Console template](../get-started/console.md).
- * **`app-nolayers`**: [Single-layer application template](../solution-templates/single-layer-web-application). Additional options:
+ * `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](Entity-Framework-Core-Other-DBMS.md) (after creating the solution).
+ * `--public-website`: Public Website is a front-facing website for describing your project, listing your products and doing SEO for marketing purposes. Users can login and register on your website with this website. This option is only included in PRO templates.
+ * `--separate-tenant-schema`: Creates a different DbContext for tenant schema. If not specified, the tenant schema is shared with the host schema. This option is only included in PRO templates.
+ * `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
+ * `leptonx`: LeptonX Theme.
+ * `basic`: Basic Theme.
+
+ * **`app-nolayers`**: Single-layer application template. Additional options:
* `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks:
- * `mvc`: ASP.NET Core MVC.
- * `angular`: Angular UI.
- * `blazor`: Blazor UI.
- * `blazor-server`: Blazor Server UI.
- * `none`: Without UI.
+ * `mvc`: ASP.NET Core MVC. There are some additional options for this template:
+ * `angular`: Angular UI. There are some additional options for this template:
+ * `blazor`: Blazor UI. There are some additional options for this template:
+ * `blazor-server`: Blazor Server UI. There are some additional options for this template:
+ * `no-ui`: Without UI. No front-end layer will be created. There are some additional options for this template:
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
- * `ef`: Entity Framework Core.
- * `mongodb`: MongoDB.
- * `--theme`: Specifes the theme. Default theme is `leptonx-lite`. Available themes:
- * `leptonx-lite`: [LeptonX Lite Theme](../ui-themes/lepton-x-lite).
- * `basic`: [Basic Theme](../framework/ui/mvc-razor-pages/basic-theme.md).
- * **`maui`**: .NET MAUI. A minimalist .NET MAUI application will be created if you specify this option.
+ * `ef`: Entity Framework Core.
+ * `mongodb`: MongoDB.
+ * `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](Entity-Framework-Core-Other-DBMS.md) (after creating the solution).
+ * `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
+ * `leptonx`: LeptonX Theme.
+ * `basic`: Basic Theme.
+
+ * **`microservice-pro`**: Microservice solution template. Additional options:
+ * `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks:
+ * `mvc`: ASP.NET Core MVC. There are some additional options for this template:
+ * `angular`: Angular UI. There are some additional options for this template:
+ * `blazor`: Blazor UI. There are some additional options for this template:
+ * `blazor-server`: Blazor Server UI. There are some additional options for this template:
+ * `maui-blazor`: Blazor Maui UI. There are some additional options for this template:
+ * `no-ui`: Without UI. No front-end layer will be created. There are some additional options for this template:
+ * `--mobile` or `-m`: Specifies the mobile application framework. Default value is `react-native`. Available frameworks:
+ * `none`: Without any mobile application.
+ * `react-native`: React Native.
+ * `maui`: MAUI.
+ * `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
+ * `ef`: Entity Framework Core.
+ * `mongodb`: MongoDB.
+ * `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
+ * `leptonx`: LeptonX Theme.
+ * `basic`: Basic Theme.
+ * `--public-website`: Public Website is a front-facing website for describing your project, listing your products and doing SEO for marketing purposes. Users can login and register on your website with this website. This option is only included in PRO templates.
+
* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
-* `--version` or `-v`: Specifies the ABP & template version. It can be a [release tag](https://github.com/abpframework/abp/releases) or a [branch name](https://github.com/abpframework/abp/branches). Uses the latest release if not specified. Most of the times, you will want to use the latest version.
-* `--preview`: Use latest preview version.
-* `--template-source` or `-ts`: Specifies a custom template source to use to build the project. Local and network sources can be used(Like `D:\local-template` or `https://.../my-template-file.zip`).
+* `--local-framework-ref` or `-lfr`: Uses local projects references to the ABP framework instead of using the NuGet packages. It tries to find the paths from `ide-state.json`. The file is located at `%UserProfile%\.abp\studio\ui\ide-state.json` (for Windows) and `~/.abp/studio/ui/ide-state.json` (for MAC).
* `--create-solution-folder` or `-csf`: Specifies if the project will be in a new folder in the output folder or directly the output folder.
-* `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](../framework/data/entity-framework-core/other-dbms.md) (after creating the solution).
* `--database-management-system` or `-dbms`: Sets the database management system. Default is **SQL Server**. Supported DBMS's:
* `SqlServer`
* `MySQL`
- * `SQLite`
- * `Oracle`
- * `Oracle-Devart`
* `PostgreSQL`
-* `--local-framework-ref --abp-path`: Uses local projects references to the ABP instead of using the NuGet packages. This can be useful if you download the ABP source code and have a local reference to the framework from your application.
-* `--no-random-port`: Uses template's default ports.
-* `--skip-installing-libs` or `-sib`: Skip installing client side packages.
-* `--skip-cache` or `-sc`: Always download the latest from our server and refresh their templates folder cache.
-* `--with-public-website`: **Public Website** is a front-facing website for describing your project, listing your products and doing SEO for marketing purposes. Users can login and register on your website with this website.
+ * `SQLite` (`app` & `app-nolayers`)
+ * `Oracle` (`app` & `app-nolayers`)
+ * `Oracle-Devart` (`app` & `app-nolayers`)
+* `--dont-run-install-libs`: Skip installing client side packages.
+* `--dont-run-bundling`: Skip bundling for Blazor packages.
+* `--no-kubernetes-configuration` or `-nkc`: Skips the Kubernetes configuration files.
+* *Module Options*: You can skip some modules if you don't want to add them to your solution. Available commands:
+ * `-no-saas`: Skips the Saas module.
+ * `-no-gdpr`: Skips the GDPR module.
+ * `-no-openiddict-admin-ui`: Skips the OpenIddict Admin UI module.
+ * `-no-audit-logging`: Skips the Audit Logging module.
+ * `-no-file-management`: Skips the File Management module.
+ * `-no-language-management`: Skips the Language Management module.
+ * `-no-text-template-management`: Skips the Text Template Management module.
+ * `-no-chat`: Skips the Chat module.
+* `--legacy`: Generates a legacy solution.
+
+### new-module
+
+Generates a new module.
-See some [examples for the new command](./new-command-samples.md) here.
+````bash
+abp new-module [options]
+````
+
+Example:
+
+````bash
+abp new-module Acme.BookStore -t module:ddd
+````
+
+#### options
+
+* `--template` or `-t`: Specifies the template name. Default template name is `module:ddd`, which generates a DDD module. Module templates are provided by the main template, see their own startup template documentation for available modules. `empty:empty` and `module:ddd` template is available for all solution structure.
+* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
+* `--target-solution` or `-ts`: If set, the new module will be added to the given solution. Otherwise the new module will added to the closest solution in the file system. If no solution found, it will throw an error.
+* `--solution-folder` or `-sf`: Specifies the target folder in the [Solution Explorer](./solution-explorer.md#folder) virtual folder system.
+* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. This option is only available if the module template supports it. You can add multiple values separated by commas, such as `ef, mongodb` if the module template supports it. Available providers:
+ * `ef`: Entity Framework Core.
+ * `mongodb`: MongoDB.
+* `--ui-framework` or `-u`: Specifies the UI framework. This option is only available if the module template supports it. You can add multiple values separated by commas, such as `mvc,angular` if the module template supports it. Available frameworks:
+ * `mvc`: ASP.NET Core MVC.
+ * `angular`: Angular UI.
+ * `blazor`: Blazor UI.
+ * `blazor-server`: Blazor Server UI.
+
+### new-package
+
+Generates a new package.
+
+````bash
+abp new-package [options]
+````
+
+Example:
+
+````bash
+abp new-package --name Acme.BookStore.Domain --template lib.domain
+````
+
+#### options
+
+* `--template` or `-t`: Specifies the template name. This parameter doesn't have a default value and must be set. Available templates and their sub-options:
+ * `lib.class-library`
+ * `lib.domain-shared`
+ * `lib.domain`
+ * `lib.application-contracts`
+ * `lib.application`
+ * `--with-automapper`: Adds automapper configuration.
+ * `lib.ef`
+ * `--include-migrations`: Allows migration operations on this package.
+ * `--connection-string-name`: Default value is the last part of the package's namespace (or package name simply).
+ * `--connection-string`: Connection string value. Defaut value is null. You can set it alter.
+ * `lib.mongodb`
+ * `lib.http-api`
+ * `lib.http-api-client`
+ * `lib.mvc`
+ * `lib.blazor`
+ * `lib.blazor-wasm`
+ * `lib.blazor-server`
+ * `host.http-api`
+ * `--with-serilog`: Includes Serilog configuration.
+ * `--with-swagger`: Includes Swagger configuration.
+ * `host.mvc`
+ * `--with-serilog`: Includes Serilog configuration.
+ * `--with-swagger`: Includes Swagger configuration.
+ * `host.blazor-wasm`
+ * `--backend`: Name of the backend project in the module (not path).
+ * `host.blazor-server`
+ * `csharp.console`
+ * `csharp.library`
+* `--module-file` or `-m`: If set, the new package will be added to the given module. Otherwise the new package will added to the closest module in the file system. If no module found, it will throw an error.
+* `--name` or `-n`: Specifies the name of the package. If not set, a name based on the template type and module name will be generated.
+* `--folder` or `-f`: Specifies the target folder in the target module's virtual folder system.
### update
@@ -243,44 +362,65 @@ abp add-package Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic
> - Volo.Abp.AspNetCore.Components.Web.BasicTheme
> - Volo.Abp.AspNetCore.Components.Server.BasicTheme
+### add-package-ref
+
+Adds one or more package reference to target project, also adds ABP module dependency. Both reference and target projects must belong to same module.
+
+````bash
+abp add-package-ref [options]
+````
-### add-module
+Example:
+
+````bash
+abp add-package-ref Acme.BookStore.Domain
+abp add-package-ref "Acme.BookStore.Domain Acme.BookStore.Domain.Shared" -t Acme.BookStore.Web
+````
-Adds a [multi-package application module](../modules) to a solution by finding all packages of the module, finding related projects in the solution and adding each package to the corresponding project in the solution.
+#### Options
-It can also create a new module for your solution and add it to your solution. See `--new` option.
+* `--target-project` or `-t`: Name of the project that reference will be added. If not set, project in the current directory will be used.
-> A business module generally consists of several packages (because of layering, different database provider options or other reasons). Using `add-module` command dramatically simplifies adding a module to a solution. However, each module may require some additional configurations which is generally indicated in the documentation of the related module.
+### install-module
-Usage:
+Installs a module, that is published as nuget packages, to a local module. Project relations are created according the types of the projects. For example: a `lib.domain-shared` project is added to `lib.domain-shared` project
````bash
-abp add-module [options]
+abp install-module [options]
````
-Examples:
+Example:
-```bash
-abp add-module Volo.Blogging
-```
+````bash
+abp install-module Volo.Blogging
-* This example adds the `Volo.Blogging` module to the solution.
+abp install-module Volo.Blogging -t "modules/crm/Acme.Crm.abpmdl"
+````
-```bash
-abp add-module ProductManagement --new --add-to-solution-file
-```
+#### Options
+
+* `--target-module` or `-t`: Path (or folder path) of the target module that the other module will be installed to. If not set, the closest module to the current directory will be used.
+* `--version` or `-v`: Nuget version of the module to be installed.
-* This command creates a fresh new module customized for your solution (named `ProductManagement`) and adds it to your solution.
+### install-local-module
+Installs one module to another. Project relations are created according the types of the projects. For example: a `lib.domain-shared` project is added to `lib.domain-shared` project
+
+````bash
+abp install-local-module [options]
+````
+
+Example:
+
+````bash
+abp install-local-module Acme.OrderManagement
+
+abp install-local-module Acme.OrderManagement -t "modules/crm/Acme.Crm.abpmdl"
+````
#### Options
-* `--solution` or `-s`: Specifies the solution (.sln) file path. If not specified, CLI tries to find a .sln file in the current directory.
-* `--skip-db-migrations`: For EF Core database provider, it automatically adds a new code first migration (`Add-Migration`) and updates the database (`Update-Database`) if necessary. Specify this option to skip this operation.
-* `-sp` or `--startup-project`: Relative path to the project folder of the startup project. Default value is the current folder.
-* `--new`: Creates a fresh new module (customized for your solution) and adds it to your solution.
-* `--with-source-code`: Downloads the source code of the module to your solution folder and uses local project references instead of NuGet/NPM packages. This options is always `True` if `--new` is used.
-* `--add-to-solution-file`: Adds the downloaded/created module to your solution file, so you will also see the projects of the module when you open the solution on a IDE. (only available when `--with-source-code` is `True`.)
+* `--target-module` or `-t`: Path (or folder path) of the target module that the other module will be installed to. If not set, the closest module to the current directory will be used.
### list-modules
@@ -337,6 +477,157 @@ abp get-source Volo.Blogging --local-framework-ref --abp-path D:\GitHub\abp
* `--preview`: If no version option is specified, this option specifies if latest [preview version](../release-info/previews.md) will be used instead of latest stable version.
* `--local-framework-ref --abp-path`: Path of [ABP GitHub repository](https://github.com/abpframework/abp) in your computer. This will be used for converting project references to your local system. If this is not specified, project references will be converted to NuGet references.
+### add-source-code
+
+Downloads the source code of a module and replaces package references with project references. This command only works if your ABP Commercial License has source-code access, or if source-code of the target module is free to all type of ABP Commercial Licenses.
+
+````bash
+abp add-source-code [options]
+````
+
+Example:
+
+````bash
+abp add-source-code Volo.Chat --add-to-solution-file
+````
+
+#### Options
+
+* `--target-module` or `-t`: The module that will refer the downloaded source code. If not set, the module in the current directory will be used.
+* `--add-to-solution-file`: Adds the downloaded source code to C# solution file and ABP Studio solution file.
+
+### init-solution
+
+Creates necessary files for a solution to be readable by ABP Studio. If the solution is generated via ABP Studio, you don't need this command. But it is not generated by ABP Studio, you need this command to make it work with ABP Studio.
+
+````bash
+abp init-solution [options]
+````
+
+Example:
+
+````bash
+abp init-solution --name Acme.BookStore
+````
+
+#### Options
+
+* `--name` or `-n`: Name for the solution. If not set, it will be the same as the name of closest c# solution in the file system.
+
+### kube-connect
+
+Connects to Kubernetes cluster. Press `ctrl+c` to disconnect.
+
+````bash
+abp kube-connect [options]
+````
+
+Example:
+
+````bash
+abp kube-connect
+
+abp kube-connect -p Default.abpk8s.json
+
+abp kube-connect -c docker-desktop -ns mycrm-local
+````
+
+#### Options
+
+* `--profile` or `-p`: Kubernetes Profile path or name to be used. Path can be relative (to current directory) or full path, or you can simply give the name of profile if you run this command in same directory with the solution or profile. This parameter is not needed if you use `--namespace` and `--context` parameters.
+* `--namespace` or `-ns`: The namespace that services running on.
+* `--context` or `-c`: The context that services running in.
+* `--wireguard-password` or `-wp`: Wireguard password for the profile. This is not needed if you already set it on the ABP Studio user interface.
+* `--solution-id` or `-si`: Id of the solution. If not set, the closest solution in file system will be used.
+
+### kube-intercept
+
+Intercepts a service running in Kubernetes environment. Press `ctrl+c` to stop interception.
+
+````bash
+abp kube-intercept [options]
+````
+
+Example:
+
+````bash
+abp kube-intercept mycrm-product-service -ns mycrm-local
+
+abp kube-intercept mycrm-product-service -ns mycrm-local -a MyCrm.ProductService.HttpApi.Host.csproj
+
+abp kube-intercept mycrm-product-service -ns mycrm-local -a MyCrm.ProductService.HttpApi.Host.csproj -pm 8080:80,8081:443
+````
+
+#### Options
+
+* `--application` or `-a`: Relative or full path of the project that will intercept the service. If not set, the project in the current directory will be used.
+* `--namespace` or `-ns`: The namespace that service running on.
+* `--context` or `-sc`: The context that service running in. Default value is `docker-desktop`.
+* `--port-mappings` or `-pm`: Port mappings for the service.
+
+### list-module-sources
+
+With this command, you can see the list of remote module sources that you can use to install modules. It is similar to the NuGet feed list in Visual Studio.
+
+````bash
+abp list-module-sources
+````
+
+### add-module-source
+
+Adds a remote module source to the list of sources that you can use to install modules.
+
+````bash
+abp add-module-source [options]
+````
+
+You can create your own module source and add it to the list. It accepts a name and a url or a path as parameter. If you provide a path, it should be a local path that contains the modules json file. If you provide a url, it should be a url that contains the modules json file. The json file should be in the following format:
+
+````json
+{
+ "name": "ABP Open Source Modules",
+ "modules" : {
+ "Volo.Abp.Account": {},
+ "Volo.Abp.AuditLogging": {},
+ "Volo.Abp.Identity": {},
+ ...
+ }
+}
+````
+
+When you add a module source, you can install modules from that source using the `install-module` command. It attempts to find the package from NuGet, such as `Volo.Abp.Account.Installer`. You can configure a private NuGet feed and publish your modules to that feed. Each module has an installer package that is utilized to install the module into a solution. When you publish your module to a private feed, you should also publish the installer package to the same feed.
+
+Example:
+
+````bash
+abp add-module-source -n "Custom Source" -p "D:\packages\abp\modules.json"
+
+abp add-module-source -n "Custom Http Source" -p "https://raw.githubusercontent.com/x/abp-module-store/main/abp-module-store.json"
+````
+
+#### Options
+
+* `--name` or `-n`: The name of the module source.
+* `--path` or `-p`: The path of the module source. It can be a local path or a url.
+
+### delete-module-source
+
+Deletes a remote module source from the list of sources that you can use to install modules.
+
+````bash
+abp delete-module-source [options]
+````
+
+Example:
+
+````bash
+abp delete-module-source -n "Custom Source"
+````
+
+#### Options
+
+* `--name` or `-n`: The name of the module source.
+
### generate-proxy
Generates Angular, C# or JavaScript service proxies for your HTTP APIs to make easy to consume your services from the client side. Your host (server) application must be up and running before running this command.
diff --git a/docs/en/cli/new-command-samples.md b/docs/en/cli/new-command-samples.md
index a30ce692e0..ad45166615 100644
--- a/docs/en/cli/new-command-samples.md
+++ b/docs/en/cli/new-command-samples.md
@@ -67,7 +67,7 @@ The following commands are for creating MVC UI projects:
* **Public Website**, Entity Framework Core, no mobile app, creates the project in a new folder:
```bash
- abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef -csf --with-public-website
+ abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef -csf --public-website
```
_Note that Public Website is only included in PRO templates._
@@ -146,61 +146,18 @@ It's a template of a basic .NET console application with ABP module architecture
## Module
-Module are reusable sub applications used by your main project. Using ABP Module is a best practice if you are building a microservice solution. As modules are not final applications, each module has all the frontend UI projects and database providers. The module template comes with an MVC UI to be able to develop without the final solution. But if you will develop your module under a final solution, you add `--no-ui` parameter to exclude MVC UI project.
+Module are reusable sub applications used by your main project. Using ABP Module is a best practice if you are building a microservice solution. As modules are not final applications, each module could contains different frontend UI projects and database providers.
-* Included frontends: `MVC`, `Angular`, `Blazor`. Included database providers: `Entity Framework Core`, `MongoDB`. Includes MVC startup project.
+* Available frontends: `MVC`, `Angular`, `Blazor`. Available database providers: `Entity Framework Core`, `MongoDB`.
```bash
- abp new Acme.IssueManagement -t module
+ abp new-module Acme.IssueManagement
```
-* The same with the upper but doesn't include MVC startup project.
- ```bash
- abp new Acme.IssueManagement -t module --no-ui
- ```
-
-* Creates the module and adds it to your solution
-
- ```bash
- abp new Acme.IssueManagement -t module --add-to-solution-file
- ```
-
-## Create a solution from a specific version
-
-When you create a solution, it always creates with the latest version. To create a project from an older version, you can pass the `--version` parameter.
-
-* Create a solution from v3.3.0, with Angular UI and Entity Framework Core.
-
- ```bash
- abp new Acme.BookStore -t app -u angular -m none --database-provider ef -csf --version 3.3.0
- ```
-
-To get the ABP version list, checkout following link: https://www.nuget.org/packages/Volo.Abp.Core/
-
-## Create from a custom template
-
-ABP CLI uses the default [app template](https://github.com/abpframework/abp/tree/dev/templates/app) to create your project. If you want to create a new solution from your customized template, you can use the parameter `--template-source`.
-
-* MVC UI, Entity Framework Core, no mobile app, using the template in `c:\MyProjects\templates\app` directory.
-
- ```bash
- abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef --template-source "c:\MyProjects\templates\app"
- ```
-
-* Same with the previous one except this command retrieves the template from the URL `https://myabp.com/app-template.zip`.
-
- ```bash
- abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef --template-source https://myabp.com/app-template.zip
- ```
-
-## Create a preview version
-
-ABP CLI always uses the latest version. In order to create a solution from a preview (RC) version add the `--preview` parameter.
-
-* Blazor UI, Entity Framework Core, no mobile, **preview version**, creates the project in a new folder:
+* The same with the upper but includes MVC and angular projects.
```bash
- abp new Acme.BookStore -t app -u blazor --mobile none -csf --preview
+ abp new-module Acme.IssueManagement -u mvc,angular
```
## Choose database management system
@@ -213,18 +170,6 @@ The default database management system (DBMS) is `Entity Framework Core` / ` SQL
abp new Acme.BookStore -u angular --database-management-system PostgreSQL -csf
```
-
-
-## Use static HTTP ports
-
-ABP CLI always assigns random ports to the hostable projects. If you need to keep the default ports and create a solution always with the same HTTP ports, add the parameter `--no-random-port`.
-
-* MVC UI, Entity Framework Core, **static ports**, creates the project in a new folder:
-
- ```bash
- abp new Acme.BookStore --no-random-port -csf
- ```
-
## Use local ABP references
ABP libraries are referenced from NuGet by default in the ABP solutions. Sometimes you need to reference ABP libraries locally to your solution. This is useful to debug the framework itself. Your local ABP 's root directory must have the `Volo.Abp.sln` file. You can copy the content of the following directory to your file system https://github.com/abpframework/abp/tree/dev/framework
diff --git a/docs/en/modules/audit-logging-pro.md b/docs/en/modules/audit-logging-pro.md
index 28002256f1..2944012745 100644
--- a/docs/en/modules/audit-logging-pro.md
+++ b/docs/en/modules/audit-logging-pro.md
@@ -1,4 +1,6 @@
-# Audit Logging module
+# Audit Logging Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
This module implements the Audit Logging system of an application;
diff --git a/docs/en/modules/chat.md b/docs/en/modules/chat.md
index 22c0ebb2bd..55d9f3b98f 100644
--- a/docs/en/modules/chat.md
+++ b/docs/en/modules/chat.md
@@ -1,4 +1,6 @@
-# Chat module
+# Chat Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
This module implements real time messaging between users for an application.
diff --git a/docs/en/modules/cms-kit-pro/index.md b/docs/en/modules/cms-kit-pro/index.md
index c641721dc5..e3eb20debe 100644
--- a/docs/en/modules/cms-kit-pro/index.md
+++ b/docs/en/modules/cms-kit-pro/index.md
@@ -1,4 +1,6 @@
-# CMS Kit Pro Module
+# CMS Kit Pro Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
This module extends the [open-source CMS Kit module](../cms-kit) and adds additional CMS (Content Management System) capabilities to your application.
diff --git a/docs/en/modules/cms-kit-pro/newsletter.md b/docs/en/modules/cms-kit-pro/newsletter.md
index 5a5ae54093..3cc4338228 100644
--- a/docs/en/modules/cms-kit-pro/newsletter.md
+++ b/docs/en/modules/cms-kit-pro/newsletter.md
@@ -1,6 +1,6 @@
# Newsletter System
-CMS kit provides a **newsletter** system to allow users to subscribe to newsletters. Here a screenshot of the newsletter subscription widget:
+CMS Kit provides a **newsletter** system to allow users to subscribe to newsletters. Here a screenshot of the newsletter subscription widget:

diff --git a/docs/en/modules/cms-kit-pro/page-feedback.md b/docs/en/modules/cms-kit-pro/page-feedback.md
index d25059ae9b..6648f8ae2e 100644
--- a/docs/en/modules/cms-kit-pro/page-feedback.md
+++ b/docs/en/modules/cms-kit-pro/page-feedback.md
@@ -1,6 +1,6 @@
# Page Feedback System
-The CMS kit provides a **Page Feedback** system to collect feedback from users about pages.
+The CMS Kit provides a **Page Feedback** system to collect feedback from users about pages.
|  | |
| --- | --- |
diff --git a/docs/en/modules/cms-kit-pro/poll.md b/docs/en/modules/cms-kit-pro/poll.md
index 7fedb36c58..4c04ce62c7 100644
--- a/docs/en/modules/cms-kit-pro/poll.md
+++ b/docs/en/modules/cms-kit-pro/poll.md
@@ -1,6 +1,6 @@
# Poll System
-CMS kit provides a **poll** system to allow users to create, edit and delete polls. Here is a screenshot of the poll widget:
+CMS Kit provides a **poll** system to allow users to create, edit and delete polls. Here is a screenshot of the poll widget:

diff --git a/docs/en/modules/cms-kit-pro/url-forwarding.md b/docs/en/modules/cms-kit-pro/url-forwarding.md
index 6f65dee540..7cae786d0f 100644
--- a/docs/en/modules/cms-kit-pro/url-forwarding.md
+++ b/docs/en/modules/cms-kit-pro/url-forwarding.md
@@ -1,6 +1,6 @@
# URL Forwarding System
-CMS kit provides a **URL forwarding** system to create URLs that redirect to other pages or external websites.
+CMS Kit provides a **URL forwarding** system to create URLs that redirect to other pages or external websites.
## Enabling the URL Forwarding System
diff --git a/docs/en/modules/cms-kit/comments.md b/docs/en/modules/cms-kit/comments.md
index 9bfc35c1f4..0a3a093957 100644
--- a/docs/en/modules/cms-kit/comments.md
+++ b/docs/en/modules/cms-kit/comments.md
@@ -1,6 +1,6 @@
# CMS Kit: Comments
-CMS kit provides a **comment** system to add the comment feature to any kind of resource, like blog posts, products, etc.
+CMS Kit provides a **comment** system to add the comment feature to any kind of resource, like blog posts, products, etc.
## Enabling the Comment Feature
diff --git a/docs/en/modules/cms-kit/dynamic-widget.md b/docs/en/modules/cms-kit/dynamic-widget.md
index 9603c68153..54a8d63b57 100644
--- a/docs/en/modules/cms-kit/dynamic-widget.md
+++ b/docs/en/modules/cms-kit/dynamic-widget.md
@@ -1,6 +1,6 @@
# Dynamic Widget
-CMS kit provides a dynamic [widget](../../framework/ui/mvc-razor-pages/widgets.md) 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.
+CMS Kit provides a dynamic [widget](../../framework/ui/mvc-razor-pages/widgets.md) 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 blog post contents.
diff --git a/docs/en/modules/cms-kit/ratings.md b/docs/en/modules/cms-kit/ratings.md
index 2e33c203d7..42ecec4b33 100644
--- a/docs/en/modules/cms-kit/ratings.md
+++ b/docs/en/modules/cms-kit/ratings.md
@@ -1,6 +1,6 @@
# Rating System
-CMS kit provides a **rating** system to to add ratings feature to any kind of resource like blog posts, comments, etc. Here how the rating component looks like on a sample page:
+CMS Kit provides a **rating** system to to add ratings feature to any kind of resource like blog posts, comments, etc. Here how the rating component looks like on a sample page:

diff --git a/docs/en/modules/cms-kit/reactions.md b/docs/en/modules/cms-kit/reactions.md
index e5adfc12d3..40855b1615 100644
--- a/docs/en/modules/cms-kit/reactions.md
+++ b/docs/en/modules/cms-kit/reactions.md
@@ -1,6 +1,6 @@
# Reaction System
-CMS kit provides a **reaction** system to add reactions feature to any kind of resource, like blog posts or comments.
+CMS Kit provides a **reaction** system to add reactions feature to any kind of resource, like blog posts or comments.
Reaction component allows users to react to your content via pre-defined icons/emojis. Here how the reactions component may looks like:
diff --git a/docs/en/modules/cms-kit/tags.md b/docs/en/modules/cms-kit/tags.md
index d08c6749a9..076379482e 100644
--- a/docs/en/modules/cms-kit/tags.md
+++ b/docs/en/modules/cms-kit/tags.md
@@ -1,6 +1,6 @@
# Tag Management
-CMS kit provides a **tag** system to tag any kind of resources, like a blog post.
+CMS Kit provides a **tag** system to tag any kind of resources, like a blog post.
## Enabling the Tag Management Feature
diff --git a/docs/en/modules/file-management.md b/docs/en/modules/file-management.md
index ed5e4c3274..fd2a339b7f 100644
--- a/docs/en/modules/file-management.md
+++ b/docs/en/modules/file-management.md
@@ -1,4 +1,6 @@
-# File Management Module
+# File Management Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
This module is used to upload, download and organize files in a hierarchical folder structure. It is also compatible to multi-tenancy and you can determine total size limit for your tenants.
diff --git a/docs/en/modules/forms.md b/docs/en/modules/forms.md
index 8f09bdfd08..b00cf41208 100644
--- a/docs/en/modules/forms.md
+++ b/docs/en/modules/forms.md
@@ -1,4 +1,6 @@
-# Forms Module
+# Forms Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
This module allows you to create questionnaires to gather information. The forms module can store responses as they come in and you can export the data to a CSV file. You can share your form with others with your form unique link. You can request authentication or allow anonymous reply. It is similar to the Google Form application. Usage area is quite wide, you can create surveys, manage event registrations, collect email addresses for a newsletter, create a quiz, and even receive an order request.
diff --git a/docs/en/modules/gdpr.md b/docs/en/modules/gdpr.md
index b837bad3ff..b2cd0b5547 100644
--- a/docs/en/modules/gdpr.md
+++ b/docs/en/modules/gdpr.md
@@ -1,4 +1,6 @@
-# GDPR Module
+# GDPR Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
This module allows users to download and delete their personal data collected by the application.
diff --git a/docs/en/modules/identity-pro.md b/docs/en/modules/identity-pro.md
index 8d4b8a0ced..8a9974bc70 100644
--- a/docs/en/modules/identity-pro.md
+++ b/docs/en/modules/identity-pro.md
@@ -1,4 +1,6 @@
-# Identity module
+# Identity Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
This module implements the User and Role system of an application;
diff --git a/docs/en/modules/identity-server-pro.md b/docs/en/modules/identity-server-pro.md
index 346dcae7db..fc45dc7634 100644
--- a/docs/en/modules/identity-server-pro.md
+++ b/docs/en/modules/identity-server-pro.md
@@ -1,4 +1,6 @@
-# Identity Server Module
+# Identity Server Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
This module provides integration and management functionality for Identity Server;
diff --git a/docs/en/modules/identity/idap.md b/docs/en/modules/identity/idap.md
index 3c983efbce..7079f726c8 100644
--- a/docs/en/modules/identity/idap.md
+++ b/docs/en/modules/identity/idap.md
@@ -1,4 +1,4 @@
-# LDAP External login Provider
+# LDAP External Login Provider
## Introduction
diff --git a/docs/en/modules/language-management.md b/docs/en/modules/language-management.md
index a545f83d79..6187dc034e 100644
--- a/docs/en/modules/language-management.md
+++ b/docs/en/modules/language-management.md
@@ -1,4 +1,6 @@
-# Language Management Module
+# Language Management Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
This module implements the Language management system of an application;
diff --git a/docs/en/modules/openiddict-pro.md b/docs/en/modules/openiddict-pro.md
index 45a5ecc4ff..607690b134 100644
--- a/docs/en/modules/openiddict-pro.md
+++ b/docs/en/modules/openiddict-pro.md
@@ -1,4 +1,6 @@
-# OpenIddict Module
+# OpenIddict Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
This module provides integration and management functionality for the OpenIddict library;
diff --git a/docs/en/modules/payment-custom-gateway.md b/docs/en/modules/payment-custom-gateway.md
index 782f74b013..f98a1f4846 100644
--- a/docs/en/modules/payment-custom-gateway.md
+++ b/docs/en/modules/payment-custom-gateway.md
@@ -1,7 +1,9 @@
# Creating a Custom Payment Gateway
+
This document explains creating custom a payment gateway that's different than the existing ones in the [Payment Module](payment#packages).
## Creating Core Operations
+
- Create **MyPaymentGateway.cs** and implement `IPaymentGateway`
```csharp
diff --git a/docs/en/modules/payment.md b/docs/en/modules/payment.md
index d8cfe59f88..29b05cb7b6 100644
--- a/docs/en/modules/payment.md
+++ b/docs/en/modules/payment.md
@@ -1,4 +1,6 @@
-# Payment module
+# Payment Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
Payment module implements payment gateway integration of an application. It provides one time payment and recurring payment options.
diff --git a/docs/en/modules/saas.md b/docs/en/modules/saas.md
index 967278c734..3c5992195f 100644
--- a/docs/en/modules/saas.md
+++ b/docs/en/modules/saas.md
@@ -1,4 +1,6 @@
-# SaaS module
+# SaaS Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
This module is used to manage your tenants and editions in multi-tenant applications;
diff --git a/docs/en/modules/text-template-management.md b/docs/en/modules/text-template-management.md
index 8a04f560dc..22ce8b95e2 100644
--- a/docs/en/modules/text-template-management.md
+++ b/docs/en/modules/text-template-management.md
@@ -1,4 +1,6 @@
-# Text Template Management Module
+# Text Template Management Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
This module is used to store and edit template contents for [the text templating system](https://docs.abp.io/en/abp/latest/Text-Templating) of the ABP. So, you may need to understand it to better understand the purpose of this module.
diff --git a/docs/en/modules/twilio-sms.md b/docs/en/modules/twilio-sms.md
index 1a85685699..73871f9626 100644
--- a/docs/en/modules/twilio-sms.md
+++ b/docs/en/modules/twilio-sms.md
@@ -1,4 +1,6 @@
-# Twilio SMS Module
+# Twilio SMS Module (Pro)
+
+> You must have an ABP Team or a higher license to use this module.
[Twilio](https://www.twilio.com) is a cloud communication provider that makes it easy to send and receive SMS. ABP Twilio SMS module implements the SMS sending feature of `ISmsSender` interface with Twilio.
diff --git a/docs/en/solution-templates/microservice/authentication.md b/docs/en/solution-templates/microservice/authentication.md
index 08045ca6e6..94cbcacf20 100644
--- a/docs/en/solution-templates/microservice/authentication.md
+++ b/docs/en/solution-templates/microservice/authentication.md
@@ -1,3 +1,31 @@
# Microservice Solution: Authentication
-*TODO*
\ No newline at end of file
+The [microservice solution template](index.md) is fully configured for authentication. All the services and applications are configured to use the [OpenIddict](https://documentation.openiddict.com) library for authentication and authorization. They are configured in a common way for authentication. This document explains that common authentication structure.
+
+## OpenIddict
+
+[OpenIddict](https://documentation.openiddict.com) is an open-source library that provides a simple and easy way to implement an OpenID Connect server in your application. ABP has built-in modules ([OpenIddict](../../modules/openiddict.md), [OpenIddict UI](../../modules/openiddict-pro.md)) to integrate OpenIddict into the solution.
+
+## Identity Service
+
+The microservice solution template has the [identity](microservices.md#identity-microservice) service that is responsible for the OpenIddict definitions (Applications, Scopes, etc.). Also, it provides the *OpenIddictDataSeeder* class to seed the initial data. It creates the default clients(applications) and scopes for the solution. Each microservice has its own scope and the web applications use these scopes to get access to the microservices, so when you add a new microservice, you should add a new scope and add the allowed scopes for related clients(applications).
+
+The [OpenIddict UI](../../modules/openiddict-pro.md) module gonna be added to the identity service only if you choose the OpenIddict UI module while creating the solution.
+
+
+
+The OpenIddict UI module provides a user interface to manage the OpenIddict entities such as applications, scopes, etc. You can manage these entities from application.
+
+
+
+## Authentication Server
+
+The solution has an authentication server(auth-server) application to provide the token generation, validation and login page. Additionally, it adds the [account](../../modules/account-pro.md) module to the auth-server application to provide the such as register, forgot password and etc features.
+
+Also, the [account](../../modules/account-pro.md) module provides the [social logins](../../modules/account-pro.md#social--external-logins) (Google, Facebook, etc.) feature. You can enable/disable and configure the social logins from the application UI.
+
+
+
+## Authentication Flow
+
+The applications use several flows to authenticate users based on the application type. The MVC UI web application uses the [hybrid flow](https://openid.net/specs/openid-connect-core-1_0.html#HybridFlowAuth) (OpenID Connect Authentication) to authenticate users, while the SPA and Swagger applications use the [authorization code flow](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth) to authenticate users. After the user logs into the system and receives the token from the authentication server, the applications (microservices) use [JWT Bearer Authentication](https://jwt.io/introduction/) to authorize users.
diff --git a/docs/en/solution-templates/microservice/database-configurations.md b/docs/en/solution-templates/microservice/database-configurations.md
index 21604b305f..9e25480c1a 100644
--- a/docs/en/solution-templates/microservice/database-configurations.md
+++ b/docs/en/solution-templates/microservice/database-configurations.md
@@ -71,7 +71,7 @@ Let's examine that class. The first important thing is the `ConnectionStringName
[ConnectionStringName(DatabaseName)]
````
-[The `ConnectionStringName` attribute](https://docs.abp.io/en/abp/latest/Connection-Strings#set-the-connection-string-name) defines the unique name of the connection string that is being used by that `DbContext` class. It matches with the connection string defined in the `appsettings.json` file. That name is also used in database migrations to distinguish different database schemas, and used as the key while storing tenant connection strings for a multi-tenant system. So, each physically separate database should have a unique connection string / database name as here.
+[The `ConnectionStringName` attribute](../../framework/fundamentals/connection-strings.md#set-the-connection-string-name) defines the unique name of the connection string that is being used by that `DbContext` class. It matches with the connection string defined in the `appsettings.json` file. That name is also used in database migrations to distinguish different database schemas, and used as the key while storing tenant connection strings for a multi-tenant system. So, each physically separate database should have a unique connection string / database name as here.
The `DatabaseName` constant is defined in the `DbContext` class:
@@ -88,7 +88,7 @@ The second important part of that class is the `ReplaceDbContext` attribute's us
)]
````
-The Identity microservice utilizes the [Identity](../../modules/identity.md) and [OpenIddict](../../modules/openiddict.md) modules and creates a single database that contains these modules' database schemas. These modules define their own `DbContext` class normally. But [the `ReplaceDbContext` attribute](https://docs.abp.io/en/abp/8.0/Entity-Framework-Core#replace-other-dbcontextes) tells to ABP to use this (`IdentityServiceDbContext`) `DbContext` class instead of the `DbContext` classes defined by these modules. Technically, it replaces the given `DbContext` classes on runtime. We are doing that to ensure that we have a single (merged) database schema, single database migration path and a single database transaction operation when we work these multiple modules. When we replace a `DbContext`, we should implement its interface as done with the `IdentityServiceDbContext` class:
+The Identity microservice utilizes the [Identity](../../modules/identity.md) and [OpenIddict](../../modules/openiddict.md) modules and creates a single database that contains these modules' database schemas. These modules define their own `DbContext` class normally. But [the `ReplaceDbContext` attribute](../../framework/data/entity-framework-core/index.md#replace-other-dbcontextes) tells to ABP to use this (`IdentityServiceDbContext`) `DbContext` class instead of the `DbContext` classes defined by these modules. Technically, it replaces the given `DbContext` classes on runtime. We are doing that to ensure that we have a single (merged) database schema, single database migration path and a single database transaction operation when we work these multiple modules. When we replace a `DbContext`, we should implement its interface as done with the `IdentityServiceDbContext` class:
````csharp
public class IdentityServiceDbContext :
@@ -188,7 +188,7 @@ There are two important points in that class:
### The AbpDbConnectionOptions Configuration
-Every microservice (and the other applications that touches to a database) configures the `AbpDbConnectionOptions` [options class](https://docs.abp.io/en/abp/latest/Options). It is typically done in a method (named `ConfigureDatabase`) defined in the service's (or application's) [module class](https://docs.abp.io/en/abp/latest/Module-Development-Basics). For example, the Identity microservices has a `CloudCrmIdentityServiceModule` class that defines a `ConfigureDatabase` method:
+Every microservice (and the other applications that touches to a database) configures the `AbpDbConnectionOptions` [options class](../../framework/fundamentals/options.md). It is typically done in a method (named `ConfigureDatabase`) defined in the service's (or application's) [module class](../../framework/architecture/modularity/basics.md). For example, the Identity microservices has a `CloudCrmIdentityServiceModule` class that defines a `ConfigureDatabase` method:
````csharp
private void ConfigureDatabase(ServiceConfigurationContext context)
@@ -236,7 +236,7 @@ Configure(options =>
});
````
-That configuration basically defines the different databases that is accessed by that service/application and defines [the mapping](https://docs.abp.io/en/abp/latest/Connection-Strings#configuring-the-database-structures) between module database schemas to physical databases.
+That configuration basically defines the different databases that is accessed by that service/application and defines [the mapping](../../framework/fundamentals/connection-strings.md#configuring-the-database-structures) between module database schemas to physical databases.
For example, Permission Management, Feature Management, Setting Management and the Language Management modules will use the `Administration` database, because we have merged that modules into the Administration microservice - we don't wanted to create separate services and databases for them.
@@ -271,7 +271,7 @@ We are basically setting the SQL Server as the default DBMS for this service (or
### Registering the `DbContext` Class
-Finally, the `ConfigureDatabase` method registers `IdentityServiceDbContext` class to the [dependency injection](https://docs.abp.io/en/abp/latest/Dependency-Injection) system and configures it:
+Finally, the `ConfigureDatabase` method registers `IdentityServiceDbContext` class to the [dependency injection](../../framework/fundamentals/dependency-injection.md) system and configures it:
````csharp
context.Services.AddAbpDbContext(options =>
@@ -280,7 +280,7 @@ context.Services.AddAbpDbContext(options =>
});
````
-`AddDefaultRepositories` is used to register the default [repository](https://docs.abp.io/en/abp/latest/Best-Practices/Repositories) implementations for all the aggregate root [entities](https://docs.abp.io/en/abp/latest/Best-Practices/Entities).
+`AddDefaultRepositories` is used to register the default [repository](../../framework/architecture/best-practices/repositories.md) implementations for all the aggregate root [entities](../../framework/architecture/best-practices/entities.md).
## Database Migrations
@@ -290,7 +290,7 @@ For example, if you have added a new field to a database table, you should also
Managing the schema changes manually is not a good practice and error-prone in a highly dynamic system like a microservice solution. The Microservice solution template uses [Entity Framework migrations](https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/) to maintain the database schema and automatically migrate it whenever you deploy a new version of your service/application.
-In addition to the schema changes, you may also need to insert some initial (seed) data to some tables in order to make your server properly works. That process is called as [data seeding](https://docs.abp.io/en/abp/latest/Data-Seeding). The Microservice solution is also configured so it can seed such initial data on the application startup.
+In addition to the schema changes, you may also need to insert some initial (seed) data to some tables in order to make your server properly works. That process is called as [data seeding](../../framework/infrastructure/data-seeding.md). The Microservice solution is also configured so it can seed such initial data on the application startup.
> If you are using **MongoDB** as your database provider, the schema migration is not needed (But you should care about some kind of data and schema migrations in case of you made a breaking change on your database schema - this is something depends on your application, so you should understand how to work with a document database like MongoDB). However, the data seeding system is still used to insert initial data to the database.
@@ -337,7 +337,7 @@ Here, we are just overriding the `SeedAsync` method that runs just after the dat
Let's explain how `EfCoreRuntimeDatabaseMigratorBase` behaves:
* First of all, **it re-tries the migration operation** in case of any failure. It tries 3 times in total, then re-throws the exception and causes the application crash. Since Kubernetes (or ABP Studio [solution runner](../../studio/running-applications.md)) will re-start it on crash, it will continue to try until it succeed. Temporary failures are especially expected if the database server is not ready when the service starts. It waits a random value between 5 and 15 seconds before the next try.
-* It uses a [distributed lock](https://docs.abp.io/en/abp/latest/Distributed-Locking) to ensure that the migration operation is performed only by one service instance in a time. This is especially important if you run multiple instances of your service, which is usual in a microservice system. It uses a unique distributed key name based on the `DatabaseName` property, so different databases can be migrated in parallel.
+* It uses a [distributed lock](../../framework/infrastructure/distributed-locking.md) to ensure that the migration operation is performed only by one service instance in a time. This is especially important if you run multiple instances of your service, which is usual in a microservice system. It uses a unique distributed key name based on the `DatabaseName` property, so different databases can be migrated in parallel.
* It uses Entity Framework's API to get a list of pending migrations and migrates the database if there were pending migrations.
* It then seeds the database by calling the virtual `SeedAsync` method. Remember that we have overridden that method to seed the initial data for the identity microservice.
* Finally, if a database schema migration has applied, it publishes a distributed event, `AppliedDatabaseMigrationsEto`, with the `DatabaseName`. This event is then used by the [SaaS module](../../modules/saas.md) to trigger migration of tenant databases in a multi-tenant system. See the *Database Migrations for Tenants* section in this document.
@@ -371,7 +371,7 @@ As explained above, `EfCoreRuntimeDatabaseMigratorBase` publishes a distributed
For all that events, we need to migrate the related database for the tenant (the migration system creates the initial database if it doesn't exists). The migration logic is like that:
-* Switches to the related tenant context using the [`ICurrentTenant.Change` method](https://docs.abp.io/en/abp/latest/Multi-Tenancy#change-the-current-tenant).
+* Switches to the related tenant context using the [`ICurrentTenant.Change` method](../../framework/architecture/multi-tenancy/index.md#change-the-current-tenant).
* If the given tenant has a dedicated connection string for the current microservice, it migrates the database schema and seeds the initial data.
* In case a failure, it re-tries a maximum of 3 times by waiting a random duration between 5 and 15 seconds. It does that by ignoring the error and re-publishing the event that is handled.
diff --git a/docs/en/solution-templates/microservice/images/account-external-provider.png b/docs/en/solution-templates/microservice/images/account-external-provider.png
new file mode 100644
index 0000000000..03db9688d6
Binary files /dev/null and b/docs/en/solution-templates/microservice/images/account-external-provider.png differ
diff --git a/docs/en/solution-templates/microservice/images/grafana-dashboard.png b/docs/en/solution-templates/microservice/images/grafana-dashboard.png
new file mode 100644
index 0000000000..74c9a95171
Binary files /dev/null and b/docs/en/solution-templates/microservice/images/grafana-dashboard.png differ
diff --git a/docs/en/solution-templates/microservice/images/new-solution-openiddict-module.png b/docs/en/solution-templates/microservice/images/new-solution-openiddict-module.png
new file mode 100644
index 0000000000..c10beb765d
Binary files /dev/null and b/docs/en/solution-templates/microservice/images/new-solution-openiddict-module.png differ
diff --git a/docs/en/solution-templates/microservice/images/openiddict-ui.png b/docs/en/solution-templates/microservice/images/openiddict-ui.png
new file mode 100644
index 0000000000..398eefda01
Binary files /dev/null and b/docs/en/solution-templates/microservice/images/openiddict-ui.png differ
diff --git a/docs/en/solution-templates/microservice/index.md b/docs/en/solution-templates/microservice/index.md
index b391dc3418..e83846cf46 100644
--- a/docs/en/solution-templates/microservice/index.md
+++ b/docs/en/solution-templates/microservice/index.md
@@ -21,7 +21,7 @@ ABP Studio provides pre-architected and production-ready templates to jump start
* [Authentication](authentication.md)
* [Database configurations](database-configurations.md)
* [Logging (with Serilog and Elasticsearch)](logging.md)
- * Monitoring (with Prometheus and Grafana)
+ * [Monitoring (with Prometheus and Grafana)](monitoring.md)
* Swagger integration
* Permission management
* Feature management
diff --git a/docs/en/solution-templates/microservice/logging.md b/docs/en/solution-templates/microservice/logging.md
index c45bf965bc..8fe25f4b46 100644
--- a/docs/en/solution-templates/microservice/logging.md
+++ b/docs/en/solution-templates/microservice/logging.md
@@ -1,6 +1,6 @@
# Microservice Solution: Logging
-The ABP Studio [microservice solution template](index.md) is fully configured for [logging](https://docs.abp.io/en/abp/latest/Logging). All the services, applications and gateways are configured to use the [Serilog](https://serilog.net/) library for structured logging. They are configured in a common way for logging. This document explains that common logging structure.
+The ABP Studio [microservice solution template](index.md) is fully configured for [logging](../../framework/fundamentals/logging.md). All the services, applications and gateways are configured to use the [Serilog](https://serilog.net/) library for structured logging. They are configured in a common way for logging. This document explains that common logging structure.
## The Serilog Sinks
@@ -21,6 +21,6 @@ The `Program.cs` file is the main point that configures the logging system. It i
You can easily understand the Serilog configuration when you check your `Program.cs`. However, there are a few things worth mentioning here:
-* We are adding an `Application` property to every log record, so you can filter logs by the application name. It is done in the `Program.cs` file with the `.Enrich.WithProperty("Application", applicationName)` line. The `applicationName` value is taken from [the `IApplicationInfoAccessor` service](https://docs.abp.io/en/abp/8.0/Application-Startup#the-applicationname-option) of ABP. By default, it is the name of the entrance assembly (that contains the `Program.cs` file) of the application.
-* We are using ABP Serilog Enrichers in the module class of the application. It is done by the `app.UseAbpSerilogEnrichers();` line in the `OnApplicationInitialization` method of your module class. That ASP.NET Core middleware adds current [tenant](https://docs.abp.io/en/abp/latest/Multi-Tenancy), [user](https://docs.abp.io/en/abp/latest/CurrentUser), client and correlation id information to the log records.
+* We are adding an `Application` property to every log record, so you can filter logs by the application name. It is done in the `Program.cs` file with the `.Enrich.WithProperty("Application", applicationName)` line. The `applicationName` value is taken from [the `IApplicationInfoAccessor` service](../../framework/fundamentals/application-startup.md#the-applicationname-option) of ABP. By default, it is the name of the entrance assembly (that contains the `Program.cs` file) of the application.
+* We are using ABP Serilog Enrichers in the module class of the application. It is done by the `app.UseAbpSerilogEnrichers();` line in the `OnApplicationInitialization` method of your module class. That ASP.NET Core middleware adds current [tenant](../../framework/architecture/multi-tenancy/index.md), [user](../../framework/infrastructure/current-user.md), client and correlation id information to the log records.
diff --git a/docs/en/solution-templates/microservice/microservices.md b/docs/en/solution-templates/microservice/microservices.md
index da28a3d85f..a5bd56f924 100644
--- a/docs/en/solution-templates/microservice/microservices.md
+++ b/docs/en/solution-templates/microservice/microservices.md
@@ -43,9 +43,9 @@ The following figure shows the Administration microservice's module structure in

-Administration service is basically used to to manage **permissions** (using the [Permission Management](https://docs.abp.io/en/abp/latest/Modules/Permission-Management) module), **features** (using the [Feature Management](https://docs.abp.io/en/abp/latest/Modules/Feature-Management) module), **settings** (using the [Setting Management](https://docs.abp.io/en/abp/latest/Modules/Setting-Management) module) and **languages** (using the [Language Management](../../modules/language-management.md) module) (maybe some others based on your preferences) of the system. These are the common infrastructure services that are used by all the services and applications in the solution. Administration service is responsible to serve management HTTP APIs to UI for these services, and it also maintains the database schema for them.
+Administration service is basically used to to manage **permissions** (using the [Permission Management](../../modules/permission-management.md) module), **features** (using the [Feature Management](../../modules/feature-management.md) module), **settings** (using the [Setting Management](../../modules/setting-management.md) module) and **languages** (using the [Language Management](../../modules/language-management.md) module) (maybe some others based on your preferences) of the system. These are the common infrastructure services that are used by all the services and applications in the solution. Administration service is responsible to serve management HTTP APIs to UI for these services, and it also maintains the database schema for them.
-In addition to these fundamental infrastructure services, Administration service also creates the [BLOB Storing database](https://docs.abp.io/en/abp/latest/Blob-Storing-Database), so other services can easily store BLOBs.
+In addition to these fundamental infrastructure services, Administration service also creates the [BLOB Storing database](../../framework/infrastructure/blob-storing/database.md), so other services can easily store BLOBs.
### Identity Microservice
@@ -63,7 +63,7 @@ If you've selected the [SaaS](../../modules/saas.md) module while [creating your
This microservice serves the [SaaS](../../modules/saas.md) module's HTTP API, creates and manages its database.
-> [Multi-Tenancy](https://docs.abp.io/en/abp/latest/Multi-Tenancy) is a common feature of the solution. If you install the SaaS module, multi-tenancy is automatically enabled for all the services and applications in the solution and the necessary configurations are done for you.
+> [Multi-Tenancy](../../framework/architecture/multi-tenancy/index.md) is a common feature of the solution. If you install the SaaS module, multi-tenancy is automatically enabled for all the services and applications in the solution and the necessary configurations are done for you.
### Audit Logging Microservice (optional)
diff --git a/docs/en/solution-templates/microservice/monitoring.md b/docs/en/solution-templates/microservice/monitoring.md
new file mode 100644
index 0000000000..4fa4a99448
--- /dev/null
+++ b/docs/en/solution-templates/microservice/monitoring.md
@@ -0,0 +1,62 @@
+# Microservice Solution: Monitoring
+
+In a distributed system it is important to monitor the health of the system and the services. Monitoring helps to detect issues before they become problems and helps to understand the system's behavior. All the services, applications and gateways are configured to use the [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/) libraries for monitoring. They are configured in a common way for monitoring. This document explains that common monitoring structure.
+
+## Configuration
+
+The monitoring configuration is done in the each *Module* class of the project. The `OnApplicationInitialization` method of the module class is used to set the monitoring system. We're adding the `prometheus-net.AspNetCore` package to the project to use Prometheus. The `prometheus-net.AspNetCore` package is a library that provides a middleware to expose metrics for Prometheus. The `app.UseHttpMetrics();` line is collect the HTTP request metrics. The `endpoints.MapMetrics();` line is used to expose the metrics to the `/metrics` endpoint. Existing templates includes the prometheus and grafana configurations in the `docker-compose` file. So, you can visit the `http://localhost:9090` to see the [Prometheus](https://prometheus.io/) dashboard and `http://localhost:3001` to see the [Grafana](https://grafana.com/) dashboard.
+
+> Default username and password for Grafana is `admin` and `admin`. You can change the password after the first login.
+
+After you login to the Grafana dashboard, you can add a new data source to connect to the Prometheus server and create a new dashboard to monitor the system.
+
+
+
+## Custom Metrics
+
+To create custom metrics, you can use the [IMeterFactory](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.metrics.imeterfactory) interface. Basically, you can follow the steps in the [official documentation](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/metrics-instrumentation) to create custom metrics. For example, you can create a custom metric to monitor the number of requests to a specific endpoint.
+
+```csharp
+public class AdministrationMetrics : ISingletonDependency
+{
+ private readonly Counter _demoRequested;
+
+ public AdministrationMetrics(IMeterFactory meterFactory)
+ {
+ var meter = meterFactory.Create("Microservice.Administration");
+ _demoRequested = meter.CreateCounter("demo_controller.requested");
+ }
+
+ public void DemoRequested()
+ {
+ _demoRequested.Add(1);
+ }
+}
+```
+
+In the demo controller, you can inject the `AdministrationMetrics` class and use the `DemoRequested` method to increase the counter.
+
+```csharp
+[Route("api/administration/demo")]
+public class DemoController : AbpController
+{
+ public AdministrationMetrics AdministrationMetrics { get; }
+
+ public DemoController(AdministrationMetrics administrationMetrics)
+ {
+ AdministrationMetrics = administrationMetrics;
+ }
+
+ [HttpGet]
+ [Route("requested")]
+ public Task DemoRequested()
+ {
+ AdministrationMetrics.DemoRequested();
+ return Task.CompletedTask;
+ }
+}
+```
+
+## Kubernetes Monitoring
+
+If you check the *Kubernetes Configuration* option during project creation, the monitoring system is automatically configured for Kubernetes. The `prometheus` and `grafana` configurations are added to the `helm` chart.
\ No newline at end of file
diff --git a/docs/en/solution-templates/microservice/overview.md b/docs/en/solution-templates/microservice/overview.md
index a025c2b2c0..a9b7998754 100644
--- a/docs/en/solution-templates/microservice/overview.md
+++ b/docs/en/solution-templates/microservice/overview.md
@@ -10,13 +10,13 @@ In this document, you will learn what the Microservice solution template offers
All the following **libraries and services** are **pre-installed** and **configured** for both of **development** and **production** environments. After creating your solution, you can **change** to **remove** most of them.
-* **[Autofac](https://autofac.org/)** for [Dependency Injection](https://docs.abp.io/en/abp/latest/Dependency-Injection)
-* **[Serilog](https://serilog.net/)** with File, Console and Elasticsearch [logging](https://docs.abp.io/en/abp/latest/Logging) providers
+* **[Autofac](https://autofac.org/)** for [Dependency Injection](../../framework/fundamentals/dependency-injection.md)
+* **[Serilog](https://serilog.net/)** with File, Console and Elasticsearch [logging](../../framework/fundamentals/logging.md) providers
* **[Prometheus](https://prometheus.io/)** for collecting metrics
* **[Grafana](https://grafana.com/)** to visualize the collected metrics
-* **[Redis](https://redis.io/)** for [distributed caching](https://docs.abp.io/en/abp/latest/Caching) and [distributed locking](https://docs.abp.io/en/abp/latest/Distributed-Locking)
+* **[Redis](https://redis.io/)** for [distributed caching](../../framework/fundamentals/caching.md) and [distributed locking](../../framework/infrastructure/distributed-locking.md)
* **[Swagger](https://swagger.io/)** to explore and test HTTP APIs
-* **[RabbitMQ](https://www.rabbitmq.com/)** as the [distributed event bus](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus)
+* **[RabbitMQ](https://www.rabbitmq.com/)** as the [distributed event bus](../../framework/infrastructure/event-bus/distributed/index.md)
* **[YARP](https://microsoft.github.io/reverse-proxy/)** to implement the API Gateways
* **[OpenIddict](https://github.com/openiddict/openiddict-core)** as the in-house authentication server.
@@ -29,14 +29,14 @@ The following features are built and pre-configured for you in the solution.
* **OpenId Connect Authentication**, if you have selected the MVC UI.
* **Authorization code flow** is implemented, if you have selected a SPA UI (Angular or Blazor WASM).
* Other flows (resource owner password, client credentials...) are easy to use when you need them.
-* **[Permission](https://docs.abp.io/en/abp/latest/Authorization)** (authorization), **[setting](https://docs.abp.io/en/abp/latest/Settings)**, **[feature](https://docs.abp.io/en/abp/latest/Features)** and the **[localization](https://docs.abp.io/en/abp/latest/Localization)** management systems are pre-configured and ready to use.
-* **[Background job system](https://docs.abp.io/en/abp/latest/Background-Jobs)** with [RabbitMQ integrated](https://docs.abp.io/en/abp/latest/Background-Jobs-RabbitMq).
-* **[BLOB storge](https://docs.abp.io/en/abp/latest/Blob-Storing)** system is installed with the [database provider](https://docs.abp.io/en/abp/latest/Blob-Storing-Database) and a separate database.
+* **[Permission](../../framework/fundamentals/authorization.md)** (authorization), **[setting](../../framework/fundamentals/settings.md)**, **[feature](../../framework/infrastructure/features.md)** and the **[localization](../../framework/fundamentals/localization.md)** management systems are pre-configured and ready to use.
+* **[Background job system](../../framework/infrastructure/background-jobs/index.md)** with [RabbitMQ integrated](../../framework/infrastructure/background-jobs/rabbitmq.md).
+* **[BLOB storge](../../framework/infrastructure/blob-storing/index.md)** system is installed with the [database provider](../../framework/infrastructure/blob-storing/database.md) and a separate database.
* **On-the-fly database migration** system (services automatically migrated their database schema when you deploy a new version)
* Infrastructure dependencies are configured via **[docker-compose](https://docs.docker.com/compose/)** for running the solution in local environment.
* **[Helm](https://helm.sh/)** charts are included to deploy the solution to **[Kubernetes](https://kubernetes.io/)**.
* **[Swagger](https://swagger.io/)** authentication is configured to test the authorized HTTP APIs.
-* Configured the **[Inbox & Outbox patterns](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus#outbox-inbox-for-transactional-events)** for [distributed event bus](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus).
+* Configured the **[Inbox & Outbox patterns](../../framework/infrastructure/event-bus/distributed/index.md#outbox--inbox-for-transactional-events)** for [distributed event bus](../../framework/infrastructure/event-bus/distributed/index.md).
## Fundamental Modules
@@ -44,9 +44,9 @@ The following modules are pre-installed and configured for the solution:
* **[Account](../../modules/account.md)** to authenticate users (login, register, two factor auth, etc)
* **[Identity](../../modules/identity.md)** to manage roles and users
-* **[OpenIddict](https://docs.abp.io/en/abp/latest/Modules/OpenIddict)** (the core part) to implement the OAuth authentication flows
+* **[OpenIddict](../../modules/openiddict.md)** (the core part) to implement the OAuth authentication flows
-In addition these, [Feature Management](https://docs.abp.io/en/abp/latest/Modules/Feature-Management), [Permission Management](https://docs.abp.io/en/abp/latest/Modules/Permission-Management) and [Setting Management](https://docs.abp.io/en/abp/latest/Modules/Setting-Management) modules are pre-installed as they are the fundamental feature modules of the ABP.
+In addition these, [Feature Management](../../modules/feature-management.md), [Permission Management](../../modules/permission-management.md) and [Setting Management](../../modules/setting-management.md) modules are pre-installed as they are the fundamental feature modules of the ABP.
## Optional Modules
@@ -71,8 +71,8 @@ Microservice startup template asks for some preferences while creating your solu
There are two database provider options are provided on a new microservice solution creation:
-* **[Entity Framework Core](https://docs.abp.io/en/abp/latest/Entity-Framework-Core)** with SQL Server, MySQL and PostgreSQL DBMS options. You can [switch to anther DBMS](https://docs.abp.io/en/abp/latest/Entity-Framework-Core-Other-DBMS) manually after creating your solution.
-* **[MongoDB](https://docs.abp.io/en/abp/latest/MongoDB)**
+* **[Entity Framework Core](../../framework/data/entity-framework-core/index.md)** with SQL Server, MySQL and PostgreSQL DBMS options. You can [switch to anther DBMS](../../framework/data/entity-framework-core/other-dbms.md) manually after creating your solution.
+* **[MongoDB](../../framework/data/mongodb/index.md)**
### UI Frameworks
@@ -95,7 +95,7 @@ If you prefer, the solution includes a mobile application with its dedicated API
### Multi-Tenancy & SaaS Module
-The **[SaaS module](../../modules/saas.md)** is included as an option. When you select it, the **[multi-tenancy](https://docs.abp.io/en/abp/latest/Multi-Tenancy)** system is automatically configured. Otherwise, the system will not include any multi-tenancy overhead.
+The **[SaaS module](../../modules/saas.md)** is included as an option. When you select it, the **[multi-tenancy](../../framework/architecture/multi-tenancy/index.md)** system is automatically configured. Otherwise, the system will not include any multi-tenancy overhead.
## Next
diff --git a/docs/en/solution-templates/microservice/solution-structure.md b/docs/en/solution-templates/microservice/solution-structure.md
index 74d4a3e24d..ddd9b3faf6 100644
--- a/docs/en/solution-templates/microservice/solution-structure.md
+++ b/docs/en/solution-templates/microservice/solution-structure.md
@@ -37,7 +37,7 @@ The folder structure basically matches to the solution in ABP Studio's *Solution
* `k8s` folder contains some additional files to setup *Kubernetes Dashboard* on your local machine.
* `gateways` folder contains one or more API Gateways (the count depends on if you've selected mobile application or other applications if available). This solution implements the [BFF](https://learn.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontends) (Backend for frontend pattern), that means it has a dedicated API Gateway for each different UI application.
* `services` folder contains the microservices. The microservice count varies based on the options you've selected during the solution creation. However, the following microservices are always included:
- * `adminstration` microservice is used to manage permissions, languages and other fundamental settings of the system.
+ * `administration` microservice is used to manage permissions, languages and other fundamental settings of the system.
* `identity` microservice is used to manage users, roles and their permissions. It basically serves to the [Identity](../../modules/identity.md) module's UI (and [OpenIddict](../../modules/openiddict.md) module's UI, if selected).
## Next
diff --git a/docs/en/studio/cli.md b/docs/en/studio/cli.md
deleted file mode 100644
index 1d730c743d..0000000000
--- a/docs/en/studio/cli.md
+++ /dev/null
@@ -1,376 +0,0 @@
-# ABP Studio CLI
-
-ABP Studio CLI is a command line tool that extends [ABP CLI](../cli) by adding more commands to perform operations of ABP Studio features.
-
-## Installation
-
-ABP Studio CLI is installed automatically when you install ABP Studio.
-
-## Commands
-
-As ABP Studio CLI extends [ABP CLI](../cli), all commands provided by [ABP CLI](../cli) is also valid for ABP Studio CLI. Here, is the list of additional commands before explaining their details:
-
-* new-solution: Generates a new solution based on the ABP Studio [startup templates](../solution-templates).
-* new-module: Generates a new module based on the given template.
-* new-package: Generates a new package based on the given template.
-* add-package-ref: Adds package to given project.
-* add-source: Downloads the source code and replaces package references with project references.
-* init-solution: Creates ABP Studio configuration files for a given solution.
-* install-local-module: Installs a local module to given module.
-* install-module: Installs a module to given module via NuGet packages.
-* upgrade: Upgrades solution with Pro modules
-* kube-connect: Connects to kubernetes environment.
-* kube-intercept: Intercepts a service running in Kubernetes environment.
-
-### new-solution
-
-Generates a new solution based on the ABP Studio [startup templates](../solution-templates).
-
-````bash
-abpc new-solution [options]
-````
-
-Example:
-
-````bash
-abpc new-solution Acme.BookStore
-````
-
-* `Acme.BookStore` is the solution name here.
-* Common convention is to name a solution is like *YourCompany.YourProject*. However, you can use different naming like *YourProject* (single level namespacing) or *YourCompany.YourProduct.YourModule* (three levels namespacing).
-
-#### options
-
-* `--template` or `-t`: Specifies the template name. Default template name is `empty`, which generates a empty solution. Available templates:
- * **`empty`**: Empty solution template.
- * **`app-pro`**: Application template. Additional options:
- * `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks:
- * `mvc`: ASP.NET Core MVC. There are some additional options for this template:
- * `--tiered`: Creates a tiered solution where Web and Http API layers are physically separated. If not specified, it creates a layered solution which is less complex and suitable for most scenarios.
- * `angular`: Angular UI. There are some additional options for this template:
- * `--separate-auth-server`: The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side.
- * `--pwa`: Specifies the project as Progressive Web Application.
- * `blazor`: Blazor UI. There are some additional options for this template:
- * `--separate-auth-server`The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side.
- * `--pwa`: Specifies the project as Progressive Web Application.
- * `blazor-server`: Blazor Server UI. There are some additional options for this template:
- * `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project.
- * `maui-blazor`: Blazor Maui UI. There are some additional options for this template:
- * `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project.
- * `no-ui`: Without UI. No front-end layer will be created. There are some additional options for this template:
- * `--separate-auth-server`: The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side.
- * `--mobile` or `-m`: Specifies the mobile application framework. Default value is `react-native`. Available frameworks:
- * `none`: Without any mobile application.
- * `react-native`: React Native.
- * `maui`: MAUI.
- * `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
- * `ef`: Entity Framework Core.
- * `mongodb`: MongoDB.
- * `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](../framework/data/entity-framework-core/other-dbms.md) (after creating the solution).
- * `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
- * `leptonx`: LeptonX Theme.
- * `basic`: Basic Theme.
-
- * **`app-nolayers-pro`**: Single-layer application template. Additional options:
- * `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks:
- * `mvc`: ASP.NET Core MVC. There are some additional options for this template:
- * `angular`: Angular UI. There are some additional options for this template:
- * `blazor`: Blazor UI. There are some additional options for this template:
- * `blazor-server`: Blazor Server UI. There are some additional options for this template:
- * `no-ui`: Without UI. No front-end layer will be created. There are some additional options for this template:
- * `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
- * `ef`: Entity Framework Core.
- * `mongodb`: MongoDB.
- * `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](../framework/data/entity-framework-core/other-dbms.md) (after creating the solution).
- * `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
- * `leptonx`: LeptonX Theme.
- * `basic`: Basic Theme.
-
- * **`microservice-pro`**: Microservice solution template. Additional options:
- * `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks:
- * `mvc`: ASP.NET Core MVC. There are some additional options for this template:
- * `angular`: Angular UI. There are some additional options for this template:
- * `blazor`: Blazor UI. There are some additional options for this template:
- * `blazor-server`: Blazor Server UI. There are some additional options for this template:
- * `maui-blazor`: Blazor Maui UI. There are some additional options for this template:
- * `no-ui`: Without UI. No front-end layer will be created. There are some additional options for this template:
- * `--mobile` or `-m`: Specifies the mobile application framework. Default value is `react-native`. Available frameworks:
- * `none`: Without any mobile application.
- * `react-native`: React Native.
- * `maui`: MAUI.
- * `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
- * `ef`: Entity Framework Core.
- * `mongodb`: MongoDB.
- * `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
- * `leptonx`: LeptonX Theme.
- * `basic`: Basic Theme.
-* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
-* `--database-management-system` or `-dbms`: Sets the database management system. Default is **SQL Server**. Supported DBMS's:
- * `SqlServer`
- * `MySQL`
- * `PostgreSQL`
- * `SQLite` (`app-pro` & `app-nolayers-pro`)
- * `Oracle` (`app-pro` & `app-nolayers-pro`)
- * `Oracle-Devart` (`app-pro` & `app-nolayers-pro`)
-* `--dont-run-install-libs`: Skip installing client side packages.
-* `--dont-run-bundling`: Skip bundling for Blazor packages.
-* `--no-kubernetes-configuration` or `-nkc`: Skips the Kubernetes configuration files.
-* *Module Options*: You can skip some modules if you don't want to add them to your solution. Available commands:
- * `-no-saas`: Skips the Saas module.
- * `-no-gdpr`: Skips the GDPR module.
- * `-no-openiddict-admin-ui`: Skips the OpenIddict Admin UI module.
- * `-no-audit-logging`: Skips the Audit Logging module.
- * `-no-file-management`: Skips the File Management module.
- * `-no-language-management`: Skips the Language Management module.
- * `-no-text-template-management`: Skips the Text Template Management module.
- * `-no-chat`: Skips the Chat module.
-### new-module
-
-Generates a new module.
-
-````bash
-abpc new-module [options]
-````
-
-Example:
-
-````bash
-abpc new-module Acme.BookStore -t module:ddd
-````
-
-#### options
-
-* `--template` or `-t`: Specifies the template name. Default template name is `empty`, which generates a empty module. Module templates are provided by the main template, see their own startup template documentation for available modules. `empty` and `module:ddd` template is available for all solution structure.
-* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
-* `--target-solution` or `-ts`: If set, the new module will be added to the given solution. Otherwise the new module will added to the closest solution in the file system. If no solution found, it will throw an error.
-* `--solution-folder` or `-sf`: Specifies the target folder in the [Solution Explorer](./solution-explorer.md#folder) virtual folder system.
-* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. This option is only available if the module template supports it. You can add multiple values separated by commas, such as `ef, mongodb` if the module template supports it. Available providers:
- * `ef`: Entity Framework Core.
- * `mongodb`: MongoDB.
-* `--ui-framework` or `-u`: Specifies the UI framework. Default framework is `mvc`. This option is only available if the module template supports it. You can add multiple values separated by commas, such as `mvc,angular` if the module template supports it. Available frameworks:
- * `mvc`: ASP.NET Core MVC.
- * `angular`: Angular UI.
- * `blazor`: Blazor UI.
- * `blazor-server`: Blazor Server UI.
-
-### new-package
-
-Generates a new package.
-
-````bash
-abpc new-package [options]
-````
-
-Example:
-
-````bash
-abpc new-package --name Acme.BookStore.Domain --template lib.domain
-````
-
-#### options
-
-* `--template` or `-t`: Specifies the template name. This parameter doesn't have a default value and must be set. Available templates and their sub-options:
- * `lib.class-library`
- * `lib.domain-shared`
- * `lib.domain`
- * `lib.application-contracts`
- * `lib.application`
- * `--with-automapper`: Adds automapper configuration.
- * `lib.ef`
- * `--include-migrations`: Allows migration operations on this package.
- * `--connection-string-name`: Default value is the last part of the package's namespace (or package name simply).
- * `--connection-string`: Connection string value. Defaut value is null. You can set it alter.
- * `lib.mongodb`
- * `lib.http-api`
- * `lib.http-api-client`
- * `lib.mvc`
- * `lib.blazor`
- * `lib.blazor-wasm`
- * `lib.blazor-server`
- * `host.http-api`
- * `--with-serilog`: Includes Serilog configuration.
- * `--with-swagger`: Includes Swagger configuration.
- * `host.mvc`
- * `--with-serilog`: Includes Serilog configuration.
- * `--with-swagger`: Includes Swagger configuration.
- * `host.blazor-wasm`
- * `--backend`: Name of the backend project in the module (not path).
- * `host.blazor-server`
- * `csharp.console`
- * `csharp.library`
-* `--module-file` or `-m`: If set, the new package will be added to the given module. Otherwise the new package will added to the closest module in the file system. If no module found, it will throw an error.
-* `--name` or `-n`: Specifies the name of the package. If not set, a name based on the template type and module name will be generated.
-* `--folder` or `-f`: Specifies the target folder in the target module's virtual folder system.
-
-
-### add-package-ref
-
-Adds one or more package reference to target project, also adds ABP module dependency. Both reference and target projects must belong to same module.
-
-````bash
-abpc add-package-ref [options]
-````
-
-Example:
-
-````bash
-abpc add-package-ref Acme.BookStore.Domain
-abpc add-package-ref "Acme.BookStore.Domain Acme.BookStore.Domain.Shared" -t Acme.BookStore.Web
-````
-
-#### options
-
-* `--target-project` or `-t`: Name of the project that reference will be added. If not set, project in the current directory will be used.
-
-### add-source
-
-Downloads the source code of a module and replaces package references with project references. This command only works if your ABP License has source-code access, or if source-code of the target module is free to all type of ABP Licenses.
-
-````bash
-abpc add-source [options]
-````
-
-Example:
-
-````bash
-abpc add-source Volo.Chat --add-to-solution-file
-````
-
-#### options
-
-* `--target-module` or `-t`: The module that will refer the downloaded source code. If not set, the module in the current directory will be used.
-* `--add-to-solution-file`: Adds the downloaded source code to C# solution file and ABP Studio solution file.
-
-### init-solution
-
-Creates necessary files for a solution to be readable by ABP Studio. If the solution is generated via ABP Studio, you don't need this command. But it is not generated by ABP Studio, you need this command to make it work with ABP Studio.
-
-````bash
-abpc init-solution [options]
-````
-
-Example:
-
-````bash
-abpc init-solution --name Acme.BookStore
-````
-
-#### options
-
-* `--name` or `-n`: Name for the solution. If not set, it will be the same as the name of closest c# solution in the file system.
-
-### install-local-module
-
-Installs one module to another. Project relations are created according the types of the projects. For example: a `lib.domain-shared` project is added to `lib.domain-shared` project
-
-````bash
-abpc install-local-module [options]
-````
-
-Example:
-
-````bash
-abpc install-local-module Acme.OrderManagement
-
-abpc install-local-module Acme.OrderManagement -t "modules/crm/Acme.Crm.abpmdl"
-````
-
-#### options
-
-* `--target-module` or `-t`: Path (or folder path) of the target module that the other module will be installed to. If not set, the closest module to the current directory will be used.
-
-### install-module
-
-Installs a module, that is published as nuget packages, to a local module. Project relations are created according the types of the projects. For example: a `lib.domain-shared` project is added to `lib.domain-shared` project
-
-````bash
-abpc install-module [options]
-````
-
-Example:
-
-````bash
-abpc install-module Volo.Blogging
-
-abpc install-module Volo.Blogging -t "modules/crm/Acme.Crm.abpmdl"
-````
-
-#### options
-
-* `--target-module` or `-t`: Path (or folder path) of the target module that the other module will be installed to. If not set, the closest module to the current directory will be used.
-* `--version` or `-v`: Nuget version of the module to be installed.
-
-### upgrade
-
-Upgrades the solution with Pro modules. Especially designed for users who already started their development before having a license. Therefore this command requires license. For more info, see the related document.
-
-````bash
-abpc upgrade [options]
-````
-
-Example:
-
-````bash
-abpc upgrade -t app
-
-abpc upgrade -t app-nolayers
-````
-
-#### options
-
-* `--template` or `-t`: The template type of the solution. Only `app` and `app-nolayers` are valid currently.
-
-### kube-connect
-
-Connects to Kubernetes cluster. Press `ctrl+c` to disconnect.
-
-````bash
-abpc kube-connect [options]
-````
-
-Example:
-
-````bash
-abpc kube-connect
-
-abpc kube-connect -p Default.abpk8s.json
-
-abpc kube-connect -c docker-desktop -ns mycrm-local
-````
-
-#### options
-
-* `--profile` or `-p`: Kubernetes Profile path or name to be used. Path can be relative (to current directory) or full path, or you can simply give the name of profile if you run this command in same directory with the solution or profile. This parameter is not needed if you use `--namespace` and `--context` parameters.
-* `--namespace` or `-ns`: The namespace that services running on.
-* `--context` or `-c`: The context that services running in.
-* `--wireguard-password` or `-wp`: Wireguard password for the profile. This is not needed if you already set it on the ABP Studio user interface.
-* `--solution-id` or `-si`: Id of the solution. If not set, the closest solution in file system will be used.
-
-### kube-intercept
-
-Intercepts a service running in Kubernetes environment. Press `ctrl+c` to stop interception.
-
-````bash
-abpc kube-intercept [options]
-````
-
-Example:
-
-````bash
-abpc kube-intercept mycrm-product-service -ns mycrm-local
-
-abpc kube-intercept mycrm-product-service -ns mycrm-local -a MyCrm.ProductService.HttpApi.Host.csproj
-
-abpc kube-intercept mycrm-product-service -ns mycrm-local -a MyCrm.ProductService.HttpApi.Host.csproj -pm 8080:80,8081:443
-````
-
-#### options
-
-* `--application` or `-a`: Relative or full path of the project that will intercept the service. If not set, the project in the current directory will be used.
-* `--namespace` or `-ns`: The namespace that service running on.
-* `--context` or `-sc`: The context that service running in. Default value is `docker-desktop`.
-* `--port-mappings` or `-pm`: Port mappings for the service.
-
-## See Also
-
-* [ABP CLI](../cli)
diff --git a/docs/en/studio/images/preference-theme-change.png b/docs/en/studio/images/preference-theme-change.png
index 8e2dc109b9..e1d5d95532 100644
Binary files a/docs/en/studio/images/preference-theme-change.png and b/docs/en/studio/images/preference-theme-change.png differ
diff --git a/docs/en/studio/index.md b/docs/en/studio/index.md
index 6965a50a04..a44b768cdd 100644
--- a/docs/en/studio/index.md
+++ b/docs/en/studio/index.md
@@ -16,5 +16,4 @@ If you haven't installed yet, please see [the installation guide](installation.m
- Fundamentals
- [Solution Explorer](./solution-explorer.md)
- [Running Applications](./running-applications.md)
- - [Working with Kubernetes](./kubernetes.md)
- - [CLI](./cli.md)
\ No newline at end of file
+ - [Working with Kubernetes](./kubernetes.md)
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs
index 81f3357bfb..d7c47c8aee 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs
@@ -31,24 +31,11 @@ public class ClientProxyExceptionEventHandler : ILocalEventHandler>();
-
if (!options.Value.IsBlazorWebApp)
{
- var navigationManager = scope.ServiceProvider.GetRequiredService();
- var accessTokenProvider = scope.ServiceProvider.GetRequiredService();
var authenticationOptions = scope.ServiceProvider.GetRequiredService>();
- var result = await accessTokenProvider.RequestAccessToken();
- if (result.Status != AccessTokenResultStatus.Success)
- {
- navigationManager.NavigateToLogout(authenticationOptions.Value.LogoutUrl);
- return;
- }
-
- result.TryGetToken(out var token);
- if (token != null && DateTimeOffset.Now >= token.Expires.AddMinutes(-5))
- {
- navigationManager.NavigateToLogout(authenticationOptions.Value.LogoutUrl);
- }
+ var navigationManager = scope.ServiceProvider.GetRequiredService();
+ navigationManager.NavigateToLogout(authenticationOptions.Value.LogoutUrl, "/");
}
else
{
diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
index 593992aed4..730fe98533 100644
--- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
@@ -102,6 +102,7 @@ public static class AbpApplicationBuilderExtensions
return app.UseMiddleware();
}
+ [Obsolete("Replace with AbpClaimsTransformation")]
public static IApplicationBuilder UseAbpClaimsMap(this IApplicationBuilder app)
{
return app.UseMiddleware();
diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs
index bda87a4e32..c6f8dd7ddc 100644
--- a/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs
@@ -1,6 +1,7 @@
-using System.Linq;
+using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
+using Volo.Abp.AspNetCore.Security.Claims;
namespace Microsoft.Extensions.DependencyInjection;
@@ -20,4 +21,9 @@ public static class AbpAspNetCoreServiceCollectionExtensions
return hostingEnvironment;
}
+
+ public static IServiceCollection TransformAbpClaims(this IServiceCollection services)
+ {
+ return services.AddTransient();
+ }
}
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs
index bb2bedf901..2104edab0a 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs
@@ -1,4 +1,5 @@
-using System.Linq;
+using System;
+using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
@@ -10,6 +11,7 @@ using Volo.Abp.Security.Claims;
namespace Volo.Abp.AspNetCore.Security.Claims;
+[Obsolete("Replace with AbpClaimsTransformation")]
public class AbpClaimsMapMiddleware : AbpMiddlewareBase, ITransientDependency
{
public async override Task InvokeAsync(HttpContext context, RequestDelegate next)
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsTransformation.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsTransformation.cs
new file mode 100644
index 0000000000..17e8f0d599
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsTransformation.cs
@@ -0,0 +1,35 @@
+using System.Linq;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.Extensions.Options;
+
+namespace Volo.Abp.AspNetCore.Security.Claims;
+
+public class AbpClaimsTransformation : IClaimsTransformation
+{
+ protected IOptions AbpClaimsMapOptions { get; }
+
+ public AbpClaimsTransformation(IOptions abpClaimsMapOptions)
+ {
+ AbpClaimsMapOptions = abpClaimsMapOptions;
+ }
+
+ public virtual Task TransformAsync(ClaimsPrincipal principal)
+ {
+ var mapClaims = principal.Claims.Where(claim => AbpClaimsMapOptions.Value.Maps.Keys.Contains(claim.Type));
+
+ principal.AddIdentity(new ClaimsIdentity(mapClaims.Select(
+ claim => new Claim(
+ AbpClaimsMapOptions.Value.Maps[claim.Type](),
+ claim.Value,
+ claim.ValueType,
+ claim.Issuer
+ )
+ )
+ )
+ );
+
+ return Task.FromResult(principal);
+ }
+}
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs
index 7795493fea..ecbc0d2e9c 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs
@@ -107,9 +107,15 @@ public class BundlingService : IBundlingService, ITransientDependency
if (!bundleConfig.InteractiveAuto)
{
var fileName = bundleConfig.IsBlazorWebApp
- ? Directory.GetFiles(Path.GetDirectoryName(projectFilePath)!.Replace(".Client", ""), "App.razor", SearchOption.AllDirectories).FirstOrDefault()
+ ? Directory.GetFiles(Path.GetDirectoryName(projectFilePath)!.Replace(".Client", ""), "App.razor", SearchOption.AllDirectories).FirstOrDefault() ??
+ Directory.GetFiles(Path.GetDirectoryName(projectFilePath)!.Replace(".Blazor", ".Host"), "App.razor", SearchOption.AllDirectories).FirstOrDefault()
: Path.Combine(PathHelper.GetWwwRootPath(directory), "index.html");
+ if (fileName == null)
+ {
+ throw new BundlingException($"App.razor file could not be found in the {projectFilePath} directory.");
+ }
+
await UpdateDependenciesInBlazorFileAsync(fileName, styleDefinitions, scriptDefinitions);
Logger.LogInformation($"Script and style references in the {fileName} file have been updated.");
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeThemeStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeThemeStep.cs
index e29ee96a1d..450434d219 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeThemeStep.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeThemeStep.cs
@@ -702,7 +702,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
context,
$"_Host.cshtml",
$"{defaultThemeName}Theme.Components",
- Basic
+ "BasicTheme.Themes.Basic"
);
ReplaceAllKeywords(
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs
index 3f9c605f64..027403d226 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs
@@ -73,9 +73,10 @@ public class AbpAspNetCoreMvcTestModule : AbpModule
context.Services.AddAuthentication(options =>
{
+ options.DefaultAuthenticateScheme = FakeAuthenticationSchemeDefaults.Scheme;
options.DefaultChallengeScheme = "Bearer";
options.DefaultForbidScheme = "Cookie";
- }).AddCookie("Cookie").AddJwtBearer("Bearer", _ => { });
+ }).AddFakeAuthentication().AddCookie("Cookie").AddJwtBearer("Bearer", _ => { });
context.Services.AddAuthorization(options =>
{
@@ -137,6 +138,8 @@ public class AbpAspNetCoreMvcTestModule : AbpModule
{
options.Contributors.Add(new TestApplicationConfigurationContributor());
});
+
+ context.Services.TransformAbpClaims();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
@@ -148,8 +151,6 @@ public class AbpAspNetCoreMvcTestModule : AbpModule
app.UseAbpRequestLocalization();
app.UseAbpSecurityHeaders();
app.UseRouting();
- app.UseMiddleware();
- app.UseAbpClaimsMap();
app.UseAuthentication();
app.UseAuthorization();
app.UseAuditing();
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs
index a3cd4a57e6..886e22f1dd 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
@@ -8,6 +9,7 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc;
+[Obsolete("Use FakeAuthenticationScheme instead.")]
public class FakeAuthenticationMiddleware : AbpMiddlewareBase, ITransientDependency
{
private readonly FakeUserClaims _fakeUserClaims;
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationScheme.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationScheme.cs
new file mode 100644
index 0000000000..641bbe03d7
--- /dev/null
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationScheme.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Security.Claims;
+using System.Text.Encodings.Web;
+using System.Threading.Tasks;
+using DeviceDetectorNET;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace Volo.Abp.AspNetCore.Mvc;
+
+public static class FakeAuthenticationSchemeDefaults
+{
+ public static string Scheme => "FakeAuthenticationScheme";
+}
+
+public static class FakeAuthenticationBuilderExtensions
+{
+ public static AuthenticationBuilder AddFakeAuthentication(this AuthenticationBuilder builder)
+ {
+ return builder.AddScheme(FakeAuthenticationSchemeDefaults.Scheme, _ => { });
+ }
+}
+
+public class FakeAuthenticationOptions : AuthenticationSchemeOptions
+{
+
+}
+
+public class FakeAuthenticationHandler : AuthenticationHandler
+{
+ private readonly FakeUserClaims _fakeUserClaims;
+
+ [Obsolete]
+ public FakeAuthenticationHandler(
+ IOptionsMonitor options,
+ ILoggerFactory logger,
+ UrlEncoder encoder,
+ ISystemClock clock,
+ FakeUserClaims fakeUserClaims) : base(options, logger, encoder, clock)
+ {
+ _fakeUserClaims = fakeUserClaims;
+ }
+
+ public FakeAuthenticationHandler(
+ IOptionsMonitor options,
+ ILoggerFactory logger,
+ UrlEncoder encoder,
+ FakeUserClaims fakeUserClaims)
+ : base(options, logger, encoder)
+ {
+ _fakeUserClaims = fakeUserClaims;
+ }
+
+ protected override Task HandleAuthenticateAsync()
+ {
+ if (_fakeUserClaims.Claims.Any())
+ {
+ return Task.FromResult(AuthenticateResult.Success(
+ new AuthenticationTicket(
+ new ClaimsPrincipal(new ClaimsIdentity(_fakeUserClaims.Claims,
+ FakeAuthenticationSchemeDefaults.Scheme)),
+ FakeAuthenticationSchemeDefaults.Scheme)));
+ }
+
+ return Task.FromResult(AuthenticateResult.NoResult());
+ }
+}
diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/wwwroot/themes/basic/layout.js b/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/wwwroot/themes/basic/layout.js
index d87045c85e..7a85ffc172 100644
--- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/wwwroot/themes/basic/layout.js
+++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/wwwroot/themes/basic/layout.js
@@ -1,5 +1,7 @@
$(function () {
$('.dropdown-menu a.dropdown-toggle').on('click', function (e) {
+ $(this).next().toggleClass('show');
+
if (!$(this).next().hasClass('show')) {
$(this).parents('.dropdown-menu').first().find('.show').removeClass("show");
}
diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html
index 59d50a40ec..e9b08947e9 100644
--- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html
+++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html
@@ -17,7 +17,7 @@
*ngTemplateOutlet="actionsTemplate || gridActions; context: { $implicit: row, index: i }"
>
- @if (hasAvailableActions(i, row)) {
+ @if (hasAvailableActions(row)) {
}
diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts
index a99ba37907..80321d4ef0 100644
--- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts
+++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts
@@ -206,12 +206,20 @@ export class ExtensibleTableComponent implements OnChanges {
});
}
- hasAvailableActions(index, data): boolean {
- const { permission, visible } = this.actionList.get(index)?.value || {};
- let isActionAvailable = this.permissionService.getGrantedPolicy(permission);
- if (data && data.record) {
- isActionAvailable &&= visible(data);
- }
+ hasAvailableActions(rowData): boolean {
+ let isActionAvailable = true;
+ this.actionList.toArray().map(action => {
+ const { visible, permission } = action;
+ if (rowData && action) {
+ const visibilityCheck = visible({
+ record: rowData,
+ getInjected: this.getInjected,
+ });
+ const permissionCheck = this.permissionService.getGrantedPolicy(permission);
+
+ isActionAvailable = visibilityCheck && permissionCheck;
+ }
+ });
return isActionAvailable;
}
}
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/Components/Routes.razor b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/Components/Routes.razor
index 2dd023ed6a..fff90cbc35 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/Components/Routes.razor
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/Components/Routes.razor
@@ -9,6 +9,5 @@
-
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Components/Routes.razor b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Components/Routes.razor
index 2dd023ed6a..fff90cbc35 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Components/Routes.razor
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Components/Routes.razor
@@ -9,6 +9,5 @@
-
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Client/Routes.razor b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Client/Routes.razor
index c0cc7d4c6a..12cf8988f1 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Client/Routes.razor
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Client/Routes.razor
@@ -7,6 +7,5 @@
-
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Client/Routes.razor b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Client/Routes.razor
index 518ab7c055..455a0ffcb7 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Client/Routes.razor
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Client/Routes.razor
@@ -7,6 +7,5 @@
-
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Components/Routes.razor b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Components/Routes.razor
index 22d300af6c..d2b6a9be7b 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Components/Routes.razor
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Components/Routes.razor
@@ -9,6 +9,5 @@
-
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Components/Routes.razor b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Components/Routes.razor
index 22d300af6c..d2b6a9be7b 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Components/Routes.razor
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Components/Routes.razor
@@ -9,6 +9,5 @@
-
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Client/Routes.razor b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Client/Routes.razor
index 22d300af6c..d2b6a9be7b 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Client/Routes.razor
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Client/Routes.razor
@@ -9,6 +9,5 @@
-
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client/Routes.razor b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client/Routes.razor
index 22d300af6c..d2b6a9be7b 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client/Routes.razor
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client/Routes.razor
@@ -9,6 +9,5 @@
-
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host.Client/Routes.razor b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host.Client/Routes.razor
index b5c63c6839..d7cc3acec7 100644
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host.Client/Routes.razor
+++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host.Client/Routes.razor
@@ -7,6 +7,5 @@
-
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Components/Routes.razor b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Components/Routes.razor
index 3103d0a2b8..b2251911fa 100644
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Components/Routes.razor
+++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Components/Routes.razor
@@ -9,6 +9,5 @@
-