@ -0,0 +1,137 @@ |
|||
# EditorConfig is awesome: https://EditorConfig.org |
|||
# Please feel free to update it (by considering the code style of ABP Team). |
|||
# top-most EditorConfig file |
|||
root = true |
|||
|
|||
[*.cs] |
|||
|
|||
#Namespace settings |
|||
csharp_style_namespace_declarations = file_scoped |
|||
dotnet_diagnostic.IDE0161.severity = warning |
|||
|
|||
#Core editorconfig formatting - indentation |
|||
|
|||
#use tabs for indentation |
|||
indent_style = tabs |
|||
|
|||
#Formatting - indentation options |
|||
|
|||
#indent switch case contents. |
|||
csharp_indent_case_contents = true |
|||
#indent switch labels |
|||
csharp_indent_switch_labels = true |
|||
|
|||
#Formatting - new line options |
|||
|
|||
#place catch statements on a new line |
|||
csharp_new_line_before_catch = true |
|||
#place else statements on a new line |
|||
csharp_new_line_before_else = true |
|||
#require members of object intializers to be on separate lines |
|||
csharp_new_line_before_members_in_object_initializers = true |
|||
#require braces to be on a new line for object_collection_array_initializers, methods, control_blocks, types, and lambdas (also known as "Allman" style) |
|||
csharp_new_line_before_open_brace = object_collection_array_initializers, methods, control_blocks, types, lambdas |
|||
|
|||
#Formatting - organize using options |
|||
|
|||
#sort System.* using directives alphabetically, and place them before other usings |
|||
dotnet_sort_system_directives_first = true |
|||
|
|||
#Formatting - spacing options |
|||
|
|||
#require NO space between a cast and the value |
|||
csharp_space_after_cast = false |
|||
#require a space before the colon for bases or interfaces in a type declaration |
|||
csharp_space_after_colon_in_inheritance_clause = true |
|||
#require a space after a keyword in a control flow statement such as a for loop |
|||
csharp_space_after_keywords_in_control_flow_statements = true |
|||
#require a space before the colon for bases or interfaces in a type declaration |
|||
csharp_space_before_colon_in_inheritance_clause = true |
|||
#remove space within empty argument list parentheses |
|||
csharp_space_between_method_call_empty_parameter_list_parentheses = false |
|||
#remove space between method call name and opening parenthesis |
|||
csharp_space_between_method_call_name_and_opening_parenthesis = false |
|||
#do not place space characters after the opening parenthesis and before the closing parenthesis of a method call |
|||
csharp_space_between_method_call_parameter_list_parentheses = false |
|||
#remove space within empty parameter list parentheses for a method declaration |
|||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false |
|||
#place a space character after the opening parenthesis and before the closing parenthesis of a method declaration parameter list. |
|||
csharp_space_between_method_declaration_parameter_list_parentheses = false |
|||
|
|||
#Formatting - wrapping options |
|||
|
|||
#leave code block on single line |
|||
csharp_preserve_single_line_blocks = true |
|||
|
|||
#Style - Code block preferences |
|||
|
|||
#prefer curly braces even for one line of code |
|||
csharp_prefer_braces = true:suggestion |
|||
|
|||
#Style - expression bodied member options |
|||
|
|||
#prefer block bodies for constructors |
|||
csharp_style_expression_bodied_constructors = false:suggestion |
|||
#prefer block bodies for methods |
|||
csharp_style_expression_bodied_methods = false:suggestion |
|||
#prefer expression-bodied members for properties |
|||
csharp_style_expression_bodied_properties = true:suggestion |
|||
|
|||
#Style - expression level options |
|||
|
|||
#prefer out variables to be declared inline in the argument list of a method call when possible |
|||
csharp_style_inlined_variable_declaration = true:suggestion |
|||
#prefer the language keyword for member access expressions, instead of the type name, for types that have a keyword to represent them |
|||
dotnet_style_predefined_type_for_member_access = true:suggestion |
|||
|
|||
#Style - Expression-level preferences |
|||
|
|||
#prefer default over default(T) |
|||
csharp_prefer_simple_default_expression = true:suggestion |
|||
#prefer objects to be initialized using object initializers when possible |
|||
dotnet_style_object_initializer = true:suggestion |
|||
#prefer inferred tuple element names |
|||
dotnet_style_prefer_inferred_tuple_names = true:suggestion |
|||
|
|||
#Style - implicit and explicit types |
|||
|
|||
#prefer var over explicit type in all cases, unless overridden by another code style rule |
|||
csharp_style_var_elsewhere = true:suggestion |
|||
#prefer var is used to declare variables with built-in system types such as int |
|||
csharp_style_var_for_built_in_types = true:suggestion |
|||
#prefer var when the type is already mentioned on the right-hand side of a declaration expression |
|||
csharp_style_var_when_type_is_apparent = true:suggestion |
|||
|
|||
#Style - language keyword and framework type options |
|||
|
|||
#prefer the language keyword for local variables, method parameters, and class members, instead of the type name, for types that have a keyword to represent them |
|||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion |
|||
|
|||
#Style - Miscellaneous preferences |
|||
|
|||
#prefer local functions over anonymous functions |
|||
csharp_style_pattern_local_over_anonymous_function = true:suggestion |
|||
|
|||
#Style - modifier options |
|||
|
|||
#prefer accessibility modifiers to be declared except for public interface members. This will currently not differ from always and will act as future proofing for if C# adds default interface methods. |
|||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion |
|||
|
|||
#Style - Modifier preferences |
|||
|
|||
#when this rule is set to a list of modifiers, prefer the specified ordering. |
|||
csharp_preferred_modifier_order = public,protected,private,virtual,async,readonly,static,override,abstract:suggestion |
|||
|
|||
#Style - Pattern matching |
|||
|
|||
#prefer pattern matching instead of is expression with type casts |
|||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion |
|||
|
|||
#Style - qualification options |
|||
|
|||
#prefer fields not to be prefaced with this. or Me. in Visual Basic |
|||
dotnet_style_qualification_for_field = false:suggestion |
|||
#prefer methods not to be prefaced with this. or Me. in Visual Basic |
|||
dotnet_style_qualification_for_method = false:suggestion |
|||
#prefer properties not to be prefaced with this. or Me. in Visual Basic |
|||
dotnet_style_qualification_for_property = false:suggestion |
|||
@ -1,24 +1,24 @@ |
|||
name: Merge branch rel-5.1 with rel-5.0 |
|||
name: Merge branch rel-5.2 with rel-5.1 |
|||
on: |
|||
push: |
|||
branches: |
|||
- rel-5.0 |
|||
- rel-5.1 |
|||
jobs: |
|||
merge-rel-5-1-with-rel-5-0: |
|||
merge-rel-5-2-with-rel-5-1: |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- uses: actions/checkout@v2 |
|||
with: |
|||
ref: rel-5.1 |
|||
ref: rel-5.2 |
|||
- name: Reset promotion branch |
|||
run: | |
|||
git fetch origin rel-5.0:rel-5.0 |
|||
git reset --hard rel-5.0 |
|||
git fetch origin rel-5.1:rel-5.1 |
|||
git reset --hard rel-5.1 |
|||
- name: Create Pull Request |
|||
uses: peter-evans/create-pull-request@v3 |
|||
with: |
|||
branch: auto-merge/rel-5-0/${{github.run_number}} |
|||
title: Merge branch rel-5.1 with rel-5.0 |
|||
body: This PR generated automatically to merge rel-5.1 with rel-5.0. Please review the changed files before merging to prevent any errors that may occur. |
|||
branch: auto-merge/rel-5-1/${{github.run_number}} |
|||
title: Merge branch rel-5.2 with rel-5.1 |
|||
body: This PR generated automatically to merge rel-5.2 with rel-5.1. Please review the changed files before merging to prevent any errors that may occur. |
|||
reviewers: ${{github.actor}} |
|||
token: ${{ github.token }} |
|||
|
|||
|
After Width: | Height: | Size: 907 KiB |
|
After Width: | Height: | Size: 61 KiB |
@ -0,0 +1,47 @@ |
|||
# ABP.IO Platform 5.0 Final Has Been Released! |
|||
|
|||
[ABP Framework](https://abp.io/) and [ABP Commercial](https://commercial.abp.io/) 5.0 versions have been released today. |
|||
|
|||
## What's new with 5.0? |
|||
|
|||
Since all the new features are already explained in details with the [5.0 RC.1 Announcement Post](https://blog.abp.io/abp/ABP-IO-Platform-5.0-RC-1-Has-Been-Released), I will not repeat all the details again. See the [RC Blog Post](https://blog.abp.io/abp/ABP-IO-Platform-5.0-RC-1-Has-Been-Released) for all the features and enhancements. |
|||
|
|||
## Getting started with 5.0 |
|||
|
|||
### Creating new solutions |
|||
|
|||
You can create a new solution with the ABP Framework version 5.0 by either using the `abp new` command or using the **direct download** tab on the [get started page](https://abp.io/get-started). |
|||
|
|||
Type the following command in a command-line terminal to install the ABP CLI version 5.0: |
|||
|
|||
````bash |
|||
dotnet tool install -g Volo.Abp.Cli --version 5.0.0 |
|||
```` |
|||
|
|||
To upgrade your existing ABP CLI installation: |
|||
|
|||
````bash |
|||
dotnet tool update -g Volo.Abp.Cli --version 5.0.0 |
|||
```` |
|||
|
|||
Then you can create a new solution using the `abp new` command: |
|||
|
|||
````bash |
|||
abp new Acme.BookStore |
|||
```` |
|||
|
|||
> See the [getting started document](https://docs.abp.io/en/abp/latest/Getting-Started) for details. |
|||
|
|||
### Upgrading existing solutions |
|||
|
|||
Check [the migration guide](https://docs.abp.io/en/abp/latest/Migration-Guides/Abp-5_0) for the applications with the version 4.x upgrading to the version 5.0. Also see [the upgrading guide](https://docs.abp.io/en/abp/latest/Upgrading) to understand how to update existing solutions. |
|||
|
|||
## ABP Community Talks 2021.12 |
|||
|
|||
 |
|||
|
|||
As the core ABP development team, we've decided to organize monthly live meetings with the ABP community. The first live meeting will be at **December 16, 2021, 17:00 (UTC)** on YouTube. ABP core team members will present some of the new features coming with ABP 5.0. |
|||
|
|||
**Join this event on the Kommunity platform: https://kommunity.com/volosoft/events/abp-community-talks-4afca9c9** |
|||
|
|||
See you in the event! |
|||
|
After Width: | Height: | Size: 907 KiB |
@ -0,0 +1,155 @@ |
|||
# ABP.IO Platform 5.1 Has Been Released |
|||
|
|||
Today, we are releasing the [ABP Framework](https://abp.io/) and [ABP Commercial](https://commercial.abp.io/) version 5.1 (with a version number `5.1.1`). This blog post introduces the new features and important changes in this new version. |
|||
|
|||
> **Warning** |
|||
> |
|||
> For a long time we've been releasing RC (Release Candidate) versions a few weeks prior to every minor and major release. **This version has been released without a preview version.** This is because we've accidently released all the packages with a stable version number, without a `-rc.1` suffix and there is no clear way to unpublish all the NuGet and NPM packages. We're sorry about that. However, it doesn't mean that this release is buggy. We've already resolved the known problems. We will publish one or more patch releases if needed. You can follow [this milestone](https://github.com/abpframework/abp/milestone/64?closed=1) for the common problems or submit your own bug report. If you are worried about its stability, you can wait for the next patch release. |
|||
|
|||
## Get Started with 5.1 |
|||
|
|||
Follow the steps below to try the 5.1 version today: |
|||
|
|||
1) **Upgrade** the ABP CLI to the latest version using a command line terminal: |
|||
|
|||
````bash |
|||
dotnet tool update Volo.Abp.Cli -g |
|||
```` |
|||
|
|||
**or install** if you haven't installed it before: |
|||
|
|||
````bash |
|||
dotnet tool install Volo.Abp.Cli -g |
|||
```` |
|||
|
|||
2) Create a **new application**: |
|||
|
|||
````bash |
|||
abp new BookStore |
|||
```` |
|||
|
|||
Check out the [ABP CLI documentation](https://docs.abp.io/en/abp/latest/CLI) for all the available options. |
|||
|
|||
> You can also use the *Direct Download* tab on the [Get Started](https://abp.io/get-started) page. |
|||
|
|||
You can use any IDE that supports .NET 6.x development (e.g. [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/)). |
|||
|
|||
### Migration Notes & Breaking Changes |
|||
|
|||
This is a minor feature release, mostly with enhancements and improvements based on [version 5.0](https://blog.abp.io/abp/ABP-IO-Platform-5-0-Final-Has-Been-Released). There aren't any breaking changes except for the Angular UI upgrade. ABP 5.1 startup templates use **Angular 13**. |
|||
|
|||
### Angular UI |
|||
|
|||
**If you want to upgrade the ABP Framework but want to continue with Angular 12**, add the following section to the `package.json` file of the Angular project: |
|||
|
|||
````json |
|||
"resolutions": { |
|||
"ng-zorro-antd": "^12.1.1", |
|||
"@ng-bootstrap/ng-bootstrap": "11.0.0-beta.2" |
|||
} |
|||
```` |
|||
|
|||
### Blazor UI |
|||
|
|||
If you are using Blazor WebAssembly, open the `Program` class and replace `InitializeAsync` with `InitializeApplicationAsync`. |
|||
|
|||
## What's New with the ABP Framework 5.1? |
|||
|
|||
In this section, I will introduce some major features released with this version. |
|||
|
|||
### The New Hosting Model |
|||
|
|||
The ABP startup application template now uses the new ASP.NET Core hosting APIs ([check out the Microsoft's minimal APIs document](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis?view=aspnetcore-6.0)) on application startup ([check out the exact place in the ABP startup template](https://github.com/abpframework/abp/blob/46cdfbe7b06c93690181633be4e96bf62e7f34e2/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Program.cs#L33-L40)). So, the `Startup.cs` file has been removed. |
|||
|
|||
Old-style hosting logic will continue to work as long as ASP.NET Core supports it. It is recommended to switch to the new model if it's possible for your solution. Check out [this guide](https://docs.abp.io/en/abp/latest/Migration-Guides/Upgrading-Startup-Template) if you need to know how to do that. |
|||
|
|||
### Asynchronous Startup Lifecycle Methods |
|||
|
|||
The new hosting model allows us to execute asynchronous code on application initialization in the [ABP module](https://docs.abp.io/en/abp/latest/Module-Development-Basics) classes. If you are using the new hosting model (which is default with 5.1 startup templates), you can override the `Async` versions of the module lifecycle methods. |
|||
|
|||
For example, you can now override the `ConfigureServicesAsync` (instead of `ConfigureServices`) or `OnApplicationInitializationAsync` (instead of `OnApplicationInitialization`) as shown in the following code block: |
|||
|
|||
````csharp |
|||
public class MyModule : AbpModule |
|||
{ |
|||
public override async Task ConfigureServicesAsync(ServiceConfigurationContext context) |
|||
{ |
|||
/* You can use await here and safely execute other async methods */ |
|||
} |
|||
|
|||
public override async Task OnApplicationInitializationAsync(ApplicationInitializationContext context) |
|||
{ |
|||
/* You can use await here and safely execute other async methods */ |
|||
} |
|||
} |
|||
```` |
|||
|
|||
If you override both the asynchronous and synchronous versions of the same method, only the asynchronous one will be executed. So, override only one of them based on your needs. |
|||
|
|||
### eShopOnABP Is Getting More Stable |
|||
|
|||
Our team is working to finalize the [eShopOnAbp](https://github.com/abpframework/eShopOnAbp) example solution, which is a reference **microservice solution** built with the ABP Framework. They will explain the project status and show what's done in the next **ABP Community Talks** meeting (Check out the *ABP Community Talks 2021.1* section at the bottom of this post). |
|||
|
|||
### The New ABP.IO Design! |
|||
|
|||
We've been working on a new design for the [abp.io](https://abp.io/) websites for a while. We are adding the final touches; the new design will be live very soon. Here's a screenshot from the design work: |
|||
|
|||
 |
|||
|
|||
The [ABP Commercial](https://commercial.abp.io/) and [ABP Community](https://community.abp.io/) websites will also have new designs as part of this update. |
|||
|
|||
### Other Changes |
|||
|
|||
Here are some other notable changes that come with this release: |
|||
|
|||
* Support markdown in [CMS-Kit comments ](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Comments)feature ([#10792](https://github.com/abpframework/abp/pull/10792)) |
|||
* Used file scoped namespaces for all the ABP Framework source code :) ([#10552](https://github.com/abpframework/abp/pull/10696)) |
|||
* Developers should control `EnableLegacyTimestampBehavior` when using PostgreSQL. [#11371](https://github.com/abpframework/abp/pull/11371) [#65](https://github.com/abpframework/eShopOnAbp/pull/65) |
|||
|
|||
|
|||
All issues & PRs in [5.1 milesone](https://github.com/abpframework/abp/milestone/60?closed=1). |
|||
|
|||
### About ABP Commercial |
|||
|
|||
The core team is also working on ABP Commercial (which provides pre-built modules, themes, tooling and support on top of the ABP Framework). We've done a lot of minor improvements and fixes to the modules and tooling. |
|||
|
|||
There's some exciting news about the **LeptonX theme**; We are working on making it available in the **MVC (Razor Pages)** and **Blazor** UI options too (in addition to Angular UI). We are also adding more components, layout options, demo pages, etc... We are planning to release a beta version in the next weeks. Here's an animated GIF from the dashboard we've prepared as a demonstration: |
|||
|
|||
 |
|||
|
|||
If you are wondering what is the LeptonX project, please check out this [blog post](https://blog.abp.io/abp/LeptonX-Theme-for-ABP-Framework-Alpha-Release). |
|||
|
|||
As another visible functionality, we've added a new feature to the [CMS Kit Pro](https://docs.abp.io/en/commercial/latest/modules/cms-kit/index) module that is used to forward a URL to another URL. This is a screenshot from the management UI: |
|||
|
|||
 |
|||
|
|||
This feature can be used to create short URLs in your application (like URL shortening services providers) or forward old pages to their new URLs. |
|||
|
|||
In addition to the new features shipped in every minor version, we are working on long-term projects for ABP.IO Platform and ABP Commercial (a little secret for now :). We will have announcements once these projects get more stable. |
|||
|
|||
## Community News |
|||
|
|||
### ABP Community Talks 2021.1 |
|||
|
|||
 |
|||
|
|||
This is the second episode of the ABP Community Talks and we are talking about microservice development with the ABP Framework, based on the [eShopOnAbp](https://github.com/abpframework/eShopOnAbp) reference solution. We will also briefly talk about the changes that come with ABP version 5.1. This **live meeting** will be on **January 20, 2022, 17:00 (UTC)** on YouTube. |
|||
|
|||
**Join this event on the Kommunity platform: https://kommunity.com/volosoft/events/abp-community-talks-20221-microservice-development-acd0f44b** |
|||
|
|||
You can also [subscribe to Volosoft YouTube channel](https://www.youtube.com/channel/UCO3XKlpvq8CA5MQNVS6b3dQ) for reminders of further ABP events and videos. |
|||
|
|||
### New ABP Community Posts |
|||
|
|||
Here are some of the recent posts added to the [ABP community](https://community.abp.io/): |
|||
|
|||
* [Minimal API development with the ABP Framework](https://community.abp.io/articles/minimal-api-with-abp-hello-world-part-1-sg5i44p8) by [@antosubash](https://github.com/antosubash) (three parts, video tutorial). |
|||
* [Integrating the Syncfusion MVC Components to the ABP MVC UI](https://community.abp.io/articles/integrating-the-syncfusion-mvc-components-to-the-abp-mvc-ui-0gpkr1if) by [@EngincanV](https://github.com/EngincanV). |
|||
* [Add Tailwind CSS to your ABP Blazor UI](https://community.abp.io/articles/add-tailwindcss-to-your-abp-blazor-ui-vidiwzcy) by [@antosubash](https://github.com/antosubash) (video tutorial). |
|||
* [Import external users into the users Table from an ABP Framework application](https://community.abp.io/articles/import-external-users-into-the-users-table-from-an-abp-framework-application-7lnyw415) by [@bartvanhoey](https://github.com/bartvanhoey). |
|||
|
|||
Thanks to the ABP Community for all the contents they have published. You can also [post your ABP and .NET related (text or video) contents](https://community.abp.io/articles/submit) to the ABP Community. |
|||
|
|||
## Conclusion |
|||
|
|||
In this blog post, I summarized the news about the new version and the ABP Community. Please try it and provide feedback by opening issues on the [GitHub repository](https://github.com/abpframework/abp). Thank you all! |
|||
|
After Width: | Height: | Size: 559 KiB |
|
After Width: | Height: | Size: 6.6 MiB |
|
After Width: | Height: | Size: 162 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 2.9 MiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 366 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 33 KiB |
@ -0,0 +1,321 @@ |
|||
# Integrating the Syncfusion MVC Components to the ABP MVC UI |
|||
|
|||
## Introduction |
|||
|
|||
In this article we will see how we can integrate the Syncfusion MVC Components into our ABP application. |
|||
|
|||
## Source Code |
|||
|
|||
You can find the source code of the application at https://github.com/EngincanV/ABP-Syncfusion-Components-Demo. |
|||
|
|||
## Prerequisites |
|||
|
|||
* [.NET 6](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) |
|||
|
|||
* In this article, we will create a new startup template in v5.0.0-rc.2 and if you follow this article from top to bottom and create a new startup template with me, you need to install the [.NET 6 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) before starting. |
|||
|
|||
**NOTE:** ABP v5.X stable version has been released. You can replace v5.0.0-rc.2 with the latest stable version in your steps. |
|||
|
|||
Also, you need to update your ABP CLI to the v5.0.0-rc.2, you can use the command below to update your CLI version: |
|||
|
|||
```bash |
|||
dotnet tool update Volo.Abp.Cli -g --version 5.0.0-rc.2 |
|||
``` |
|||
|
|||
or install it if you haven't installed it before: |
|||
|
|||
```bash |
|||
dotnet tool install Volo.Abp.Cli -g --version 5.0.0-rc.2 |
|||
``` |
|||
|
|||
## Creating the Solution |
|||
|
|||
In this article, we will create a new startup template with EF Core as a database provider and MVC for the UI framework. But if you already have a project with MVC UI, you don't need to create a new startup template, you can directly implement the following steps to your existing project. |
|||
|
|||
> If you already have a project with MVC/Razor Pages UI, you can skip this section. |
|||
|
|||
We can create a new startup template by using the [ABP CLI](https://docs.abp.io/en/abp/latest/CLI): |
|||
|
|||
```bash |
|||
abp new SyncfusionComponentsDemo -t app --preview |
|||
``` |
|||
|
|||
Our project boilerplate will be ready after the download is finished. Then, we can open the solution and start developing. |
|||
|
|||
## Starting the Development |
|||
|
|||
### Pre-requisite |
|||
|
|||
> If you've already had a license from Syncfusion, you can skip this section. |
|||
|
|||
* The first thing we need to do is create an account to be able to get a license from Syncfusion. |
|||
|
|||
* So, let's navigate to https://www.syncfusion.com/aspnet-core-ui-controls and click the "Download Free Trial" button. |
|||
|
|||
* Then fill the form and start your 30-day free trial. |
|||
|
|||
* After that, navigate to https://www.syncfusion.com/account/manage-trials/downloads to get our license key that will be used in our application. |
|||
|
|||
 |
|||
|
|||
Click the "Get License Key" link for "ASP.NET Core (Essential JS 2)". |
|||
|
|||
 |
|||
|
|||
Then a modal will be opened like in the above image, select a version and click the "Get License Key" button. |
|||
|
|||
 |
|||
|
|||
Lastly, copy the generated license key value. |
|||
|
|||
In order to use the relevant components, Syncfusion needs to check this license key to know that our license is valid. |
|||
|
|||
### Configurations |
|||
|
|||
After providing a license key from Syncfusion, we can start with the configuration that needs to be done in our application. |
|||
|
|||
#### 1-) Install the Syncfusion.EJ2.AspNet.Core package |
|||
|
|||
We need to install the `Syncfusion.EJ2.AspNet.Core` Nuget package to our Web project (*.Web). |
|||
|
|||
We can install it via **Visual Studio's Nuget Package Manager**: |
|||
|
|||
 |
|||
|
|||
or via dotnet cli: |
|||
|
|||
```bash |
|||
dotnet add package Syncfusion.EJ2.AspNet.Core --version 19.3.0.57 |
|||
``` |
|||
|
|||
> In this article, I've used the package in version 19.3.0.57. |
|||
|
|||
#### 2-) Register the License Key |
|||
|
|||
* After installing the package, we need to register our license key to be able to use the Syncfusion Components. |
|||
|
|||
* To register the license key, open your web module class and update the `ConfigureServices` method as follows: |
|||
|
|||
```csharp |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
//Register Syncfusion license |
|||
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(licenseKey: configuration["Syncfusion:LicenseKey"].ToString()); |
|||
|
|||
ConfigureUrls(configuration); |
|||
ConfigureBundles(); |
|||
ConfigureAuthentication(context, configuration); |
|||
ConfigureAutoMapper(); |
|||
ConfigureVirtualFileSystem(hostingEnvironment); |
|||
ConfigureLocalizationServices(); |
|||
ConfigureNavigationServices(); |
|||
ConfigureAutoApiControllers(); |
|||
ConfigureSwaggerServices(context.Services); |
|||
} |
|||
``` |
|||
|
|||
Instead of writing the license key directly in here we can define it in the **appsettings.json** file and use it here by using the Configuration system of .NET. |
|||
|
|||
|
|||
* Open your **appsettings.json** file and add a new section named "Syncfusion" as below: |
|||
|
|||
```json |
|||
{ |
|||
//... |
|||
|
|||
"Syncfusion": { |
|||
"LicenseKey": "<your-license-key>" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
> Replace the `<your-license-key> part with your license key that we've obtained in the previous section.` |
|||
|
|||
* To be able to use the Syncfusion Components we need to define them in our **_ViewImports.cshtml** file. By doing that we can use the Syncfusion components everywhere in our application. |
|||
|
|||
* Open your **/Pages/_ViewImports.cshtml** file and add a new tag helper: |
|||
|
|||
```cshtml |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling |
|||
@addTagHelper *, Syncfusion.EJ2 //use Syncfusion components |
|||
``` |
|||
|
|||
#### 3-) Adding Syncfusion styles and scripts to our application |
|||
|
|||
Firstly, let's install the `@syncfusion/ej2` package from **npm**. |
|||
|
|||
* Open your **package.json** file and add the `@syncfusion/ej2` package with version **19.3.57**: |
|||
|
|||
```json |
|||
{ |
|||
"version": "1.0.0", |
|||
"name": "my-app", |
|||
"private": true, |
|||
"dependencies": { |
|||
"@abp/aspnetcore.mvc.ui.theme.basic": "^5.0.0-rc.2", |
|||
"@syncfusion/ej2": "^19.3.57" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
* Then, open the **abp.resourcemapping.js** file and update the **mappings** section: |
|||
|
|||
```js |
|||
module.exports = { |
|||
aliases: { |
|||
|
|||
}, |
|||
mappings: { |
|||
"@node_modules/@syncfusion/ej2/dist/ej2.min.js": "@libs/syncfusion/", |
|||
"@node_modules/@syncfusion/ej2/material.css": "@libs/syncfusion/" |
|||
} |
|||
}; |
|||
``` |
|||
|
|||
> ABP copies related packages from **node_modules** folder to the **libs** folder by examining this file. You can read this [document](docs.abp.io/en/abp/latest/UI/AspNetCore/Client-Side-Package-Management#mapping-the-library-resources) for more info. |
|||
|
|||
* Then run the `abp install-libs` to install the dependencies and copy them into the libs folder by your mappings configuration. After running this command, in your **libs** folder it should be a folder named **syncfusion** folder. |
|||
|
|||
 |
|||
|
|||
The last thing we need to do is, add some style and script files provided by Syncfusion, between our head-body tags. |
|||
|
|||
* We can do this by creating two view components (one for Styles and the other for Scripts). Let's do that. |
|||
|
|||
First, create a folder structure as shown below under the **Components** folder. |
|||
|
|||
 |
|||
|
|||
Then open the related files and add the following codes to each of these files. |
|||
|
|||
* **Default.cshtml** (/Components/Syncfusion/Script/Default.cshtml) |
|||
|
|||
```cshtml |
|||
@addTagHelper *, Syncfusion.EJ2 //add this line |
|||
|
|||
<!-- Syncfusion Essential JS 2 Scripts --> |
|||
<script src="/libs/syncfusion/ej2.min.js"></script> |
|||
|
|||
<!-- Syncfusion Essential JS 2 ScriptManager --> |
|||
<ejs-scripts></ejs-scripts> |
|||
``` |
|||
|
|||
* **SyncfusionScriptComponent.cs** |
|||
|
|||
```csharp |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace SyncfusionComponentsDemo.Web.Components.Syncfusion.Script |
|||
{ |
|||
public class SyncfusionScriptComponent : AbpViewComponent |
|||
{ |
|||
public IViewComponentResult Invoke() |
|||
{ |
|||
return View("~/Components/Syncfusion/Script/Default.cshtml"); |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
* **Default.cshtml** (/Components/Syncfusion/Style/Default.cshtml) |
|||
|
|||
```cshtml |
|||
<!-- Syncfusion Essential JS 2 Styles --> |
|||
<link rel="stylesheet" href="/libs/syncfusion/material.css"> |
|||
``` |
|||
|
|||
* SyncfusionStyleComponent.cs |
|||
|
|||
```csharp |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace SyncfusionComponentsDemo.Web.Components.Syncfusion.Style |
|||
{ |
|||
public class SyncfusionStyleComponent : AbpViewComponent |
|||
{ |
|||
public IViewComponentResult Invoke() |
|||
{ |
|||
return View("~/Components/Syncfusion/Style/Default.cshtml"); |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
After creating these two components, we can use the [**Layout Hooks**](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Layout-Hooks) system of ABP to inject these two components between head and script tags. |
|||
|
|||
To do this, open your web module class and update the `ConfigureServices` method as below: |
|||
|
|||
|
|||
```csharp |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
//Register Syncfusion license |
|||
var licenseKey = configuration["Syncfusion:LicenseKey"].ToString(); |
|||
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(licenseKey: licenseKey); |
|||
|
|||
Configure<AbpLayoutHookOptions>(options => |
|||
{ |
|||
//Now, the SyncfusionStyleComponent code will be inserted in the head of the page as the last item. |
|||
options.Add(LayoutHooks.Head.Last, typeof(SyncfusionStyleComponent)); |
|||
|
|||
//the SyncfusionScriptComponent will be inserted in the body of the page as the last item. |
|||
options.Add(LayoutHooks.Body.Last, typeof(SyncfusionScriptComponent)); |
|||
}); |
|||
|
|||
ConfigureUrls(configuration); |
|||
ConfigureBundles(); |
|||
ConfigureAuthentication(context, configuration); |
|||
ConfigureAutoMapper(); |
|||
ConfigureVirtualFileSystem(hostingEnvironment); |
|||
ConfigureLocalizationServices(); |
|||
ConfigureNavigationServices(); |
|||
ConfigureAutoApiControllers(); |
|||
ConfigureSwaggerServices(context.Services); |
|||
} |
|||
``` |
|||
|
|||
After injecting the Syncfusion style and script into our application, our configurations have been completed. We can try with a simple component to see if it works as we expected. |
|||
|
|||
* Let's try with the [Calendar](https://www.syncfusion.com/aspnet-core-ui-controls/calendar) component. Open your **Index.cshtml** file and update with the below content: |
|||
|
|||
```cshtml |
|||
@page |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using SyncfusionComponentsDemo.Localization |
|||
@using Volo.Abp.Users |
|||
@model SyncfusionComponentsDemo.Web.Pages.IndexModel |
|||
|
|||
@section styles { |
|||
<abp-style src="/Pages/Index.css" /> |
|||
} |
|||
|
|||
@section scripts { |
|||
<abp-script src="/Pages/Index.js" /> |
|||
} |
|||
|
|||
<div class="container"> |
|||
<h2>Syncfusion - Calendar Component</h2> |
|||
<ejs-calendar id="calendar"></ejs-calendar> |
|||
</div> |
|||
``` |
|||
|
|||
* Then when we run the application, we need to see the relevant calendar component as below. |
|||
|
|||
 |
|||
|
|||
### Conclusion |
|||
|
|||
In this article, we've explained how to integrate the **Syncfusion Components** into our applications. After following this article, you can use the Syncfusion components in your application. |
|||
|
|||
Thanks for reading the article, I hope you've found it useful :) |
|||
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 53 KiB |
@ -1,100 +1,6 @@ |
|||
# Multi Lingual Entities |
|||
|
|||
ABP Framework defines two basic interfaces for Multi-Lingual entity definitions to provide a standard model for translating entities. |
|||
This feature is still under development. |
|||
Follow the below link to get information about the development status |
|||
|
|||
## IHasMultiLingual |
|||
|
|||
`IHasMultiLingual<TTranslation>` interface is used to mark multi lingual entities. The entities marked with `IHasMultiLingual<TTranslation>` interface must define language-neutral information. The entities marked with `IHasMultiLingual<TTranslation>` contains a collection of Translations which contains language-dependent information. |
|||
|
|||
Example: |
|||
|
|||
```csharp |
|||
public class Product : Entity, IMultiLingualEntity<ProductTranslation> |
|||
{ |
|||
public decimal Price { get; set; } |
|||
|
|||
public ICollection<ProductTranslation> Translations { get; set; } |
|||
} |
|||
``` |
|||
|
|||
## IMultiLingualTranslation |
|||
|
|||
`IMultiLingualTranslation` interface is used to mark translation of a Multi-Lingual entity. The entities marked with `IMultiLingualTranslation` interface must define language dependent information. The entities marked with `IMultiLingualTranslation` contains Language field which contains a language code for the translation. |
|||
|
|||
Example: |
|||
|
|||
```csharp |
|||
public class ProductTranslation : Entity, IMultiLingualTranslation |
|||
{ |
|||
public string Name { get; set; } |
|||
|
|||
public string Language { get; set; } |
|||
} |
|||
``` |
|||
|
|||
## Map to DTO object |
|||
|
|||
ABP provdies the [Object To Object Mapping](Object-To-Object-Mapping.md) system, you can implement the `IObjectMapper<TSource, TDestination>` interface to map multi lingual entities to DTOs. |
|||
|
|||
Example: |
|||
|
|||
```csharp |
|||
public class MultiLingualProductObjectMapper : IObjectMapper<Product, ProductDto>, ITransientDependency |
|||
{ |
|||
private readonly IMultiLingualObjectManager _multiLingualObjectManager; |
|||
|
|||
public MultiLingualProductObjectMapper(IMultiLingualObjectManager multiLingualObjectManager) |
|||
{ |
|||
_multiLingualObjectManager = multiLingualObjectManager; |
|||
} |
|||
|
|||
public ProductDto Map(Product source) |
|||
{ |
|||
var translation = _multiLingualObjectManager.GetTranslation<Product, ProductDto>(source); |
|||
|
|||
return new ProductDto |
|||
{ |
|||
Price = source.Price, |
|||
Id = source.Id, |
|||
Name = translation?.Name |
|||
}; |
|||
} |
|||
|
|||
public ProductDto Map(Product source, ProductDto destination) |
|||
{ |
|||
return default; |
|||
} |
|||
} |
|||
|
|||
``` |
|||
|
|||
### AutoMapper integration |
|||
|
|||
ABP provides the `CreateMultiLingualMap` extension method for mapping multilingual entities to DTOs. |
|||
|
|||
Example: |
|||
|
|||
```csharp |
|||
public class ProductProfile : Profile |
|||
{ |
|||
public ProductProfile() |
|||
{ |
|||
var mapResult = this.CreateMultiLingualMap<Product, ProductTranslation, ProductDto>(); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
`CreateMultiLingualMap` extension method returns an object of type `CreateMultiLingualMapResult` which contains `EntityMap` and `TranslationMap` fields. These fields can be used to customize multi lingual mapping. |
|||
|
|||
Example: |
|||
|
|||
```csharp |
|||
this.CreateMultiLingualMap<Order, OrderTranslation, OrderListDto>(context) |
|||
.EntityMap.ForMember(dest => dest.ProductCount, opt => opt.MapFrom(src => src.Products.Count)); |
|||
``` |
|||
|
|||
## IMultiLingualObjectManager |
|||
|
|||
`IMultiLingualObjectManager` interface defines `GetTranslation` and `GetTranslationAsync` method to get the translation object of the entity. |
|||
|
|||
The default implementation of the `IMultiLingualObjectManager` interface finds the translation with selected UI language first. If there is no translation with selected UI language, then extension method searches for the default language setting (see [Setting](Settings.md)) and uses the translation in default language. If extension method couldn't find any translation in current UI language or default language, it uses one of the existing translations. |
|||
https://github.com/abpframework/abp/issues/1169 |
|||
|
|||
@ -1,3 +1,256 @@ |
|||
# Emailing |
|||
# 邮件发送系统 |
|||
|
|||
待添加 |
|||
ABP 框架为发送电子邮件提供各种服务、设置和集成; |
|||
|
|||
* 提供用于发送电子邮件的`IEmailSender`服务. |
|||
* 定义 [settings](Settings.md)来配置电子邮件发送. |
|||
* 集成到[后台作业系统](Background-Jobs.md)以通过后台作业发送电子邮件. |
|||
* 提供[MailKit 集成](MailKit.md)包. |
|||
|
|||
## 安装 |
|||
|
|||
> 如果你使用的是[应用程序启动模板](Startup-Templates/Application.md),则该软件包已安装。 |
|||
> |
|||
建议使用 [ABP CLI](CLI.md) 安装此包。在项目文件夹(.csproj 文件)中打开命令行窗口并键入以下命令: |
|||
|
|||
````bash |
|||
abp add-package Volo.Abp.Emailing |
|||
```` |
|||
如果你还没有做到这一点,你首先需要安装 ABP CLI。有关其他安装选项,请参阅 [包描述页面](https://abp.io/package-detail/Volo.Abp.Emailing)。 |
|||
|
|||
## 发送电子邮件 |
|||
|
|||
### IEmailSender |
|||
|
|||
[Inject](Dependency-Injection.md) 将 `IEmailSender` 注入任何服务并使用 `SendAsync` 方法发送电子邮件。 |
|||
**Example** |
|||
|
|||
````csharp |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Emailing; |
|||
|
|||
namespace MyProject |
|||
{ |
|||
public class MyService : ITransientDependency |
|||
{ |
|||
private readonly IEmailSender _emailSender; |
|||
|
|||
public MyService(IEmailSender emailSender) |
|||
{ |
|||
_emailSender = emailSender; |
|||
} |
|||
|
|||
public async Task DoItAsync() |
|||
{ |
|||
await _emailSender.SendAsync( |
|||
"target@domain.com", // target email address |
|||
"Email subject", // subject |
|||
"This is email body..." // email body |
|||
); |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
`SendAsync` 方法具有重载以提供更多参数,例如; |
|||
|
|||
* **from**: 你可以将其设置为设置发件人电子邮件地址。如果未提供,则使用默认发件人地址(请参阅下面的电子邮件设置) |
|||
* **isBodyHtml**: 表示邮件正文是否可以包含HTML标签。**默认:true**。 |
|||
|
|||
> `IEmailSender` 是建议的发送邮件的方式,因为它使你的代码提供者独立。 |
|||
|
|||
#### 邮件消息 |
|||
|
|||
除了原始参数之外,你还可以传递一个**标准的 `MailMessage` 对象**([参见](https://docs.microsoft.com/en-us/dotnet/api/system.net.mail.mailmessage) ) 到 `SendAsync` 方法以设置更多选项,例如添加附件。 |
|||
|
|||
### ISmtpEmailSender |
|||
|
|||
默认情况下,发送电子邮件由标准的 `SmtpClient` 类([参见](https://docs.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient))实现。实现类是`SmtpEmailSender`。此类还公开了 `ISmtpEmailSender` 服务(除了 `IEmailSender`)。 |
|||
|
|||
大多数时候你想直接使用`IEmailSender`来让你的代码提供者独立。但是,如果要创建具有相同电子邮件设置的 `SmtpClient` 对象,可以注入 `ISmtpEmailSender` 并使用其 `BuildClientAsync` 方法获取 `SmtpClient` 对象并自己发送电子邮件。 |
|||
|
|||
## 发送邮件任务队列/后台作业 |
|||
|
|||
`IEmailSender`有一个`QueueAsync`方法,可以用来将邮件添加到后台作业队列中,在后台线程中发送。通过这种方式,你不会因为等待发送邮件而占用用户的时间。`QueueAsync`方法得到的参数与`SendAsync`方法相同。 |
|||
|
|||
发送邮件任务队列可以容忍错误,因为后台作业系统具有重试机制来克服临时网络/服务器问题。 |
|||
|
|||
有关后台作业系统的更多信息,请参阅[后台作业文档](Background-Jobs.md)。 |
|||
|
|||
## 电子邮件设置 |
|||
|
|||
电子邮件发送使用 [设置系统](Settings.md) 来定义设置并在运行时获取这些设置的值。 `Volo.Abp.Emailing.EmailSettingNames` 定义了设置名称的常量,如下所示: |
|||
|
|||
* **Abp.Mailing.DefaultFromAddress**: 当你在发送电子邮件时未指定发件人时,用作发件人的电子邮件地址(就像上面的示例一样). |
|||
* **Abp.Mailing.DefaultFromDisplayName**: 当你在发送电子邮件时未指定发件人时,用作发件人的显示名称(就像在上面的示例中一样). |
|||
* **Abp.Mailing.Smtp.Host**: SMTP 服务器的 IP/域(默认值:127.0.0.1)。 |
|||
* **Abp.Mailing.Smtp.Port**: SMTP 服务器的端口(默认值:25). |
|||
* **Abp.Mailing.Smtp.UserName**: 用户名,如果 SMTP 服务器需要身份验证需要。 |
|||
* **Abp.Mailing.Smtp.Password**: 密码,如果 SMTP 服务器需要身份验证需要。 **此值已加密**(请参阅下面的部分). |
|||
* **Abp.Mailing.Smtp.Domain**: 账号域,如果 SMTP 服务器需要身份验证需要. |
|||
* **Abp.Mailing.Smtp.EnableSsl**: 指示 SMTP 服务器是否使用 SSL 的值(“true”或“false”。默认值:“false”). |
|||
* **Abp.Mailing.Smtp.UseDefaultCredentials**:如果为 true,则使用默认凭据,而不是提供的用户名和密码(“true”或“false”。默认值:“true”)。. |
|||
|
|||
可以从[设置管理](Modules/Setting-Management.md)模块的*设置页面*管理电子邮件设置: |
|||
|
|||
 |
|||
|
|||
>如果你已从 ABP 启动模板创建解决方案,则已安装设置管理模块。 |
|||
|
|||
如果你不使用设置管理模块,你可以简单地在 `appsettings.json` 文件中定义设置: |
|||
|
|||
````json |
|||
"Settings": { |
|||
"Abp.Mailing.Smtp.Host": "127.0.0.1", |
|||
"Abp.Mailing.Smtp.Port": "25", |
|||
"Abp.Mailing.Smtp.UserName": "", |
|||
"Abp.Mailing.Smtp.Password": "", |
|||
"Abp.Mailing.Smtp.Domain": "", |
|||
"Abp.Mailing.Smtp.EnableSsl": "false", |
|||
"Abp.Mailing.Smtp.UseDefaultCredentials": "true", |
|||
"Abp.Mailing.DefaultFromAddress": "noreply@abp.io", |
|||
"Abp.Mailing.DefaultFromDisplayName": "ABP application" |
|||
} |
|||
```` |
|||
|
|||
You can set/change these settings programmatically using the `ISettingManager` and store values in a database. See the [setting system document](Settings.md) to understand the setting system better. |
|||
你可以使用 `ISettingManager` 以编程方式设置/更改这些设置,并将值存储在数据库中。请参阅 [设置系统文档](Settings.md)更好地了解设置系统。 |
|||
|
|||
### 加密 SMTP 密码 |
|||
|
|||
*Abp.Mailing.Smtp.Password* 必须是一个**加密**值。如果你使用 `ISettingManager` 设置密码,你不必担心。它在内部加密 set 上的值并在 get 上解密。 |
|||
|
|||
如果使用 `appsettings.json` 存储密码,则应手动注入 `ISettingEncryptionService` 并使用其 `Encrypt` 方法获取加密值。这可以通过在你的应用程序中创建一个简单的代码来完成。然后你可以删除代码。更好的是,你可以在应用程序中创建一个 UI 来配置电子邮件设置。在这种情况下,你可以直接使用 `ISettingManager` 而不用担心加密。 |
|||
|
|||
### ISmtpEmailSenderConfiguration |
|||
|
|||
如果你不想使用设置系统来存储电子邮件发送配置,你可以将 `ISmtpEmailSenderConfiguration` 服务替换为你自己的实现,以从任何其他来源获取配置。 `ISmtpEmailSenderConfiguration` 默认由 `SmtpEmailSenderConfiguration` 实现,如上所述,它从设置系统中获取配置。 |
|||
|
|||
## 文本模板集成 |
|||
|
|||
ABP 框架提供了一个强大而灵活的[文本模板系统](Text-Templating.md)。你可以使用文本模板系统来创建动态电子邮件内容。注入 `ITemplateRenderer` 并使用 `RenderAsync` 渲染模板。然后将结果用作电子邮件正文。 |
|||
|
|||
虽然你可以定义和使用自己的文本模板,但电子邮件发送系统提供了两个简单的内置文本模板。 |
|||
|
|||
**示例:使用标准和简单的消息模板发送电子邮件** |
|||
|
|||
````csharp |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Emailing; |
|||
using Volo.Abp.Emailing.Templates; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace Acme.BookStore.Web |
|||
{ |
|||
public class MyService : ITransientDependency |
|||
{ |
|||
private readonly IEmailSender _emailSender; |
|||
private readonly ITemplateRenderer _templateRenderer; |
|||
|
|||
public MyService( |
|||
IEmailSender emailSender, |
|||
ITemplateRenderer templateRenderer) |
|||
{ |
|||
_emailSender = emailSender; |
|||
_templateRenderer = templateRenderer; |
|||
} |
|||
|
|||
public async Task DoItAsync() |
|||
{ |
|||
var body = await _templateRenderer.RenderAsync( |
|||
StandardEmailTemplates.Message, |
|||
new |
|||
{ |
|||
message = "This is email body..." |
|||
} |
|||
); |
|||
|
|||
await _emailSender.SendAsync( |
|||
"target-address@domain.com", |
|||
"Email subject", |
|||
body |
|||
); |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
生成的电子邮件正文将如下所示: |
|||
|
|||
````html |
|||
<!DOCTYPE html> |
|||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> |
|||
<head> |
|||
<meta charset="utf-8" /> |
|||
</head> |
|||
<body> |
|||
This is email body... |
|||
</body> |
|||
</html> |
|||
```` |
|||
|
|||
电子邮件系统定义了具有给定名称的内置文本模板: |
|||
|
|||
"**Abp.StandardEmailTemplates.Message**" 是最简单的带有文本消息的模板: |
|||
|
|||
````html |
|||
{%{{{model.message}}}%} |
|||
```` |
|||
|
|||
此模板使用“Abp.StandardEmailTemplates.Layout”作为其布局. |
|||
|
|||
"**Abp.StandardEmailTemplates.Layout**" 是一个提供 HTML 文档布局的简单模板: |
|||
|
|||
````html |
|||
<!DOCTYPE html> |
|||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> |
|||
<head> |
|||
<meta charset="utf-8" /> |
|||
</head> |
|||
<body> |
|||
{%{{{content}}}%} |
|||
</body> |
|||
</html> |
|||
```` |
|||
|
|||
最终呈现的消息如上所示。 |
|||
|
|||
> 这些模板名称是在 `Volo.Abp.Emailing.Templates.StandardEmailTemplates` 类中定义的。 |
|||
|
|||
### 覆盖/替换标准模板 |
|||
|
|||
You typically want to replace the standard templates with your own ones, so you can prepare a branded email messages. To do that, you can use the power of the [virtual file system](Virtual-File-System.md) (VFS) or replace them in your own template definition provider. |
|||
你希望用自己的模板替换标准模板,这样你就可以准备电子邮件模板文件。你可以使用 [虚拟文件系统](Virtual-File-System.md) (VFS),或在你自己的模板定义提供程序中替换它们。 |
|||
|
|||
虚拟文件系统中模板的路径如下图所示: |
|||
|
|||
* `/Volo/Abp/Emailing/Templates/Layout.tpl` |
|||
* `/Volo/Abp/Emailing/Templates/Message.tpl` |
|||
|
|||
如果你将文件添加到虚拟文件系统中的相同位置,你的文件将覆盖它们。 |
|||
|
|||
模板是内联本地化的,这意味着你可以利用 [本地化系统](Localization.md) 的强大功能使你的模板具有多元文化。 |
|||
|
|||
详见[文本模板系统](Text-Templating.md) 文档。 |
|||
|
|||
> 请注意,你可以为应用程序定义和使用自己的模板,而不是使用标准的简单模板。这些标准模板主要用于可重用的模块,它们不定义自己的模板,而是依赖内置的模板。只需覆盖标准的电子邮件布局模板,就可以轻松自定义使用的模块发送的电子邮件。 |
|||
|
|||
## NullEmailSender |
|||
|
|||
`NullEmailSender` 是实现 `IEmailSender` 的内置类,但将电子邮件内容写入 [标准日志系统](Logging.md),而不是实际发送电子邮件。 |
|||
|
|||
这个类特别有用,尤其是在你开发是不想发送真实电子邮件。 [应用启动模板](Startup-Templates/Application.md)已经在**DEBUG模式**中使用了这个类,在领域层配置如下: |
|||
|
|||
````csharp |
|||
#if DEBUG |
|||
context.Services.Replace(ServiceDescriptor.Singleton<IEmailSender, NullEmailSender>()); |
|||
#endif |
|||
```` |
|||
|
|||
因此,你在 DEBUG 模式下不会收到电子邮件。电子邮件将在生产时按预期发送(RELEASE 模式)。如果你也想在 DEBUG 上发送电子邮件,请删除这些行。 |
|||
|
|||
## 其他 |
|||
|
|||
* [用于发送电子邮件的MailKit集成](MailKit.md) |
|||
|
|||