mirror of https://github.com/abpframework/abp.git
477 changed files with 43676 additions and 1741 deletions
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
@ -0,0 +1,138 @@ |
|||||
|
# Auto API Controllers |
||||
|
|
||||
|
Once you create an [application service](Application-Services.md), you generally want to create an API controller to expose this service as an HTTP (REST) API endpoint. A typical API controller does nothing but redirects method calls to the application service and configures the REST API using attributes like [HttpGet], [HttpPost], [Route]... etc. |
||||
|
|
||||
|
ABP can **automagically** configures your application services as MVC API Controllers by convention. Most of time you don't care about its detailed configuration, but it's possible fully customize it. |
||||
|
|
||||
|
## Configuration |
||||
|
|
||||
|
Basic configuration is simple. Just configure `AbpAspNetCoreMvcOptions` and use `ConventionalControllers.Create` method as shown below: |
||||
|
|
||||
|
````csharp |
||||
|
[DependsOn(BookStoreApplicationModule)] |
||||
|
public class BookStoreWebModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<AbpAspNetCoreMvcOptions>(options => |
||||
|
{ |
||||
|
options.ConventionalControllers.Create(typeof(BookStoreApplicationModule).Assembly); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
This example code configures all the application services in the assembly containing the class `BookStoreApplicationModule`. The figure below shows the resulting API on the [Swagger UI](https://swagger.io/tools/swagger-ui/). |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### Examples |
||||
|
|
||||
|
Some example method names and the corresponding routes calculated by convention: |
||||
|
|
||||
|
| Service Method Name | HTTP Method | Route | |
||||
|
| ----------------------------------------------------- | ----------- | -------------------------- | |
||||
|
| GetAsync(Guid id) | GET | /api/app/book/{id} | |
||||
|
| GetListAsync() | GET | /api/app/book | |
||||
|
| CreateAsync(CreateBookDto input) | POST | /api/app/book | |
||||
|
| UpdateAsync(Guid id, UpdateBookDto input) | PUT | /api/app/book/{id} | |
||||
|
| DeleteAsync(Guid id) | DELETE | /api/app/book/{id} | |
||||
|
| GetEditorsAsync(Guid id) | GET | /api/app/book/{id}/editors | |
||||
|
| CreateEditorAsync(Guid id, BookEditorCreateDto input) | POST | /api/app/book/{id}/editor | |
||||
|
|
||||
|
### HTTP Method |
||||
|
|
||||
|
ABP uses a naming convention while determining the HTTP method for a service method (action): |
||||
|
|
||||
|
- **Get**: Used if the method name starts with 'GetList', 'GetAll' or 'Get'. |
||||
|
- **Put**: Used if the method name starts with 'Put' or 'Update'. |
||||
|
- **Delete**: Used if the method name starts with 'Delete' or 'Remove'. |
||||
|
- **Post**: Used if the method name starts with 'Create', 'Add', 'Insert' or 'Post'. |
||||
|
- **Patch**: Used if the method name starts with 'Patch'. |
||||
|
- Otherwise, **Post** is used **by default**. |
||||
|
|
||||
|
If you need to customize HTTP method for a particular method, then you can use one of the standard ASP.NET Core attributes ([HttpPost], [HttpGet], [HttpPut]... etc.). This requires to add [Microsoft.AspNetCore.Mvc.Core](https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.Core) nuget package to your project that contains the service. |
||||
|
|
||||
|
### Route |
||||
|
|
||||
|
Route is calculated based on some conventions: |
||||
|
|
||||
|
* It always starts with '**/api**'. |
||||
|
* Continues with a **route path**. Default value is '**/app**' and can be configured as like below: |
||||
|
|
||||
|
````csharp |
||||
|
Configure<AbpAspNetCoreMvcOptions>(options => |
||||
|
{ |
||||
|
options.ConventionalControllers |
||||
|
.Create(typeof(BookStoreApplicationModule).Assembly, opts => |
||||
|
{ |
||||
|
opts.RootPath = "volosoft/book-store"; |
||||
|
}); |
||||
|
}); |
||||
|
```` |
||||
|
|
||||
|
Then the route for getting a book will be '**/api/volosoft/book-store/book/{id}**'. This sample uses two-level root path, but you generally use a single level depth. |
||||
|
|
||||
|
* Continues with the **normalized controller/service name**. Normalization removes 'AppService', 'ApplicationService' and 'Service' postfixes and converts it to **camelCase**. If your application service class name is 'BookAppService' then it becomes only '/book'. |
||||
|
* If you want to customize naming, then set the `UrlControllerNameNormalizer` option. It's a func delegate which allows you to determine the name per controller/service. |
||||
|
* If the method has an '**id**' parameter then it adds '**/{id}**' ro the route. |
||||
|
* Then it adds the action name if necessary. Action name is obtained from the method name on the service and normalized by; |
||||
|
* Removing '**Async**' postfix. If the method name is 'GetPhonesAsync' then it becomes 'GetPhones'. |
||||
|
* Removing **HTTP method prefix**. 'GetList', 'GetAll', 'Get', 'Put', 'Update', 'Delete', 'Remove', 'Create', 'Add', 'Insert', 'Post' and 'Patch' prefixes are removed based on the selected HTTP method. So, 'GetPhones' becomes 'Phones' since 'Get' prefix is a duplicate for a GET request. |
||||
|
* Converting the result to **camelCase**. |
||||
|
* If the resulting action name is **empty** then it's not added to the route. If it's not empty, it's added to the route (like '/phones'). For 'GetAllAsync' method name it will be empty, for 'GetPhonesAsync' method name is will be 'phones'. |
||||
|
* Normalization can be customized by setting the `UrlActionNameNormalizer` option. It's an action delegate that is called for every method. |
||||
|
* If there is another parameter with 'Id' postfix, then it's also added to the route as the final route segment (like '/phoneId'). |
||||
|
|
||||
|
## Service Selection |
||||
|
|
||||
|
Creating conventional HTTP API controllers are not unique to application services actually. |
||||
|
|
||||
|
### IRemoteService Interface |
||||
|
|
||||
|
If a class implements the `IRemoteService` interface then it's automatically selected to be a conventional API controller. Since application services inherently implement it, they are considered as natural API controllers. |
||||
|
|
||||
|
### RemoteService Attribute |
||||
|
|
||||
|
`RemoteService` attribute can be used to mark a class as a remote service or disable for a particular class that inherently implements the `IRemoteService` interface. Example: |
||||
|
|
||||
|
````csharp |
||||
|
[RemoteService(IsEnabled = false)] //or simply [RemoteService(false)] |
||||
|
public class PersonAppService : ApplicationService |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
### TypePredicate Option |
||||
|
|
||||
|
You can further filter classes to become an API controller by providing the `TypePedicate` option: |
||||
|
|
||||
|
````csharp |
||||
|
services.Configure<AbpAspNetCoreMvcOptions>(options => |
||||
|
{ |
||||
|
options.ConventionalControllers |
||||
|
.Create(typeof(BookStoreApplicationModule).Assembly, opts => |
||||
|
{ |
||||
|
opts.TypePredicate = type => { return true; }; |
||||
|
}); |
||||
|
}); |
||||
|
```` |
||||
|
|
||||
|
Instead of returning `true` for every type, you can check it and return `false` if you don't want to expose this type as an API controller. |
||||
|
|
||||
|
## API Explorer |
||||
|
|
||||
|
API Exploring a service that makes possible to investigate API structure by the clients. Swagger uses it to create a documentation and test UI for an endpoint. |
||||
|
|
||||
|
API Explorer is automatically enabled for conventional HTTP API controllers by default. Use `RemoteService` attribute to control it per class or method level. Example: |
||||
|
|
||||
|
````csharp |
||||
|
[RemoteService(IsMetadataEnabled = false)] |
||||
|
public class PersonAppService : ApplicationService |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
Disabled `IsMetadataEnabled` which hides this service from API explorer and it will not be discoverable. However, it still can be usable for the clients know the exact API path/route. |
||||
@ -0,0 +1,153 @@ |
|||||
|
# Dynamic C# API Clients |
||||
|
|
||||
|
ABP can dynamically create C# API client proxies to call remote HTTP services (REST APIs). In this way, you don't need to deal with `HttpClient` and other low level HTTP features to call remote services and get results. |
||||
|
|
||||
|
## Service Interface |
||||
|
|
||||
|
Your service/controller should implement an interface that is shared between the server and the client. So, first define a service interface in a shared library project. Example: |
||||
|
|
||||
|
````csharp |
||||
|
public interface IBookService : IApplicationService |
||||
|
{ |
||||
|
Task<List<BookDto>> GetListAsync(); |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
Your interface should implement the `IRemoteService` interface. Since the `IApplicationService` inherits the `IRemoteService` interface, the `IBookService` above satisfies this condition. |
||||
|
|
||||
|
Implement this class in your service application. You can use [auto API controller system](Auto-API-Controllers.md) to expose the service as a REST API endpoint. |
||||
|
|
||||
|
## Client Proxy Generation |
||||
|
|
||||
|
First, add [Volo.Abp.Http.Client](https://www.nuget.org/packages/Volo.Abp.Http.Client) nuget package to your client project: |
||||
|
|
||||
|
```` |
||||
|
Install-Package Volo.Abp.Http.Client |
||||
|
```` |
||||
|
|
||||
|
Then add `AbpHttpClientModule` dependency to your module: |
||||
|
|
||||
|
````csharp |
||||
|
[DependsOn(typeof(AbpHttpClientModule))] //add the dependency |
||||
|
public class MyClientAppModule : AbpModule |
||||
|
{ |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
Now, it's ready to create the client proxies. Example: |
||||
|
|
||||
|
````csharp |
||||
|
[DependsOn( |
||||
|
typeof(AbpHttpClientModule), //used to create client proxies |
||||
|
typeof(BookStoreApplicationModule) //contains the application service interfaces |
||||
|
)] |
||||
|
public class MyClientAppModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
//Configure remote end point |
||||
|
context.Services.Configure<RemoteServiceOptions>(options => |
||||
|
{ |
||||
|
options.RemoteServices.Default = |
||||
|
new RemoteServiceConfiguration("http://localhost:53929/"); |
||||
|
}); |
||||
|
|
||||
|
//Create dynamic client proxies |
||||
|
context.Services.AddHttpClientProxies( |
||||
|
typeof(BookStoreApplicationModule).Assembly |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
`RemoteServiceOptions` is used to configure endpoints for remote services (This example sets the default endpoint while you can have different service endpoints used by different clients. See the "Multiple Remote Service Endpoint" section). |
||||
|
|
||||
|
`AddHttpClientProxies` method gets an assembly, finds all service interfaces in the given assembly, creates and registers proxy classes. |
||||
|
|
||||
|
## Usage |
||||
|
|
||||
|
It's straightforward to use. Just inject the service interface in the client application code: |
||||
|
|
||||
|
````csharp |
||||
|
public class MyService : ITransientDependency |
||||
|
{ |
||||
|
private readonly IBookService _bookService; |
||||
|
|
||||
|
public MyService(IBookService bookService) |
||||
|
{ |
||||
|
_bookService = bookService; |
||||
|
} |
||||
|
|
||||
|
public async Task DoIt() |
||||
|
{ |
||||
|
var books = await _bookService.GetListAsync(); |
||||
|
foreach (var book in books) |
||||
|
{ |
||||
|
Console.WriteLine($"[BOOK {book.Id}] Name={book.Name}"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
This sample injects the `IBookService` service interface defined above. The dynamic client proxy implementation makes an HTTP call whenever a service method is called by the client. |
||||
|
|
||||
|
## Configuration Details |
||||
|
|
||||
|
### RemoteServiceOptions |
||||
|
|
||||
|
While you can configure `RemoteServiceOptions` as the example shown above, you can let it to read from your `appsettings.json` file. Add a `RemoteServices` section to your `appsettings.json` file: |
||||
|
|
||||
|
````json |
||||
|
{ |
||||
|
"RemoteServices": { |
||||
|
"Default": { |
||||
|
"BaseUrl": "http://localhost:53929/" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
Then you can pass your `IConfigurationRoot` instance directly to the `Configure<RemoteServiceOptions>()` method as shown below: |
||||
|
|
||||
|
````csharp |
||||
|
var configuration = new ConfigurationBuilder() |
||||
|
.SetBasePath(Directory.GetCurrentDirectory()) |
||||
|
.AddJsonFile("appsettings.json") |
||||
|
.Build(); |
||||
|
|
||||
|
context.Services.Configure<RemoteServiceOptions>(configuration); |
||||
|
```` |
||||
|
|
||||
|
This approach is useful since it's easy to change the configuration later without touching to the code. |
||||
|
|
||||
|
#### Multiple Remote Service Endpoint |
||||
|
|
||||
|
The examples above have configured the "Default" remote service endpoint. You may have different endpoints for different services (as like in a microservice approach where each microservice has different endpoint). In this case, you can add other endpoints to your configuration file: |
||||
|
|
||||
|
````json |
||||
|
{ |
||||
|
"RemoteServices": { |
||||
|
"Default": { |
||||
|
"BaseUrl": "http://localhost:53929/" |
||||
|
}, |
||||
|
"BookStore": { |
||||
|
"BaseUrl": "http://localhost:48392/" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
See the next section to learn how to use this new endpoint. |
||||
|
|
||||
|
### AddHttpClientProxies Method |
||||
|
|
||||
|
`AddHttpClientProxies` method can get an additional parameter for the remote service name. Example: |
||||
|
|
||||
|
````csharp |
||||
|
context.Services.AddHttpClientProxies( |
||||
|
typeof(BookStoreApplicationModule).Assembly, |
||||
|
remoteServiceName: "BookStore" |
||||
|
); |
||||
|
```` |
||||
|
|
||||
|
`remoteServiceName` parameter matches the service endpoint configured via `RemoteServiceOptions`. If the `BookStore` endpoint is not defined then it fallbacks to the `Default` endpoint. |
||||
@ -1,64 +1,30 @@ |
|||||
# ABP Documentation |
# ABP Documentation |
||||
|
|
||||
* Getting Started |
ABP is an **open source application framework** focused on ASP.NET Core based web application development, but also supports developing other types of applications. |
||||
* From Startup Templates |
|
||||
* [ASP.NET Core MVC Template](Getting-Started-AspNetCore-MVC-Template.md) |
Explore the left navigation menu to deep dive in the documentation. |
||||
* From Empty Projects |
|
||||
* [With Console Application](Getting-Started-Console-Application.md) |
## Project Status |
||||
* [With ASP.NET Core Web Application](Getting-Started-AspNetCore-Application.md) |
|
||||
* Tutorials |
ABP is the **next generation** of the open source [ASP.NET Boilerplate](https://aspnetboilerplate.com/) framework. It's currently in early preview stage and not ready to use in production. The documentation is in progress and currently is very incomplete. |
||||
* Application Development |
|
||||
* [With ASP.NET Core MVC](Tutorials/AspNetCore-Mvc/Part-I.md) |
For short-term and production applications, it's suggested to use the [ASP.NET Boilerplate](https://aspnetboilerplate.com/) framework which is feature rich, mature, maintained and up-to-date. |
||||
* Fundamentals |
|
||||
* [Dependency Injection](Dependency-Injection.md) |
## Getting Started |
||||
* [AutoFac Integration](Autofac-Integration.md) |
|
||||
* [Virtual File System](Virtual-File-System.md) |
Easiest way to start a new project with ABP is to use the Startup templates: |
||||
* [Localization](Localization.md) |
|
||||
* [Exception Handling](Exception-Handling.md) |
* [ASP.NET Core MVC Template](Getting-Started-AspNetCore-MVC-Template.md) |
||||
* Validation |
|
||||
* Authorization |
If you want to start from scratch (with an empty project) then manually install the ABP framework, use the following tutorials: |
||||
* Caching |
|
||||
* Auditing |
* [Console Application](Getting-Started-Console-Application.md) |
||||
* Setting Management |
* [ASP.NET Core Web Application](Getting-Started-AspNetCore-Application.md) |
||||
* Object to Object Mapping |
|
||||
* AutoMapper Integration |
## Source Code |
||||
* Events |
|
||||
* Event Bus (local) |
ABP is being developed on GitHub. See [the source code](https://github.com/abpframework/abp). |
||||
* Distributed Event Bus |
|
||||
* RabbitMQ Integration |
## Want to Contribute? |
||||
* Services |
|
||||
* Object Serialization |
ABP is a community-driven open source project. See [the contribution guide](Contribution/Index.md) if you want to be a part of this project. |
||||
* JSON Serialization |
|
||||
* Emailing |
|
||||
* GUIDs |
|
||||
* Threading |
|
||||
* Timing |
|
||||
* [Multi Tenancy](Multi-Tenancy.md) |
|
||||
* Module Development |
|
||||
* [Basics](Module-Development-Basics.md) |
|
||||
* Plug-In Modules |
|
||||
* [Best Practices](Best-Practices/Index.md) |
|
||||
* Domain Driven Design |
|
||||
* Domain Layer |
|
||||
* [Entities & Aggregate Roots](Entities.md) |
|
||||
* Value Objects |
|
||||
* [Repositories](Repositories.md) |
|
||||
* Domain Services |
|
||||
* Specifications |
|
||||
* Application Layer |
|
||||
* Application Services |
|
||||
* Data Transfer Objects |
|
||||
* Unit Of Work |
|
||||
* ASP.NET Core MVC |
|
||||
* API Versioning |
|
||||
* User Interface |
|
||||
* [Client Side Package Management](AspNetCore/Client-Side-Package-Management.md) |
|
||||
* [Bundling & Minification](AspNetCore/Bundling-Minification.md) |
|
||||
* [Tag Helpers](Tag-Helpers.md) |
|
||||
* [Theming](AspNetCore/Theming.md) |
|
||||
* Data Access |
|
||||
* [Entity Framework Core Integration](Entity-Framework-Core.md) |
|
||||
* [MongoDB Integration](MongoDB.md) |
|
||||
* Background |
|
||||
* [Background Jobs](Background-Jobs.md) |
|
||||
* Testing |
|
||||
@ -0,0 +1,475 @@ |
|||||
|
# Docs Module |
||||
|
|
||||
|
## What is Docs Module? |
||||
|
|
||||
|
Docs module is an application module for ABP framework. It simplifies software documentation. This module is free and open-source. |
||||
|
|
||||
|
### Integration |
||||
|
|
||||
|
Currently docs module provides you to store your docs both on GitHub and file system. |
||||
|
|
||||
|
### Hosting |
||||
|
|
||||
|
Docs module is an application module and does not offer any hosting solution. You can host your docs on-premise or on cloud. |
||||
|
|
||||
|
### Versioning |
||||
|
|
||||
|
When you use GitHub to store your docs, Docs Module supports versioning. If you have multiple versions for your docs, there will be a combo-box on the UI to switch between versions. If you choose file system to store your docs, it does not support multiple versions. |
||||
|
|
||||
|
[The documents](https://abp.io/documents/) for ABP framework is also using this module. |
||||
|
|
||||
|
> Docs module follows the [module architecture best practices](../Best-Practices/Module-Architecture.md) guide. |
||||
|
|
||||
|
|
||||
|
|
||||
|
## Installation |
||||
|
|
||||
|
### 1- Download |
||||
|
|
||||
|
If you do not have an existing ABP project, this step shows you how to create a new project from [abp.io](https://abp.io) to add the Docs Module. If you already have an ABP project, you can skip this step. |
||||
|
|
||||
|
Navigate to https://abp.io/Templates. Enter your project name as `Acme.MyProject`, select `ASP.NET Core Mvc Application` and select `Entity Framework Core` for the database provider. |
||||
|
|
||||
|
Note that this document covers `Entity Framework Core` provider but you can also select `MongoDB` as your database provider. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### 2- Running The Empty Application |
||||
|
|
||||
|
After you download the project, extract the ZIP file and open `Acme.MyProject.sln`. You will see that the solution consists of `Application`, `Domain `, `EntityFrameworkCore` and `Web` projects. Right click on `Acme.MyProject.Web` project and **Set as StartUp Project**. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
The database connection string is located in `appsettings.json` of your `Acme.MyProject.Web` project. If you have a different database configuration, change the connection string. |
||||
|
|
||||
|
```json |
||||
|
{ |
||||
|
"ConnectionStrings": { |
||||
|
"Default": "Server=localhost;Database=MyProject;Trusted_Connection=True;MultipleActiveResultSets=true" |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
|
||||
|
Open `Package Manager Console` in the Visual Studio and choose `src\Acme.MyProject.EntityFrameworkCore` as the default project. Run `Update-Database` command to create your new database. The database `MyProject` will be created in your database server. |
||||
|
|
||||
|
Now an empty ABP project has been created! You can now run your project and see the empty website. |
||||
|
|
||||
|
To login your website enter `admin` as the username and `1q2w3E*` as the password. |
||||
|
|
||||
|
### 2- Referencing Docs Module Packages |
||||
|
|
||||
|
Docs module packages are hosted on NuGet. There are 4 packages that needs be to installed to your application. Each package has to be installed to the relevant project. |
||||
|
|
||||
|
* [Volo.Docs.Domain](https://www.nuget.org/packages/Volo.Docs.Domain/) needs to be referenced to `Acme.MyProject.Domain` project. |
||||
|
|
||||
|
* Edit `Acme.MyProject.Domain.csproj`file and add the below line to as a reference. Note that you need to change version (v0.9.0) to the latest. |
||||
|
|
||||
|
```csharp |
||||
|
<PackageReference Include="Volo.Docs.Domain" Version="0.9.0" /> |
||||
|
``` |
||||
|
* [Volo.Docs.EntityFrameworkCore](https://www.nuget.org/packages/Volo.Docs.EntityFrameworkCore/) needs to be referenced to `Acme.MyProject.EntityFrameworkCore` project. |
||||
|
|
||||
|
- Edit `Acme.MyProject.EntityFrameworkCore.csproj`file and add the below line to as a reference. Note that you need to change version (v0.9.0) to the latest. |
||||
|
|
||||
|
```csharp |
||||
|
<PackageReference Include="Volo.Docs.EntityFrameworkCore" Version="0.9.0" /> |
||||
|
``` |
||||
|
* [Volo.Docs.Application](https://www.nuget.org/packages/Volo.Docs.Application/) needs to be referenced to `Acme.MyProject.Application` project. |
||||
|
|
||||
|
* Edit `Acme.MyProject.Application.csproj`file and add the below line to as a reference. Note that you need to change version (v0.9.0) to the latest. |
||||
|
|
||||
|
```csharp |
||||
|
<PackageReference Include="Volo.Docs.Application" Version="0.9.0" /> |
||||
|
``` |
||||
|
* [Volo.Docs.Web ](https://www.nuget.org/packages/Volo.Docs.Web/)needs to be referenced to `Acme.MyProject.Web` project. |
||||
|
|
||||
|
- Edit `Acme.MyProject.Web.csproj`file and add the below line to as a reference. Note that you need to change version (v0.9.0) to the latest. |
||||
|
|
||||
|
```csharp |
||||
|
<PackageReference Include="Volo.Docs.Web" Version="0.9.0" /> |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
|
||||
|
### 3- Adding Module Dependencies |
||||
|
|
||||
|
An ABP module must declare `[DependsOn]` attribute if it has a dependency upon another module. Each module has to be added in`[DependsOn]` attribute to the relevant project. |
||||
|
|
||||
|
* Open `MyProjectDomainModule.cs`and add `typeof(DocsDomainModule)` as shown below; |
||||
|
|
||||
|
```csharp |
||||
|
[DependsOn( |
||||
|
typeof(DocsDomainModule), |
||||
|
typeof(AbpIdentityDomainModule), |
||||
|
typeof(AbpAuditingModule), |
||||
|
typeof(BackgroundJobsDomainModule), |
||||
|
typeof(AbpAuditLoggingDomainModule) |
||||
|
)] |
||||
|
public class MyProjectDomainModule : AbpModule |
||||
|
{ |
||||
|
//... |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
* Open `MyProjectEntityFrameworkCoreModule.cs`and add `typeof(DocsEntityFrameworkCoreModule)` as shown below; |
||||
|
|
||||
|
```csharp |
||||
|
[DependsOn( |
||||
|
typeof(DocsEntityFrameworkCoreModule), |
||||
|
typeof(MyProjectDomainModule), |
||||
|
typeof(AbpIdentityEntityFrameworkCoreModule), |
||||
|
typeof(AbpPermissionManagementEntityFrameworkCoreModule), |
||||
|
typeof(AbpSettingManagementEntityFrameworkCoreModule), |
||||
|
typeof(AbpEntityFrameworkCoreSqlServerModule), |
||||
|
typeof(BackgroundJobsEntityFrameworkCoreModule), |
||||
|
typeof(AbpAuditLoggingEntityFrameworkCoreModule) |
||||
|
)] |
||||
|
public class MyProjectEntityFrameworkCoreModule : AbpModule |
||||
|
{ |
||||
|
//... |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
* Open `MyProjectApplicationModule.cs`and add `typeof(DocsApplicationModule)` as shown below; |
||||
|
|
||||
|
```csharp |
||||
|
[DependsOn( |
||||
|
typeof(DocsApplicationModule), |
||||
|
typeof(MyProjectDomainModule), |
||||
|
typeof(AbpIdentityApplicationModule))] |
||||
|
public class MyProjectApplicationModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<PermissionOptions>(options => |
||||
|
{ |
||||
|
options.DefinitionProviders.Add<MyProjectPermissionDefinitionProvider>(); |
||||
|
}); |
||||
|
|
||||
|
Configure<AbpAutoMapperOptions>(options => |
||||
|
{ |
||||
|
options.AddProfile<MyProjectApplicationAutoMapperProfile>(); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
* Open `MyProjectWebModule.cs`and add `typeof(DocsWebModule)` as shown below; |
||||
|
|
||||
|
```csharp |
||||
|
[DependsOn( |
||||
|
typeof(DocsWebModule), |
||||
|
typeof(MyProjectApplicationModule), |
||||
|
typeof(MyProjectEntityFrameworkCoreModule), |
||||
|
typeof(AbpAutofacModule), |
||||
|
typeof(AbpIdentityWebModule), |
||||
|
typeof(AbpAccountWebModule), |
||||
|
typeof(AbpAspNetCoreMvcUiBasicThemeModule) |
||||
|
)] |
||||
|
public class MyProjectWebModule : AbpModule |
||||
|
{ |
||||
|
//... |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
|
||||
|
### 4- Database Integration |
||||
|
|
||||
|
#### 4.1- Entity Framework Integration |
||||
|
|
||||
|
If you choose Entity Framework as your database provider, you need to configure the Docs Module in your DbContext. To do this; |
||||
|
|
||||
|
- Open `MyProjectDbContext.cs` and add `modelBuilder.ConfigureDocs()` to the `OnModelCreating()` |
||||
|
|
||||
|
```csharp |
||||
|
[ConnectionStringName("Default")] |
||||
|
public class MyProjectDbContext : AbpDbContext<MyProjectDbContext> |
||||
|
{ |
||||
|
public MyProjectDbContext(DbContextOptions<MyProjectDbContext> options) |
||||
|
: base(options) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder) |
||||
|
{ |
||||
|
//... |
||||
|
modelBuilder.ConfigureDocs(); |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
* Open `Package Manager Console` in `Visual Studio` and choose `Acme.MyProject.EntityFrameworkCore` as default project. Then write the below command to add the migration for Docs Module. |
||||
|
|
||||
|
```csharp |
||||
|
add-migration Added_Docs_Module |
||||
|
``` |
||||
|
|
||||
|
When the command successfully executes , you will see a new migration file named as `20181221111621_Added_Docs_Module` in the folder `Acme.MyProject.EntityFrameworkCore\Migrations`. |
||||
|
|
||||
|
Now, update the database for Docs module database changes. To do this run the below code on `Package Manager Console` in `Visual Studio`. Be sure `Acme.MyProject.EntityFrameworkCore` is still default project. |
||||
|
|
||||
|
```csharp |
||||
|
update-database |
||||
|
``` |
||||
|
|
||||
|
Finally, you can check your database to see the newly created tables. For example you can see `DocsProjects` table must be added to your database. |
||||
|
|
||||
|
|
||||
|
### 5- Linking Docs Module |
||||
|
|
||||
|
The default route for Docs module is; |
||||
|
|
||||
|
``` |
||||
|
/Documents |
||||
|
``` |
||||
|
|
||||
|
To add Docs module link to your application menu; |
||||
|
|
||||
|
* Open `MyProjectMenuContributor.cs` and add the below line to the method `ConfigureMainMenuAsync()`. |
||||
|
|
||||
|
```csharp |
||||
|
context.Menu.Items.Add(new ApplicationMenuItem("MyProject.Docs", l["Menu:Docs"], "/Documents")); |
||||
|
``` |
||||
|
|
||||
|
Final look of **MyProjectMenuContributor.cs** |
||||
|
|
||||
|
```csharp |
||||
|
private async Task ConfigureMainMenuAsync(MenuConfigurationContext context) |
||||
|
{ |
||||
|
var l = context.ServiceProvider.GetRequiredService<IStringLocalizer<MyProjectResource>>(); |
||||
|
|
||||
|
context.Menu.Items.Insert(0, new ApplicationMenuItem("MyProject.Home", l["Menu:Home"], "/")); |
||||
|
|
||||
|
context.Menu.Items.Add(new ApplicationMenuItem("MyProject.Docs", l["Menu:Docs"], "/Documents")); |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
The `Menu:Docs` keyword is a localization key. To localize the menu text, open `Localization\MyProject\en.json` in the project `Acme.MyProject.Domain`. And add the below line |
||||
|
|
||||
|
```json |
||||
|
"Menu:Docs": "Documents" |
||||
|
``` |
||||
|
|
||||
|
Final look of **en.json** |
||||
|
|
||||
|
```json |
||||
|
{ |
||||
|
"culture": "en", |
||||
|
"texts": { |
||||
|
"Menu:Home": "Home", |
||||
|
"Welcome": "Welcome", |
||||
|
"LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io.", |
||||
|
"Menu:Docs": "Documents" |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
The new menu item for Docs Module is added to the menu. Run your web application and browse to `http://localhost:YOUR_PORT_NUMBER/documents` URL. |
||||
|
|
||||
|
You will see a warning says; |
||||
|
|
||||
|
``` |
||||
|
There are no projects yet! |
||||
|
``` |
||||
|
|
||||
|
As we have not added any projects yet, this warning is normal. |
||||
|
|
||||
|
### 6- Adding New Docs Project |
||||
|
|
||||
|
Open `DocsProjects` in your database, and insert a new record with the following field information; |
||||
|
|
||||
|
* **Name**: The display name of the document name which will be shown on the web page. |
||||
|
* **ShortName**: A short and URL friendly name that will be used in your docs URL. |
||||
|
* **Format**: The format of the document (for Markdown: `md`, for HTML: `html`) |
||||
|
* **DefaultDocumentName**: The document for the initial page. |
||||
|
* **NavigationDocumentName**: The document to be used for the navigation menu (index). |
||||
|
* **MinimumVersion**: The minimum version to show the docs. Below version will not be listed. |
||||
|
* **DocumentStoreType**: The source of the documents (for GitHub:`GitHub`, for file system`FileSystem`) |
||||
|
* **ExtraProperties**: A serialized `JSON` that stores special configuration for the selected `DocumentStoreType`. |
||||
|
* **MainWebsiteUrl**: The URL when user clicks to the logo of the Docs module page. You can simply set as `/` to link to your website root address. |
||||
|
* **LatestVersionBranchName**: This is a config for GitHub. It's the branch name which to retrieve the docs. You can set it as `master`. |
||||
|
|
||||
|
#### Sample Project Record for "GitHub" |
||||
|
|
||||
|
You can use [ABP Framework](https://github.com/abpframework/abp/) GitHub documents to configure your GitHub document store. |
||||
|
|
||||
|
- Name: `ABP framework (GitHub)` |
||||
|
|
||||
|
- ShortName: `abp` |
||||
|
|
||||
|
- Format: `md` |
||||
|
|
||||
|
- DefaultDocumentName: `Index` |
||||
|
|
||||
|
- NavigationDocumentName: `docs-nav.json` |
||||
|
|
||||
|
- MinimumVersion: `<NULL>` (no minimum version) |
||||
|
|
||||
|
- DocumentStoreType: `GitHub` |
||||
|
|
||||
|
- ExtraProperties: |
||||
|
|
||||
|
```json |
||||
|
{"GitHubRootUrl":"https://github.com/abpframework/abp/tree/{version}/docs/en/","GitHubAccessToken":"***"} |
||||
|
``` |
||||
|
|
||||
|
Note that `GitHubAccessToken` is masked with `***`. It's a private token that you must get it from GitHub. See https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/ |
||||
|
|
||||
|
- MainWebsiteUrl: `/` |
||||
|
|
||||
|
- LatestVersionBranchName: `master` |
||||
|
|
||||
|
For `SQL` databases, you can use the below `T-SQL` command to insert the specified sample into your `DocsProjects` table: |
||||
|
|
||||
|
```mssql |
||||
|
INSERT [dbo].[DocsProjects] ([Id], [Name], [ShortName], [Format], [DefaultDocumentName], [NavigationDocumentName], [MinimumVersion], [DocumentStoreType], [ExtraProperties], [MainWebsiteUrl], [LatestVersionBranchName]) VALUES (N'12f21123-e08e-4f15-bedb-ae0b2d939658', N'ABP framework (GitHub)', N'abp', N'md', N'Index', N'docs-nav.json', NULL, N'GitHub', N'{"GitHubRootUrl":"https://github.com/abpframework/abp/tree/{version}/docs/en/","GitHubAccessToken":"***"}', N'/', N'master') |
||||
|
``` |
||||
|
|
||||
|
Be aware that `GitHubAccessToken` is masked. It's a private token and you must get your own token and replace the `***` string. |
||||
|
|
||||
|
#### Sample Project Record for "FileSystem" |
||||
|
|
||||
|
You can use [ABP Framework](https://github.com/abpframework/abp/) GitHub documents to configure your GitHub document store. |
||||
|
|
||||
|
- Name: `ABP framework (FileSystem)` |
||||
|
|
||||
|
- ShortName: `abp` |
||||
|
|
||||
|
- Format: `md` |
||||
|
|
||||
|
- DefaultDocumentName: `Index` |
||||
|
|
||||
|
- NavigationDocumentName: `docs-nav.json` |
||||
|
|
||||
|
- MinimumVersion: `<NULL>` (no minimum version) |
||||
|
|
||||
|
- DocumentStoreType: `FileSystem` |
||||
|
|
||||
|
- ExtraProperties: |
||||
|
|
||||
|
```json |
||||
|
{"Path":"C:\\Github\\abp\\docs\\en"} |
||||
|
``` |
||||
|
|
||||
|
Note that `Path` must be replaced with your local docs directory. You can fetch the ABP Framework's documents from https://github.com/abpframework/abp/tree/master/docs/en and copy to the directory `C:\\Github\\abp\\docs\\en` to get it work. |
||||
|
|
||||
|
- MainWebsiteUrl: `/` |
||||
|
|
||||
|
- LatestVersionBranchName: `<NULL>` |
||||
|
|
||||
|
For `SQL` databases, you can use the below `T-SQL` command to insert the specified sample into your `DocsProjects` table: |
||||
|
|
||||
|
```mssql |
||||
|
INSERT [dbo].[DocsProjects] ([Id], [Name], [ShortName], [Format], [DefaultDocumentName], [NavigationDocumentName], [MinimumVersion], [DocumentStoreType], [ExtraProperties], [MainWebsiteUrl], [LatestVersionBranchName]) VALUES (N'12f21123-e08e-4f15-bedb-ae0b2d939659', N'ABP framework (FileSystem)', N'abp', N'md', N'Index', N'docs-nav.json', NULL, N'FileSystem', N'{"Path":"C:\\Github\\abp\\docs\\en"}', N'/', NULL) |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
|
||||
|
Add one of the sample projects above and run the application. In the menu you will see `Documents` link, click the menu link to open the documents page. |
||||
|
|
||||
|
So far, we have created a new application from abp.io website and made it up and ready for Docs module. |
||||
|
|
||||
|
### 7- Creating a New Document |
||||
|
|
||||
|
In the sample Project records, you see that `Format` is specified as `md` which refers to [Mark Down](https://en.wikipedia.org/wiki/Markdown). You can see the mark down cheat sheet following the below link; |
||||
|
|
||||
|
https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet |
||||
|
|
||||
|
ABP Docs Module can render mark down to HTML. |
||||
|
|
||||
|
Now let's have a look a sample document in markdown format. |
||||
|
|
||||
|
~~~markdown |
||||
|
# This is a header |
||||
|
|
||||
|
Welcome to Docs Module. |
||||
|
|
||||
|
## This is a sub header |
||||
|
|
||||
|
[This is a link](https://abp.io) |
||||
|
|
||||
|
 |
||||
|
|
||||
|
## This is a code block |
||||
|
|
||||
|
```csharp |
||||
|
public class Person |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
public string Address { get; set; } |
||||
|
} |
||||
|
``` |
||||
|
~~~ |
||||
|
|
||||
|
|
||||
|
|
||||
|
As an example you can see ABP Framework documentation: |
||||
|
|
||||
|
[https://github.com/abpframework/abp/blob/master/docs/en/](https://github.com/abpframework/abp/blob/master/docs/en/) |
||||
|
|
||||
|
### 8- Creating the Navigation Document |
||||
|
|
||||
|
Navigation document is the main menu of the documents page. It is located on the left side of the page. It is a `JSON` file. Take a look at the below sample navigation document to understand the structure. |
||||
|
|
||||
|
```json |
||||
|
{ |
||||
|
"items":[ |
||||
|
{ |
||||
|
"text":"Sample Menu Item - 1", |
||||
|
"items":[ |
||||
|
{ |
||||
|
"text":"Sample Menu Item - 1.1", |
||||
|
"items":[ |
||||
|
{ |
||||
|
"text":"Sample Menu Item - 1.1.1", |
||||
|
"path":"SampleMenuItem_1_1_1.md" |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"text":"Sample Menu Item - 1.2", |
||||
|
"items":[ |
||||
|
{ |
||||
|
"text":"Sample Menu Item - 1.2.1", |
||||
|
"path":"SampleMenuItem_1_2_1.md" |
||||
|
}, |
||||
|
{ |
||||
|
"text":"Sample Menu Item - 1.2.2", |
||||
|
"path":"SampleMenuItem_1_2_2.md" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"text":"Sample Menu Item - 2", |
||||
|
"items":[ |
||||
|
{ |
||||
|
"text":"Sample Menu Item - 2.1", |
||||
|
"items":[ |
||||
|
{ |
||||
|
"text":"Sample Menu Item - 2.1.1", |
||||
|
"path":"SampleMenuItem_2_1_1.md" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
The upper sample `JSON` file renders the below navigation menu as `HTML`. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
|
||||
|
|
||||
|
Finally a new Docs Module is added to your project which is feeded with GitHub. |
||||
@ -0,0 +1,26 @@ |
|||||
|
# Application Modules |
||||
|
|
||||
|
ABP is a **modular application framework** which consists of dozens of **nuget packages**. It also provides a complete infrastructure to build your own application modules which may have entities, services, database integration, APIs, UI components and so on. |
||||
|
|
||||
|
There are **two types of modules.** They don't have any structural difference but categorized by functionality and purpose: |
||||
|
|
||||
|
* [**Framework modules**](https://github.com/abpframework/abp/tree/master/framework/src): These are **core modules of the framework** like caching, emailing, theming, security, serialization, validation, EF Core integration, MongoDB integration... etc. They do not have application/business functionalities but makes your daily development easier by providing common infrastructure, integration and abstractions. |
||||
|
* [**Application modules**](https://github.com/abpframework/abp/tree/master/modules): These modules implement specific application/business functionalities like blogging, document management, identity management, tenant management... etc. They generally have their own entities, services, APIs and UI components. |
||||
|
|
||||
|
## Open Source Application Modules |
||||
|
|
||||
|
There are some **free and open source** application modules developed and maintained by the ABP community: |
||||
|
|
||||
|
* **Account**: Used to make user login/register to the application. |
||||
|
* **Audit Logging**: Used to persist audit logs to a database. |
||||
|
* **Background Jobs**: Used to persist background jobs when using default background job manager. |
||||
|
* **Blogging**: Used to create fancy blogs. ABP's [own blog](https://abp.io/blog/abp/) already using this module. |
||||
|
* [**Docs**](Docs.md): Used to create technical documentation pages. ABP's [own documentation](https://abp.io/documents/) already using this module. |
||||
|
* **Identity**: Used to manage roles, users and their permissions. |
||||
|
* **Identity Server**: Integrates to IdentityServer4. |
||||
|
* **Permission Management**: Used to persist permissions. |
||||
|
* **Setting Management**: Used to persist settings. |
||||
|
* **Tenant Management**: Used to manage tenants for a [multi-tenant](../Multi-Tenancy.md) application. |
||||
|
* **Users**: Used the abstract users, so other modules can depend on this instead of the Identity module. |
||||
|
|
||||
|
Documenting the modules is in the progress. See [this repository](https://github.com/abpframework/abp/tree/master/modules) for source code of all modules. |
||||
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,11 @@ |
|||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button |
||||
|
{ |
||||
|
public class AbpButtonToolbarTagHelper : AbpTagHelper<AbpButtonToolbarTagHelper, AbpButtonToolbarTagHelperService> |
||||
|
{ |
||||
|
public AbpButtonToolbarTagHelper(AbpButtonToolbarTagHelperService tagHelperService) |
||||
|
: base(tagHelperService) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button |
||||
|
{ |
||||
|
public class AbpButtonToolbarTagHelperService : AbpTagHelperService<AbpButtonToolbarTagHelper> |
||||
|
{ |
||||
|
public override void Process(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
output.Attributes.AddClass("btn-toolbar"); |
||||
|
output.Attributes.Add("role","toolbar"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
using Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card |
||||
|
{ |
||||
|
[HtmlTargetElement("abp-card", Attributes = "background")] |
||||
|
[HtmlTargetElement("abp-card-header", Attributes = "background")] |
||||
|
[HtmlTargetElement("abp-card-body", Attributes = "background")] |
||||
|
[HtmlTargetElement("abp-card-footer", Attributes = "background")] |
||||
|
public class AbpCardBackgroundTagHelper : AbpTagHelper<AbpCardBackgroundTagHelper, AbpCardBackgroundTagHelperService> |
||||
|
{ |
||||
|
public AbpCardBackgroundType Background { get; set; } = AbpCardBackgroundType.Default; |
||||
|
|
||||
|
public AbpCardBackgroundTagHelper(AbpCardBackgroundTagHelperService tagHelperService) |
||||
|
: base(tagHelperService) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card |
||||
|
{ |
||||
|
public class AbpCardBackgroundTagHelperService : AbpTagHelperService<AbpCardBackgroundTagHelper> |
||||
|
{ |
||||
|
public override void Process(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
SetBackground(context, output); |
||||
|
} |
||||
|
|
||||
|
protected virtual void SetBackground(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
if (TagHelper.Background == AbpCardBackgroundType.Default) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
output.Attributes.AddClass("bg-" + TagHelper.Background.ToString().ToLowerInvariant()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card |
||||
|
{ |
||||
|
public enum AbpCardBackgroundType |
||||
|
{ |
||||
|
Default, |
||||
|
Primary, |
||||
|
Secondary, |
||||
|
Success, |
||||
|
Danger, |
||||
|
Warning, |
||||
|
Info, |
||||
|
Light, |
||||
|
Dark, |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card |
||||
|
{ |
||||
|
public enum AbpCardBorderColorType |
||||
|
{ |
||||
|
Default, |
||||
|
Primary, |
||||
|
Secondary, |
||||
|
Success, |
||||
|
Danger, |
||||
|
Warning, |
||||
|
Info, |
||||
|
Light, |
||||
|
Dark, |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card |
||||
|
{ |
||||
|
public class AbpCardFooterTagHelper : AbpTagHelper<AbpCardFooterTagHelper, AbpCardFooterTagHelperService> |
||||
|
{ |
||||
|
public AbpCardFooterTagHelper(AbpCardFooterTagHelperService tagHelperService) |
||||
|
: base(tagHelperService) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card |
||||
|
{ |
||||
|
public class AbpCardFooterTagHelperService : AbpTagHelperService<AbpCardFooterTagHelper> |
||||
|
{ |
||||
|
public override void Process(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
output.Attributes.AddClass("card-footer"); |
||||
|
output.TagName = "div"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
using Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card |
||||
|
{ |
||||
|
[HtmlTargetElement("abp-card", Attributes = "text-color")] |
||||
|
[HtmlTargetElement("abp-card-header", Attributes = "text-color")] |
||||
|
[HtmlTargetElement("abp-card-body", Attributes = "text-color")] |
||||
|
[HtmlTargetElement("abp-card-footer", Attributes = "text-color")] |
||||
|
public class AbpCardTextColorTagHelper : AbpTagHelper<AbpCardTextColorTagHelper, AbpCardTextColorTagHelperService> |
||||
|
{ |
||||
|
public AbpCardTextColorType TextColor { get; set; } = AbpCardTextColorType.Default; |
||||
|
|
||||
|
public AbpCardTextColorTagHelper(AbpCardTextColorTagHelperService tagHelperService) |
||||
|
: base(tagHelperService) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card |
||||
|
{ |
||||
|
public class AbpCardTextColorTagHelperService : AbpTagHelperService<AbpCardTextColorTagHelper> |
||||
|
{ |
||||
|
public override void Process(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
SetTextColor(context, output); |
||||
|
} |
||||
|
|
||||
|
protected virtual void SetTextColor(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
if (TagHelper.TextColor == AbpCardTextColorType.Default) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
output.Attributes.AddClass("text-" + TagHelper.TextColor.ToString().ToLowerInvariant()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card |
||||
|
{ |
||||
|
public enum AbpCardTextColorType |
||||
|
{ |
||||
|
Default, |
||||
|
White, |
||||
|
Primary, |
||||
|
Secondary, |
||||
|
Success, |
||||
|
Danger, |
||||
|
Warning, |
||||
|
Info, |
||||
|
Light, |
||||
|
Dark |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown |
||||
|
{ |
||||
|
public class AbpDropdownItemTextTagHelper : AbpTagHelper<AbpDropdownItemTextTagHelper, AbpDropdownItemTextTagHelperService> |
||||
|
{ |
||||
|
public AbpDropdownItemTextTagHelper(AbpDropdownItemTextTagHelperService tagHelperService) |
||||
|
: base(tagHelperService) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown |
||||
|
{ |
||||
|
public class AbpDropdownItemTextTagHelperService : AbpTagHelperService<AbpDropdownItemTextTagHelper> |
||||
|
{ |
||||
|
public override void Process(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
output.Attributes.AddClass("dropdown-item-text"); |
||||
|
output.TagName = "span"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form |
||||
|
{ |
||||
|
public enum AbpFormControlSize |
||||
|
{ |
||||
|
Default, |
||||
|
Small, |
||||
|
Medium, |
||||
|
Large |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form |
||||
|
{ |
||||
|
public enum AbpReadonlyInputType |
||||
|
{ |
||||
|
False, |
||||
|
True, |
||||
|
True_PlainText |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form |
||||
|
{ |
||||
|
[AttributeUsage(AttributeTargets.Property)] |
||||
|
public class FormControlSize : Attribute |
||||
|
{ |
||||
|
public AbpFormControlSize Size { get; set; } |
||||
|
|
||||
|
public FormControlSize(AbpFormControlSize size) |
||||
|
{ |
||||
|
Size = size; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form |
||||
|
{ |
||||
|
[AttributeUsage(AttributeTargets.Property)] |
||||
|
public class InputInfoText : Attribute |
||||
|
{ |
||||
|
public string Text { get; set; } |
||||
|
|
||||
|
public InputInfoText(string text) |
||||
|
{ |
||||
|
Text = text; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form |
||||
|
{ |
||||
|
[AttributeUsage(AttributeTargets.Property)] |
||||
|
public class Placeholder : Attribute |
||||
|
{ |
||||
|
public string Value { get; set; } |
||||
|
|
||||
|
public Placeholder(string value) |
||||
|
{ |
||||
|
Value = value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,11 +0,0 @@ |
|||||
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid |
|
||||
{ |
|
||||
public class AbpColBreakTagHelper : AbpTagHelper<AbpColBreakTagHelper, AbpColBreakTagHelperService> |
|
||||
{ |
|
||||
public AbpColBreakTagHelper(AbpColBreakTagHelperService tagHelperService) |
|
||||
: base(tagHelperService) |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,11 @@ |
|||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid |
||||
|
{ |
||||
|
public class AbpColumnBreakerTagHelper : AbpTagHelper<AbpColumnBreakerTagHelper, AbpColumnBreakerTagHelperService> |
||||
|
{ |
||||
|
public AbpColumnBreakerTagHelper(AbpColumnBreakerTagHelperService tagHelperService) |
||||
|
: base(tagHelperService) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,10 +0,0 @@ |
|||||
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Image |
|
||||
{ |
|
||||
public enum AbpImagePosition |
|
||||
{ |
|
||||
Default, |
|
||||
Right, |
|
||||
Left, |
|
||||
Center |
|
||||
} |
|
||||
} |
|
||||
@ -1,23 +0,0 @@ |
|||||
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Image |
|
||||
{ |
|
||||
public class AbpImageTagHelper : AbpTagHelper<AbpImageTagHelper, AbpImageTagHelperService> |
|
||||
{ |
|
||||
public bool? Responsive { get; set; } |
|
||||
|
|
||||
public bool? Thumbnail { get; set; } |
|
||||
|
|
||||
public bool? Rounded { get; set; } |
|
||||
|
|
||||
public AbpImagePosition Position { get; set; } = AbpImagePosition.Default; |
|
||||
|
|
||||
public string Alt { get; set; } |
|
||||
|
|
||||
public string Src { get; set; } |
|
||||
|
|
||||
public AbpImageTagHelper(AbpImageTagHelperService tagHelperService) |
|
||||
: base(tagHelperService) |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,68 +0,0 @@ |
|||||
using Microsoft.AspNetCore.Razor.TagHelpers; |
|
||||
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; |
|
||||
|
|
||||
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Image |
|
||||
{ |
|
||||
public class AbpImageTagHelperService : AbpTagHelperService<AbpImageTagHelper> |
|
||||
{ |
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output) |
|
||||
{ |
|
||||
output.TagName = "img"; |
|
||||
SetSourceFile(context,output); |
|
||||
SetPosition(context,output); |
|
||||
SetResponsive(context,output); |
|
||||
SetThumbnail(context,output); |
|
||||
SetRounded(context,output); |
|
||||
SetAlt(context,output); |
|
||||
} |
|
||||
|
|
||||
protected virtual void SetSourceFile(TagHelperContext context, TagHelperOutput output) { |
|
||||
output.Attributes.Add("src",TagHelper.Src); |
|
||||
} |
|
||||
|
|
||||
protected virtual void SetPosition(TagHelperContext context, TagHelperOutput output) |
|
||||
{ |
|
||||
if (TagHelper.Position == default) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
if (TagHelper.Position == AbpImagePosition.Left || TagHelper.Position == AbpImagePosition.Right) |
|
||||
{ |
|
||||
output.Attributes.AddClass("float-" + TagHelper.Position.ToString().ToLowerInvariant()); |
|
||||
} |
|
||||
if (TagHelper.Position == AbpImagePosition.Center) |
|
||||
{ |
|
||||
output.PreElement.SetHtmlContent("<div class=\"text-center\">"); |
|
||||
output.PostElement.SetHtmlContent("</div>"); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
protected virtual void SetResponsive(TagHelperContext context, TagHelperOutput output) { |
|
||||
if (TagHelper.Responsive ?? false) |
|
||||
{ |
|
||||
output.Attributes.AddClass("img-fluid"); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
protected virtual void SetThumbnail(TagHelperContext context, TagHelperOutput output) |
|
||||
{ |
|
||||
if (TagHelper.Thumbnail ?? false) |
|
||||
{ |
|
||||
output.Attributes.AddClass("img-thumbnail"); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
protected virtual void SetRounded(TagHelperContext context, TagHelperOutput output) |
|
||||
{ |
|
||||
if (TagHelper.Rounded ?? false) |
|
||||
{ |
|
||||
output.Attributes.AddClass("rounded"); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
protected virtual void SetAlt(TagHelperContext context, TagHelperOutput output) |
|
||||
{ |
|
||||
output.Attributes.Add("alt",TagHelper.Alt); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,11 @@ |
|||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.ProgressBar |
||||
|
{ |
||||
|
public class AbpProgressGroupTagHelper : AbpTagHelper<AbpProgressGroupTagHelper, AbpProgressGroupTagHelperService> |
||||
|
{ |
||||
|
public AbpProgressGroupTagHelper(AbpProgressGroupTagHelperService groupTagHelperService) |
||||
|
: base(groupTagHelperService) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,11 +0,0 @@ |
|||||
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.ProgressBar |
|
||||
{ |
|
||||
public class AbpProgressTagHelper : AbpTagHelper<AbpProgressTagHelper, AbpProgressTagHelperService> |
|
||||
{ |
|
||||
public AbpProgressTagHelper(AbpProgressTagHelperService tagHelperService) |
|
||||
: base(tagHelperService) |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,31 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Concurrent; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling |
||||
|
{ |
||||
|
public class BundleContributorOptions |
||||
|
{ |
||||
|
public ConcurrentDictionary<Type, BundleContributorCollection> AllExtensions { get; } |
||||
|
|
||||
|
public BundleContributorOptions() |
||||
|
{ |
||||
|
AllExtensions = new ConcurrentDictionary<Type, BundleContributorCollection>(); |
||||
|
} |
||||
|
|
||||
|
public BundleContributorCollection Extensions<TContributor>() |
||||
|
{ |
||||
|
return Extensions(typeof(TContributor)); |
||||
|
} |
||||
|
|
||||
|
public BundleContributorCollection Extensions([NotNull] Type contributorType) |
||||
|
{ |
||||
|
Check.NotNull(contributorType, nameof(contributorType)); |
||||
|
|
||||
|
return AllExtensions.GetOrAdd( |
||||
|
contributorType, |
||||
|
_ => new BundleContributorCollection() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Clipboard; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs |
||||
|
{ |
||||
|
[DependsOn(typeof(ClipboardScriptBundleContributor))] |
||||
|
public class PrismjsScriptBundleContributor : BundleContributor |
||||
|
{ |
||||
|
public override void ConfigureBundle(BundleConfigurationContext context) |
||||
|
{ |
||||
|
context.Files.AddIfNotContains("/libs/prismjs/prism.js"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs |
||||
|
{ |
||||
|
public class PrismjsStyleBundleContributor : BundleContributor |
||||
|
{ |
||||
|
public override void ConfigureBundle(BundleConfigurationContext context) |
||||
|
{ |
||||
|
context.Files.AddIfNotContains("/libs/prismjs/themes/prism-okaidia.css"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue