Browse Source

Merge branch 'dev' into feliks

pull/8416/head
Feliks 6 years ago
parent
commit
204310378b
  1. 8
      .github/workflows/angular.yml
  2. 16
      .github/workflows/auto-pr.yml
  3. 22
      .github/workflows/build-and-test.yml
  4. 6
      Directory.Build.props
  5. 2
      README.md
  6. 62
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
  7. 56
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json
  8. 63
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json
  9. 14
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
  10. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
  11. 9
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
  12. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
  13. 31
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
  14. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
  15. 7
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
  16. 2
      common.props
  17. 2
      configureawait.props
  18. 20
      delete-bin-obj-folders.bat
  19. 2
      docs/en/API/Dynamic-CSharp-API-Clients.md
  20. 48
      docs/en/Application-Services.md
  21. 139
      docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/POST.md
  22. BIN
      docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/abp-suite-separate-tenant-schema.png
  23. BIN
      docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/account-lepton-source.png
  24. BIN
      docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/cms-kit-menu.png
  25. BIN
      docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/cms-kit-selection.png
  26. BIN
      docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/enable-disable-features.png
  27. BIN
      docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/forms-answer.png
  28. BIN
      docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/forms-edit-report.png
  29. BIN
      docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/new-tenant-modal.png
  30. BIN
      docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/tenant-db-migrate.png
  31. 189
      docs/en/Blog-Posts/2021-03-31 v4_3 Preview/POST.md
  32. BIN
      docs/en/Blog-Posts/2021-03-31 v4_3 Preview/email-settings-page.png
  33. 3
      docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md
  34. 216
      docs/en/CLI-New-Command-Samples.md
  35. 4
      docs/en/CLI.md
  36. 2
      docs/en/Community-Articles/2020-10-08-How-To-Add-Custom-Property-To-The-User-Entity/How-To-Add-Custom-Property-To-The-User-Entity.md
  37. 99
      docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md
  38. BIN
      docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/add-endpoint.jpg
  39. BIN
      docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/add-script-bundles.jpg
  40. BIN
      docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/article-signalr-banner.png
  41. BIN
      docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/notification-hub.jpg
  42. BIN
      docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/preconfigureservices.jpg
  43. BIN
      docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/resource-mappings.jpg
  44. BIN
      docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/result.jpg
  45. BIN
      docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/signalr-architecture.png
  46. BIN
      docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/signalr-folder.jpg
  47. BIN
      docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/signalr-package.jpg
  48. 8
      docs/en/Domain-Driven-Design-Implementation-Guide.md
  49. 10
      docs/en/Emailing.md
  50. 2
      docs/en/Entity-Framework-Core-Oracle.md
  51. 16
      docs/en/Features.md
  52. 12
      docs/en/Getting-Started-Create-Solution.md
  53. 14
      docs/en/Getting-Started-Running-Solution.md
  54. 2
      docs/en/Getting-Started-Setup-Environment.md
  55. 2
      docs/en/Getting-Started.md
  56. 37
      docs/en/Migration-Guides/Abp-4_3.md
  57. 1
      docs/en/Migration-Guides/Index.md
  58. 88
      docs/en/Migration-Guides/Upgrading-Startup-Template.md
  59. 4
      docs/en/Module-Entity-Extensions.md
  60. 3
      docs/en/Modules/Blogging.md
  61. 3
      docs/en/Modules/Client-Simulation.md
  62. 3
      docs/en/Modules/Index.md
  63. 3
      docs/en/Modules/Users.md
  64. 100
      docs/en/Multi-Lingual-Entities.md
  65. 55
      docs/en/Road-Map.md
  66. 2
      docs/en/Tutorials/Part-1.md
  67. 32
      docs/en/Tutorials/Part-10.md
  68. 4
      docs/en/Tutorials/Part-2.md
  69. 8
      docs/en/Tutorials/Part-3.md
  70. 2
      docs/en/Tutorials/Part-4.md
  71. 8
      docs/en/Tutorials/Part-5.md
  72. 2
      docs/en/Tutorials/Part-6.md
  73. 2
      docs/en/Tutorials/Part-7.md
  74. 6
      docs/en/Tutorials/Part-8.md
  75. 8
      docs/en/Tutorials/Part-9.md
  76. BIN
      docs/en/Tutorials/images/blazor-edit-book-action-2.png
  77. 125
      docs/en/UI/Angular/Account-Module.md
  78. 36
      docs/en/UI/Angular/Authorization.md
  79. 2
      docs/en/UI/Angular/Entity-Action-Extensions.md
  80. 103
      docs/en/UI/Angular/HTTP-Requests.md
  81. 2
      docs/en/UI/Angular/How-Replaceable-Components-Work-with-Extensions.md
  82. 6
      docs/en/UI/Angular/Modal.md
  83. 218
      docs/en/UI/Angular/Page-Component.md
  84. 2
      docs/en/UI/Angular/Permission-Management-Component-Replacement.md
  85. BIN
      docs/en/UI/Angular/images/custom-error-handler-404-component.jpg
  86. BIN
      docs/en/UI/Angular/images/custom-error-handler-toaster-message.jpg
  87. 41
      docs/en/UI/AspNetCore/Bundling-Minification.md
  88. 20
      docs/en/UI/AspNetCore/Navigation-Menu.md
  89. 17
      docs/en/UI/AspNetCore/Toolbars.md
  90. 8
      docs/en/Upgrading.md
  91. 21
      docs/en/docs-nav.json
  92. 3
      docs/en/docs-params.json
  93. BIN
      docs/en/images/email-settings.png
  94. BIN
      docs/en/images/upgrade-diff-empty-folders.png
  95. BIN
      docs/en/images/winmerge-comparison-result.png
  96. BIN
      docs/en/images/winmerge-file-diff.png
  97. BIN
      docs/en/images/winmerge-open-folders.png
  98. 4
      docs/pt-BR/Tutorials/Angular/Part-II.md
  99. 3
      docs/zh-Hans/CLI.md
  100. 10
      docs/zh-Hans/Domain-Driven-Design-Implementation-Guide.md

8
.github/workflows/angular.yml

@ -2,8 +2,14 @@ name: 'Angular'
on:
pull_request:
paths:
- 'npm/ng-packs/**'
- 'npm/ng-packs/**/*.ts'
- 'npm/ng-packs/**/*.html'
- 'npm/ng-packs/*.json'
- '!npm/ng-packs/scripts/**'
- '!npm/ng-packs/packages/schematics/**'
branches:
- 'rel-*'
- 'dev'
jobs:
build-test-lint:
runs-on: ubuntu-18.04

16
.github/workflows/auto-pr.yml

@ -1,10 +1,10 @@
name: Merge branch dev with rel-4.2
name: Merge branch dev with rel-4.3
on:
push:
branches:
- rel-4.2
- rel-4.3
jobs:
merge-dev-with-rel-4-2:
merge-dev-with-rel-4-3:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@ -12,13 +12,13 @@ jobs:
ref: dev
- name: Reset promotion branch
run: |
git fetch origin rel-4.2:rel-4.2
git reset --hard rel-4.2
git fetch origin rel-4.3:rel-4.3
git reset --hard rel-4.3
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
branch: auto-merge/rel-4-2/${{github.run_number}}
title: Merge branch dev with rel-4.2
body: This PR generated automatically to merge dev with rel-4.2. Please review the changed files before merging to prevent any errors that may occur.
branch: auto-merge/rel-4-3/${{github.run_number}}
title: Merge branch dev with rel-4.3
body: This PR generated automatically to merge dev with rel-4.3. Please review the changed files before merging to prevent any errors that may occur.
reviewers: ${{github.actor}}
token: ${{ github.token }}

22
.github/workflows/build-and-test.yml

@ -2,14 +2,18 @@ name: "build and test"
on:
pull_request:
paths:
- "framework/**"
- "modules/**"
- "templates/**"
push:
paths:
- "framework/**"
- "modules/**"
- "templates/**"
- 'framework/**/*.cs'
- 'framework/**/*.cshtml'
- 'framework/**/*.csproj'
- 'framework/**/*.razor'
- 'modules/**/*.cs'
- 'modules/**/*.cshtml'
- 'modules/**/*.csproj'
- 'modules/**/*.razor'
- 'templates/**/*.cs'
- 'templates/**/*.cshtml'
- 'templates/**/*.csproj'
- 'templates/**/*.razor'
jobs:
build-test:
runs-on: windows-latest
@ -17,7 +21,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-dotnet@master
with:
dotnet-version: 5.0.100
dotnet-version: 5.0.201
- name: Build All
run: .\build-all.ps1

6
Directory.Build.props

@ -5,13 +5,13 @@
<MicrosoftPackageVersion>5.0.*</MicrosoftPackageVersion>
<!-- Microsoft.NET.Test.Sdk https://www.nuget.org/packages/Microsoft.NET.Test.Sdk -->
<MicrosoftNETTestSdkPackageVersion>16.8.3</MicrosoftNETTestSdkPackageVersion>
<MicrosoftNETTestSdkPackageVersion>16.9.1</MicrosoftNETTestSdkPackageVersion>
<!-- NSubstitute https://www.nuget.org/packages/NSubstitute -->
<NSubstitutePackageVersion>4.2.2</NSubstitutePackageVersion>
<!-- Shouldly https://www.nuget.org/packages/Shouldly -->
<ShouldlyPackageVersion>4.0.1</ShouldlyPackageVersion>
<ShouldlyPackageVersion>4.0.3</ShouldlyPackageVersion>
<!-- xunit https://www.nuget.org/packages/xUnit -->
<xUnitPackageVersion>2.4.1</xUnitPackageVersion>
@ -23,7 +23,7 @@
<xUnitRunnerVisualstudioPackageVersion>2.4.3</xUnitRunnerVisualstudioPackageVersion>
<!-- Mongo2Go https://www.nuget.org/packages/Mongo2Go -->
<Mongo2GoPackageVersion>2.2.14</Mongo2GoPackageVersion>
<Mongo2GoPackageVersion>3.0.0</Mongo2GoPackageVersion>
</PropertyGroup>
</Project>

2
README.md

@ -1,6 +1,6 @@
# ABP Framework
![build and test](https://github.com/abpframework/abp/workflows/build%20and%20test/badge.svg)
![build and test](https://img.shields.io/github/workflow/status/abpframework/abp/build%20and%20test/dev?style=flat-square)
[![NuGet](https://img.shields.io/nuget/v/Volo.Abp.Core.svg?style=flat-square)](https://www.nuget.org/packages/Volo.Abp.Core)
[![NuGet (with prereleases)](https://img.shields.io/nuget/vpre/Volo.Abp.Core.svg?style=flat-square)](https://www.nuget.org/packages/Volo.Abp.Core)
[![MyGet (nightly builds)](https://img.shields.io/myget/abp-nightly/vpre/Volo.Abp.svg?style=flat-square)](https://docs.abp.io/en/abp/latest/Nightly-Builds)

62
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json

@ -207,7 +207,7 @@
"DeleteCoverImageConfirmationMessage": "Are you sure you want to delete the cover image for \"{0}\"?",
"DeleteCoverImageSuccessMessage": "Cover image successfully deleted",
"PaymentsOf": "Payments of",
"ShowPaymentsOfOrganization": "Show payments",
"ShowPaymentsOfOrganization": "Payments",
"Date": "Date",
"Products": "Products",
"TotalAmount": "Total amount",
@ -215,8 +215,62 @@
"Gateway": "Gateway",
"State": "State",
"FailReason": "Fail reason",
"ReIndexAllPosts": "ReIndex All Posts",
"ReIndexAllPostsConfirmationMessage": "Are you sure to reindex all posts?",
"SuccessfullyReIndexAllPosts": "Successfully reindex for all posts"
"ReIndexAllPosts": "Reindex All Posts",
"ReIndexAllPostsConfirmationMessage": "Are you sure you want to reindex all posts?",
"SuccessfullyReIndexAllPosts": "All posts have been successfully reindexed.",
"Permission:FullSearch": "Full text search",
"Menu:CliAnalytics": "Cli Analytics",
"TemplateName": "Template name",
"TemplateVersion": "Template version",
"DatabaseProvider": "Database provider",
"IsTiered": "Is Tiered",
"ProjectName": "Project name",
"Username": "User name",
"Tool": "Tool",
"Command": "Command",
"UiFramework": "Ui framework",
"Options": "Options",
"CliAnalytics": "Cli Analytics",
"Permission:CliAnalyticses": "Cli Analyticses",
"Permission:CliAnalytics": "Cli Analytics",
"Search": "Search",
"ClearFilter": "Clear filter",
"LicensePrivateKey": "License private key",
"LicensePublicKey": "License public key",
"ApiKey": "NuGet API key",
"ShowInvoiceRequestsOfOrganization": "Invoice requests",
"ShowQuestionsOfOrganization": "Questions",
"Question": "Question",
"Open": "Open",
"Questions": "Questions",
"InvoiceRequests": "Invoice Requests",
"Address": "Address",
"TaxNo": "Tax No",
"Permission:InvoiceRequest": "Invoice Request",
"Permission:Question": "Question",
"AddNoteSuccessMessage": "Note successfully added",
"NameSurname": "Name Surname",
"Note": "Note",
"Add": "Add",
"ProjectDownloads": "Project Downloads",
"ShowProjectDownloadsOfOrganization": "Project Downloads",
"ShowAuditLogsOfOrganization": "Audit Logs",
"Enum:EntityChangeType:0": "Created",
"Enum:EntityChangeType:1": "Updated",
"Enum:EntityChangeType:2": "Deleted",
"TenantId": "Tenant ID",
"ChangeTime": "Change time",
"EntityTypeFullName": "Entity type full name",
"AuditLogsFor{0}Organization": "Audit logs for \"{0}\" organization",
"Permission:EntityChange": "Entity Change",
"Permission:ProjectDownload": "Project Download",
"Permission:PaymentRequest": "Payment Request",
"CreatorEmailAddress": "Creator email address",
"EmailSendDate": "Email send date",
"PaymentRequestsFor{0}Organization": "Payment requests for \"{0}\" organization",
"PaymentDetails": "Payment Details",
"PaymentProduct": "Payment Product",
"ProductName": "Product Name",
"Code": "Code"
}
}

56
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json

@ -166,6 +166,60 @@
"DeleteCoverImageSuccessMessage": "Kapak fotoğrafı başarılı bir şekilde silinmiştir",
"ReIndexAllPosts": "Yeniden indeksle",
"ReIndexAllPostsConfirmationMessage": "Tüm gönderileri yeniden indeksleyeceğinizden emin misiniz?",
"SuccessfullyReIndexAllPosts": "Tüm gönderiler başarıyla yeniden indekslendi"
"SuccessfullyReIndexAllPosts": "Tüm gönderiler başarıyla yeniden indekslendi",
"Menu:CliAnalytics": "Cli Analitik",
"TemplateName": "Şablon ismi",
"TemplateVersion": "Şablon versiyon",
"DatabaseProvider": "Veritabanı sağlayıcı",
"IsTiered": "Katmanlı mı",
"ProjectName": "Proje ismi",
"Username": "Kullanıcı adı",
"Tool": "Araç",
"Command": "Komut",
"UiFramework": "Ui çerçevesi",
"Options": "Seçenekler",
"CliAnalytics": "Cli Analitik",
"Permission:CliAnalyticses": "Cli Analitikleri",
"Permission:CliAnalytics": "Cli Analitik",
"Search": "Ara",
"ShowPaymentsOfOrganization": "Ödemeler",
"ClearFilter": "Filtreyi temizle",
"LicensePrivateKey": "Lisans özel anahtar",
"LicensePublicKey": "Lisans genel key",
"ApiKey": "NuGet API anahatar",
"ShowInvoiceRequestsOfOrganization": "Fatura talepleri",
"ShowQuestionsOfOrganization": "Sorular",
"Question": "Soru",
"Open": "Aç",
"Questions": "Sorular",
"InvoiceRequests": "Fatura talepleri",
"Address": "Adres",
"TaxNo": "Vergi no",
"Permission:InvoiceRequest": "Fatura Talebi",
"Permission:Question": "Soru",
"AddNoteSuccessMessage": "Not başarıyla eklendi",
"NameSurname": "Adı Soyadı",
"Note": "Not",
"Add": "Ekle",
"ProjectDownloads": "Proje İndirmeleri",
"ShowProjectDownloadsOfOrganization": "Proje İndirmeleri",
"ShowAuditLogsOfOrganization": "Denetim Günlükleri",
"Enum:EntityChangeType:0": "Oluşturuldu",
"Enum:EntityChangeType:1": "Güncellendi",
"Enum:EntityChangeType:2": "Silindi",
"TenantId": "Kiracı Kimliği",
"ChangeTime": "Değişiklik Zamanı",
"EntityTypeFullName": "Varlık türü tam adı",
"AuditLogsFor{0}Organization": "\"{0}\" kuruluşu için denetim günlükleri",
"Permission:EntityChange": "Varlık Değişikliği",
"Permission:ProjectDownload": "Proje İndirme",
"Permission:PaymentRequest": "Ödeme isteği",
"CreatorEmailAddress": "Oluşturan kişinin e-posta adresi",
"EmailSendDate": "E-posta gönderme tarihi",
"PaymentRequestsFor{0}Organization": "\"{0}\" kuruluşu için ödeme istekleri",
"PaymentDetails": "Ödeme Detayları",
"PaymentProduct": "Ödeme Ürünü",
"ProductName": "Ürün İsmi",
"Code": "Kod"
}
}

63
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json

@ -35,6 +35,7 @@
"NameFilter": "名称",
"CreationTime": "创建时间",
"IsPro": "是否为专业版",
"IsFreeToActiveLicenseOwners": "许可证所有者免费",
"ShowOnModuleList": "展示模块列表",
"EfCoreConfigureMethodName": "配置方法法",
"IsProFilter": "是否为专业版",
@ -90,6 +91,7 @@
"UserNotFound": "用户不存在",
"{0}WillBeRemovedFromDevelopers": "{0} 将从开发者中移除, 你确定吗?",
"{0}WillBeRemovedFromOwners": "{0} 将从所有者中移除, 你确定吗?",
"{0}WillBeRemovedFromMembers": "{0} 将从成员中删除, 你确定吗?",
"Computers": "计算机",
"UniqueComputerId": "计算机唯一ID",
"LastSeenDate": "上次查看日期",
@ -194,6 +196,65 @@
"CoverImage": "封面图片",
"RemoveCacheConfirmationMessage": "你确定要删除\"{0}\" 文章缓存?",
"SuccessfullyRemoved": "清除成功",
"RemoveCache": "删除缓存"
"RemoveCache": "删除缓存",
"Language": "语言",
"Optional": "可选的",
"CreateArticleLanguageInfo": "发帖所用的语言",
"Enum:ContentSource:2": "视频发布",
"VideoPreview": "视频预览",
"VideoPreviewErrorMessage": "无法从YouTube获取给定的视频网址. 可能是由于视频是私有视频,或者给定的URL不可用.",
"DeleteCoverImage": "删除封面图片",
"DeleteCoverImageConfirmationMessage": "你确定要删除封面图片吗",
"DeleteCoverImageSuccessMessage": "成功删除封面图片",
"PaymentsOf": "付款的",
"ShowPaymentsOfOrganization": "显示付款",
"Date": "日期",
"Products": "商品",
"TotalAmount": "总金额",
"Currency": "货币",
"Gateway": "网关",
"State": "状态",
"FailReason": "失败原因",
"ReIndexAllPosts": "重新索引所有帖子",
"ReIndexAllPostsConfirmationMessage": "你确定要重新索引所有的帖子吗",
"SuccessfullyReIndexAllPosts": "成功索引所有的帖子",
"ClearFilter": "清除过滤",
"LicensePrivateKey": "许可私有密钥",
"LicensePublicKey": "许可公有密钥",
"ApiKey": "NuGet API密钥",
"ShowInvoiceRequestsOfOrganization": "发票请求",
"ShowQuestionsOfOrganization": "问题",
"Question": "问题",
"Open": "打开",
"Questions": "问题",
"InvoiceRequests": "发票请求",
"Address": "地址",
"TaxNo": "税号",
"Permission:InvoiceRequest": "发票请求",
"Permission:Question": "问题",
"AddNoteSuccessMessage": "注释添加成功",
"NameSurname": "姓",
"Note": "注释",
"Add": "添加",
"ProjectDownloads": "项目下载",
"ShowProjectDownloadsOfOrganization": "项目下载",
"ShowAuditLogsOfOrganization": "审核日志",
"Enum:EntityChangeType:0": "已建立",
"Enum:EntityChangeType:1": "更新",
"Enum:EntityChangeType:2": "已删除",
"TenantId": "租户ID",
"ChangeTime": "变更时间",
"EntityTypeFullName": "实体类型全名",
"AuditLogsFor{0}Organization": "\"{0}\" 组织的审核日志",
"Permission:EntityChange": "实体变更",
"Permission:ProjectDownload": "项目下载",
"Permission:PaymentRequest": "支付请求",
"CreatorEmailAddress": "创作者的电子邮件地址",
"EmailSendDate": "电子邮件发送日期",
"PaymentRequestsFor{0}Organization": "\"{0}\" 组织的付款请求",
"PaymentDetails": "付款详情",
"PaymentProduct": "付款产品",
"ProductName": "产品名称",
"Code": "代码"
}
}

14
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json

@ -128,13 +128,13 @@
"YourFullName": "Your full name",
"EmailField": "E-mail Address",
"YourEmailAddress": "Your e-mail address",
"HowMayWeHelpYou": "How may we help you",
"HowMayWeHelpYou": "How may we help you?",
"SendMessage": "Send Message",
"Success": "Success",
"WeWillReplyYou.": "Your message is sent! We will reply you in a short time.",
"WeWillReplyYou": "We received your message and will be in touch shortly.",
"GoHome": "Go Home",
"CreateLiveDemo": "Create Live Demo",
"RegisterToTheNewsletter": "Register to the newsletter to get information on happenings about ABP.IO, like new releases.",
"RegisterToTheNewsletter": "Register for the newsletter to receive information regarding ABP.IO, including new releases etc.",
"EnterYourEmailOrLogin": "Enter your e-mail address to create your demo or <a href=\"{0}\">Login</a> using your existing account.",
"ApplicationTemplate": "Application Template",
"ApplicationTemplateExplanation": "Application startup template is used to create a new web application.",
@ -285,6 +285,10 @@
"YearPremiumForumSupport": "1 year premium forum support",
"ForumSupportIncidentCountYear": "Forum support incident count/year",
"PrivateTicketEmailSupport": "Private ticket & email support",
"BuyNow": "Buy Now"
"BuyNow": "Buy Now",
"PayViaAmexCard": "How can I pay via my AMEX card?",
"PayViaAmexCardDescription": "The default payment gateway 'Iyzico' may decline some AMEX credit cards due to the security measures. In this case, you can pay through the alternative payment gateway '2Checkout'.",
"ThankYou": "Thank you",
"InvalidReCaptchaErrorMessage": "There was an error verifying reCAPTCHA. Please try again."
}
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json

@ -30,6 +30,7 @@
"UserNameNotFound": "{0} kullanıcı adı ile bir kullanıcı yok",
"SuccessfullyAddedToNewsletter": "Bültenimize abone olduğunuz için teşekkürler!",
"MyProfile": "Profilim",
"EmailNotValid": "Lütfen uygun bir e-posta adresi giriniz"
"EmailNotValid": "Lütfen uygun bir e-posta adresi giriniz",
"InvalidReCaptchaErrorMessage": "ReCAPTCHA doğrulanırken hata oluştu, lütfen tekrar deneyin."
}
}

9
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json

@ -131,7 +131,7 @@
"HowMayWeHelpYou": "我们如何帮助你",
"SendMessage": "发送消息",
"Success": "成功",
"WeWillReplyYou.": "你的消息已经发送! 我们会在短时间内给你答复.",
"WeWillReplyYou": "你的消息已经发送! 我们会在短时间内给你答复.",
"GoHome": "回到主页面",
"CreateLiveDemo": "创建在线演示",
"RegisterToTheNewsletter": "注册到时事简报以获取有关ABP.IO的消息,比如新发布的内容.",
@ -285,6 +285,9 @@
"YearPremiumForumSupport": "1年高级论坛支持",
"ForumSupportIncidentCountYear": "论坛支持事件数量/年",
"PrivateTicketEmailSupport": "私有票和email支持",
"BuyNow": "现在购买"
"BuyNow": "现在购买",
"PayViaAmexCard": "我如何通过我的AMEX卡付款?",
"PayViaAmexCardDescription": "由于安全措施,默认付款网关“ Iyzico”可能会拒绝某些AMEX信用卡。 在这种情况下,您可以通过备用付款网关“ 2Checkout”付款。",
"InvalidReCaptchaErrorMessage": "验证reCAPTCHA时出错,请重试。"
}
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json

@ -138,6 +138,7 @@
"TwitterUserNameValidationMessage": "Your Twitter username can not include whitespace, please be sure your Twitter username is correct.",
"LinkedinUrlValidationMessage": "Your Linkedin URL can not include whitespace, please be sure your Linkedin URL is correct.",
"NoPostsFound": "No posts found!",
"SearchInPosts": "Search in posts..."
"SearchInPosts": "Search in posts...",
"MinimumSearchContent": "You must enter at least 3 characters!"
}
}

31
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json

@ -110,7 +110,34 @@
"VideoContentForm": "视频内容来源",
"GithubPostForm": "Github文章来源",
"ExternalPostForm": "外部文章来源",
"PostSourceTypeChooses": "我们接受文章的三种来源类型;",
"Posts": "文章"
"HowToPost": "如何发布",
"Posts": "文章",
"VideoUrl": "视频Url",
"GithubArticleUrl": "Github文章Url",
"ExternalArticleUrl": "外部文章Url",
"CreatePostCoverInfo": "要创建一个有效的帖子,需要添加封面图片. 上传16:9的图片获取最佳视觉效果. 文件最大支持: 1MB",
"ThankYouForContribution": "感谢你对ABP社区的贡献",
"GithubArticle": "Github文章",
"GithubArticleSubmitStepOne": "<span class=\"font-weight-bold\">1.</span> 用Markdown格式在GitHub的任何公共存储库上写一篇文章. <a target=\"_blank\" href=\"https://github.com/abpframework/abp/blob/dev/docs/en/Community-Articles/2020-12-04-Event-Organizer/Post.md\">示例</a>",
"GithubArticleSubmitStepTwo": "<span class=\"font-weight-bold\">2.</span> 使用表单提交你的文章URL.",
"GithubArticleSubmitStepThree": "<span class=\"font-weight-bold\">3.</span> 你的文章将在这个网站中呈现.",
"YoutubeVideo": "Youtube视频",
"YoutubeVideoSubmitStepOne": "<span class=\"font-weight-bold\">1.</span> 在YouTube上发布你的视频.",
"YoutubeVideoSubmitStepTwo": "<span class=\"font-weight-bold\">2.</span> 使用表单提交视频URL.",
"YoutubeVideoSubmitStepThree": "<span class=\"font-weight-bold\">3.</span> 访客将能够在这个网站上直接观看你的视频内容.",
"ExternalContent": "外部内容",
"ExternalContentSubmitStepOne": "<span class=\"font-weight-bold\">1.</span> 在任何公开的平台创建内容(medium, 你自己的博客或者任何你喜欢的).",
"ExternalContentSubmitStepTwo": "<span class=\"font-weight-bold\">2.</span> 使用表单提交内容URL.",
"ExternalContentSubmitStepThree": "<span class=\"font-weight-bold\">3.</span> 访客被重定向到原网站的内容.",
"ChooseYourContentType": "请选择你想要添加内容的方式",
"PostContentViaGithub": "我想要使用<span class=\"font-weight-bold\"><i class=\"fa fa-github\"></i> GitHub</span>提交markdown格式的文章",
"PostContentViaYoutube": "我想要分享我在<span class=\"font-weight-bold\"><i class=\"fa fa-youtube\"></i> Youtube</span>的可用视频",
"PostContentViaExternalSource": "我想要添加我在<span class=\"font-weight-bold\">其他平台</span>发布的内容",
"GitHubUserNameValidationMessage": "您的Github用户名不能包含空格, 请确认你的Github用户名是正确的.",
"PersonalSiteUrlValidationMessage": "你的个人网站URL不能包含空格, 请确定你的个人网站URL是正确的.",
"TwitterUserNameValidationMessage": "你的Twitter用户名不能包含空格, 请确认你的Twitter用户名是正确的.",
"LinkedinUrlValidationMessage": "你的领英URL不能包含空格, 请确认你的领英URL是正确的",
"NoPostsFound": "没有发现帖子",
"SearchInPosts": "搜索帖子…"
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json

@ -196,6 +196,7 @@
"MultipleDBOptionsExplanation": "The framework can work with any data source, while the following providers are officially developed and supported;",
"SelectLanguage": "Select language",
"LatestArticleOnCommunity": "Latest Article on ABP Community",
"Register": "Register"
"Register": "Register",
"IsDownloadable": "Is downloadable"
}
}

7
abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json

@ -8,6 +8,7 @@
"ProjectName": "项目名称",
"ProjectType": "项目类型",
"DatabaseProvider": "数据库提供者",
"DatabaseManagementSystem": "数据库管理系统",
"NTier": "N层",
"IncludeUserInterface": "包含用户界面",
"CreateNow": "现在创建",
@ -194,7 +195,7 @@
"MultipleUIOptionsExplanation": "核心框架设计为独立与UI,可以和任何类型的UI系统一起使用. 同时提供了多个开箱即用的预构建集成选项.",
"MultipleDBOptionsExplanation": "该框架可以使用任何数据源,并且以下提供程序已得到正式开发和支持;",
"SelectLanguage": "选择语言",
"LatestArticleOnCommunity": "关于ABP社区的最新文章",
"Register": "寄存器"
"LatestArticleOnCommunity": "关于ABP社区的最新文章",
"Register": "寄存器"
}
}
}

2
common.props

@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>4.3.0</Version>
<Version>4.4.0</Version>
<NoWarn>$(NoWarn);CS1591;CS0436</NoWarn>
<PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl>
<PackageProjectUrl>https://abp.io/</PackageProjectUrl>

2
configureawait.props

@ -1,7 +1,7 @@
<Project>
<ItemGroup>
<PackageReference Include="ConfigureAwait.Fody" Version="3.3.1" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.2.0">
<PackageReference Include="Fody" Version="6.5.0">
<PrivateAssets>All</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>

20
delete-bin-obj-folders.bat

@ -0,0 +1,20 @@
@ECHO off
cls
ECHO Deleting all BIN and OBJ folders...
ECHO.
FOR /d /r . %%d in (bin,obj) DO (
IF EXIST "%%d" (
ECHO %%d | FIND /I "\node_modules\" > Nul && (
ECHO.Skipping: %%d
) || (
ECHO.Deleting: %%d
rd /s/q "%%d"
)
)
)
ECHO.
ECHO.BIN and OBJ folders have been successfully deleted. Press any key to exit.
pause > nul

2
docs/en/API/Dynamic-CSharp-API-Clients.md

@ -2,7 +2,7 @@
ABP can dynamically create C# API client proxies to call your remote HTTP services (REST APIs). In this way, you don't need to deal with `HttpClient` and other low level details to call remote services and get results.
Dynamic C# proxies automatically handles the following stuff for you;
Dynamic C# proxies automatically handle the following stuff for you;
* Maps C# **method calls** to remote server **HTTP calls** by considering the HTTP method, route, query string parameters, request payload and other details.
* **Authenticates** the HTTP Client by adding access token to the HTTP header.

48
docs/en/Application-Services.md

@ -468,10 +468,37 @@ namespace MyProject.Test
{
Task Upload(Guid id, IRemoteStreamContent streamContent);
Task<IRemoteStreamContent> Download(Guid id);
Task CreateFile(CreateFileInput input);
Task CreateMultipleFile(CreateMultipleFileInput input);
}
public class CreateFileInput
{
public Guid Id { get; set; }
public IRemoteStreamContent Content { get; set; }
}
public class CreateMultipleFileInput
{
public Guid Id { get; set; }
public IEnumerable<IRemoteStreamContent> Contents { get; set; }
}
}
````
**You need to configure `AbpAspNetCoreMvcOptions` to add DTO class to `FormBodyBindingIgnoredTypes` to use `IRemoteStreamContent` in** **DTO ([Data Transfer Object](Data-Transfer-Objects.md))**
````csharp
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(CreateFileInput));
options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(CreateMultipleFileInput));
});
````
**Example: Application Service Implementation that can be used to get and return streams**
````csharp
@ -504,6 +531,27 @@ namespace MyProject.Test
await fs.FlushAsync();
}
}
public async Task CreateFileAsync(CreateFileInput input)
{
using (var fs = new FileStream("C:\\Temp\\" + input.Id + ".blob", FileMode.Create))
{
await input.Content.GetStream().CopyToAsync(fs);
await fs.FlushAsync();
}
}
public async Task CreateMultipleFileAsync(CreateMultipleFileInput input)
{
using (var fs = new FileStream("C:\\Temp\\" + input.Id + ".blob", FileMode.Append))
{
foreach (var content in input.Contents)
{
await content.GetStream().CopyToAsync(fs);
}
await fs.FlushAsync();
}
}
}
}
````

139
docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/POST.md

@ -0,0 +1,139 @@
# ABP Commercial 4.3 RC Has Been Published
ABP Commercial version 4.3 RC (Release Candidate) has been published alongside [ABP Framework 4.3. RC](https://blog.abp.io/abp/ABP-Framework-4.3-RC-Has-Been-Published). I will introduce the new features in this blog post. Here, a list of highlights for this release;
* The **microservice starter template** is getting more mature. We've also added a **service template** to add new microservices to the solution.
* New option for the application starter template to have a **separate database schema for tenant databases**.
* New **Forms** module to create surveys
* **Enable/disable modules** per edition/tenant.
* **Lepton theme** and **Account module**'s source codes are available with the Team License.
Here, some other features already covered in the ABP Framework announcement, but worth mentioning here since they are also implemented for the ABP Commercial;
* **Blazor UI server-side** support
* **Email setting** management UI
* **Module extensibility** system is now available for the **Blazor UI** too.
> This post doesn't cover the features and changes done on the ABP Framework side. Please also see the **[ABP Framework 4.3. RC blog post](https://blog.abp.io/abp/ABP-Framework-4.3-RC-Has-Been-Published)**.
## The Migration Guide
**This upgrade requires some manual work documented in [the migration guide](https://docs.abp.io/en/commercial/4.3/migration-guides/v4_3).** Please read the guide carefully. Even if your application doesn't break on upgrade, you should apply the changes to avoid future release problems.
## What's New With The ABP Commercial 4.3
### The Microservice Starter Template
We'd introduced an initial version of the [microservice starter template](https://docs.abp.io/en/commercial/4.3/startup-templates/microservice/index) in the [previous version](https://blog.abp.io/abp/ABP-IO-Platform-v4-2-RC-Has-Been-Released). It is getting more mature with this release. We've made a lot of improvements and changes, including;
* New **"service" template** to add new microservices for the solution. It still requires some manual work to integrate to other services and gateways; however, it makes progress very easy and straightforward.
* Added [Tye](https://github.com/dotnet/tye) configuration to develop and test the solution easier.
* Added [Prometheus](https://prometheus.io/), [Grafana](https://grafana.com/) integrations for monitoring the solution.
* **Automatic database migrations**. Every microservice automatically checks and migrates/seeds its database on startup (concurrency issues are resolved for multiple instances). For multi-tenant systems, tenant databases are also upgraded by the queue.
* For multi-tenant systems, **databases are being created on the fly** for new tenants with separate connection strings.
* Created **separate solution (`.sln`) file** for each microservice, gateway, and application. In this way, you can focus on what you are working on. The main (roof) solution file only includes the executable projects in these solutions.
* All microservices are converted to the standard **layered module structure**, making it easier to align with ABP application development practices.
After this release, **we will be preparing microservice development guides** based on this startup solution.
### Separate Tenant Schema
ABP's multi-tenancy system allows to the creation of dedicated databases for tenants. However, the application startup solution comes with a single database migration path; hence it has a single database schema. As a result, tenant databases have some host-related tables. These tables are not used for tenants, and they are always empty. However, their existence may disturb us as a clean developer.
With this release, the application startup template provides an option to address this problem. So, if you want, you can have a separate migration path for tenant databases. Of course, this has a cost; You will have two DbContexts for migration purposes, bringing additional complexity to your solution. We've done our best to reduce this complexity and added a README file into the migration assembly. If you prefer this approach, please check that README file.
You can specify the new `--separate-tenant-schema` parameter while you are creating a new solution using the [ABP CLI](https://docs.abp.io/en/abp/4.3/CLI):
````bash
abp new Acme.BookStore --separate-tenant-schema
````
If you prefer the [ABP Suite](https://docs.abp.io/en/commercial/latest/abp-suite/create-solution) to create solutions, you can check the *Separated tenant schema* option.
![abp-suite-separate-tenant-schema](abp-suite-separate-tenant-schema.png)
### Creating Tenant Databases On The Fly
With this release, the separate tenant database feature becomes more mature. When you create a new tenant with specifying a connection string, the **new database is automatically created** with all the tables and the initial seed data if available. So, tenants can immediately start to use the new database. With this change, tenant connection string textboxes come in the tenant creation modal:
![new-tenant-modal](new-tenant-modal.png)
Besides, we've added an "**Apply database migrations**" action to the tenant management UI to manually trigger the database creation & migration in case you have a problem with automatic migration:
![tenant-db-migrate](tenant-db-migrate.png)
Automatic migration only tries one time. If it fails, it writes the exception log and discards this request. For example, this can happen if the connection string is wrong or the database server is not available. In this case, you can manually retry with this action.
> Note that this feature requires to **make changes in your solution**, if you upgrade from an older version. Because the tenant database creation and migration code are located in the application startup template. See the [version 4.3 migration guide](https://docs.abp.io/en/commercial/4.3/migration-guides/v4_3) for details.
### New Module: CMS Kit
CMS Kit module initial version has been released with this version. As stated in the [ABP Framework 4.3 announcement post](https://blog.abp.io/abp/ABP-Framework-4.3-RC-Has-Been-Published), it should be considered premature for now.
For ABP Commercial application startup template, we are providing an option to include the CMS Kit into the solution while creating new solutions:
![cms-kit-selection](cms-kit-selection.png)
It is available only if you select the *Public web site* option. Once you include CMS Kit, a *Cms* item is shown on the menu:
![cms-kit-menu](cms-kit-menu.png)
Each CMS Kit feature can be individually enabled/disabled, using the global feature system. Once you disable a feature, it becomes completely invisible; even the related tables are not included in your database.
CMS Kit features are separated into two categories: Open source (free) features and pro (commercial) features. For now, only newsletter and contact form features are commercial. By the time, we will add more free and commercial features.
> We will create a separate blog post for the CMS Kit module, so I keep it short.
### New Module: Forms
*Forms* is a new module that is being introduced with this version. It looks like the Google Forms application; You dynamically create forms on the UI and send them to people to answer. Then you can get statistics/report and export answers to a CSV file.
Forms module currently supports the following question types;
* **Free text**
* Selecting a **single option** from a **dropdown** list or a **radio button** list
* **Multiple choice**: Selecting multiple options from a checkbox list
**Screenshot: editing form and questions - view responses**
![forms-edit-report](forms-edit-report.png)
**Screenshot: answering to the form**
![forms-answer](forms-answer.png)
### Team License Source Code for Modules
Team License users can't access the source code of modules and themes as a license restriction. You have to buy a Business or Enterprise license to download any module/theme's full source code. However, we got a lot of feedback from the Team License owners on the source code of the account module and the lepton theme. We see that customization of these two modules is highly necessary for most of our customers.
With this version, we decided to allow Team License holders to download the source code of the **Account Module** and the **Lepton Theme** to freely customize them based on their requirements.
You can **Replace these modules with their source code** using the ABP Suite:
![account-lepton-source](account-lepton-source.png)
Remember that; when you include the source code in your solution, it is your responsibility to upgrade them when we release new versions (while you don't have to upgrade them).
### Lepton Theme Public Website Layout
We'd added a public website application in the application starter template in the previous versions. It was using the public website layout of the Lepton Theme. We realized that the layout of this application is customized or completely changed in most of the solutions. So, with this version, the layout is included inside the application in the downloaded solution. You can freely change it. Before, you had to download it separately and include it in your solution manually.
### Enable/Disable Modules
With this release, all modules can be enabled/disabled per edition/tenant. You can allow/disallow modules when you click *Features* action for an edition or tenant:
![enable-disable-features](enable-disable-features.png)
### Other Features/Changes
* ABP Suite now supports defining *required* navigation properties on code generation.
* **Blazor server-side** (with tiered option) is added for the application and microservice starter templates.
* An **"Email"** tab has been added to the Settings page to configure the email settings.
## Feedback
Please check out the ABP Commercial 4.3 RC to help us to release a more stable version. **The planned release date for the 4.3.0 final version is April 15, 2021**.

BIN
docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/abp-suite-separate-tenant-schema.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

BIN
docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/account-lepton-source.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

BIN
docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/cms-kit-menu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/cms-kit-selection.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/enable-disable-features.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/forms-answer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/forms-edit-report.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

BIN
docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/new-tenant-modal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/tenant-db-migrate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

189
docs/en/Blog-Posts/2021-03-31 v4_3 Preview/POST.md

@ -0,0 +1,189 @@
# ABP Framework 4.3 RC Has Been Published
We are super excited to announce the ABP Framework 4.3 RC (Release Candidate). Here, a list of highlights of this release;
* **CMS Kit** module initial release.
* **Blazor UI server-side** support.
* **Module extensibility** system for the Blazor UI.
* Angular UI **resource owner password** flow comes back.
* **Volo.Abp.EntityFrameworkCore.Oracle** package is now compatible with .NET 5.
* CLI support to easily add the **Basic Theme** into the solution.
* New **IInitLogger** service to write logs before dependency injection phase completed.
Besides the new features above, we've done many performance improvements, enhancements and bug fixes on the current features. See the [4.3 milestone](https://github.com/abpframework/abp/milestone/49?closed=1) on GitHub for all changes made on this version.
This version was a big development journey for us; [~160 issues](https://github.com/abpframework/abp/issues?q=is%3Aissue+milestone%3A4.3-preview+is%3Aclosed) resolved, [~300 PRs](https://github.com/abpframework/abp/issues?q=is%3Apr+milestone%3A4.3-preview+is%3Aclosed) merged and **~1,700 commits** done only in the [main framework repository](https://github.com/abpframework/abp). **Thanks to the ABP Framework team and all the contributors.**
> ABP Commercial 4.3 RC has also been published. Check out [the commercial blog post](https://blog.abp.io/abp/ABP-Commercial-4.3-RC-Has-Been-Published).
## The Migration Guide
We normally don't make breaking changes in feature versions. However, this version has some small **breaking changes** mostly related to Blazor UI WebAssembly & Server separation. **Please check the [migration guide](https://docs.abp.io/en/abp/4.3/Migration-Guides/Abp-4_3) while upgrading to version 4.3**.
## Known Issues
Some minor issues will be fixed in the stable release. You can see the known issues [here](https://github.com/abpframework/abp/issues?q=is%3Aopen+is%3Aissue+milestone%3A4.3-final).
## Get Started With The 4.3 RC
If you want to try version 4.3 today, follow the steps below;
1) **Upgrade** the ABP CLI to the version `4.3.0-rc.1` using a command-line terminal:
````bash
dotnet tool update Volo.Abp.Cli -g --version 4.3.0-rc.1
````
**or install** if you haven't installed before:
````bash
dotnet tool install Volo.Abp.Cli -g --version 4.3.0-rc.1
````
2) Create a **new application** with the `--preview` option:
````bash
abp new BookStore --preview
````
See the [ABP CLI documentation](https://docs.abp.io/en/abp/4.3/CLI) for all the available options.
> You can also use the *Direct Download* tab on the [Get Started](https://abp.io/get-started) page by selecting the **Preview checkbox**.
## What's New With The ABP Framework 4.3
### CMS Kit
CMS (Content Management System) Kit was a module we worked on for the last couple of months. It is usable now, and we are releasing the initial version with this release. We are considering this module as pre-mature. It will be improved in the next versions. The goal to provide a flexible and extensible CMS infrastructure to .NET community. It currently has the following features;
* **Pages**: Used to create UI pages with a Markdown + WYSIWYG editor. Once you create a page, it becomes available via URL like `/pages/my-page-url`.
* **Blog**: A built-in blog system that supports multiple blogs with blog posts.
* **Comments**: Allows users to write comments under contents. It is used for blog posts.
* **Tags**: To add tag feature to any content/entity. It is used for blog posts.
* **Reactions**: Allows users to react to content via emojis, like a smile, upvote, downvote, etc.
* **Rating**: This component is used to rate content by users.
All features are separately usable. For example, you can create an image gallery and reuse the Comments and Tags features for the images. You can enable/disable features individually using the [Global Features System](https://docs.abp.io/en/abp/4.3/Global-Features).
> We will create a separate blog post for the CMS Kit module, so I keep it short.
### Blazor Server Side
We'd implemented Blazor WebAssembly before. With version 4.3, we have the Blazor Server-Side option too. All the current functionalities are available to the Blazor Server.
You can select Blazor Server as the UI type while creating a new solution.
**Example:**
````bash
abp new Acme.BookStore -u blazor-server
````
If you write `blazor` as the UI type, it will create Blazor WebAssembly just as before.
> You can also select the Blazor Server on the [get started](https://abp.io/get-started) page.
Blazor Server applications are mixed applications; You can mix the server-side MVC / Razor Pages with the Blazor SPA. This brings an interesting opportunity: MVC / Razor Pages modules can work seamlessly in the Blazor Server applications. For example, the CMS Kit module has no Blazor UI yet, but you can use its MVC UI inside your Blazor Server application.
> Blazor Server UI has a `--tiered` option just [like](https://docs.abp.io/en/abp/latest/Startup-Templates/Application#tiered-structure) the MVC / Razor Pages UI. This can be used to separate the HTTP API server from the UI server (UI application doesn't directly connect to the database).
### Blazor UI Module Extensibility
Module Entity Extensions and some other extensibility features was not supported by the Blazor UI. With this version, we've implemented that system for Blazor UI.
For anyone wondering what the module entity extensions is, please check [the document](https://docs.abp.io/en/abp/4.3/Module-Entity-Extensions) or [this community video](https://community.abp.io/articles/overview-of-abp-framework-4.1-module-extensions-part-1-n04f7bhf).
### Email Setting Management UI
With this release, a new item is added to the main menu to navigate to the setting management page. This page contains the email setting management UI, as shown below:
![email-settings-page](email-settings-page.png)
The setting page is provided by the [setting management module](https://docs.abp.io/en/abp/4.3/Modules/Setting-Management), and it is extensible; You can add your tabs to this page for your application settings.
### Angular UI Resource Owner Password Flow
The login page was removed from the Angular UI in previous versions because Authorization Code flow is the recommended approach for SPAs. However, it requires redirecting the user to the authentication server, logging there, and returning to the application. We got a lot of feedback because this brings overhead for simple applications.
With version 4.3, Angular UI can use its login page with resource owner password flow. Please refer to [the documentation](https://github.com/abpframework/abp/blob/dev/docs/en/UI/Angular/Account-Module.md) to learn how to make it work.
### Volo.Abp.EntityFrameworkCore.Oracle Package
We couldn't update the [Oracle.EntityFrameworkCore](https://www.nuget.org/packages/Oracle.EntityFrameworkCore/) package on .NET 5.0 upgrade since it was not supporting .NET 5.0 at that time. Now, it supports .NET 5.0 and we've upgraded the package.
See [the documentation](https://docs.abp.io/en/abp/4.3/Entity-Framework-Core-Oracle-Official) to learn how to switch to this package for the Oracle database.
### Add Basic Theme Into Your Solution
ABP Framework provides a strong theming system. However, the default theme, named the Basic Theme, has a non-styled, base Bootstrap UI. It is expected that you override the styles and UI components of that theme in a serious application.
There are some articles (see for [mvc](https://community.abp.io/articles/creating-a-new-ui-theme-by-copying-the-basic-theme-for-mvc-ui-yt9b18io) & [blazor](https://community.abp.io/articles/creating-a-new-ui-theme-by-copying-the-basic-theme-for-blazor-ui-qaf5ho1b)) to explain how to include the Basic Theme's source code into your solution to modify it fully. However, it still requires some manual work.
With this version, ABP CLI providing a command to add the Basic Theme's source code into your solution. Run the following command in a command-line terminal inside the root directory of your solution:
**MVC UI**
````bash
abp add-package Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic --with-source-code --add-to-solution
````
**Blazor Web Assembly UI**
````bash
abp add-package Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme --with-source-code --add-to-solution
abp add-package Volo.Abp.AspNetCore.Components.Web.BasicTheme --with-source-code --add-to-solution
````
**Blazor Server UI**
````bash
abp add-package Volo.Abp.AspNetCore.Components.Server.BasicTheme --with-source-code --add-to-solution
abp add-package Volo.Abp.AspNetCore.Components.Web.BasicTheme --with-source-code --add-to-solution
````
As you see, Blazor UI developers should add two packages. The Basic Theme consists of two packages for the Blazor UI: one for wasm/server and one shared.
**Angular UI**
Execute the following command in a terminal inside the `angular` folder of your solution:
````bash
abp add-package @abp/ng.theme.basic --with-source-code
````
### IInitLogger
In ASP.NET Core, logging is not possible before the dependency injection phase is completed. For example, you can't write log in `ConfigureServices` method. However, we sometimes need to write logs in this stage.
We are introducing the `IInitLogger` service, which allows writing logs inside the `ConfigureServices` method.
**Example:**
````csharp
public class MyModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var logger = context.Services.GetInitLogger<MyModule>();
logger.LogInformation("Some log...");
}
}
````
Logs are written once the service registration phase is completed. It stores the written logs in memory and then writes logs to the actual `ILogger` when ready.
> Notice: Startup templates come with [Serilog](https://serilog.net/) pre-installed. So, you can write logs everywhere by directly using its static API (ex: `Log.Information("...");`). The `InitLogger` is a way to write pre-initialization logs without depending on a particular logging library. So, it makes it very handy to write logs inside reusable modules.
### Other Features/Changes
* [#7423](https://github.com/abpframework/abp/issues/7423) MongoDB repository base aggregation API.
* [#8163](https://github.com/abpframework/abp/issues/8163) Ignoring given files on minification for MVC UI.
* [#7799](https://github.com/abpframework/abp/pull/7799) Added `RequiredPermissionName` to `ApplicationMenuItem` for MVC & Blazor UI to easily show/hide menu items based on user permissions. Also added `RequiredPermissionName` to `ToolbarItem` for the MVC UI for the same purpose.
* [#7523](https://github.com/abpframework/abp/pull/7523) Add more bundle methods to the distributed cache.
* [#8013](https://github.com/abpframework/abp/pull/8013) Handle `JsonProperty` attribute on Angular proxy generation.
See the [4.3 milestone](https://github.com/abpframework/abp/milestone/49) on GitHub for all changes made on this version.
## Feedback
Please check out the ABP Framework 4.3 RC and [provide feedback](https://github.com/abpframework/abp/issues/new) to help us release a more stable version. **The planned release date for the [4.3.0 final](https://github.com/abpframework/abp/milestone/50) version is April 15, 2021**.

BIN
docs/en/Blog-Posts/2021-03-31 v4_3 Preview/email-settings-page.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

3
docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md

@ -0,0 +1,3 @@
# Introducing the CMS Kit Module for the ABP Framework
TODO...

216
docs/en/CLI-New-Command-Samples.md

@ -0,0 +1,216 @@
# ABP CLI Create Solution Sample Commands
The `abp new` command creates an ABP solution or other artifacts based on an ABP template. ABP CLI has several parameters to create a new ABP solution. In this document we will show you some sample commands to create a new solution. All the project names are `Acme.BookStore`. Currently, the only available mobile project is a `React Native` mobile app. Available database providers are `Entity Framework Core` and `MongoDB`. All the commands starts with `abp new`.
## Angular
The following commands are for creating Angular UI projects:
* **Entity Framework Core**, no mobile app, creates the project in a new folder:
````bash
abp new Acme.BookStore -u angular --mobile none --database-provider ef -csf
````
* **Entity Framework Core**, default app template, **separate Identity Server**, creates the project in a new folder:
```bash
abp new Acme.BookStore -t app -u angular -m none --separate-identity-server --database-provider ef -csf
```
* **Entity Framework Core**, **custom connection string**, creates the project in a new folder:
```bash
abp new Acme.BookStore -u angular -csf --connection-string Server=localhost;Database=MyDatabase;Trusted_Connection=True
```
* **MongoDB**, default app template, mobile project included, creates solution in `C:\MyProjects\Acme.BookStore`
```bash
abp new Acme.BookStore -u angular --database-provider mongodb --output-folder C:\MyProjects\Acme.BookStore
```
* **MongoDB**, default app template, no mobile app, **separate Identity Server**, creates the project in a new folder:
```bash
abp new Acme.BookStore -t app -u angular -m none --separate-identity-server --database-provider mongodb -csf
```
## MVC
The following commands are for creating MVC UI projects:
* **Entity Framework Core**, no mobile app, creates the project in a new folder:
```bash
abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef -csf
```
* **Entity Framework Core**, **tier architecture** (*Web and HTTP API are separated*), no mobile app, creates the project in a new folder:
```bash
abp new Acme.BookStore -u mvc --mobile none --tiered --database-provider ef -csf
```
* **MongoDB**, no mobile app, creates the project in a new folder:
```bash
abp new Acme.BookStore -t app -u mvc --mobile none --database-provider mongodb -csf
```
* **MongoDB**, **tier architecture**, creates the project in a new folder:
```bash
abp new Acme.BookStore -u mvc --tiered --database-provider mongodb -csf
```
## Blazor
The following commands are for creating Blazor projects:
* **Entity Framework Core**, no mobile app:
```bash
abp new Acme.BookStore -t app -u blazor --mobile none
```
* **Entity Framework Core**, **separate Identity Server**, mobile app included:
```bash
abp new Acme.BookStore -u blazor --separate-identity-server
```
* **MongoDB**, no mobile app, creates the project in a new folder:
```bash
abp new Acme.BookStore -u blazor --database-provider mongodb --mobile none -csf
```
## No UI
In the default app template, there is always a frontend project. In this option there is no frontend project. It has a `HttpApi.Host` project to serve your HTTP WebAPIs. It's appropriate if you want to create a WebAPI service.
* **Entity Framework Core**, separate Identity Server, creates the project in a new folder:
```bash
abp new Acme.BookStore -u none --separate-identity-server -csf
```
* **MongoDB**, no mobile app:
```bash
abp new Acme.BookStore -u none --mobile none --database-provider mongodb
```
## Console application
It's a template of a basic .NET console application with ABP module architecture integrated. To create a console application use the following command:
* This project consists of the following files: `Acme.BookStore.csproj`, `appsettings.json`, `BookStoreHostedService.cs`, `BookStoreModule.cs`, `HelloWorldService.cs` and `Program.cs`.
```bash
abp new Acme.BookStore -t console -csf
```
## Module
Module are reusable sub applications used by your main project. Using ABP Module is a best practice if you are building a microservice solution. As modules are not final applications, each module has all the frontend UI projects and database providers. The module template comes with an MVC UI to be able to develop without the final solution. But if you will develop your module under a final solution, you add `--no-ui` parameter to exclude MVC UI project.
* Included frontends: `MVC`, `Angular`, `Blazor`. Included database providers: `Entity Framework Core`, `MongoDB`. Includes MVC startup project.
```bash
abp new Acme.IssueManagement -t module
```
* The same with the upper but doesn't include MVC startup project.
```bash
abp new Acme.IssueManagement -t module --no-ui
```
## Create a solution from a specific version
When you create a solution, it always creates with the latest version. To create a project from an older version, you can pass the `--version` parameter.
* Create a solution from v3.3.0, with Angular UI and Entity Framework Core.
```bash
abp new Acme.BookStore -t app -u angular -m none --database-provider ef -csf --version 3.3.0
```
To get the ABP version list, checkout following link: https://www.nuget.org/packages/Volo.Abp.Core/
## Create from a custom template
ABP CLI uses the default [app template](https://github.com/abpframework/abp/tree/dev/templates/app) to create your project. If you want to create a new solution from your customized template, you can use the parameter `--template-source`.
* MVC UI, Entity Framework Core, no mobile app, using the template in `c:\MyProjects\templates\app` directory.
```bash
abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef --template-source "c:\MyProjects\templates\app"
```
* Same with the previous one except this command retrieves the template from the URL `https://myabp.com/app-template.zip`.
```bash
abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef --template-source https://myabp.com/app-template.zip
```
## Create a preview version
ABP CLI always uses the latest version. In order to create a solution from a preview (RC) version add the `--preview` parameter.
* Blazor UI, Entity Framework Core, no mobile, **preview version**, creates the project in a new folder:
```bash
abp new Acme.BookStore -t app -u blazor --mobile none -csf --preview
```
## Choose database management system
The default database management system (DBMS) is `Entity Framework Core` / ` SQL Server`. You can choose a DBMS by passing `--database-management-system` parameter. Accepted values are `SqlServer`, `MySQL`, `SQLite`, `Oracle-Devart`, `PostgreSQL`. The default value is `SqlServer`.
* Angular UI, **PostgreSQL** database, creates the project in a new folder:
```bash
abp new Acme.BookStore -u angular --database-management-system PostgreSQL -csf
```
## Use static HTTP ports
ABP CLI always assigns random ports to the hostable projects. If you need to keep the default ports and create a solution always with the same HTTP ports, add the parameter `--no-random-port`.
* MVC UI, Entity Framework Core, **static ports**, creates the project in a new folder:
```bash
abp new Acme.BookStore --no-random-port -csf
```
## Use local ABP framework references
ABP libraries are referenced from NuGet by default in the ABP solutions. Sometimes you need to reference ABP libraries locally to your solution. This is useful to debug the framework itself. Your local ABP Framework 's root directory must have the `Volo.Abp.sln` file. You can copy the content of the following directory to your file system https://github.com/abpframework/abp/tree/dev/framework
* MVC UI, Entity Framework Core, **ABP libraries are local project references**:
The local path must be the root directory of ABP repository.
If `C:\source\abp\framework\Volo.Abp.sln` is your framework solution path, then you must write `C:\source\abp` to the `--abp-path` paramter.
```bash
abp new Acme.BookStore --local-framework-ref --abp-path C:\source\abp
```
**Output**:
As seen below, ABP Framework libraries are local project references.
```xml
<ItemGroup>
<ProjectReference Include="C:\source\abp\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
<ProjectReference Include="C:\source\abp\framework\src\Volo.Abp.AspNetCore.Serilog\Volo.Abp.AspNetCore.Serilog.csproj" />
<ProjectReference Include="C:\source\abp\framework\src\Volo.Abp.AspNetCore.Authentication.JwtBearer\Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj" />
<ProjectReference Include="..\Acme.BookStore.Application\Acme.BookStore.Application.csproj" />
<ProjectReference Include="..\Acme.BookStore.HttpApi\Acme.BookStore.HttpApi.csproj" />
<ProjectReference Include="..\Acme.BookStore.EntityFrameworkCore.DbMigrations\Acme.BookStore.EntityFrameworkCore.DbMigrations.csproj" />
</ItemGroup>
```

4
docs/en/CLI.md

@ -80,6 +80,8 @@ abp new Acme.BookStore
* `Acme.BookStore` is the solution name here.
* Common convention is to name a solution is like *YourCompany.YourProject*. However, you can use different naming like *YourProject* (single level namespacing) or *YourCompany.YourProduct.YourModule* (three levels namespacing).
For more samples, go to [ABP CLI Create Solution Samples](CLI-New-Command-Samples.md)
#### Options
* `--template` or `-t`: Specifies the template name. Default template name is `app`, which generates a web application. Available templates:
@ -164,6 +166,8 @@ abp add-package Volo.Abp.MongoDB
#### Options
* `--project` or `-p`: Specifies the project (.csproj) file path. If not specified, CLI tries to find a .csproj file in the current directory.
* `--with-source-code`: Downloads the source code of the package to your solution folder and uses local project references instead of NuGet/NPM packages.
* `--add-to-solution-file`: Adds the downloaded package to your solution file, so you will also see the package when you open the solution on a IDE. (only available when `--with-source-code` is True.)
### add-module

2
docs/en/Community-Articles/2020-10-08-How-To-Add-Custom-Property-To-The-User-Entity/How-To-Add-Custom-Property-To-The-User-Entity.md

@ -78,7 +78,7 @@ public static class CustomizeUserDemoEfCoreEntityExtensionMappings
nameof(AppUser.Title),
(entityBuilder, propertyBuilder) =>
{
propertyBuilder.IsRequired();
propertyBuilder.HasDefaultValue();
propertyBuilder.HasMaxLength(UserConsts.MaxTitleLength);
}
).MapEfCoreProperty<IdentityUser, int>(

99
docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md

@ -0,0 +1,99 @@
# Send Real-time Notifications via SignalR in ABP Project
SignalR is an open source library that adds real-time operation functionality to applications. Real-time web functionality enables server-side code to instantly send content to clients without refreshing the page. I'll show you how to add SignalR and use it to send notifications from backend. I'll implement this functionality in MVC template of ABP Framework.
![signalr-architecture](signalr-architecture.png)
## Implement Backend
### Create Notification Hub
Create a new folder named `SignalR` in your root directory of your Web project.
![SignalR Folder](signalr-folder.jpg)
Then add the following classes to the folder:
1. [INotificationClient.cs](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-inotificationclient-cs)
2. [UiNotificationClient.cs](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-uinotificationclient-cs)
3. [UiNotificationHub.cs](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-uinotificationhub-cs)
### Configure Module
These 3 steps will be done in your web module class.
#### 1- Add SignalR
Open `YourProjectWebModule.cs` class and add the following line to the `PreConfigureServices` method:
```csharp
context.Services.AddSignalR();
```
![PreConfigureServices](preconfigureservices.jpg)
#### 2- Add Client Scripts
2- In the `ConfigureServices` method of your web module add the following code to add the `signalr.js` and `notification-hub.js`. We'll add these packages in the next steps.
![Script Bundles](add-script-bundles.jpg)
#### 3- Add Hub Endpoint
Add the following code to add the notification hub endpoint in `OnApplicationInitialization` method:
```csharp
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<UiNotificationHub>("/notification-hub");
});
```
![Add endpoint](add-endpoint.jpg)
### Implement Frontend
We'll write the client-side code to be able to handle the SignalR response.
#### 1- Add Notification Hub
Add the following JavaScript class into your `Pages` folder in your Web project. We already added this script to our global scripts.
[notification-hub.js](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-notification-hub-js)
![notification-hub.js](notification-hub.jpg)
#### 2- Add SignalR NPM package
Add [Microsoft.SignalR](https://www.npmjs.com/package/@microsoft/signalr) JavaScript package to the `package.json` which is located in your root folder of the Web project. After you add it, run `yarn` command in your Web directory to be able to install this package.
![Add SignalR package](signalr-package.jpg)
#### 3- Add resource Mapping
We added SignalR to the `package.json` but it comes into your `node_modules` folder. We need to copy the related files to `wwwroot/libs` folder. To do this copy the content of the following file to your `abp.resourcemappings.js` file. It's in your root directory of Web folder. After you do this, go to your web directory and run `gulp` command. By doing this, it'll copy the related files into your `wwwroot/libs` folder.
[abp.resourcemappings.js](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-abp-resourcemapping-js)
![Resource mappings](resource-mappings.jpg)
#### 4- Usage
We have completed the implementation part. Let's check if it's running...
We will show the current time which comes from server.
To do this replace the `Index.cshtml` and `Index.cshtml.cs` with the followings:
- [Index.cshtml](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-index-cshtml)
- [Index.cshtml.cs](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-index-cshtml-cs)
#### 5- See it in action
Run your web project and in the Index page you'll see a button named as "Get Notification". Click the button and see the notification that comes from SignalR. This is a basic usage of SignalR notification system. You can implement it according to your own requirements.
![Result](result.jpg)

BIN
docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/add-endpoint.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

BIN
docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/add-script-bundles.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/article-signalr-banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/notification-hub.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/preconfigureservices.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

BIN
docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/resource-mappings.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/result.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/signalr-architecture.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/signalr-folder.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/signalr-package.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

8
docs/en/Domain-Driven-Design-Implementation-Guide.md

@ -155,9 +155,9 @@ The projects have been explained before. Now, we can explain the reasons of the
* `Application.Contracts` depends on the `Domain.Shared`. In this way, you can reuse these types in the DTOs. For example, the same `IssueType` enum in the `Domain.Shared` can be used by a `CreateIssueDto` as a property.
* `Application` depends on the `Application.Contracts` since it implements the Application Service interfaces and uses the DTOs inside it. It also depends on the `Domain` since the Application Services are implemented using the Domain Objects defined inside it.
* `EntityFrameworkCore` depends on the `Domain` since it maps the Domain Objects (entities and value types) to database tables (as it is an ORM) and implements the repository interfaces defined in the `Domain`.
* `HttpApi` depends on the `Application.Contacts` since the Controllers inside it inject and use the Application Service interfaces as explained before.
* `HttpApi.Client` depends on the `Application.Contacts` since it can consume the Application Services as explained before.
* `Web` depends on the `HttpApi` since it serves the HTTP APIs defined inside it. Also, in this way, it indirectly depends on the `Application.Contacts` project to consume the Application Services in the Pages/Components.
* `HttpApi` depends on the `Application.Contracts` since the Controllers inside it inject and use the Application Service interfaces as explained before.
* `HttpApi.Client` depends on the `Application.Contracts` since it can consume the Application Services as explained before.
* `Web` depends on the `HttpApi` since it serves the HTTP APIs defined inside it. Also, in this way, it indirectly depends on the `Application.Contracts` project to consume the Application Services in the Pages/Components.
#### Dashed Dependencies
@ -1801,7 +1801,7 @@ Such a design makes it even more important to distinguish between Domain logic a
To be more clear about the implementation, you can create different projects (`.csproj`) for each application types. For example;
* `IssueTracker.Admin.Application` & `IssueTracker.Admin.Application.Contacts` projects for the Back Office (admin) Application.
* `IssueTracker.Admin.Application` & `IssueTracker.Admin.Application.Contracts` projects for the Back Office (admin) Application.
* `IssueTracker.Public.Application` & `IssueTracker.Public.Application.Contracts` projects for the Public Web Application.
* `IssueTracker.Mobile.Application` & `IssueTracker.Mobile.Application.Contracts` projects for the Mobile Application.

10
docs/en/Emailing.md

@ -94,7 +94,13 @@ Email sending uses the [setting system](Settings.md) to define settings and get
* **Abp.Mailing.Smtp.EnableSsl**: A value that indicates if the SMTP server uses SSL or not ("true" or "false". Default: "false").
* **Abp.Mailing.Smtp.UseDefaultCredentials**: If true, uses default credentials instead of the provided username and password ("true" or "false". Default: "true").
The easiest way to define these settings it to add them to the `appsettings.json` file. The [application startup template](Startup-Templates/Application.md) already has these settings in the `appsettings.json`:
Email settings can be managed from the *Settings Page* of the [Setting Management](Modules/Setting-Management.md) module:
![email-settings](images/email-settings.png)
> Setting Management module is already installed if you've created your solution from the ABP Startup template.
If you don't use the Setting Management module, you can simply define the settings inside your `appsettings.json` file:
````json
"Settings": {
@ -110,7 +116,7 @@ The easiest way to define these settings it to add them to the `appsettings.json
}
````
You can set/change these settings using the `ISettingManager` and store values in a database. See the [setting system document](Settings.md) to understand the setting system better.
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.
### Encrypt the SMTP Password

2
docs/en/Entity-Framework-Core-Oracle.md

@ -4,7 +4,7 @@ This document explains how to switch to the **Oracle** database provider for **[
ABP Framework provides integrations for two different Oracle packages. See one of the following documents based on your provider decision:
* **[Volo.Abp.EntityFrameworkCore.Oracle](Entity-Framework-Core-Oracle-Official.md)** package uses the official & free oracle driver (which is **currently in beta**).
* **[Volo.Abp.EntityFrameworkCore.Oracle](Entity-Framework-Core-Oracle-Official.md)** package uses the official & free oracle driver.
* **[Volo.Abp.EntityFrameworkCore.Oracle.Devart](Entity-Framework-Core-Oracle-Devart.md)** package uses the commercial (paid) driver of [Devart](https://www.devart.com/) company.
> You can choose one of the package you want. If you don't know the differences of the packages, please search for it. ABP Framework only provides integrations it doesn't provide support for such 3rd-party libraries.

16
docs/en/Features.md

@ -326,20 +326,12 @@ if (feature != null)
A feature value is available at the client side too, unless you set `IsVisibleToClients` to `false` on the feature definition. The feature values are exposed from the [Application Configuration API](API/Application-Configuration.md) and usable via some services on the UI.
### ASP.NET Core MVC / Razor Pages UI
See the following documents to learn how to check features in different UI types:
Use `abp.features` API to get the feature values.
* [ASP.NET Core MVC / Razor Pages / JavaScript API](UI/AspNetCore/JavaScript-API/Features.md)
* [Angular](UI/Angular/Features.md)
**Example: Get feature values in the JavaScript code**
````js
var isEnabled = abp.features.values["MyApp.ExcelReporting"] === "true";
var count = abp.features.values["MyApp.MaxProductCount"];
````
### Angular UI
See the [features](Features.md) document for the Angular UI.
**Blazor** applications can use the same `IFeatureChecker` service as explained above.
## Feature Management

12
docs/en/Getting-Started-Create-Solution.md

@ -3,7 +3,7 @@
````json
//[doc-params]
{
"UI": ["MVC", "Blazor", "NG"],
"UI": ["MVC", "Blazor", "BlazorServer", "NG"],
"DB": ["EF", "Mongo"],
"Tiered": ["Yes", "No"]
}
@ -13,17 +13,21 @@
## Create a New Project
We will use the ABP CLI to create a new ABP project.
> Alternatively, you can **create and download** projects from [ABP Framework website](https://abp.io/get-started) by easily selecting the all the options from the page.
Use the `new` command of the ABP CLI to create a new project:
````shell
abp new Acme.BookStore{{if UI == "NG"}} -u angular{{else if UI == "Blazor"}} -u blazor{{end}}{{if DB == "Mongo"}} -d mongodb{{end}}{{if Tiered == "Yes"}}{{if UI == "MVC"}} --tiered{{else}} --separate-identity-server{{end}}{{end}}
abp new Acme.BookStore{{if UI == "NG"}} -u angular{{else if UI == "Blazor"}} -u blazor{{else if UI == "BlazorServer"}} -u blazor-server{{end}}{{if DB == "Mongo"}} -d mongodb{{end}}{{if Tiered == "Yes"}}{{if UI == "MVC" || UI == "BlazorServer"}} --tiered{{else}} --separate-identity-server{{end}}{{end}}
````
*You can use different level of namespaces; e.g. BookStore, Acme.BookStore or Acme.Retail.BookStore.*
{{ if Tiered == "Yes" }}
{{ if UI == "MVC" }}
{{ if UI == "MVC" || UI == "BlazorServer" }}
* `--tiered` argument is used to create N-tiered solution where authentication server, UI and API layers are physically separated.
@ -37,8 +41,6 @@ abp new Acme.BookStore{{if UI == "NG"}} -u angular{{else if UI == "Blazor"}} -u
> [ABP CLI document](./CLI.md) covers all of the available commands and options.
> Alternatively, you can **create and download** projects from [ABP Framework website](https://abp.io/get-started) by easily selecting the all the options from the page.
### The Solution Structure
The solution has a layered structure (based on the [Domain Driven Design](Domain-Driven-Design.md)) and contains unit & integration test projects. See the [application template document](Startup-Templates/Application.md) to understand the solution structure in details.

14
docs/en/Getting-Started-Running-Solution.md

@ -3,7 +3,7 @@
````json
//[doc-params]
{
"UI": ["MVC", "Blazor", "NG"],
"UI": ["MVC", "Blazor", "BlazorServer", "NG"],
"DB": ["EF", "Mongo"],
"Tiered": ["Yes", "No"]
}
@ -15,13 +15,13 @@
### Connection String
Check the **connection string** in the `appsettings.json` file under the {{if Tiered == "Yes"}}`.IdentityServer` and `.HttpApi.Host` projects{{else}}{{if UI=="MVC"}}`.Web` project{{else}}`.HttpApi.Host` project{{end}}{{end}}
Check the **connection string** in the `appsettings.json` file under the {{if Tiered == "Yes"}}`.IdentityServer` and `.HttpApi.Host` projects{{else}}{{if UI=="MVC"}}`.Web` project{{else if UI=="BlazorServer"}}`.Blazor` project{{else}}`.HttpApi.Host` project{{end}}{{end}}.
{{ if DB == "EF" }}
````json
"ConnectionStrings": {
"Default": "Server=localhost;Database=BookStore;Trusted_Connection=True"
"Default": "Server=(LocalDb)\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True"
}
````
@ -91,7 +91,7 @@ Right click to the `.DbMigrator` project and select **Set as StartUp Project**
## Run the Application
{{ if UI == "MVC" }}
{{ if UI == "MVC" || UI == "BlazorServer" }}
{{ if Tiered == "Yes" }}
@ -109,7 +109,7 @@ You can login, but you cannot enter to the main application here. This is **just
This is the HTTP API that is used by the web application.
3. Lastly, ensure that the `.Web` project is the startup project and run the application which will open a **welcome** page in your browser
3. Lastly, ensure that the {{if UI=="MVC"}}`.Web`{{else}}`.Blazor`{{end}} project is the startup project and run the application which will open a **welcome** page in your browser
![mvc-tiered-app-home](images/bookstore-home.png)
@ -119,7 +119,7 @@ Click to the **login** button which will redirect you to the *authentication ser
{{ else # Tiered != "Yes" }}
Ensure that the `.Web` project is the startup project. Run the application which will open the **login** page in your browser:
Ensure that the {{if UI=="MVC"}}`.Web`{{else}}`.Blazor`{{end}} project is the startup project. Run the application which will open the **login** page in your browser:
> Use Ctrl+F5 in Visual Studio (instead of F5) to run the application without debugging. If you don't have a debug purpose, this will be faster.
@ -127,7 +127,7 @@ Ensure that the `.Web` project is the startup project. Run the application which
{{ end # Tiered }}
{{ else # UI != "MVC" }}
{{ else # UI != MVC || BlazorServer }}
### Running the HTTP API Host (Server Side)

2
docs/en/Getting-Started-Setup-Environment.md

@ -3,7 +3,7 @@
````json
//[doc-params]
{
"UI": ["MVC", "Blazor", "NG"],
"UI": ["MVC", "Blazor", "BlazorServer", "NG"],
"DB": ["EF", "Mongo"],
"Tiered": ["Yes", "No"]
}

2
docs/en/Getting-Started.md

@ -3,7 +3,7 @@
````json
//[doc-params]
{
"UI": ["MVC", "Blazor", "NG"],
"UI": ["MVC", "Blazor", "BlazorServer", "NG"],
"DB": ["EF", "Mongo"],
"Tiered": ["Yes", "No"]
}

37
docs/en/Migration-Guides/Abp-4_3.md

@ -0,0 +1,37 @@
# ABP Framework 4.x to 4.3 Migration Guide
This version comes with some changes in the startup template, mostly related to Blazor UI. This document explains the breaking changes. However, **it is suggested to [compare the startup templates manually](Upgrading-Startup-Template.md) to see all the changes** and apply to your solution.
## Common
* `app.UseVirtualFiles()` has been marked as **obsolete**. Use `app.UseStaticFiles()` instead. ABP will handle the virtual file system integrated to the static files middleware.
## Blazor UI
Implemented the Blazor Server Side support with this release. It required some packages and namespaces arrangements. **Existing Blazor (WebAssembly) applications should done the changes explained in this section**.
### Namespace Changes
- `AbpBlazorMessageLocalizerHelper` -> moved to Volo.Abp.AspNetCore.Components.Web
- `AbpRouterOptions` -> moved to Volo.Abp.AspNetCore.Components.Web.Theming.Routing
- `AbpToolbarOptions` and `IToolbarContributor` -> moved to Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars
- `IAbpUtilsService` -> moved to Volo.Abp.AspNetCore.Components.Web
- `PageHeader` -> moved to `Volo.Abp.AspNetCore.Components.Web.Theming.Layout`.
In practice, if your application is broken because of the `Volo.Abp.AspNetCore.Components.WebAssembly.*` namespace, please try to switch to `Volo.Abp.AspNetCore.Components.Web.*` namespace.
Remember to change namespaces in the `_Imports.razor` files.
### Package Changes
No change on the framework packages, but **module packages are separated as Web Assembly & Server**;
* Use `Volo.Abp.Identity.Blazor.WebAssembly` NuGet package instead of `Volo.Abp.Identity.Blazor` package. Also, change `AbpIdentityBlazorModule` usage to `AbpIdentityBlazorWebAssemblyModule` in the `[DependsOn]` attribute on your module class.
* Use `Volo.Abp.TenantManagement.Blazor.WebAssembly` NuGet package instead of `Volo.Abp.TenantManagement.Blazor` package. Also, change `AbpTenantManagementBlazorModule` usage to `AbpTenantManagementBlazorWebAssemblyModule` in the `[DependsOn]` attribute on your module class.
* Use `Volo.Abp.PermissionManagement.Blazor.WebAssembly` NuGet package instead of `Volo.Abp.PermissionManagement.Blazor` package. Also, change `AbpPermissionManagementBlazorModule` usage to `AbpPermissionManagementBlazorWebAssemblyModule` in the `[DependsOn]` attribute on your module class.
* Use `Volo.Abp.SettingManagement.Blazor.WebAssembly` NuGet package instead of `Volo.Abp.SettingManagement.Blazor` package. Also, change `AbpSettingManagementBlazorModule` usage to `AbpSettingManagementBlazorWebAssemblyModule` in the `[DependsOn]` attribute on your module class.
* Use `Volo.Abp.FeatureManagement.Blazor.WebAssembly` NuGet package instead of `Volo.Abp.FeatureManagement.Blazor` package. Also, change `AbpFeatureManagementBlazorModule` usage to `AbpFeatureManagementBlazorWebAssemblyModule` in the `[DependsOn]` attribute on your module class.
### Other Changes
* `EntityAction.RequiredPermission` has been marked as **obsolete**, because of performance reasons. It is suggested to use the `Visible` property by checking the permission/policy yourself and assigning to a variable.

1
docs/en/Migration-Guides/Index.md

@ -1,5 +1,6 @@
# ABP Framework Migration Guides
* [4.2 to 4.3](Abp-4_3.md)
* [4.x to 4.2](Abp-4_2.md)
* [3.3.x to 4.0](Abp-4_0.md)
* [2.9.x to 3.0](../UI/Angular/Migration-Guide-v3.md)

88
docs/en/Migration-Guides/Upgrading-Startup-Template.md

@ -0,0 +1,88 @@
# Upgrading the Startup Template
Sometimes we introduce new features/changes that requires to **make changes in the startup template**. We already implement the changes in the startup template for new applications. However, in some cases you need to manually make some minor changes in your existing solution.
This guide explains a suggested way of upgrading your solution templates, using the WinMerge tool.
> See also the [Upgrading document](../Upgrading.md) for an overall progress of upgrading. This document focuses on upgrading the startup template.
## 1) Create Dummy Solutions
We will create two solutions to compare the changes;
* The first solution is with your existing version
* The second solution is the version you want to upgrade
Assume that we are upgrading from the version **4.2.2** to version **4.3.0-rc.1**. First, create two empty folders:
![upgrade-diff-empty-folders](../images/upgrade-diff-empty-folders.png)
**A)** Open a command-line terminal inside the `4_2_2` folder and create a new solution with the version `4.2.2` using the ABP [CLI](../CLI.md) (install it if you haven't installed before).
**Example:**
````bash
abp new MyCompareApp -u blazor -v 4.2.2
````
> Important: You need to create the solution with the exact configuration of your solution. If your application has Angular UI and MongoDB, you should use the same options here.
**B)** Then open a command-line terminal inside the `4_3_0-rc1` folder and create a new solution with the version `4.3.0-rc.1` using the ABP [CLI](../CLI.md).
**Example:**
````bash
abp new MyCompareApp -u blazor -v 4.3.0-rc.1
````
Now, we have the same application with different versions.
## 2) Upgrade the Old Application
If we compare two folders now, we will see unnecessary differences because of NuGet & NPM package differences. It is better to upgrade the old application to the new version before comparing them.
Open a command-line terminal inside the `4_2_2` folder and type the following command:
````bash
abp update -v 4.3.0-rc.1
````
This will update all NuGet & NPM packages in your solution. We are ready to compare the folders to see the differences.
## 3) Compare the Folders
We will use the [WinMerge](https://winmerge.org/) utility for the comparison. So, please install it if it wasn't installed before. After installation, open the WinMerge application, select the the *File > Open* menu item, select the folders you want to compare:
![winmerge-open-folders](../images/winmerge-open-folders.png)
Now, we can click to the *Compare* button to see all the differences. Here, a screenshot from the comparison:
![winmerge-comparison-result](../images/winmerge-comparison-result.png)
See the *Comparison result* column or the yellow coloring to understand if two files or folder are different. It shows almost all folders are different. However, don't worry. Generally a few files will be different in a folder and a few lines will be different in a file comparison.
For example, I select the `MyCompareApp.Blazor.csproj` to understand what's changed in this file:
![winmerge-file-diff](../images/winmerge-file-diff.png)
We see that;
* `Blazorise.Bootstrap` package is upgraded from version `0.9.3-preview6` to version `0.9.3.3`.
* `Blazorise.Icons.FontAwesome` package is upgraded from version `0.9.3-preview6` to version `0.9.3.3`.
* `Volo.Abp.Identity.Blazor` package is replaced by `Volo.Abp.Identity.Blazor.WebAssembly`.
* `Volo.Abp.TenantManagement.Blazor` package is replaced by `Volo.Abp.TenantManagement.Blazor.WebAssembly`.
* `Volo.Abp.SettingManagement.Blazor.WebAssembly` package is newly added.
In this way, we can understand all the changes.
## 4) Apply Changes on Your Solution
Comparison result clearly shows the necessary changes should be done on upgrade. All you need to do is to apply the same changes in your own solution.
> **It is important you first upgrade your own solution to the new version, using the `abp update` command. Then you can apply the manual changes**
## Notes
* Sometimes, you may find some changes are unnecessary for your own solution. You may deleted these or already customized. In these cases, you can just ignore it.
* If you do not upgrade your solution as described in this document, your application will continue to work as long as you implement the breaking changes documented in the [migration guide](Index.md). However, you may not get benefit of some new features those require changes in your solution files.
* Most of the times, there will be a few or no differences on the startup templates. When there are important changes, we write a note to the related migration guide, so you apply them manually.

4
docs/en/Module-Entity-Extensions.md

@ -1,9 +1,5 @@
# Module Entity Extensions
> This feature is not supported by the Blazor UI yet.
## Introduction
Module entity extension system is a **high level** extension system that allows you to **define new properties** for existing entities of the depended modules. It automatically **adds properties to the entity, database, HTTP API and the user interface** in a single point.
> The module must be developed the *Module Entity Extensions* system in mind. All the **official modules** supports this system wherever possible.

3
docs/en/Modules/Blogging.md

@ -1,3 +0,0 @@
# Blogging Module
TODO

3
docs/en/Modules/Client-Simulation.md

@ -1,3 +0,0 @@
# Client Simulation Module
TODO

3
docs/en/Modules/Index.md

@ -14,8 +14,6 @@ There are some **free and open source** application modules developed and mainta
* [**Account**](Account.md): Provides UI for the account management and allows user to login/register to the application.
* [**Audit Logging**](Audit-Logging.md): Persists audit logs to a database.
* [**Background Jobs**](Background-Jobs.md): Persist background jobs when using the default background job manager.
* [**Blogging**](Blogging.md): Used to create fancy blogs. ABP's [own blog](https://blog.abp.io/) already using this module.
* [**Client Simulation**](Client-Simulation.md): A simple web UI to stress test HTTP APIs by simulating concurrent clients.
* [**CMS Kit**](Cms-Kit.md): A set of reusable *Content Management System* features.
* [**Docs**](Docs.md): Used to create technical documentation website. ABP's [own documentation](https://docs.abp.io) already using this module.
* [**Feature Management**](Feature-Management.md): Used to persist and manage the [features](../Features.md).
@ -24,7 +22,6 @@ There are some **free and open source** application modules developed and mainta
* [**Permission Management**](Permission-Management.md): Used to persist permissions.
* **[Setting Management](Setting-Management.md)**: Used to persist and manage the [settings](../Settings.md).
* [**Tenant Management**](Tenant-Management.md): Manages tenants for a [multi-tenant](../Multi-Tenancy.md) application.
* [**Users**](Users.md): Abstract users, so other modules can depend on this module instead of the Identity module.
* [**Virtual File Explorer**](Virtual-File-Explorer.md): Provided a simple UI to view files in [virtual file system](../Virtual-File-System.md).
See [the GitHub repository](https://github.com/abpframework/abp/tree/master/modules) for source code of all modules.

3
docs/en/Modules/Users.md

@ -1,3 +0,0 @@
# Users Module
TODO

100
docs/en/Multi-Lingual-Entities.md

@ -0,0 +1,100 @@
# Multi Lingual Entities
ABP Framework defines two basic interfaces for Multi-Lingual entity definitions to provide a standard model for translating entities.
## 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.

55
docs/en/Road-Map.md

@ -1,14 +1,52 @@
# ABP Framework Road Map
You can always check the milestone planning and the prioritized backlog issues on [the GitHub repository](https://github.com/abpframework/abp/milestones) for a detailed road map. Here, a list of some major items in the backlog;
This document provides a road map, release schedule and planned features for the ABP Framework.
* CMS Kit: A set of reusable, extensible and composable Content Management System features.
## Next Versions
### v4.4
This version will focus on **documentation** and **improvements** of current features. In addition, the following features are planned;
* Publishing distributed events as transactional ([#6126](https://github.com/abpframework/abp/issues/6126))
* Revisit the microservice demo solution ([#8385](https://github.com/abpframework/abp/issues/8385))
* A new UI Theme alternative to the Basic Theme ([#6132](https://github.com/abpframework/abp/issues/6132))
* Improvements and new features to the [CMS Kit](Modules/Cms-Kit.md) module ([#8380](https://github.com/abpframework/abp/issues/8380) [#8381](https://github.com/abpframework/abp/issues/8381))
* Pre-configured test project for the [Blazor UI](UI/Blazor/Overall.md) ([#5516](https://github.com/abpframework/abp/issues/5516))
* Razor engine support for text templating ([#8373](https://github.com/abpframework/abp/issues/8373))
**Planned release date**: End of Quarter 2, 2021.
### v4.5
We planned to focus on v5.0 after 4.4 release. However, we may release v4.5 if we see it necessary.
### v5.0
This version will focus on .NET 6 and performance improvements.
* Upgrading to .NET 6
* .NET Trimming compatibility
* Using source generators and reducing reflection usage
* Performance improvements
* Improving the abp.io platform
* API Versioning system: finalize & document ([#497](https://github.com/abpframework/abp/issues/497))
**Planned release date**: End of Quarter 4, 2021.
> Note: v5.0 features will be more clear in the next months. We will consider to add new features from the *Backlog Items*.
## Backlog Items
The *Next Versions* section above shows the main focus of the planned versions. However, in each release we add new features to the core framework and the [application modules](Modules/Index.md).
Here, a list of major items in the backlog we are considering to work on in the next versions.
* [#2183](https://github.com/abpframework/abp/issues/2183) / Dapr integration
* [#2882](https://github.com/abpframework/abp/issues/2882) / Providing a gRPC integration infrastructure (while it is [already possible](https://github.com/abpframework/abp-samples/tree/master/GrpcDemo) to create or consume gRPC endpoints for your application, we plan to create endpoints for the [standard application modules](https://docs.abp.io/en/abp/latest/Modules/Index))
* [#236](https://github.com/abpframework/abp/issues/236) Resource based authorization system
* [#6132](https://github.com/abpframework/abp/issues/6132) A New Theme alternative to the Basic Theme
* [#1754](https://github.com/abpframework/abp/issues/1754) / Multi-lingual entities
* [#497](https://github.com/abpframework/abp/issues/497) API Versioning system finalize & document
* [#633](https://github.com/abpframework/abp/issues/633) / Realtime notification system
* [#236](https://github.com/abpframework/abp/issues/236) / Resource based authorization system
* [#1754](https://github.com/abpframework/abp/issues/1754) / Multi-lingual entities
* [#57](https://github.com/abpframework/abp/issues/57) / Built-in CQRS infrastructure
* [#336](https://github.com/abpframework/abp/issues/336) / Health Check abstraction
* [#2532](https://github.com/abpframework/abp/issues/2532), [#2564](https://github.com/abpframework/abp/issues/2465) / CosmosDB integration with EF Core and MongoDB API
@ -16,6 +54,9 @@ You can always check the milestone planning and the prioritized backlog issues o
* [#162](https://github.com/abpframework/abp/issues/162) / Azure ElasticDB Integration for multitenancy
* [#2296](https://github.com/abpframework/abp/issues/2296) / Feature toggling infrastructure
The backlog items are subject to change. We are adding new items and changing priorities based on the community feedbacks and goals of the project.
You can always check the milestone planning and the prioritized backlog issues on [the GitHub repository](https://github.com/abpframework/abp/milestones) for a detailed road map. The backlog items are subject to change. We are adding new items and changing priorities based on the community feedbacks and goals of the project.
## Feature Requests
Vote for your favorite feature on the related GitHub issues (and write your thoughts). You can create an issue on [the GitHub repository](https://github.com/abpframework/abp) for your feature requests, but first search in the existing issues.

2
docs/en/Tutorials/Part-1.md

@ -2,7 +2,7 @@
````json
//[doc-params]
{
"UI": ["MVC","Blazor","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````

32
docs/en/Tutorials/Part-10.md

@ -2,7 +2,7 @@
````json
//[doc-params]
{
"UI": ["MVC","Blazor","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
@ -326,6 +326,7 @@ Open the `BookAppService` interface in the `Books` folder of the `Acme.BookStore
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Acme.BookStore.Authors;
using Acme.BookStore.Permissions;
@ -387,23 +388,17 @@ namespace Acme.BookStore.Books
public override async Task<PagedResultDto<BookDto>> GetListAsync(PagedAndSortedResultRequestDto input)
{
//Set a default sorting, if not provided
if (input.Sorting.IsNullOrWhiteSpace())
{
input.Sorting = nameof(Book.Name);
}
//Get the IQueryable<Book> from the repository
var queryable = await Repository.GetQueryableAsync();
//Prepare a query to join books and authors
var query = from book in queryable
join author in _authorRepository on book.AuthorId equals author.Id
orderby input.Sorting //TODO: Can not sort like that!
select new {book, author};
//Paging
query = query
.OrderBy(NormalizeSorting(input.Sorting))
.Skip(input.SkipCount)
.Take(input.MaxResultCount);
@ -435,6 +430,25 @@ namespace Acme.BookStore.Books
ObjectMapper.Map<List<Author>, List<AuthorLookupDto>>(authors)
);
}
private static string NormalizeSorting(string sorting)
{
if (sorting.IsNullOrEmpty())
{
return $"book.{nameof(Book.Name)}";
}
if (sorting.Contains("authorName", StringComparison.OrdinalIgnoreCase))
{
return sorting.Replace(
"authorName",
"author.Name",
StringComparison.OrdinalIgnoreCase
);
}
return $"book.{sorting}";
}
}
}
```
@ -1078,7 +1092,7 @@ That's all. Just run the application and try to create or edit an author.
{{end}}
{{if UI == "Blazor"}}
{{if UI == "Blazor" || UI == "BlazorServer"}}
### The Book List

4
docs/en/Tutorials/Part-2.md

@ -2,7 +2,7 @@
````json
//[doc-params]
{
"UI": ["MVC","Blazor","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
@ -531,7 +531,7 @@ Now you can see the final result on your browser:
![Book list final result](images/bookstore-book-list.png)
{{else if UI == "Blazor"}}
{{else if UI == "Blazor" || UI == "BlazorServer"}}
## Create a Books Page

8
docs/en/Tutorials/Part-3.md

@ -2,7 +2,7 @@
````json
//[doc-params]
{
"UI": ["MVC","Blazor","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
@ -709,7 +709,7 @@ Open `/src/app/book/book.component.html` and make the following changes:
<ng-template #abpBody> </ng-template>
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" #abpClose>
<button type="button" class="btn btn-secondary" abpClose>
{%{{{ '::Close' | abpLocalization }}}%}
</button>
</ng-template>
@ -844,7 +844,7 @@ Also replace `<ng-template #abpFooter> </ng-template>` with the following code p
````html
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" #abpClose>
<button type="button" class="btn btn-secondary" abpClose>
{%{{{ '::Close' | abpLocalization }}}%}
</button>
@ -1158,7 +1158,7 @@ Clicking the "Delete" action calls the `delete` method which then shows a confir
{{end}}
{{if UI == "Blazor"}}
{{if UI == "Blazor" || UI == "BlazorServer"}}
## Creating a New Book

2
docs/en/Tutorials/Part-4.md

@ -2,7 +2,7 @@
````json
//[doc-params]
{
"UI": ["MVC","Blazor","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````

8
docs/en/Tutorials/Part-5.md

@ -2,7 +2,7 @@
````json
//[doc-params]
{
"UI": ["MVC","Blazor","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
@ -516,7 +516,7 @@ Wrap the *New Book* button by an `if` block as shown below:
#### Hide the Edit/Delete Actions
`EntityAction` component defines `RequiredPolicy` attribute (parameter) to conditionally show the action based on the user permissions.
`EntityAction` component defines `Visible` attribute (parameter) to conditionally show the action.
Update the `EntityActions` section as shown below:
@ -524,11 +524,11 @@ Update the `EntityActions` section as shown below:
<EntityActions TItem="BookDto" EntityActionsColumn="@EntityActionsColumn">
<EntityAction TItem="BookDto"
Text="@L["Edit"]"
RequiredPolicy="@UpdatePolicyName"
Visible=HasUpdatePermission
Clicked="() => OpenEditModalAsync(context)" />
<EntityAction TItem="BookDto"
Text="@L["Delete"]"
RequiredPolicy="@DeletePolicyName"
Visible=HasDeletePermission
Clicked="() => DeleteEntityAsync(context)"
ConfirmationMessage="()=>GetDeleteConfirmationMessage(context)" />
</EntityActions>

2
docs/en/Tutorials/Part-6.md

@ -2,7 +2,7 @@
````json
//[doc-params]
{
"UI": ["MVC","Blazor","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````

2
docs/en/Tutorials/Part-7.md

@ -2,7 +2,7 @@
````json
//[doc-params]
{
"UI": ["MVC","Blazor","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````

6
docs/en/Tutorials/Part-8.md

@ -2,7 +2,7 @@
````json
//[doc-params]
{
"UI": ["MVC","Blazor","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
@ -267,7 +267,7 @@ public async Task<AuthorDto> CreateAsync(CreateAuthorDto input)
````
* `CreateAsync` requires the `BookStorePermissions.Authors.Create` permission (in addition to the `BookStorePermissions.Authors.Default` declared for the `AuthorAppService` class).
* Used the `AuthorManeger` (domain service) to create a new author.
* Used the `AuthorManager` (domain service) to create a new author.
* Used the `IAuthorRepository.InsertAsync` to insert the new author to the database.
* Used the `ObjectMapper` to return an `AuthorDto` representing the newly created author.
@ -566,4 +566,4 @@ Created some tests for the application service methods, which should be clear to
## The Next Part
See the [next part](Part-9.md) of this tutorial.
See the [next part](Part-9.md) of this tutorial.

8
docs/en/Tutorials/Part-9.md

@ -2,7 +2,7 @@
````json
//[doc-params]
{
"UI": ["MVC","Blazor","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
@ -792,7 +792,7 @@ Open the `/src/app/author/author.component.html` and replace the content as belo
</ng-template>
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" #abpClose>
<button type="button" class="btn btn-secondary" abpClose>
{%{{{ '::Close' | abpLocalization }}}%}
</button>
@ -832,7 +832,7 @@ That's all! This is a fully working CRUD page, you can create, edit and delete a
{{end}}
{{if UI == "Blazor"}}
{{if UI == "Blazor" || UI == "BlazorServer"}}
## The Author Management Page
@ -1116,7 +1116,7 @@ namespace Acme.BookStore.Blazor.Pages
await GetAuthorsAsync();
StateHasChanged();
await InvokeAsync(StateHasChanged);
}
private void OpenCreateAuthorModal()

BIN
docs/en/Tutorials/images/blazor-edit-book-action-2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 96 KiB

125
docs/en/UI/Angular/Account-Module.md

@ -0,0 +1,125 @@
# Angular UI Account Module
Angular UI account module is available as of v4.3. It contains some pages (login, register, manage your profile, etc.).
If you add the account module to your project;
- "Manage your profile" link in the current user dropdown on the top bar will redirect the user to a page in the account module.
- You can switch the authentication flow to the resource owner password flow.
### Account Module Implementation
Install the `@abp/ng.account` NPM package by running the below command:
```bash
npm install @abp/ng.account@next
```
> Make sure v4.3-rc or higher version is installed.
Open the `app.module.ts` and add `AccountConfigModule.forRoot()` to the imports array as shown below:
```js
// app.module.ts
import { AccountConfigModule } from '@abp/ng.account/config';
//...
@NgModule({
imports: [
//...
AccountConfigModule.forRoot()
],
//...
})
export class AppModule {}
```
Open the `app-routing.module.ts` and add the `account` route to `routes` array as follows:
```js
// app-routing.module.ts
const routes: Routes = [
//...
{
path: 'account',
loadChildren: () => import('@abp/ng.account').then(m => m.AccountModule.forLazy()),
},
//...
export class AppRoutingModule {}
```
### Account Public Module Implementation for Commercial Templates
The pro startup template comes with `@volo/abp.ng.account` package. You should update the package version to v4.3-rc or higher version. The package can be updated by running the following command:
```bash
npm install @volo/abp.ng.account@next
```
> Make sure v4.3-rc or higher version is installed.
Open the `app.module.ts` and add `AccountPublicConfigModule.forRoot()` to the imports array as shown below:
```js
// app.module.ts
import { AccountPublicConfigModule } from '@volo/abp.ng.account/public/config';
//...
@NgModule({
imports: [
//...
AccountPublicConfigModule.forRoot()
],
//...
})
export class AppModule {}
```
Open the `app-routing.module.ts` and add the `account` route to `routes` array as follows:
```js
// app-routing.module.ts
const routes: Routes = [
//...
{
path: 'account',
loadChildren: () => import('@volo/abp.ng.account/public').then(m => m.AccountPublicModule.forLazy()),
},
//...
export class AppRoutingModule {}
```
### Manage Profile Page
Before v4.3, the "Manage Your Profile" link in the current user dropdown on the top bar redirected the user to MVC's profile management page. As of v4.3, if you added the account module to your project, the same link will land on a page in the Angular UI account module instead.
### My Security Logs Page [COMMERCIAL]
Before v4.3, the "My Security Logs" link in the current user dropdown on the top bar redirected the user to MVC's my security logs page. As of v4.3, if you added the account module to your project, the same link will land on a page in the Angular UI account public module instead.
### Resource Owner Password Flow
OAuth is preconfigured as authorization code flow in Angular application templates by default. If you added the account module to your project, you can switch the flow to resource owner password flow by changing the OAuth configuration in the _environment.ts_ files as shown below:
```js
import { Config } from '@abp/ng.core';
export const environment = {
// other options removed for sake of brevity
oAuthConfig: {
issuer: 'https://localhost:44305', // IdentityServer url
clientId: 'MyProjectName_App',
dummyClientSecret: '1q2w3e*',
scope: 'offline_access MyProjectName',
},
// other options removed for sake of brevity
} as Config.Environment;
```
> Note: The resource owner password flow does not support the two-factor authentication for some technical reasons.
See the [Authorization in Angular UI](./Authorization.md) document for more details.

36
docs/en/UI/Angular/Authorization.md

@ -1,6 +1,9 @@
# Authorization in Angular UI
## Authorization in Angular UI
OAuth is preconfigured in Angular application templates. So, when you start a project using the CLI (or Suite, for that matter), authorization already works. You can find **OAuth configuration** in the _environment.ts_ files.
OAuth is preconfigured in Angular application templates. So, when you start a project using the CLI (or Suite, for that matter), authorization already works. ABP Angular UI packages are using [angular-oauth2-oidc library](https://github.com/manfredsteyer/angular-oauth2-oidc#logging-in) for managing OAuth in the Angular client.
You can find **OAuth configuration** in the _environment.ts_ files.
### Authorization Code Flow
```js
import { Config } from '@abp/ng.core';
@ -23,6 +26,31 @@ export const environment = {
```
This configuration results in an [OAuth authorization code flow with PKCE](https://tools.ietf.org/html/rfc7636) and we are using [angular-oauth2-oidc library](https://github.com/manfredsteyer/angular-oauth2-oidc#logging-in) for managing OAuth in the Angular client.
This configuration results in an [OAuth authorization code flow with PKCE](https://tools.ietf.org/html/rfc7636).
According to this flow, the user is redirected to an external login page which is built with MVC. So, if you need **to customize the login page**, please follow [this community article](https://community.abp.io/articles/how-to-customize-the-login-page-for-mvc-razor-page-applications-9a40f3cd).
### Resource Owner Password Flow
If you implemented the [Angular UI account module](./Account-Module) to your project, you can switch the flow to resource owner password flow by changing the OAuth configuration in the _environment.ts_ files as shown below:
```js
import { Config } from '@abp/ng.core';
export const environment = {
// other options removed for sake of brevity
oAuthConfig: {
issuer: 'https://localhost:44305',
clientId: 'MyProjectName_App',
dummyClientSecret: '1q2w3e*',
scope: 'offline_access MyProjectName',
},
// other options removed for sake of brevity
} as Config.Environment;
```
According to this flow, the user is redirected to the login page in the account module.
> Note: The resource owner password flow does not support the two-factor authentication for some technical reasons.

2
docs/en/UI/Angular/Entity-Action-Extensions.md

@ -180,7 +180,7 @@ Let's employ dependency injection to extend the functionality of `IdentityModule
</ng-template>
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" #abpClose>
<button type="button" class="btn btn-secondary" abpClose>
{%{{{ 'AbpUi::Close' | abpLocalization }}}%}
</button>
</ng-template>

103
docs/en/UI/Angular/HTTP-Requests.md

@ -27,13 +27,13 @@ An `HttpInterceptor` is able to catch `HttpErrorResponse`  and can be used for
## RestService
ABP core module has a utility service for HTTP requests: `RestService`. Unless explicitly configured otherwise, it catches HTTP errors and dispatches a `RestOccurError` action. This action is then captured by the `ErrorHandler` introduced by the `ThemeSharedModule`. Since you should already import this module in your app, when the `RestService` is used, all HTTP errors get automatically handled by deafult.
ABP core module has a utility service for HTTP requests: `RestService`. Unless explicitly configured otherwise, it catches HTTP errors and dispatches a `RestOccurError` action. This action is then captured by the `ErrorHandler` introduced by the `ThemeSharedModule`. Since you should already import this module in your app, when the `RestService` is used, all HTTP errors get automatically handled by default.
### Getting Started with RestService
In order to use the `RestService`, you must inject it in your class as a dependency.
In order to use the `RestService`, you must inject it in your class as a dependency.
```js
import { RestService } from '@abp/ng.core';
@ -101,7 +101,7 @@ postFoo(body: Foo) {
You may [check here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L23) for complete `Rest.Request<T>` type, which has only a few chages compared to [HttpRequest](https://angular.io/api/common/http/HttpRequest) class in Angular.
You may [check here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L23) for complete `Rest.Request<T>` type, which has only a few changes compared to [HttpRequest](https://angular.io/api/common/http/HttpRequest) class in Angular.
@ -200,6 +200,101 @@ getSomeCustomHeaderValue() {
}
```
You may find `Rest.Observe` enum [here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L10).
You may find `Rest.Observe` enum [here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L10).
## HTTP Error Handling
When the `RestService` is used, all HTTP errors are automatically handled by `ErrorHandler` which is a service that exposed by the `@abp/ng.theme.shared` package.
### Custom HTTP Error Handler
A custom HTTP error handler can be registered to an injection token named `HTTP_ERROR_HANDLER`. If a custom handler function is registered, the `ErrorHandler` executes that function.
See an example:
```js
// http-error-handler.ts
import { ContentProjectionService, PROJECTION_STRATEGY } from '@abp/ng.core';
import { ToasterService } from '@abp/ng.theme.shared';
import { HttpErrorResponse } from '@angular/common/http';
import { Injector } from '@angular/core';
import { throwError } from 'rxjs';
import { Error404Component } from './error404/error404.component';
export function handleHttpErrors(injector: Injector, httpError: HttpErrorResponse) {
if (httpError.status === 400) {
const toaster = injector.get(ToasterService);
toaster.error(httpError.error?.error?.message || 'Bad request!', '400');
return;
}
if (httpError.status === 404) {
const contentProjection = injector.get(ContentProjectionService);
contentProjection.projectContent(PROJECTION_STRATEGY.AppendComponentToBody(Error404Component));
return;
}
return throwError(httpError);
}
// app.module.ts
import { Error404Component } from './error404/error404.component';
import { handleHttpErrors } from './http-error-handling';
import { HTTP_ERROR_HANDLER, ... } from '@abp/ng.theme.shared';
@NgModule({
// ...
providers: [
// ...
{ provide: HTTP_ERROR_HANDLER, useValue: handleHttpErrors }
],
declarations: [
//...
Error404Component],
})
export class AppModule {}
```
In the example above:
- Created a function named `handleHttpErrors` and defined as value of the `HTTP_ERROR_HANDLER` provider in app.module. After this, the function executes when an HTTP error occurs.
- 400 bad request errors is handled. When a 400 error occurs, backend error message will be displayed as shown below:
![custom-error-handler-toaster-message](images/custom-error-handler-toaster-message.jpg)
- 404 not found errors is handled. When a 404 error occurs, `Error404Component` will be appended to the `<body>` as shown below:
![custom-error-handler-404-component](images/custom-error-handler-404-component.jpg)
- Since `throwError(httpError)` is returned at bottom of the `handleHttpErrors`, the `ErrorHandler` will handle the HTTP errors except 400 and 404 errors.
**Note 1:** If you put `return` to next line of handling an error, default error handling will not work for that error.
```js
export function handleHttpErrors(injector: Injector, httpError: HttpErrorResponse) {
if (httpError.status === 403) {
// handle 403 errors here
return; // put return to skip default error handling
}
}
```
**Note 2:** If you put `return throwError(httpError)`, default error handling will work.
- `throwError` is a function. It can be imported from `rxjs`.
- `httpError` is the second parameter of the error handler function which is registered to the `HTTP_ERROR_HANDLER` provider. Type of the `httpError` is `HttpErrorResponse`.
```js
import { throwError } from 'rxjs';
export function handleHttpErrors(injector: Injector, httpError: HttpErrorResponse) {
if (httpError.status === 500) {
// handle 500 errors here
return;
}
// you can return the throwError(httpError) at bottom of the function to run the default handler of ABP for HTTP errors that you didn't handle above.
return throwError(httpError)
}
```

2
docs/en/UI/Angular/How-Replaceable-Components-Work-with-Extensions.md

@ -215,7 +215,7 @@ Open the generated `src/app/my-role/my-role.component.html` file and replace its
</ng-template>
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" #abpClose>
<button type="button" class="btn btn-secondary" abpClose>
{%{{{ 'AbpIdentity::Cancel' | abpLocalization }}}%}
</button>
<abp-button iconClass="fa fa-check" [disabled]="form?.invalid" (click)="save()">{%{{{

6
docs/en/UI/Angular/Modal.md

@ -6,7 +6,7 @@ The `abp-modal` provides some additional benefits:
- It is **flexible**. You can pass header, body, footer templates easily by adding the templates to the `abp-modal` content. It can also be implemented quickly.
- Provides several inputs be able to customize the modal and several outputs be able to listen to some events.
- Automatically detects the close button which has a `#abpClose` template variable and closes the modal when pressed this button.
- Automatically detects the close button which has a `abpClose` directive attached to and closes the modal when pressed this button.
- Automatically detects the `abp-button` and triggers its loading spinner when the `busy` input value of the modal component is true.
- Automatically checks if the form inside the modal **has changed, but not saved**. It warns the user by displaying a [confirmation popup](Confirmation-Service) in this case when a user tries to close the modal or refresh/close the tab of the browser.
@ -47,7 +47,7 @@ You can add the `abp-modal` to your component very quickly. See an example:
</ng-template>
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" #abpClose>Close</button>
<button type="button" class="btn btn-secondary" abpClose>Close</button>
</ng-template>
</abp-modal>
```
@ -116,7 +116,7 @@ See an example form inside a modal:
</ng-template>
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" #abpClose>
<button type="button" class="btn btn-secondary" abpClose>
Cancel
</button>

218
docs/en/UI/Angular/Page-Component.md

@ -0,0 +1,218 @@
# Page Component
ABP provides a component that wraps your content with some built-in components to reduce the amount of code you need to write.
If the template of a component looks as follows, you can utilize the `abp-page` component.
Let's look at the following example without `abp-page` component.
`dashboard.component.ts`
```html
<div class="row entry-row">
<div class="col-auto">
<h1 class="content-header-title">{{ '::Dashboard' | abpLocalization }}</h1>
</div>
<div id="breadcrumb" class="col-lg-auto pl-lg-0">
<abp-breadcrumb></abp-breadcrumb>
</div>
<div class="col">
<abp-page-toolbar [record]="data"></abp-page-toolbar>
</div>
</div>
<div id="dashboard-id">
<!-- dashboard content here -->
</div>
```
## Page Parts
PageComponent divides the template shown above into three parts, `title`, `breadcrumb`, `toolbar`. Each can be configured separately. There, also, is an enum exported from the package that describes each part.
```javascript
export enum PageParts {
title = 'PageTitleContainerComponent',
breadcrumb = 'PageBreadcrumbContainerComponent',
toolbar = 'PageToolbarContainerComponent',
}
// You can import this enum from -> import { PageParts } from '@abp/ng.components/page';
```
## Usage
Firstly, you need to import `PageModule` from `@abp/ng.components/page` as follows:
`dashboard.module.ts`
```javascript
import { PageModule } from '@abp/ng.components/page';
import { DashboardComponent } from './dashboard.component';
@NgModule({
declarations: [DashboardComponent],
imports: [PageModule]
})
export class DashboardModule {}
```
And change the template of `dashboard.component.ts` to the following:
```html
<abp-page [title]="'::Dashboard' | abpLocalization" [toolbar]="data">
<div id="dashboard-id">
<!-- .... -->
</div>
</abp-page>
```
## Inputs
* title: `string`: Will be be rendered within `h1.content-header-title`. If not provided, the parent `div` will not be rendered
* breadcrumb: `boolean`: Determines whether to render `abp-breadcrumb`. Default is `true`.
* toolbar: `any`: Will be passed into `abp-page-toolbar` component through `record` input. If your page does not contain `abp-page-toolbar`, you can simply omit this field.
## Overriding template
If you need to replace the template of any part, you can use the following sub-components.
```html
<abp-page>
<abp-page-title-container>
<div class="col">
<h2>Custom Title</h2>
</div>
</abp-page-title-container>
<abp-page-breacrumb-container>
<div class="col">
<my-breadcrumb></my-breadcrumb>
</div>
</abp-page-breacrumb-container>
<abp-page-toolbar-container>
<div class="col">
<!-- ... -->
</div>
</abp-page-toolbar-container>
</abp-page>
```
You do not have to provide them all. You can just use which one you need to replace. These components have priority over the inputs declared above. If you use these components, you can omit the inputs.
## PagePartDirective
`PageModule` provides a structural directive that is used internally within `PageComponent` and can also be used externally.
`PageComponent` employs this directive internally as follows:
```html
<div class="col-lg-auto pl-lg-0" *abpPagePart="pageParts.breadcrumb">
<abp-breadcrumb></abp-breadcrumb>
</div>
```
It also can take a context input as follows:
```html
<div class="col" *abpPagePart="pageParts.toolbar; context: toolbarData">
<abp-page-toolbar [record]="toolbarData"></abp-page-toolbar>
</div>
```
Its render strategy can be provided through Angular's Dependency Injection system.
It expects a service through the `PAGE_RENDER_STRATEGY` injection token that implements the following interface.
```javascript
interface PageRenderStrategy {
shouldRender(type?: string): boolean | Observable<boolean>;
onInit?(type?: string, injector?: Injector, context?: any): void;
onDestroy?(type?: string, injector?: Injector, context?: any): void;
onContextUpdate?(change?: SimpleChange): void;
}
```
* `shouldRender` (required): It takes a string input named `type` and expects a `boolean` or `Observable<boolean>` in return.
* `onInit` (optional): Will be called when the directive is initiated. Three inputs will be passed into this method.
* `type`: type of the page part
* `injector`: injector of the directive which could be used to retrieve anything from directive's DI tree.
* `context`: whatever context is available at the initialization phase.
* `onDestroy` (optional): Will be called when the directive is destroyed. The parameters are the same with `onInit`
* `onContextUpdate` (optional): Will be called when the context is updated.
* `change`: changes of the `context` will be passed through this method.
Let's see everything in action.
```javascript
import { 
PageModule,
PageRenderStrategy,
PageParts,
PAGE_RENDER_STRATEGY
} from '@abp/ng.components/page';
@Injectable()
export class MyPageRenderStrategy implements PageRenderStrategy {
shouldRender(type: string) {
// meaning everything but breadcrumb and custom-part will be rendered
return type !== PageParts.breadcrumb && type !== 'custom-part';
}
/**
* shouldRender can also return an Observable<boolean> which means
* an async service can be used within.
constructor(private service: SomeAsyncService) {}
shouldRender(type: string) {
return this.service.checkTypeAsync(type).pipe(map(val => val.isTrue()));
}
*/
onInit(type: string, injector: Injector, context: any) {
// this method will be called in ngOnInit of the directive
}
onDestroy(type: string, injector: Injector, context: any) {
// this method will be called in ngOnDestroy of the directive
}
onContextUpdate?(change?: SimpleChange) {
// this method will be called everytime context is updated within the directive
}
}
@Component({
selector: 'app-dashboard',
template: `
<abp-page [title]="'::Dashboard' | abpLocalization">
<abp-page-toolbar-container>
<button>New Dashboard</button>
</abp-page-toolbar-container>
<div class="dashboard-content">
<h3 *abpPagePart="'custom-part'"> Inner Title </h3>
</div>
</abp-page>
`
})
export class DashboardComponent {}
@NgModule({
imports: [PageModule],
declarations: [DashboardComponent],
providers: [
{
provide: PAGE_RENDER_STRATEGY,
useClass: MyPageRenderStrategy,
}
]
})
export class DashboardModule {}
```
## See Also
- [Page Toolbar Extensions for Angular UI](./Page-Page-Toolbar-Extensions.md)

2
docs/en/UI/Angular/Permission-Management-Component-Replacement.md

@ -459,7 +459,7 @@ Open the generated `permission-management.component.html` in `src/app/permission
</div>
</ng-template>
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" #abpClose>
<button type="button" class="btn btn-secondary" abpClose>
{%{{{ 'AbpIdentity::Cancel' | abpLocalization }}}%}
</button>
<abp-button iconClass="fa fa-check" (click)="submit()">{%{{{

BIN
docs/en/UI/Angular/images/custom-error-handler-404-component.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

BIN
docs/en/UI/Angular/images/custom-error-handler-toaster-message.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

41
docs/en/UI/AspNetCore/Bundling-Minification.md

@ -50,7 +50,7 @@ The simplest way of creating a bundle is to use `abp-script-bundle` or `abp-styl
This bundle defines a style bundle with a **unique name**: `MyGlobalBundle`. It's very easy to understand how to use it. Let's see how it *works*:
* ABP creates the bundle as **lazy** from the provided files when it's **first requested**. For the subsequent calls, it's returned from the **cache**. That means if you conditionally add the files to the bundle, it's executed only once and any changes of the condition will not effect the bundle for the next requests.
* ABP adds bundle files **individually** to the page for the `development` environment. It automatically bundles & minifies for other environments (`staging`, `production`...).
* ABP adds bundle files **individually** to the page for the `development` environment. It automatically bundles & minifies for other environments (`staging`, `production`...). See the *Bundling Mode* section to change that behavior.
* The bundle files may be **physical** files or [**virtual/embedded** files](../../Virtual-File-System.md).
* ABP automatically adds **version query string** to the bundle file URL to prevent browsers from caching when the bundle is being updated. (like ?_v=67872834243042 - generated from last change date of the related files). The versioning works even if the bundle files are individually added to the page (on the development environment).
@ -351,6 +351,45 @@ services.Configure<AbpBundlingOptions>(options =>
});
````
## Additional Options
This section shows other useful options for the bundling and minification system.
### Bundling Mode
ABP adds bundle files individually to the page for the `development` environment. It automatically bundles & minifies for other environments (`staging`, `production`...). Most of the times this is the behavior you would want. However, you may want to manually configure it in some cases. There are four modes;
* `Auto`: Automatically determines the mode based on the environment.
* `None`: No bundling or minification.
* `Bundle`: Bundled but not minified.
* `BundleAndMinify`: Bundled and minified.
You can configure `AbpBundlingOptions` in the `ConfigureServices` of your [module](../../Module-Development-Basics.md).
**Example:**
````csharp
Configure<AbpBundlingOptions>(options =>
{
options.Mode = BundlingMode.Bundle;
});
````
### Ignore For Minification
It is possible to ignore a specific file for the minification.
**Example:**
````csharp
Configure<AbpBundlingOptions>(options =>
{
options.MinificationIgnoredFiles.Add("/scripts/myscript.js");
});
````
Given file is still added to the bundle, but not minified in this case.
## Themes
Themes uses the standard package contributors to add library resources to page layouts. Themes may also define some standard/global bundles, so any module can contribute to these standard/global bundles. See the [theming documentation](Theming.md) for more.

20
docs/en/UI/AspNetCore/Navigation-Menu.md

@ -104,6 +104,7 @@ There are more options of a menu item (the constructor of the `ApplicationMenuIt
* `target` (`string`): Target of the menu item. Can be `null` (default), "\_*blank*", "\_*self*", "\_*parent*", "\_*top*" or a frame name for web applications.
* `elementId` (`string`): Can be used to render the element with a specific HTML `id` attribute.
* `cssClass` (`string`): Additional string classes for the menu item.
* `RequiredPermissionName` (`string`): The required permission name, this menu item will be removed if this permission is not granted.
### Authorization
@ -120,6 +121,25 @@ if (await context.IsGrantedAsync("MyPermissionName"))
}
````
For the authorization, you can use `RequiredPermissionName` as a shortcut. It is also more performant, ABP optimizes the permission check for all the items.
````csharp
context.Menu.AddItem(
new ApplicationMenuItem("MyProject.Crm", l["Menu:CRM"])
.AddItem(new ApplicationMenuItem(
name: "MyProject.Crm.Customers",
displayName: l["Menu:Customers"],
url: "/crm/customers",
requiredPermissionName: "MyProject.Crm.Customers")
).AddItem(new ApplicationMenuItem(
name: "MyProject.Crm.Orders",
displayName: l["Menu:Orders"],
url: "/crm/orders",
requiredPermissionName: "MyProject.Crm.Orders")
)
);
````
> You can use `context.AuthorizationService` to directly access to the `IAuthorizationService`.
### Resolving Dependencies

17
docs/en/UI/AspNetCore/Toolbars.md

@ -52,6 +52,21 @@ public class MyToolbarContributor : IToolbarContributor
}
````
You can use the [authorization](../../Authorization.md) to decide whether to add a `ToolbarItem`.
````csharp
if (await context.IsGrantedAsync("MyPermissionName"))
{
//...add Toolbar items
}
````
You can use `RequiredPermissionName` as a shortcut. It is also more performant, ABP optimizes the permission check for all the items.
````csharp
context.Toolbar.Items.Insert(0, new ToolbarItem(typeof(NotificationViewComponent), requiredPermissionName: "MyPermissionName"));
````
This class adds the `NotificationViewComponent` as the first item in the `Main` toolbar.
Finally, you need to add this contributor to the `AbpToolbarOptions`, in the `ConfigureServices` of your [module](../../Module-Development-Basics.md):
@ -71,4 +86,4 @@ That's all, you will see the notification icon on the toolbar when you run the a
## IToolbarManager
`IToolbarManager` is used to render the toolbar. It returns the toolbar items by a toolbar name. This is generally used by the [themes](Theming.md) to render the toolbar on the layout.
`IToolbarManager` is used to render the toolbar. It returns the toolbar items by a toolbar name. This is generally used by the [themes](Theming.md) to render the toolbar on the layout.

8
docs/en/Upgrading.md

@ -29,14 +29,18 @@ If `Add-Migration` generates an empty migration, you can use `Remove-Migration`
## The Blog Posts & Guides
Sometimes we introduce new features/changes that requires to make changes in the startup template. We already implement the changes in the startup template for new applications. However, in some cases you need to manually make some minor changes in your solution.
Whenever you upgrade your solution, it is strongly suggested to check the [ABP BLOG](https://blog.abp.io/) to learn the new features and changes coming with the new version. We regularly publish posts and write these kind of changes.
### Migration Guides
We prepare migration guides if the new version brings breaking changes for existing applications. See the [Migration Guides](Migration-Guides/Index.md) page for all the guides.
### Upgrading the Startup Template
Sometimes we introduce new features/changes that requires to **make changes in the startup template**. We already implement the changes in the startup template for new applications. However, in some cases you need to manually make some minor changes in your existing solution.
It is not practical to document the necessary changes line by line. In this case, we suggest you to create an example solution, one with your existing version and one with the new version and compare them using a diff tool. You can [see this guide](Migration-Guides/Upgrading-Startup-Template.md) to learn how you can do it using WinMerge application.
## Semantic Versioning & Breaking Changes
We are working hard to keep the semantic versioning rules, so you don't get breaking changes for minor (feature) versions like 3.1, 3.2, 3.3...

21
docs/en/docs-nav.json

@ -882,6 +882,15 @@
]
}
]
},
{
"text": "Components",
"items": [
{
"text": "Page",
"path": "UI/Angular/Page-Component.md"
}
]
}
]
},
@ -1004,14 +1013,6 @@
"text": "Background Jobs",
"path": "Modules/Background-Jobs.md"
},
{
"text": "Blogging",
"path": "Modules/Blogging.md"
},
{
"text": "Client Simulation",
"path": "Modules/Client-Simulation.md"
},
{
"text": "CMS Kit",
"path": "Modules/Cms-Kit.md"
@ -1044,10 +1045,6 @@
"text": "Tenant Management",
"path": "Modules/Tenant-Management.md"
},
{
"text": "Users",
"path": "Modules/Users.md"
},
{
"text": "Virtual File Explorer",
"path": "Modules/Virtual-File-Explorer.md"

3
docs/en/docs-params.json

@ -5,7 +5,8 @@
"displayName": "UI",
"values": {
"MVC": "MVC / Razor Pages",
"Blazor": "Blazor",
"Blazor": "Blazor WebAssembly",
"BlazorServer": "Blazor Server",
"NG": "Angular"
}
},

BIN
docs/en/images/email-settings.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/en/images/upgrade-diff-empty-folders.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

BIN
docs/en/images/winmerge-comparison-result.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

BIN
docs/en/images/winmerge-file-diff.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
docs/en/images/winmerge-open-folders.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

4
docs/pt-BR/Tutorials/Angular/Part-II.md

@ -90,7 +90,7 @@ Abra o `book-list.component.html`e adicione o `abp-modal`para mostrar / ocultar
<ng-template #abpBody> </ng-template>
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" #abpClose>
<button type="button" class="btn btn-secondary" abpClose>
Cancel
</button>
</ng-template>
@ -276,7 +276,7 @@ Abra o `book-list.component.html`e adicione um `abp-button`para salvar o formul
```html
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" #abpClose>
<button type="button" class="btn btn-secondary" abpClose>
Cancel
</button>
<button class="btn btn-primary" (click)="save()">

3
docs/zh-Hans/CLI.md

@ -154,6 +154,8 @@ abp add-package Volo.Abp.MongoDB
#### Options
* `--project` 或 `-p`: 指定项目 (.csproj) 路径. 如果未指定,Cli会尝试在当前目录查找.csproj文件.
* `--with-source-code`: 下载包的源码到你的解决方案文件夹,而不是NuGet/NPM软件包.
* `--add-to-solution-file`: 添加下载/创建的包添加到解决方案文件中,你在IDE中打开解决方案时也会看到包的项目. (仅当 `--with-source-code` 为 `True` 时可用.)
### add-module
@ -181,6 +183,7 @@ abp add-module Volo.Blogging
* `--skip-db-migrations`: 对于EF Core 数据库提供程序,它会自动添加新代码的第一次迁移 (`Add-Migration`) 并且在需要时更新数据库 (`Update-Database`). 指定此选项可跳过此操作.
* `-sp` 或 `--startup-project`: 启动项目的项目文件夹的相对路径. 默认值是当前文件夹.
* `--with-source-code`: 添加模块的源代码,而不是NuGet/NPM软件包.
* `--add-to-solution-file`: 添加下载/创建的模块添加到解决方案文件中,你在IDE中打开解决方案时也会看到模块的项目. (仅当 `--with-source-code` 为 `True` 时可用.)
### generate-proxy

10
docs/zh-Hans/Domain-Driven-Design-Implementation-Guide.md

@ -153,9 +153,9 @@ ABP的启动解决方案中包含两个用于集成Entity Framework Core的项
* `Application.Contracts` 依赖`Domain.Shared`项目,可以在DTO中重用`Domain.Shared`中的类型.例如,`Domain.Shared`项目中的枚举类型 `IssueType` 同样被`Contracts`项目中的`CreateIssueDto`DTO所引用.
* `Application` 依赖`Application.Contracts`项目,因为此项目需要实现应用服务的接口及接口使用的DTO.另外也依赖`Domain`项目,因为应用服务的实现必须依赖领域层中的对象.
* `EntityFrameworkCore` 依赖`Domain`项目,因为此项目需要将领域对象(实体或值对象)映射到数据库的表,另外还需要实现`Domain`项目中的仓储接口.
* `HttpApi` 依赖`Application.Contacts`项目,因为Controllers需要注入应用服务.
* `HttpApi.Client` 依赖`Application.Contacts`项目,因为此项目需要是使用应用服务.
* `Web` 依赖`HttpApi`项目,因为此项目对外提供HTTP APIs.另外Pages或Components 需要使用应用服务,所以还间接依赖了`Application.Contacts`项目
* `HttpApi` 依赖`Application.Contracts`项目,因为Controllers需要注入应用服务.
* `HttpApi.Client` 依赖`Application.Contracts`项目,因为此项目需要是使用应用服务.
* `Web` 依赖`HttpApi`项目,因为此项目对外提供HTTP APIs.另外Pages或Components 需要使用应用服务,所以还间接依赖了`Application.Contracts`项目
#### 虚线依赖
@ -781,7 +781,7 @@ namespace IssueTracking.Issues
- 创建时间大于30天
- 最近30天没有评论
这个业务逻辑就被实现再了仓储内部,当我们需要重用这个业务规则时就会出现问题.
这个业务逻辑就被实现在了仓储内部,当我们需要重用这个业务规则时就会出现问题.
例如:我们需要再实体`Issue`上添加一个方法来判断是否非活动`bool IsInActive()`,以方便我们在`Issue`实例上获取.
@ -1798,7 +1798,7 @@ public async Task ChangeTitleAsync(Issue issue, string title)
为了更清楚的实现,你可以为不同的应用类型创建不同的项目(`.csproj`):
* `IssueTracker.Admin.Application` 和 `IssueTracker.Admin.Application.Contacts` 为后台管理系统提供服务.
* `IssueTracker.Admin.Application` 和 `IssueTracker.Admin.Application.Contracts` 为后台管理系统提供服务.
* `IssueTracker.Public.Application` 和 `IssueTracker.Public.Application.Contracts` 为公开网站提供服务.
* `IssueTracker.Mobile.Application` 和 `IssueTracker.Mobile.Application.Contracts` 为移动端应用提供服务.

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save