diff --git a/.github/workflows/angular.yml b/.github/workflows/angular.yml
index 0c0f8d5b6c..ee66fbcf2c 100644
--- a/.github/workflows/angular.yml
+++ b/.github/workflows/angular.yml
@@ -10,8 +10,17 @@ on:
branches:
- 'rel-*'
- 'dev'
+ types:
+ - opened
+ - synchronize
+ - reopened
+ - ready_for_review
+permissions:
+ contents: read
+
jobs:
build-test-lint:
+ if: ${{ !github.event.pull_request.draft }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
diff --git a/.github/workflows/auto-pr.yml b/.github/workflows/auto-pr.yml
index 084b0977d0..1d9a8750e6 100644
--- a/.github/workflows/auto-pr.yml
+++ b/.github/workflows/auto-pr.yml
@@ -1,10 +1,16 @@
-name: Merge branch dev with rel-5.3
+name: Merge branch dev with rel-6.0
on:
push:
branches:
- - rel-5.3
+ - rel-6.0
+permissions:
+ contents: read
+
jobs:
- merge-rel-5-3-with-rel-5-2:
+ merge-dev-with-rel-6-0:
+ permissions:
+ contents: write # for peter-evans/create-pull-request to create branch
+ pull-requests: write # for peter-evans/create-pull-request to create a PR
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@@ -12,13 +18,13 @@ jobs:
ref: dev
- name: Reset promotion branch
run: |
- git fetch origin rel-5.3:rel-5.3
- git reset --hard rel-5.3
+ git fetch origin rel-6.0:rel-6.0
+ git reset --hard rel-6.0
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
- branch: auto-merge/rel-5-3/${{github.run_number}}
- title: Merge branch dev with rel-5.3
- body: This PR generated automatically to merge dev with rel-5.3. Please review the changed files before merging to prevent any errors that may occur.
+ branch: auto-merge/rel-6-0/${{github.run_number}}
+ title: Merge branch dev with rel-6.0
+ body: This PR generated automatically to merge dev with rel-6.0. Please review the changed files before merging to prevent any errors that may occur.
reviewers: ${{github.actor}}
token: ${{ github.token }}
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index 0210efcec9..4a993352ba 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -31,9 +31,18 @@ on:
- 'templates/**/*.cshtml'
- 'templates/**/*.csproj'
- 'templates/**/*.razor'
+ types:
+ - opened
+ - synchronize
+ - reopened
+ - ready_for_review
+permissions:
+ contents: read
+
jobs:
build-test:
runs-on: windows-latest
+ if: ${{ !github.event.pull_request.draft }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-dotnet@master
diff --git a/.github/workflows/cancel-workflow.yml b/.github/workflows/cancel-workflow.yml
index 78bbf94b3b..039943ad66 100644
--- a/.github/workflows/cancel-workflow.yml
+++ b/.github/workflows/cancel-workflow.yml
@@ -1,7 +1,12 @@
name: cancel-workflow
on: [push]
+permissions:
+ contents: read
+
jobs:
cancel:
+ permissions:
+ actions: write # for styfle/cancel-workflow-action to cancel/stop running workflows
name: 'Cancel Previous Runs'
runs-on: ubuntu-latest
timeout-minutes: 3
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 7aaad739e9..d1f6c0c503 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -9,23 +9,36 @@ on:
push:
branches: [dev, rel-*]
paths:
- - 'abp/**/*.js'
- - 'abp/**/*.cs'
- - 'abp/**/*.cshtml'
- - 'abp/**/*.csproj'
- - 'abp/**/*.razor'
+ - "abp/**/*.js"
+ - "abp/**/*.cs"
+ - "abp/**/*.cshtml"
+ - "abp/**/*.csproj"
+ - "abp/**/*.razor"
pull_request:
# The branches below must be a subset of the branches above
branches: [dev]
paths:
- - 'abp/**/*.js'
- - 'abp/**/*.cs'
- - 'abp/**/*.cshtml'
- - 'abp/**/*.csproj'
- - 'abp/**/*.razor'
+ - "abp/**/*.js"
+ - "abp/**/*.cs"
+ - "abp/**/*.cshtml"
+ - "abp/**/*.csproj"
+ - "abp/**/*.razor"
+ types:
+ - opened
+ - synchronize
+ - reopened
+ - ready_for_review
+
+permissions:
+ contents: read
jobs:
analyze:
+ if: ${{ !github.event.pull_request.draft }}
+ permissions:
+ actions: read # for github/codeql-action/init to get workflow details
+ contents: read # for actions/checkout to fetch code
+ security-events: write # for github/codeql-action/autobuild to send a status report
name: Analyze
runs-on: ubuntu-latest
@@ -34,48 +47,48 @@ jobs:
matrix:
# Override automatic language detection by changing the below list
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
- language: ['csharp', 'javascript']
+ language: ["csharp", "javascript"]
# Learn more...
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
steps:
- - name: Checkout repository
- uses: actions/checkout@v2
- with:
- # We must fetch at least the immediate parents so that if this is
- # a pull request then we can checkout the head.
- fetch-depth: 2
+ - name: Checkout repository
+ uses: actions/checkout@v2
+ with:
+ # We must fetch at least the immediate parents so that if this is
+ # a pull request then we can checkout the head.
+ fetch-depth: 2
- # If this run was triggered by a pull request event, then checkout
- # the head of the pull request instead of the merge commit.
- - run: git checkout HEAD^2
- if: ${{ github.event_name == 'pull_request' }}
+ # If this run was triggered by a pull request event, then checkout
+ # the head of the pull request instead of the merge commit.
+ - run: git checkout HEAD^2
+ if: ${{ github.event_name == 'pull_request' }}
- # Initializes the CodeQL tools for scanning.
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v1
- with:
- languages: ${{ matrix.language }}
- # If you wish to specify custom queries, you can do so here or in a config file.
- # By default, queries listed here will override any specified in a config file.
- # Prefix the list here with "+" to use these queries and those in the config file.
- # queries: ./path/to/local/query, your-org/your-repo/queries@main
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v1
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
- # If this step fails, then you should remove it and run the build manually (see below)
- - name: Autobuild
- uses: github/codeql-action/autobuild@v1
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v1
- # ℹ️ Command-line programs to run using the OS shell.
- # 📚 https://git.io/JvXDl
+ # ℹ️ Command-line programs to run using the OS shell.
+ # 📚 https://git.io/JvXDl
- # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
- # and modify them (or add more) to build your code if your project
- # uses a compiled language
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
+ # and modify them (or add more) to build your code if your project
+ # uses a compiled language
- #- run: |
- # make bootstrap
- # make release
+ #- run: |
+ # make bootstrap
+ # make release
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v1
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/image-compression.yml b/.github/workflows/image-compression.yml
index 9cbaa00d90..4556622e4a 100644
--- a/.github/workflows/image-compression.yml
+++ b/.github/workflows/image-compression.yml
@@ -1,21 +1,26 @@
-name: Compress Images
-on:
- pull_request:
- paths:
- - '**.jpg'
- - '**.jpeg'
- - '**.png'
- - '**.webp'
-jobs:
- build:
- if: github.event.pull_request.head.repo.full_name == github.repository
- name: calibreapp/image-actions
- runs-on: ubuntu-latest
- steps:
- - name: Checkout Repo
- uses: actions/checkout@v2
-
- - name: Compress Images
- uses: calibreapp/image-actions@main
- with:
- githubToken: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
+name: Compress Images
+on:
+ pull_request:
+ paths:
+ - "**.jpg"
+ - "**.jpeg"
+ - "**.png"
+ - "**.webp"
+ types:
+ - opened
+ - synchronize
+ - reopened
+ - ready_for_review
+jobs:
+ build:
+ if: github.event.pull_request.head.repo.full_name == github.repository && !github.event.pull_request.draft
+ name: calibreapp/image-actions
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repo
+ uses: actions/checkout@v2
+
+ - name: Compress Images
+ uses: calibreapp/image-actions@main
+ with:
+ githubToken: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index f24ba57949..5c464400cc 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -2,8 +2,12 @@ name: Pull request labeler
on:
schedule:
- cron: '0 12 */1 * *'
+permissions:
+ contents: read
jobs:
labeler:
+ permissions:
+ pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: paulfantom/periodic-labeler@master
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/zh-Hans.json
index e790ad80af..a773568a31 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/zh-Hans.json
@@ -11,6 +11,6 @@
"CommercialSupportWebSite": "商业版支持网站",
"CommunityWebSite": "ABP社区网站",
"ManageAccount": "我的帐户 | ABP.IO",
- "ManageYourAccount": "管理您的帐户"
+ "ManageYourProfile": "管理您的个人资料"
}
-}
+}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
index 22ef0df894..7a064a8ce7 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
@@ -397,6 +397,8 @@
"BookDiscountDeletionConfirmationMessage": "Are you sure you want to delete this book discount?",
"CustomPaymentFlexSwitchDescription": "With license",
"AllowFeatureUpgradeOnLicenseExpire": "Allow feature upgrade on license expire",
- "Deleted{0}": "[Deleted {0}]"
+ "Deleted{0}": "[Deleted {0}]",
+ "Tags": "Tags",
+ "SetTagsInfo": "Tags should be comma-separated. Eg: CSharp, Entity Framework"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/ro-RO.json
index 44ac964263..409ab816a5 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/ro-RO.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/ro-RO.json
@@ -30,7 +30,7 @@
"NugetPackageDeletionWarningMessage": "Sunteţi sigur(ă) că doriţi să ştergeţi acest pachet de tip Nuget?",
"ModuleDeletionWarningMessage": "Sunteţi sigur(ă) că doriţi să ştergeţi acest modul?",
"Name": "Nume",
- "DisplayName": "Nume de afişare",
+ "DisplayName": "Nume afişat",
"ShortDescription": "Descriere scurtă",
"NameFilter": "Nume",
"CreationTime": "Data şi ora creării",
@@ -317,7 +317,7 @@
"TrialLicenseStartDateFilter": "Data de început",
"TrialLicenseEndDateFilter": "Data de încheiere",
"FirsName": "Nume",
- "LastName": "Nume",
+ "LastName": "Nume de familie",
"StartDate": "Data de început",
"EndDate": "Data de încheiere",
"PurchasedDate": "Data achiziției",
@@ -350,4 +350,4 @@
"Volo.AbpIo.Commercial:030010": "Pentru a achiziționa licența de probă, mai întâi trebuie să vă activați licența de probă!",
"Volo.AbpIo.Commercial:030011": "Nu puteți șterge o licență de probă atunci când este achiziționată!"
}
-}
\ No newline at end of file
+}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
index 382d31dd5d..b0555bfe32 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
@@ -73,6 +73,7 @@
"DeveloperFocused": "Developer Focused",
"ShareYourExperiences": "Share your experiences with the ABP Framework",
"LatestPosts": "Latest Posts",
+ "LatestVideos": "Latest Videos",
"Views": "Views",
"LearnLatestNewsAboutABPFramework": "Get information about happenings in ABP like new releases, free sources, posts, and more.",
"DeveloperTools": "Developer Tools",
@@ -98,6 +99,7 @@
"Logout": "Logout",
"Home": "Home",
"Posts": "Posts",
+ "Videos": "Videos",
"JoinTheABPCommunity": "Join the ABP Community",
"SubmitYourPost": "Submit Your Post",
"Modules": "Modules",
@@ -161,6 +163,22 @@
"Error_Page_500_Title": "Looks like something went wrong!",
"Error_Page_500_Description_1": "We track these errors automatically, but if the problem persists feel free to
contact us. In the meantime, try refreshing.",
"Error_Page_500_Description_2": "Contact with us at info@abp.io.",
- "Books": "Books"
+ "Books": "Books",
+ "ABPDiscordServer": "ABP Discord Server",
+ "ABPCommunityTalks": "ABP Community Talks",
+ "ABPCommunityPosts": "ABP Community Posts",
+ "BuyAndGetMonths": "BUY 12 MONTHS, GET 14 MONTHS!",
+ "GetYourDeal": "Get Your Deal",
+ "BuyOrRenewLicense": "Buy or Renew License Now and Get 2 Extra Months!",
+ "BuyOrRenewLicenseToGetExtra2Months": "Buy or Renew License Now and Get 2 Extra Months! HURRY UP! ⏰ Last Day: {0}",
+ "HurryUp": "HURRY UP!",
+ "LastDay": "Last Day: {0}",
+ "BuyNewLicenseBetweenDatesToGetBenefit": "Buy a new license between {0} and {1} to get benefit for extra 2 months!",
+ "CheckAllCommunityTalks": "Check All Community Posts",
+ "ReadMore": "Read More",
+ "Post": "Post",
+ "ExploreTheContentsCreatedByTheCoreABPTeamAndTheABPCommunity": "Explore the contents created by the core ABP team and the ABP community.",
+ "WelcomeFallCampaign": "Welcome Fall Campaign!",
+ "GiveAwayForNewPurchases": "Application Development Classroom Training will be given away for the new purchases!"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json
index 818b4cab5e..1eedb98c61 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json
@@ -39,6 +39,8 @@
"TrialLicensePeriodHasExpired": "Deneme lisansınızın süresi {0} gün önce sona erdi.",
"TrialLicensePeriodWillExpire": "Deneme lisansınızın süresi {0} gün içinde dolacak.",
"TrialLicensePeriodExpireToday": "Deneme lisans süreniz bugün sona erecek.",
- "PurchaseNow": "Şimdi satın al!"
+ "PurchaseNow": "Şimdi satın al!",
+ "WelcomeFallCampaign": "Hoş Geldin Sonbahar Kampanyası!",
+ "GiveAwayForNewPurchases": "Yeni alımlar için Uygulama Geliştirme Sınıfı Eğitimi hediye edilecektir!"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json
index 01335e7921..e1ad37704f 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json
@@ -14,6 +14,20 @@
"Volo.AbpIo.Domain:020002": "不能删除该NPM包因为\"{Modules}\"模块正在使用此包.",
"Volo.AbpIo.Domain:020003": "不能删除该NPM包因为\"{Modules}\"模块正在使用此包并且\"{NugetPackages}\"Nuget包依赖此包.",
"Volo.AbpIo.Domain:020004": "不能删除该Nuget包因为\"{Modules}\"模块正在使用此包.",
+ "Volo.AbpIo.Domain:030000": "您已经完成了试用期。",
+ "Volo.AbpIo.Domain:030001": "此组织名称已存在。",
+ "Volo.AbpIo.Domain:030002": "一旦激活,您将无法将试用许可证切换到 -requested- 状态!",
+ "Volo.AbpIo.Domain:030003": "没有这种状态!",
+ "Volo.AbpIo.Domain:030004": "由于意外错误,无法更改状态!",
+ "Volo.AbpIo.Domain:030005": "试用许可证处于激活状态时可以更新开始和结束日期!",
+ "Volo.AbpIo.Domain:030006": "结束日期必须大于开始日期!",
+ "Volo.AbpIo.Domain:030007": "此试用许可证已激活!",
+ "Volo.AbpIo.Domain:030008": "只有状态为-purchased-时才能设置购买日期!",
+ "Volo.AbpIo.Domain:030009": "找不到用户!",
+ "Volo.AbpIo.Domain:030010": "要购买试用许可证,您首先需要激活您的试用许可证!",
+ "Volo.AbpIo.Domain:030011": "购买后不能删除试用许可证!",
+ "Volo.AbpIo.Domain:070000": "组织名称只能包含拉丁字母、数字、点和连字符!",
+ "Volo.AbpIo.Domain:070001": "公司名称只能包含拉丁字母、数字、点、空格和连字符!",
"WantToLearn?": "想学习吗?",
"ReadyToGetStarted?": "准备开始了吗?",
"JoinOurCommunity": "加入我们的社区",
@@ -39,6 +53,129 @@
"TrialLicensePeriodHasExpired": "您的试用许可期限已于 {0} 天前到期。",
"TrialLicensePeriodWillExpire": "您的试用许可期限将在 {0} 天后到期。",
"TrialLicensePeriodExpireToday": "您的试用许可期将于今天到期。",
- "PurchaseNow": "现在买!"
+ "PurchaseNow": "现在买!",
+ "LatestReleaseLogs": "最新发布日志",
+ "RoadMap": "路线图",
+ "FAQ": "常见问题",
+ "SourceCode": "源代码",
+ "SeeAllPosts": "查看所有帖子",
+ "Contribute": "贡献",
+ "LiveDemo": "在线演示",
+ "GetLicense": "获得许可证",
+ "OpenSource": "开源",
+ "WebApplication": "Web应用程序",
+ "MeetTheABP": "认识 ABP",
+ "CompleteWebDevelopment": "一个完整的 Web 开发",
+ "Platform": "平台",
+ "ABPDescription": "ABP 框架是一个完整的基础架构,可通过遵循软件开发最佳实践和约定来创建现代 Web 应用程序。",
+ "StrongInfrastructure": "强大的基础设施",
+ "CompleteArchitecture": "完整的架构",
+ "DeveloperFocused": "以开发者为中心",
+ "ShareYourExperiences": "分享您使用 ABP 框架的经验",
+ "LatestPosts": "最新的帖子",
+ "LatestVideos": "最新的视频",
+ "Views": "意见",
+ "LearnLatestNewsAboutABPFramework": "获取有关 ABP 的最新相关信息,例如新版本、免费资源、帖子等。",
+ "DeveloperTools": "开发者工具",
+ "StartupTemplates": "启动模板",
+ "ApplicationModules": "应用模块",
+ "UI": "UI",
+ "Themes": "主题",
+ "Premium": "高级的",
+ "PrivacyPolicy": "隐私政策",
+ "TermsAndConditions": "条款 & 条件",
+ "WouldLikeToReceiveMarketingMaterials": "我想收到产品交易和特别优惠等市场推广材料。",
+ "JoinOurMarketingNewsletter": "加入我们市场推广时事通讯",
+ "CommunityPrivacyPolicyConfirmation": "我同意条款 & 条件和隐私政策 。",
+ "WouldLikeToReceiveNotification": "我想从 abp.io 网站接收最新消息。",
+ "CommercialNewsletterConfirmationMessage": "我同意条款 & 条件 和 隐私政策。",
+ "FreeDDDEBook": "免费 DDD 电子书",
+ "AdditionalServices": "额外服务",
+ "Learn": "学习",
+ "AccountOverview": "账户信息",
+ "MyOrganizations": "我的组织",
+ "MySupportQuestions": "我的支持问题",
+ "MyProfile": "我的简介",
+ "Logout": "登出",
+ "Home": "主页",
+ "Posts": "帖子",
+ "Videos": "视频",
+ "JoinTheABPCommunity": "加入 ABP 社区",
+ "SubmitYourPost": "提交您的帖子",
+ "Modules": "模块",
+ "Tools": "工具",
+ "Pricing": "价格",
+ "ChangeLogs": "更改日志",
+ "SubscribeToNewsletter": "订阅时事通讯",
+ "SubscribeToNewsletterDescription": "获取有关 ABP 的最新相关信息,例如新版本、免费资源、帖子等。",
+ "EmailAddress": "邮箱地址",
+ "Subscribe": "订阅",
+ "WelcomeToABP": "欢迎来到 ABP",
+ "EULA": "最终用户许可协议",
+ "ABPCommercialIntroductionMessage": "预建应用程序模块、高级启动模板、快速应用程序开发工具、专业 UI 主题和高级支持。",
+ "MasteringAbpFrameworkEBook": "掌握 ABP 框架",
+ "MasteringTheABPFrameworkExplanation": "本书由 ABP 框架的创建者撰写,将帮助您全面了解框架和现代 Web 应用程序开发技术。",
+ "Speakers": "发言者",
+ "PreviousEvents": "以往活动",
+ "WatchTheEvent": "观看活动",
+ "RegisterNow": "现在注册",
+ "ThereIsNoEvent": "没有活动。",
+ "Events": "活动",
+ "Volo.AbpIo.Domain:080000": "已有一个名为 \"{Name}\" 的购买项目",
+ "MasteringAbpFrameworkBook": "书籍:掌握 ABP 框架",
+ "ABPIO-CommonPreferenceDefinition": "获取有关 ABP 平台的最新消息,例如新帖子、活动等。",
+ "BuiltOn": "建立在",
+ "AbpFramework": "ABP 框架",
+ "Volo.AbpIo.Domain:080001": "开始时间不能大于结束时间",
+ "Enum:BookType:0": "掌握 ABP 框架",
+ "Enum:PurchasePlatform:0": "亚马逊",
+ "Enum:PurchasePlatform:1": "Packt",
+ "Copied": "已复制!",
+ "CouldNotCopy": "无法复制!",
+ "CopyNotSupportByYourBrowser": "此功能在您使用的浏览器中不起作用。",
+ "City": "城市",
+ "ZipCode": "邮政编码",
+ "Address": "地址",
+ "Homepage": "主页",
+ "Year": "年份",
+ "Copyright": "版权所有 © {1}",
+ "DomainDrivenDesign": "领域驱动设计",
+ "CrossCuttingConcerns": "横切关注点",
+ "AbpCommunity": "ABP 社区",
+ "Footer_GithubStarCount": "{0} GitHub Stars",
+ "Footer_NugetDownloadCount": "{0} NuGet 下载量",
+ "AbpDescription": "ABP 是一个开源应用程序框架,专注于基于 AspNet Core 的 Web 应用程序开发。 Don't repeat yourself,专注于自己的业务代码。",
+ "Layout_AbpFramework_MetaTitle": "ABP 框架 - 开源 Web 应用程序框架",
+ "CommunityTalks_CountdownDays": "天",
+ "CommunityTalks_CountdownHours": "小时",
+ "CommunityTalks_CountdownMinutes": "分钟",
+ "CommunityTalks_CountdownSeconds": "秒",
+ "SeePreviousEvents": "查看以前的活动",
+ "CookieConsent_Accept": "接受",
+ "CookieConsent_Explanation_1": "我们使用 cookie 为您提供在我们网站上的最佳体验。",
+ "CookieConsent_Explanation_2": "如果您继续浏览,则表示您同意我们的隐私政策和cookie 政策。。",
+ "Error_Page_400_Title": "提供请求的页面时出现问题。",
+ "Error_Page_400_Description_1": "通常这意味着在处理您的请求时发生了意外错误。",
+ "Error_Page_400_Description_2": "如果问题仍然存在,请通过 info@abp.io 联系我们,我们将帮助您开始。",
+ "GoToHomepage": "去首页",
+ "Error_Page_404_Title": "页面未找到!",
+ "Error_Page_404_Description_1": "这不是您要查找的网页。",
+ "Error_Page_500_Title": "好像出了什么问题!",
+ "Error_Page_500_Description_1": "我们会自动跟踪这些错误,但如果问题仍然存在,请随时
联系我们。 与此同时,尝试刷新。",
+ "Error_Page_500_Description_2": "通过 info@abp.io 与我们联系。",
+ "Books": "书籍",
+ "BuyAndGetMonths": "购买 12 个月,获得 14 个月!",
+ "GetYourDeal": "得到你的交易",
+ "BuyOrRenewLicense": "立即购买或续订许可证并额外获得 2 个月!",
+ "BuyOrRenewLicenseToGetExtra2Months": "立即购买或续订 ABP 商业许可证(适用于所有版本)并额外获得 2 个月!",
+ "HurryUp": "赶快下单!",
+ "LastDay": "活动截止日期: {0}",
+ "BuyNewLicenseBetweenDatesToGetBenefit": "在 {0} 和 {1} 之间购买一个新的许可证以获得额外 2 个月的收益!",
+ "CheckAllCommunityTalks": "检查所有社区帖子",
+ "ReadMore": "阅读更多",
+ "Post": "邮政",
+ "ExploreTheContentsCreatedByTheCoreABPTeamAndTheABPCommunity": "探索核心 ABP 团队和 ABP 社区创建的内容。",
+ "WelcomeFallCampaign": "欢迎秋季活动!",
+ "GiveAwayForNewPurchases": "新购买将赠送应用程序开发课堂培训!"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hant.json
index dbf04ae25b..f55f4a7f85 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hant.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hant.json
@@ -39,6 +39,8 @@
"TrialLicensePeriodHasExpired": "您的試用許可期限已於 {0} 天前到期。",
"TrialLicensePeriodWillExpire": "您的試用許可期限將在 {0} 天后到期。",
"TrialLicensePeriodExpireToday": "您的試用許可期將於今天到期。",
- "PurchaseNow": "現在買!"
+ "PurchaseNow": "現在買!",
+ "WelcomeFallCampaign": "欢迎秋季活动!",
+ "GiveAwayForNewPurchases": "新购买将赠送应用程序开发课堂培训!"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Blog/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Blog/Localization/Resources/zh-Hans.json
index df772fa60b..524c3345e3 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Blog/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Blog/Localization/Resources/zh-Hans.json
@@ -1,5 +1,7 @@
{
"culture": "zh-Hans",
"texts": {
+ "AbpTitle": "ABP 框架 - 开源 Web 应用程序框架",
+ "AbpDescription": "ABP 是一个开源应用程序框架,专注于基于 AspNet Core 的 Web 应用程序开发。 Don't repeat yourself,专注于自己的业务代码。"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json
index 1a9aa7cba2..c7b91a99a0 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json
@@ -89,7 +89,7 @@
"Blogging": "التدوين",
"Identity": "هوية",
"IdentityServer": "خادم الهوية",
- "Saas": "ساس",
+ "Saas": "البرمجيات كخدمة",
"LanguageManagement": "إدارة اللغة",
"TextTemplateManagement": "إدارة قالب النص",
"See All Modules": "انظر جميع الوحدات",
@@ -382,4 +382,4 @@
"RenewLicenseEarly": "إذا قمت بتجديد رخصتي في وقت مبكر ، هل سأحصل على السنة كاملة؟",
"RenewLicenseEarylExplanation": "عند تجديد الترخيص الخاص بك قبل تاريخ انتهاء الترخيص الخاص بك ، ستتم إضافة سنة واحدة إلى تاريخ انتهاء الترخيص الخاص بك. على سبيل المثال ، إذا انتهت صلاحية ترخيصك في {0} -06-06 وقمت بتجديده في {0} -01-01 ، فسيكون تاريخ انتهاء صلاحية الترخيص الجديد {1} -06-06."
}
-}
\ No newline at end of file
+}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
index 36c00e9015..64cefef9af 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
@@ -536,6 +536,7 @@
"Pricing_Page_Testimonial_2": "We are seeing the value of using ABP Commercial to reduce the overhead of custom development projects. And the team is able to unify the code pattern in different project streams. We see more potential in the framework for us to build new features faster than before. We trust we will be constantly seeing the value of leveraging ABP Commercial.",
"Pricing_Page_Testimonial_3": "We love ABP. We don't have to write everything from scratch. We start from out-of-the-box features and just focus on what we really need to write. Also, ABP is well-architected and the code is high quality with fewer bugs. If we would have to write everything we needed on our own, we might have to spend years. Once more things we like is that the new version, or issue fixing, or improvement come out very soon every other week. We don't wait too long.",
"Pricing_Page_Testimonial_4": "ABP Commercial is a fantastic product would recommend. Commercial products to market for our customers in a single configurable platform. The jump start that the framework and tooling provide any team is worth every cent. ABP Commercial was the best fit for our needs.",
+ "Pricing_Page_Testimonial_5": "ABP Framework is not only a framework, but it is also a guide for project development/management, because it provides DDD, GenericRepository, DI, Microservice, and Modularity training. Even if you are not going to use the framework itself, you can develop yourself with docs.abp.io which is well and professionally prepared (OpenIddict, Redis, Quartz etc.). Because many things are pre-built, it shortens project development time significantly (Such as login page, exception handling, data filtering, seeding, audit logging, localization, auto API controller etc.). As an example from our application, I have used Local Event Bus for stock control. So, I am able to manage order movements by writing stock handler. It is wonderful not to lose time for CreationTime, CreatorId. They are being filled automatically.",
"AbpBookDownloadArea_ClaimYourEBook": "Claim your Mastering ABP Framework E-Book",
"AddMemberModal_Warning_1": "If the username you are trying to add doesn't exist in the system, please ask your team member to register on {0} and share the username of his/her account with you.",
"MyOrganizations_Detail_WelcomeMessage": "Welcome to your organization, {0}",
@@ -730,7 +731,18 @@
"Welcome_Page_UseSameCredentialForCommercialWebsites": "Use the same credentials for both commercial.abp.io and support.abp.io.",
"WatchCrudPagesVideo": "Watch the \"Creating CRUD Pages with ABP Suite\" Video!",
"WatchGeneratingFromDatabaseVideo": "Watch the \"ABP Suite: Generating CRUD Pages From Existing Database Tables\" Video!",
- "WatchTakeCloserLookVideo": "Watch the \"Take a closer look at the code generation: ABP Suite\" Video!"
-
+ "WatchTakeCloserLookVideo": "Watch the \"Take a closer look at the code generation: ABP Suite\" Video!",
+ "ConfirmedEmailAddressRequiredToStartTrial": "You should have a confirmed email address in order to start a trial license.",
+ "EmailVerificationMailNotSent": "Email verification mail couldn't send.",
+ "GetConfirmationEmail": "Click here to get a confirmation email if you haven't got it before.",
+ "WhichLicenseTypeYouAreInterestedIn": "Which license type you are interested in?",
+ "DontTakeOurWordForIt": "Don't take our word for it...",
+ "ReadAbpCommercialUsersWantYouToKnow": "Read what ABP Commercial users want you to know",
+ "Testimonial_ShortDescription_1": "The modularity of ABP made it possible for the team to deliver in time.",
+ "Testimonial_ShortDescription_2": "Build new features faster than before.",
+ "Testimonial_ShortDescription_3": "We start from out-of-the-box features and just focus on what we really need to write.",
+ "Testimonial_ShortDescription_4": "ABP Commercial was the best fit for our needs.",
+ "OnlineReviewersOnAbpCommercial": "Online Reviews on ABP Commercial",
+ "SeeWhatToldAboutAbpCommercial": "See what has been told about ABP Commercial and write your thoughts if you want."
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
index 44b6f66037..be56afbb43 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
@@ -341,7 +341,7 @@
"SignIn": "Autentificare",
"Or": "Sau",
"TellUsAboutYourself": "Spuneţi-ne despre dumneavoastră",
- "Surname": "Nume",
+ "Surname": "Nume de familie",
"DoYouAgreePrivacyPolicy": "Sunt de acord cu Termenii şi condiţiile şi Politica de confidenţialitate.",
"VolosoftMarketingInformationMessage": "Sunt de acord să primesc informaţii, sfaturi şi oferte despre soluţii pentru afaceri şi organizaţii şi alte produse şi servicii Volosoft.",
"VolosoftSharingInformationMessage": "Sunt de acord ca Volosoft să partajeze informaţiile mele cu partenerii selectaţi astfel încât să primesc informaţii relevante despre produsele şi serviciile lor.",
@@ -380,4 +380,4 @@
"TrialLicenseExpiredInfo": "Perioada de licență de probă a expirat!",
"CommercialNewsletterConfirmationMessage": "Sunt de acord cu Termenii și condițiile și cu Politica de confidențialitate ."
}
-}
\ No newline at end of file
+}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
index 4fe47cb523..0d67d9cca5 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
@@ -9,9 +9,10 @@
"QuestionCount": "剩余/问题总数",
"Unlimited": "无限制",
"Owners": "所有者",
+ "Owner": "所有者",
"AddMember": "添加成员",
- "AddOwner": "添加所有者",
- "AddDeveloper": "添加开发者",
+ "AddNewOwner": "添加新的所有者",
+ "AddNewDeveloper": "添加新的开发者",
"UserName": "用户名",
"Name": "名称",
"EmailAddress": "电子邮件地址",
@@ -62,8 +63,6 @@
"Themes": "主题",
"JoinOurNewsletter": "加入我们的时事通讯",
"Send": "发送",
- "Learn": "学习",
- "AdditionalServices": "额外的服务",
"WhatIsABPFramework": "什么是ABP框架?",
"OpenSourceBaseFramework": "开源的框架",
"ABPFrameworkExplanation": "
ABP商业版基于ABP框架, 这是一个开源和社区驱动的ASP.NET Core web应用程序开发框架.
ABP框架提供了出色的基础设施, 使用最佳实践编写可维护,可扩展,可测试的代码.
基于你已经知道的流行工具. 低学习曲线,容易适应,舒适的开发体检.
",
@@ -110,7 +109,7 @@
"LightTheme": "浅色主题",
"ProudToWorkWith": "荣幸与你合作",
"OurConsumers": "全球70多个国家的数百家企业和开发商使用ABP商业版.",
- "JoinOurConsumers": "加它他们并快速构建令人惊叹的产品.",
+ "JoinOurConsumers": "加入他们并快速构建令人惊叹的产品.",
"AdditionalServicesExplanation": "你是否需要额外或自定义的服务? 我们和我们的合作伙伴可以提供;",
"CustomProjectDevelopment": "自定义项目开发",
"CustomProjectDevelopmentExplanation": "专为你的自定义的开发人员.",
@@ -129,6 +128,8 @@
"TellUsWhatYouNeed": "告诉我们你需要什么.",
"YourMessage": "你的消息",
"YourFullName": "你的全名",
+ "FirstNameField": "名字",
+ "LastNameField": "姓氏",
"EmailField": "E-mail地址",
"YourEmailAddress": "你的e-mail地址",
"HowMayWeHelpYou": "需要获得购买帮助?(提供中文服务)",
@@ -136,6 +137,7 @@
"Success": "成功",
"WeWillReplyYou": "你的消息已经发送! 我们会在短时间内给你答复.",
"GoHome": "回到主页面",
+ "Home": "主页",
"CreateLiveDemo": "创建在线演示",
"RegisterToTheNewsletter": "注册到时事简报以获取有关ABP.IO的消息,比如新发布的内容.",
"EnterYourEmailOrLogin": "输入你的e-mail地址来创建你的演示或者使用你的已有账号登录.",
@@ -159,6 +161,8 @@
"SearchQuestionPlaceholder": "搜索常见的问题",
"WhatIsTheABPCommercial": "什么是ABP商业版?",
"WhatAreDifferencesThanAbpFramework": "ABP框架与ABP商业版有什么不同?",
+ "AbpCommercialMetaTitle": "ABP 商业版 - 完整的网页开发平台 : {0} | ABP 商业版 ",
+ "AbpCommercialMetaDescription": "ABP 商业版是在开源ABP框架之上构建的一组预构建应用程序模块、快速开发工具、UI主题和服务架构",
"ABPCommercialExplanation": "ABP商业版是一套基于开源ABP框架之上的高级模块,工具,主题和服务. ABP商业版由ABP框架背后的同一团队开发和支持.",
"WhatAreDifferencesThanABPFrameworkExplanation": " ABP框架是模块化,主题化,微服务兼容的ASP.NET Core应用程序开发框架. 它提供了一个完整的架构和强大的基础设施,让你专注于自己的业务代码而不是重复自己的每一个项目. 它基于软件开发的最佳实践和你已经知道的流行工具
ABP框架是完全免费,开源和由社区驱动的. 它还提供了一个免费的主题和一些预构建的模块 (如 identity管理和租户管理).
",
"VisitTheFrameworkVSCommercialDocument": "访问以下链接,了解更多信息 {1} ",
@@ -191,6 +195,7 @@
"IsSourceCodeIncludedExplanation4": "将模块的源代码包含到解决方案中,可以最大程度地自定义该模块. 但是当新版本发布时,将无法自动升级模块.
这些许可均不包含ABP Suite源代码,该源代码是一个外部工具,可以为你生成代码并帮助你进行开发
有关许可类型之间的其它差异查看定价页面.
",
"ChangingDevelopers": "我将来可以更改我组织的注册开发人员吗?",
"ChangingDevelopersExplanation": "除了将新的开发人员添加到你的许可中之外,你还可以更改现有的开发人员(可以删除一个开发人员并将新的开发人员添加到同一位置),而无需任何额外费用.",
+ "WhatHappensWhenLicenseEndsExplanation8": "您生成的 ABP 项目未存储在我们的服务器上。 因此,您有责任保留下载的源代码。 当您的许可证到期时,将无法获取您生成的 ABP 项目源代码。",
"WhenShouldIRenewMyLicense": "我什么时候应该续订我的许可?",
"WhenShouldIRenewMyLicenseExplanation": "如果您在许可证到期后 1 个月内续订许可证,将享受以下折扣:团队许可证 {0}% 折扣、商业许可证 {1}% 折扣、企业许可证 {2}% 折扣 . 如果您在许可证到期后 1 个月续订许可证,续订价格将与许可证购买价格相同,并且续订不会有折扣。",
"TrialPlan": "你们有试用计划吗?",
@@ -320,7 +325,7 @@
"ImplementingDDDBuildingBlocks": "实现 DDD 构建块",
"DomainVsApplicationLogic": "领域逻辑与应用逻辑",
"SamplesAndDiscussions": "示例和讨论",
- "Free": "自由",
+ "Free": "免费",
"Download": "下载",
"DDDEBook": "DDD电子书",
"ImplementingDDD": "实现领域驱动设计",
@@ -350,7 +355,6 @@
"WeWillSendYouADownloadLink": "下载电子书的链接已发送至{0}。
检查您的收件箱/垃圾箱/垃圾邮件箱!",
"InvalidFormInputs": "请输入表格中指定的有效信息。",
"DDDBookEmailBody": "谢谢你。
要下载您的图书,请点击此处。",
- "FreeDDDEBook": "免费 DDD 电子书",
"StartFree": "免费开始",
"FreeTrial": "免费试用",
"AcceptsMarketingCommunications": " 是的,我想接收 ABP 商业营销通讯。",
@@ -361,7 +365,6 @@
"CompanySize": "公司规模",
"Next": "下一个",
"StartTrial": "开始我的免费试用",
- "ContactUsIssues": "如果您有任何问题,请联系我们",
"TrialActivatedWarning": "亲爱的{0},用户只能享受 1 个免费试用期。您已经使用了试用期。",
"SaveAndDownload": "保存和下载",
"CompanyNameValidationMessage": "公司名称太长!",
@@ -369,17 +372,346 @@
"TaxNoValidationMessage": "TAX/VAT No 太长了!",
"NotesValidationMessage": "备注字段太长!",
"CheckYourBillingInfo": "您只能创建一次发票!在创建发票之前检查您的帐单信息。",
- "Volo.AbpIo.Commercial:030000": "您已经使用了试用期。",
- "Volo.AbpIo.Commercial:030001": "此组织名称已存在。",
"StartYourFreeTrial": "开始你的免费试用",
"TrialLicenseModelInvalidErrorMessage": "以下字段之一无效:国家名称、公司规模、行业或使用目的。",
"Trial": "审判",
"Purchased": "已购买",
- "PurchaseLicense": "购买许可证",
+ "PurchaseNow": "立即购买",
"PurchaseTrialLicenseMessage": "您的许可证到期日期是 {0}。
如果您想继续使用您在免费试用期内创建的项目,您需要更改 appsettings.secrets.json 文件中的许可证密钥。这是您的许可证密钥:",
"TrialLicenseExpireMessage": "您正在使用试用许可证,您的试用许可证将于 {0}到期。",
"TryForFree": "免费试用",
"TrialLicenseExpiredInfo": "您的试用许可期限已过!",
- "CommercialNewsletterConfirmationMessage": "我同意条款和条件和隐私政策。"
+ "DowngradeLicensePlan": "我将来可以降级到较低的许可版本吗?",
+ "DowngradeLicensePlanExplanation": "您不能降级现有的许可版本。 但是您可以购买新的较低许可版本并继续使用新许可证进行开发。 购买较低的许可版本后,您只需通过 ABP CLI 命令登录到新的许可版本:` abp login -o `。",
+ "LicenseTransfer": "许可证可以从一个开发者转移到另一个开发者吗?",
+ "LicenseTransferExplanation": "是的! 购买许可证后,您将成为许可证持有者,因此您可以访问组织管理页面。 组织具有所有者和开发者角色。 业主可以管理开发者席位和分配开发者。 每个分配的开发者都将通过 ABP CLI 命令登录系统,并拥有开发和支持权限。",
+ "UserOwnerDescription": "组织的“所有者”是此帐户的管理员。 他/她通过购买许可证和分配开发者来管理组织。 “所有者”不能在 ABP 商业项目中编写代码,不能下载 ABP 示例项目,也不能在支持的网站上进行提问。 如果你想拥有这些操作权限,你必须也将自己添加为开发人员。",
+ "UserDeveloperDescription": "“开发人员”可以在 ABP 商业版项目中编写代码,下载 ABP 示例项目,并在支持的网站上进行提问。 然而另一方面,“开发者”无法管理这个组织。",
+ "RemoveCurrentUserFromOrganizationWarningMessage": "您正在将自己从自己的组织中移除。 您将无法再管理此组织,您确定吗?",
+ "RenewExistingOrganizationOrCreateNewOneMessage": "您可以通过单击下面的 \"立即延长\"按钮来更新您组织的许可证,因此您可以将许可证到期日期延长 1 年。 如果您继续结帐,您将拥有一个新的组织。 您想继续开始新的组织许可吗?",
+ "ExtendNow": "立即延长",
+ "CreateNewOrganization": "建立新的组织",
+ "RenewLicenseEarly": "如果我提前更新我的许可证,我会得到一整年吗?",
+ "RenewLicenseEarylExplanation": "当您在许可证到期日期之前续订许可证时,您的许可证到期日期仍将增加 1 年。 例如,如果您的许可在 {0}-06-06 到期,而您在 {0}-01-01 续订,那么您的新许可到期日期仍将是 {1}-06-06。",
+ "OpenSourceWebApplication": "开源Web应用程序",
+ "CompleteWebDevelopment": "一个完整的Web开发",
+ "ABPFrameworkDescription": "ABP 框架是一个完整的基础架构,可通过遵循软件开发和约定的最佳实践来创建现代 Web 应用程序。",
+ "CommunityDescription": "分享您使用 ABP 框架的经验!",
+ "GetStarted": "开始使用",
+ "Views": "意见",
+ "LatestPosts": "最新的帖子",
+ "PreBuiltApplication": "预构建应用程序",
+ "DatabaseProviders": "数据库提供者",
+ "UIFrameworks": "用户界面框架",
+ "UsefulLinks": "有用的链接",
+ "Platform": "平台",
+ "CoolestCompaniesUseABPCommercial": "最酷的公司都已经在使用 ABP Commercial。",
+ "UserInterface": "用户界面",
+ "APIGateway": "网关",
+ "Microservice": "微服务",
+ "Database": "数据库",
+ "Architecture": "结构",
+ "MicroserviceArchitectureExplanation": "这是一个完整的解决方案架构,由多个应用程序、API 网关、微服务和数据库组成,使用最新技术构建可扩展的微服务解决方案。",
+ "BusinessLogic": "业务逻辑",
+ "DataAccessLayer": "数据访问层",
+ "Monolith": "单体",
+ "ModularArchitectureExplanation": "此启动模板提供了分层、模块化和基于 DDD 的解决方案架构,以构建清晰且可维护的代码库。",
+ "SeeDetails": "阅读详情",
+ "SeeDocumentation": "查看文档",
+ "Bs5Compatible": "Bootstrap 5 兼容的专业主题,非常适合您的管理网站。",
+ "LeptonXTheme": "LeptonX 主题",
+ "LeptonXDark": "LeptonX 深色",
+ "LeptonXLight": "LeptonX 浅色",
+ "LeptonXSemiDark": "LeptonX 半深色",
+ "BuiltOnBs5Library": "基于 Bootstrap 5 库构建",
+ "FullyCompatibleWithBs5": "100% 兼容 Bootstrap 5 HTML 结构和 CSS 类",
+ "ResponsiveAndMobileCompatible": "响应式、移动兼容、RTL 支持",
+ "ProvidesStylesForDatatables": "为数据表提供样式",
+ "MultipleLayoutOptions": "多种布局选项",
+ "EasilyInstallAndUpgrade": "轻松安装和升级",
+ "SupportForum": "支持论坛",
+ "TrustedBy": "授信于",
+ "OurPricing": "我们的 价格",
+ "Plans": "计划",
+ "NameSurname": "姓名",
+ "Unspecified": "未指定的",
+ "LicenceType": "许可证类型",
+ "LicenseDiscountWarning": "此折扣页面使用默认折扣代码并适用于 VOLOSOFT 开发人员。 下面的购买链接不起作用。",
+ "DiscountedLicenseExplanation": "这些许可价格适用于小型初创公司、个人开发者、学生、非营利组织和项目!",
+ "General": "一般的",
+ "License": "许可证",
+ "Development": "开发",
+ "Payment": "支付",
+ "WatchExplainerVideo": "让我们见面吧! 观看解说视频",
+ "LightDarkAndSemiDarkThemes": "浅色、深色和半深色",
+ "LeptonXThemeExplanation": "Lepton Theme 可以根据您的系统设置更改您的主题。",
+ "PRO": "专业版",
+ "WelcomeToABPCommercial": "欢迎来到 ABP 商业版!",
+ "YourAccountDetails": "您的帐户详细信息",
+ "OrganizationName": "组织名称",
+ "AddDevelopers": "添加开发者",
+ "StartDevelopment": "开始开发",
+ "CreateAndRunApplicationUsingStartupTemplate": "了解如何使用 ABP Commercial 启动模板创建和运行新的 Web 应用程序。",
+ "CommunityDescription2": "community.abp.io 是人们可以分享 ABP 相关文章的地方。 搜索文章、教程、代码示例、案例研究并结识与您同路的人。",
+ "UseABPSuiteExplanation": "使用 ABP Suite 下载模块和主题的源代码。",
+ "ManageModulesWithSuite": "您还可以使用 Suite 管理您的 ABP 模块。",
+ "LearnHowToInstallSuite": "了解如何安装和使用 ABP 套件。",
+ "SeeMore": "查看更多",
+ "SeeLess": "收起全文",
+ "LayeredSolutionStructure": "分层解决方案结构",
+ "LayeredSolutionStructureExplanation": "该解决方案基于领域驱动设计原则和模式进行分层,以将您的业务逻辑与基础架构和集成隔离开来,并最大限度地提高代码的可维护性和可重用性。 ABP 框架已经提供了抽象、基类和指南来真正为您的应用程序实现 DDD。",
+ "MultipleUIOptions": "多个用户界面选项",
+ "MultipleUIOptionsExplanation": "我们喜欢不同的方式来创建用户界面。 此启动解决方案为您的业务应用程序提供了三种不同的 UI 框架选项。",
+ "MultipleDatabaseOptions": "多个数据库选项",
+ "MultipleDatabaseOptionsExplanation": "您有两个数据库提供程序选项(除了在单个应用程序中使用两者)。 使用 Entity Framework Core 处理任何关系数据库,当您需要编写低级查询以获得更好的性能时,可以选择使用 Dapper。 如果您需要使用基于文档的 NoSQL 数据库,MongoDB 是另一种选择。 虽然这些提供程序是良好集成、抽象和预配置的,但您实际上可以与任何可与 .NET 一起使用的数据库系统进行交互。",
+ "ModularArchitectureExplanation2": "模块化是 ABP.IO 平台的一等公民。 所有应用程序功能都被拆分为隔离良好的可选模块。 启动解决方案已经预装了基本的 ABP 商业模块。 您还可以创建自己的模块来为自己的应用程序构建模块化系统。",
+ "MultiTenancyForSaasBusiness": "SaaS 业务的多租户",
+ "MultiTenancyForSaasBusinessExplanation": "ABP 商业版 提供完整的端到端多租户系统来创建您的 SaaS(软件即服务)系统。 它允许租户通过动态数据库创建和迁移系统共享或拥有自己的数据库。",
+ "MicroserviceStartupSolution": "微服务启动解决方案",
+ "MicroserviceArchitectureExplanation2": "您可以将它用于您的下一个微服务系统,以利用预先构建的基础解决方案和提炼的经验。",
+ "PreIntegratedTools": "预集成到流行工具",
+ "PreIntegratedToolsExplanation": "该解决方案已集成到行业标准工具和技术中,而您可以随时更改它们并集成到您喜欢的工具中。",
+ "SingleSignOnAuthenticationServer": "单点登录认证服务器",
+ "SingleSignOnAuthenticationServerExplanation": "该解决方案有一个身份验证服务器应用程序,其他应用程序将其用作具有 API 访问管理功能的单点登录服务器。 它基于 IdentityServer。",
+ "WebAppsWithGateways": "2 个 Web 应用程序和 2 个 API 网关",
+ "WebAppsWithGatewaysExplanation": "该解决方案包含两个 Web 应用程序,每个应用程序都有一个专用的 API 网关(BFF - Backend For Frontend 模式)。",
+ "BackOfficeApplication": "后台应用程序",
+ "BackOfficeApplicationExplanation": "系统的实际 Web 应用程序,具有多个 UI 框架选项。 您可以创建任何类型的业务应用程序。",
+ "LandingWebsite": "登陆网站",
+ "LandingWebsiteExplanation": "可用于多种目的的通用登陆/公共网站,例如介绍您的公司、销售您的产品等。",
+ "ABPFrameworkEBook": "掌握 ABP 框架电子书",
+ "MasteringAbpFrameworkEBookDescription": "包含在您的 ABP 商业许可证中",
+ "FullName": "全名",
+ "LicenseTypeNotCorrect": "许可类型不正确!",
+ "Trainings": "培训",
+ "ChooseTrainingPlaceholder": "选择培训...",
+ "DoYouNeedTrainings": "您需要这些培训之一吗?",
+ "DoYouNeedTraining": "您需要 {0} 培训吗?",
+ "GetInTouchUs": "请与我们联系",
+ "ForMoreInformationClickHere": "如需更多信息,请点击此处。",
+ "IsGetOnboardingTraining": "您想获得入职和 Web 应用程序开发培训吗?",
+ "OnboardingWebApplicationDevelopmentTrainingMessage": "要安排您的培训日历,请在创建组织后联系 {0}",
+ "CustomPurchaseMessage": "对于下一步,单击 {0} 与我们联系。",
+ "Note": "说明",
+ "AdditionalNote": "附加说明",
+ "OnboardingTrainingFaqTitle": "你有 ABP 熟练使用培训吗?",
+ "OnboardingTrainingFaqExplanation": "是的,我们有 ABP 培训服务来帮助您快速启动您的 ABP 项目。 您将从 ABP 核心团队成员那里了解 ABP,并获得开始您的 ABP 项目的技能。 在 ABP 培训中,我们将解释如何设置开发环境、安装所需工具、创建功能齐全的 CRUD 页面。 培训将会以直播的形式并使用 Zoom 应用程序,我们也对使用其他在线会议平台持开放态度。 主要培训语言为英语。 您也可以在会议期间询问有关 ABP 的问题。 我们将安排一个方便双方的时间和日期。 要获取更多信息,请通过 info@abp.io 联系我们。",
+ "AddBasket": "添加到购物车",
+ "SendTrainingRequest": "发送培训请求",
+ "OnlyEnglishVersionOfThisDocumentIsTheRecentAndValid": "* 本文件的英文版本为最新版本,如有任何争议,以英文版本为准。",
+ "Pricing_Page_Title": "计划 & 定价",
+ "Pricing_Page_Description": "现在就选择您的业务及需要的特性和功能。 购买 ABP 商业许可证创建无限量项目。",
+ "Pricing_Page_HurryUp": "赶快行动吧!",
+ "Pricing_Page_BuyLicense": "在 1 月 16 日前以 2021 年价格 购买许可证!",
+ "Pricing_Page_ValidForExistingCustomers": "也适用于现有客户和许可证续订。",
+ "Pricing_Page_Hint1": "许可价格包括一定数量的开发者席位。 如果您有更多的开发人员,您可以随时购买额外的席位。",
+ "Pricing_Page_Hint2": "您现在或将来都可以购买更多的开发者许可证。 许可证是基于席位的,因此您可以将席位从开发人员转移到另一个开发人员。",
+ "Pricing_Page_Hint3": "您可以使用您的许可证开发无限数量的不同产品。",
+ "Pricing_Page_Hint4": "ABP Suite 是帮助您开发以提高生产力的工具。 它支持生成 CRUD 页面和创建新项目。",
+ "Pricing_Page_Hint5": "您可以在应用程序中使用所有预构建的模块。",
+ "Pricing_Page_Hint6": "您可以在应用程序中使用所有预构建的主题。",
+ "Pricing_Page_Hint7": "启动模板是一种 Visual Studio 解决方案,可让您快速启动项目。 所有基本模块都为您添加和预配置。",
+ "Pricing_Page_Hint8": "掌握 ABP 框架电子书解释了如何使用最佳实践实施 .NET 解决方案。它在 Amazon.com 上出售,您可以在许可证范围内免费下载该书。",
+ "Pricing_Page_Hint9": "您可以下载任何模块的源代码。 您可能希望将源代码添加到您的解决方案中以进行彻底的更改,或者出于安全原因将其自己保留。",
+ "Pricing_Page_Hint10": "许可证是终身的。 这意味着您可以永远继续开发您的应用程序。 在许可期限内(1 年,除非您续订)授予访问最新版本并获得支持。",
+ "Pricing_Page_Hint11": "部署没有限制! 您可以根据需要部署到任意数量的服务器,包括云服务或本地。",
+ "Pricing_Page_Hint12": "您可以在有效许可期内将模块、主题和工具更新到最新版本。 在您的许可证到期后,您需要对其进行续订,以继续获取错误修复、新功能和增强功能的更新。",
+ "Pricing_Page_Hint13": "您可以获得一年的高级支持(您可以续订许可证以延长它)。",
+ "Pricing_Page_Hint14": "团队和营业许可有事件/问题计数限制。 如果您购买额外的开发者许可,您的事件限制会按开发人员增加 {0}(对于团队许可)或 {1}(对于商业许可)每个开发者增加。",
+ "Pricing_Page_Hint15": "只有企业许可证包括私人支持。 您可以直接向 ABP 团队发送电子邮件或在 support.abp.io 上使用私人门票选项提问。 私人门票对公众不可见。",
+ "Pricing_Page_Hint16": "您可以下载所有 ABP 主题的源代码。 您可能希望将源代码添加到您的解决方案中以进行彻底的更改,或者出于安全原因将其自己保留。",
+ "Pricing_Page_Testimonial_1": "ABP Commercial 允许 SC Ventures 在 9 个月内交付银行级多租户silo数据库 SaaS 平台,以支持来自多个集成锚点的大额发票的应收账款/应付账款供应链融资。 ABP 的模块化使团队能够在创纪录的时间内交付,通过所有 VAPT,并通过完整的 CI/CD 和管道将容器化的微服务码部署到生产中。",
+ "Pricing_Page_Testimonial_2": "我们看到了使用 ABP Commercial 能减少定制开发项目开销的价值。 并且团队能够在不同的项目流中统一代码模式。 我们在框架中看到了能比以前更快地构建新功能的更多潜力。 我们相信我们将会持续地看到使用 ABP Commercial 的价值。",
+ "Pricing_Page_Testimonial_3": "我们大爱 ABP。 我们不必从头开始编写所有内容。 我们从\"开箱即用\"的功能开始,只需关注我们真正需要编写的内容。 此外,ABP 架构良好,代码质量高,错误少。 如果我们需要自己来编写所需的一切,我们可能需要花费数年时间。 另一点让我们喜欢的是新版本、问题修复或改进每隔一周很快地就会出现。 我们不会等太久。",
+ "Pricing_Page_Testimonial_4": "ABP 商业版 是一款很值得推荐的出色产品。 是在一个可配置的平台上为我们的客户推向市场的商业产品。 其框架和工具为任何团队提供的快速启动值得每一分钱。 ABP 商业版 最适合我们的需求。",
+ "AbpBookDownloadArea_ClaimYourEBook": "领取您的掌握ABP框架电子书",
+ "AddMemberModal_Warning_1": "如果您尝试添加的用户名在系统中不存在,请让您的团队成员在 {0} 上注册 a> 并与您分享他/她帐户的用户名。",
+ "MyOrganizations_Detail_WelcomeMessage": "欢迎加入您的组织,{0}",
+ "MyOrganizations_Detail_OrganizationManagement": "组织管理",
+ "OrganizationDisplayName": "组织显示名称",
+ "MyOrganizations_Detail_EditDisplayName": "编辑显示名称",
+ "MyOrganizations_Detail_UpgradeYourLicense": "升级您的许可证",
+ "MyOrganizations_Detail_LicenseStartAndExpiryDate": "许可证开始日期 - 到期日期",
+ "MyOrganizations_Detail_OwnerRightInfo": "您正在使用您的 {1} 所有者权利中的 {0}。",
+ "MyOrganizations_Detail_CopyApiKey": "复制密钥",
+ "MyOrganizations_Detail_ApiKeyDescription": "API 密钥是托管在 {1} 上的 PRO 包的令牌。 ",
+ "MyOrganizations_Detail_YourPrivateNugetSource": "您的私有 NuGet 源是 {0}",
+ "MyOrganizations_Detail_PrivateNugetSourceWarning": "这将自动添加一个源到您的 ABP 解决方案中的 NuGet.Config。 不要与未经授权的用户共享您的私钥!",
+ "MyOrganizations_Detail_DeveloperSeatInfo": "您正在使用您的 {1} 个开发者席位中的 {0} 个。",
+ "NeedMoreSeatsForYourTeam": "您的团队需要更多席位吗?",
+ "MyOrganizations_Detail_PricePerYear": "{0} / 每年",
+ "MyOrganizations_Detail_PurchaseDeveloperSeats": "购买开发者席位",
+ "Invoices": "发票",
+ "RequestInvoice": "索取发票",
+ "OrderNumber": "订单号",
+ "Date": "日期",
+ "Products": "产品",
+ "TotalPrice": "总价格",
+ "ThereIsNoInvoice": "没有发票",
+ "MyOrganizations_Detail_PaymentProviderInfo": "如果您通过 {0} 网关购买了许可证,PDF 发票会被发送到您的电子邮件地址,请参阅 { 0} 发票。",
+ "MyOrganizations_Detail_PayUInfo": "如果您是通过PayU网关购买的,请点击\"索取发票\"按钮并填写账单信息。",
+ "MyOrganizations_Detail_ConclusionInfo": "您的发票申请将在 {0} 个工作日内完成。",
+ "ExtendYourLicense": "延长您的 {0} 许可",
+ "Continue": "继续",
+ "PurchaseLicense": "购买许可证",
+ "DownloadInvoiceModal_DownloadInvoice": "下载发票",
+ "DownloadInvoiceModal_SaveInformationOnlyOnce": "您只能保存一次账单信息。",
+ "InvoiceModal_EnterCompanyName": "请输入您的法定公司名称...",
+ "InvoiceModal_EnterCompanyAddress": "请输入您的法定公司地址...",
+ "InvoiceModal_EnterTaxNumber": "请输入您的税号/增值税号(如果有)...",
+ "RequestInvoiceModal_EnterNotes": "请输入您的有关发票的额外信息...",
+ "PrePayment_PayWithIyzico": "您将使用 Iyzico 付款",
+ "ContinueToCheckout": "继续结帐",
+ "PrePayment_IyzicoRedirectionInfo": "您将被重定向到 Iyzico 支付网关以安全地完成您的购买。",
+ "PrePayment_IyzicoAcceptVisaAndMasterCard": "Iyzico 接受 Visa 和 MasterCard。",
+ "Purchase": "购买",
+ "AcceptTermsAndConditions": "我已阅读、理解并接受隐私政策, 条款和条件和 EULA。",
+ "AcceptTermsAndConditionsWarningMessage": "请接受隐私政策和条款和条件",
+ "SelectGatewayToContinue": "请选择一个网关以继续!",
+ "GatewaySelection_SelectGateway": "选择支付网关",
+ "GatewaySelection_RedirectionMessage": "接下来,您将被重定向到所选支付网关的交易网站。",
+ "PaymentSucceed_PaymentSuccessMessage": "支付成功",
+ "PaymentSucceed_ThanksForPurchase": "感谢您的购买!",
+ "PaymentSucceed_CreateYourOrganization": "创建您的组织",
+ "PaymentSucceed_AddMeAsDeveloper": "我是开发人员,请将我作为开发人员添加到我的组织中。",
+ "PaymentSucceed_CreateOrganization": "创建组织",
+ "PaymentSucceed_OrganizationDescription": "一个组织由开发人员和所有者组成。 开发人员是在 ABP 项目上编写代码的用户,将受益于 {1} 网站。 所有者是分配开发者席位和管理许可的用户。",
+ "PaymentSucceed_ViewOrganization": "点击这里查看组织",
+ "Purchase_TotalAnnualPrice": "总计 (年费)",
+ "Purchase_TrainingPrice": "培训价格",
+ "Purchase_OnboardingTraining": "ABP 熟悉使用和 Web 应用程序开发现场培训",
+ "TotalDeveloperPrice": "开发商总价",
+ "Purchase_PricePerDeveloper": "{0} {1} 每个开发者",
+ "Purchase_IncludedDeveloperInfo": "{0} {1} 包括在内。",
+ "Purchase_LicenseExtraDeveloperPurchaseMessage": "{0} 许可 包含 {1} 个开发者。 您可以现在或以后添加其他开发人员。",
+ "StartupTemplates_Page_Title": "启动模板",
+ "StartupTemplates_Page_Description": "ABP 商业版 允许您构建任何复杂程度的解决方案。 它提供了两种主要的预构建启动解决方案。 您可以选择最接近您要求的解决方案,并在此基础上构建您自己的定制解决方案。",
+ "MicroserviceStartupSolutionForDotnet": ".NET 微服务启动解决方案",
+ "MonolithSolutionForDotnet": ".NET 的单体(模块化)解决方案",
+ "TrainingDetailsHeaderInfo_TrainingHour": "{0} 小时",
+ "Trainings_Content": "培训内容",
+ "Trial_Page_StartYourFreeTrial": "开始您的免费试用",
+ "Contact_Page_Title": "联系 ABP 开发团队",
+ "Contact_Page_Description": "如果您需要任何帮助或分享您的想法和意见,请与 ABP 开发团队联系! ABP 支持团队随时准备提供帮助。",
+ "Demo_Page_Title": "创建演示",
+ "Demo_Page_Description": "创建免费演示以查看使用 ABP 商业版 启动模板创建的示例应用程序。 不要重复自己的常见应用程序要求。",
+ "Discounted_Page_Title": "折扣价",
+ "Discounted_Page_Description": "现在就选择您的业务及需要的特性和功能。 购买 ABP 商业许可证并创建无限量项目",
+ "Faq_Page_Title": "常见问题 (FAQ)",
+ "Faq_Page_Description": "您有任何问题吗? 搜索常见问题或使用联系表向我们提问。",
+ "Faq_Page_SwiftCode": "SWIFT代码",
+ "Faq_Page_BankName": "银行名称",
+ "Faq_Page_AccountName": "账户名称",
+ "Faq_Page_AccountNumber": "账号",
+ "Faq_Page_Currency": "货币",
+ "Faq_Page_VatNumber": "增值税号",
+ "Faq_Page_OtherCurrenciesInfo": "对于其他货币,请参阅所有账户",
+ "ModuleDetail_Page_Title": "模块详细信息 - {0}",
+ "ProjectCreatedSuccess_Page_Title": "您的项目已创建",
+ "ProjectCreatedSuccess_Page_Description": "您的 ABP 项目创建成功!",
+ "Suite_Page_Title": "ABP 套件 - 创建 CRUD 页面",
+ "Suite_Page_Description": "ABP Commercial 提供快速应用程序开发工具以提高开发人员的工作效率。 ABP 套件 允许您轻松创建 CRUD 页面。",
+ "Themes_Page_Title": "现代和实用的 UI 主题",
+ "Themes_Page_Description": "ABP 商业版 提供多种专业、现代的 UI 主题。 创建免费演示以快速查看 UI 的外观。",
+ "Tools_Page_Title": "快速应用程序开发工具",
+ "Tools_Page_Description": "ABP 商业版 提供快速应用程序开发工具以提高开发人员的工作效率。 ABP 套件 允许您轻松创建 CRUD 页面。",
+ "DeveloperPrice": "开发者价格",
+ "AdditionalDeveloperPaymentInfoSection_AdditionalDevelopers": "{0} 开发者",
+ "LicenseRemainingDays": " {0} 天",
+ "ExtendPaymentInfoSection_Description": "通过延长/续订您的许可,您将继续获得高级支持。 您还将能够获得模块和主题的重大更新。 您将能够继续创建新项目。 您仍然可以使用 ABP 套件 来加速您的开发。",
+ "LicenseRenewalPrice": "许可证续订价格",
+ "LicensePrice": "许可证价格",
+ "TrialLicensePaymentInfoSection_Description": "购买许可证:通过购买许可证,您将继续获得高级支持。 您还将能够获得模块和主题的重大更新。 您将能够继续创建新项目。 而且您仍然可以使用 ABP 套件 加速您的开发。
请参阅 许可证比较表来查看许可证类型之间的差异。",
+ "SelectTargetLicense": "选择目标许可证",
+ "UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "是的,将我的许可证到期日期延长 1 年。",
+ "UpgradePaymentInfoSection_WantToExtendLicense": "您想将许可证再延长 {0} 年吗?",
+ "UpgradePaymentInfoSection_UpgradingWillNotExtendLicense": "升级不会延长您的许可证到期日期!",
+ "UpgradePaymentInfoSection_LicenseUpgradeDescription": "通过升级您的许可证,您将升级到更高的许可证类型,这将使您获得额外的好处。 请参阅许可证比较表以查看许可证类型之间的差异。",
+ "Landing_Page_CustomerStories": "客户故事",
+ "Landing_Page_OurGreatCustomers": "我们的大客户",
+ "Landing_Page_WebApplicationFramework": "Web应用框架",
+ "Landing_Page_WebDevelopmentPlatform": "网页开发平台",
+ "Landing_Page_CompleteWebDevelopmentPlatform": "完整的网页开发平台",
+ "Landing_Page_TryFreeDemo": "试用免费演示",
+ "Landing_Page_StartingPointForWebApplications": "基于 ASP.NET Core 的 Web 应用程序的起点! 它是基于最佳 Web 开发的 ABP 框架。",
+ "Landing_Page_AbpProvidesSoftwareInfrastructure": "ABP 框架提供了一个软件基础架构来开发基于最佳实践的优秀 Web 应用程序。",
+ "Landing_Page_MicroserviceCompatibleArchitecture": "微服务兼容架构",
+ "Landing_Page_PreBuiltApplicationModulesAndThemes": "预建的应用程序模块和主题",
+ "Landing_Page_MultiTenantArchitecture": "多租户架构",
+ "Landing_Page_MultiTenancyDescription": "SaaS 应用程序变得简单! 从数据库到 UI 的集成多租户。",
+ "Landing_Page_DDDIntroduction": "基于 DDD 模式和原则设计和开发。 为您的应用程序提供分层模型。",
+ "Landing_Page_CrossCuttingConcernsInfo": "用于授权、验证、异常处理、缓存、审计日志记录、事务管理等的完整基础架构。",
+ "Landing_Page_PreBuiltApplicationModules": "预建应用程序模块,其中包括最常见的 Web 应用程序要求。",
+ "Landing_Page_ChatModule": "聊天",
+ "Landing_Page_DocsModule": "文档",
+ "Landing_Page_FileManagementModule": "文档",
+ "Landing_Page_CustomerStory_1": "ABP 商业版 允许 SC Ventures 在 9 个月内交付银行级多租户silo数据库 SaaS 平台,以支持来自多个集成锚点的大额发票的应收账款/应付账款供应链融资。 ABP 的模块化使团队能够在创纪录的时间内交付,通过所有 VAPT,并通过完整的 CI/CD 和管道将容器化的微服务码部署到生产中。",
+ "Landing_Page_CustomerStory_2": "我们看到了使用 ABP 商业版 来减少定制开发项目开销的价值。 并且团队能够在不同的项目流中统一代码模式。 我们在框架中看到了比以前更快地构建新功能的更多潜力。 我们相信我们将不断看到使用 ABP 商业版 的价值。",
+ "Landing_Page_CustomerStory_3": "我们很爱 ABP。 我们不必从头开始编写所有内容。 我们从\"开箱即用\"的功能开始,只关注我们真正需要编写的内容。 此外,ABP 架构良好,代码质量高,错误少。 如果我们必须自己编写所需的一切,我们可能需要花费数年时间。 另一件事是我们喜欢的是新版本、问题修复或改进每隔一周就很快会出现\n。 我们不会等太久。",
+ "Landing_Page_CustomerStory_4": "ABP 商业版 是一款值得推荐的出色产品。 在一个可配置的平台上为我们的客户推向市场的商业产品。 为任何团队提供的框架和工具的快速启动都值得每一分钱。 ABP 商业版 最适合我们的需求。",
+ "Landing_Page_AdditionalServices": "定制或批量许可、熟悉使用培训、网上培训和支持、定制项目开发、移植现有项目等等...",
+ "Landing_Page_IncludedDeveloperLicenses": "包含 {0} 开发者许可",
+ "Landing_Page_SeeOnDemo": "见演示",
+ "Landing_Page_LeptonThemes": "Lepton主题",
+ "Landing_Page_AccountModuleDescription_1": "该模块实现了应用程序的认证系统;",
+ "Landing_Page_AccountModuleDescription_2": "提供带有用户名和密码的登录页面",
+ "Landing_Page_AccountModuleDescription_3": "提供一个注册页面来创建一个新账户。",
+ "Landing_Page_AccountModuleDescription_4": "提供忘记密码页面,以电子邮件形式发送密码重置链接。",
+ "Landing_Page_AccountModuleDescription_5": "通过 UI 提供电子邮件确认功能。",
+ "Landing_Page_AccountModuleDescription_6": "实现双重身份验证(短信和电子邮件)。",
+ "Landing_Page_AccountModuleDescription_7": "实现用户锁定(当在一定时间间隔内由于无效凭据发生一定次数的登录失败时,将账户锁定设定的时间)。",
+ "Landing_Page_AccountModuleDescription_8": "实现 身份验证 身份验证服务器 UI 和功能。",
+ "Landing_Page_AccountModuleDescription_9": "允许在多租户环境中在租户之间切换。",
+ "Landing_Page_AccountModuleDescription_10": "允许更改应用程序的UI 语言。",
+ "Landing_Page_AuditLoggingModuleDescription_1": "此模块为审计基础设施提供审计日志报告 UI。 允许搜索、过滤和显示审计日志条目和实体更改日志。",
+ "Landing_Page_AuditLoggingModuleDescription_2": "审核日志条目包含有关每个客户端请求的关键数据:",
+ "Landing_Page_AuditLoggingModuleDescription_3": "URL、浏览器、IP 地址、客户端名称",
+ "Landing_Page_AuditLoggingModuleDescription_4": "用户",
+ "Landing_Page_AuditLoggingModuleDescription_5": "HTTP方法,HTTP返回状态码",
+ "Landing_Page_AuditLoggingModuleDescription_6": "成功/失败,异常详细信息(如果有)",
+ "Landing_Page_AuditLoggingModuleDescription_7": "请求执行时长",
+ "Landing_Page_AuditLoggingModuleDescription_8": "此请求中已创建、删除或更新实体(具有更改的属性)。",
+ "Landing_Page_BloggingModuleDescription_1": "该模块将一个简单的博客添加到您的 ABP 应用程序;",
+ "Landing_Page_BloggingModuleDescription_2": "允许在单个应用程序中创建多个博客。",
+ "Landing_Page_BloggingModuleDescription_3": "支持 Markdown 格式。",
+ "Landing_Page_BloggingModuleDescription_4": "允许为帖子写评论。",
+ "Landing_Page_BloggingModuleDescription_5": "允许为博客文章分配标签。",
+ "Landing_Page_BloggingModuleDescription_6": "请参阅 blog.abp.io 网站作为博客模块的实时示例。",
+ "Landing_Page_ChatModuleDescription_1": "该模块用于应用程序中用户之间的实时消息传递。",
+ "Landing_Page_ChatModuleDescription_2": "聊天页面上的实时消息。",
+ "Landing_Page_ChatModuleDescription_3": "在应用程序中搜索用户以获取新对话。",
+ "Landing_Page_ChatModuleDescription_4": "最近对话的联系人列表。",
+ "Landing_Page_ChatModuleDescription_5": "当用户正在查看另一个页面时的新消息通知。",
+ "Landing_Page_ChatModuleDescription_6": "菜单图标上的未读消息总数徽章。",
+ "Landing_Page_ChatModuleDescription_7": "每个对话的未读消息计数。",
+ "Landing_Page_ChatModuleDescription_8": "延迟加载的对话。",
+ "Landing_Page_DocsModuleDescription_1": "该模块用于创建技术文档网站;",
+ "Landing_Page_DocsModuleDescription_2": "内置 GitHub 集成:直接在 GitHub 上编写和管理文档。",
+ "Landing_Page_DocsModuleDescription_3": "版本控制支持直接集成到 GitHub 版本。",
+ "Landing_Page_DocsModuleDescription_4": "支持多语言(回退支持默认语言)。",
+ "Landing_Page_DocsModuleDescription_5": "支持 Markdown 和 HTML 格式。",
+ "Landing_Page_DocsModuleDescription_6": "提供导航和大纲部分。",
+ "Landing_Page_DocsModuleDescription_7": "允许在单个应用程序中托管多个项目文档。",
+ "Landing_Page_DocsModuleDescription_8": "GitHub 上文件的链接,因此任何人都可以通过单击编辑链接轻松贡献。",
+ "Landing_Page_DocsModuleDescription_9": "除了 GitHub 源之外,还允许简单地使用文件夹作为文档源。",
+ "Landing_Page_FileManagementModuleDescription_1": "在分层文件夹结构中上传、下载和组织文件。",
+ "Landing_Page_FileManagementModuleDescription_2": "该模块用于上传、下载和组织分层文件夹结构中的文件。 它还兼容多租户,您可以确定租户的总大小限制。",
+ "Landing_Page_FileManagementModuleDescription_3": "本模块基于BLOB Storing系统,因此可以使用不同的存储供应商存储文件内容。",
+ "Landing_Page_IdentityModuleDescription_1": "该模块实现了应用程序的用户和角色系统;",
+ "Landing_Page_IdentityModuleDescription_2": "基于 Microsoft 的 ASP.NET Core Identity 库构建。",
+ "Landing_Page_IdentityModuleDescription_3": "管理系统中的角色和用户。 一个用户可以拥有多个角色。",
+ "Landing_Page_IdentityModuleDescription_4": "在角色和用户级别设置权限。",
+ "Landing_Page_IdentityModuleDescription_5": "为每个用户启用/禁用双重身份验证和用户锁定。",
+ "Landing_Page_IdentityModuleDescription_6": "管理基本的用户个人资料和密码。",
+ "Landing_Page_IdentityModuleDescription_7": "管理系统中的声明类型,为角色和用户设置声明。,",
+ "Landing_Page_IdentityModuleDescription_8": "设置页面以管理密码复杂性、用户登录、账户和锁定。",
+ "Landing_Page_IdentityModuleDescription_9": "支持 LDAP 身份验证。",
+ "Landing_Page_IdentityModuleDescription_10": "提供电子邮件和电话号码验证。",
+ "Landing_Page_IdentityModuleDescription_11": "支持社交登录集成(Twitter、Facebook、GitHub 等)。",
+ "Landing_Page_IdentityModuleDescription_12": "管理系统中的组织单位。",
+ "Landing_Page_PaymentModuleDescription_1": "为不同的支付网关提供集成。",
+ "Landing_Page_PaymentModuleDescription_2": "该模块提供支付网关的集成,因此您可以轻松地从客户那里获得付款。",
+ "Landing_Page_PaymentModuleDescription_3": "该模块支持以下支付网关",
+ "Welcome_Page_UseSameCredentialForCommercialWebsites": "commercial.abp.io 和 support.abp.io使用相同的凭据。"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
index 81e22f05ce..c258ea0800 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
@@ -320,7 +320,7 @@
"ImplementingDDDBuildingBlocks": "實現 DDD 構建塊",
"DomainVsApplicationLogic": "領域邏輯與應用邏輯",
"SamplesAndDiscussions": "示例和討論",
- "Free": "自由",
+ "Free": "免費",
"Download": "下載",
"DDDEBook": "DDD電子書",
"ImplementingDDD": "實現領域驅動設計",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
index 0ed3eda832..c73da26137 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
@@ -150,7 +150,6 @@
"GetStarted": "Get Started",
"SourceCode": "Source Code",
"LeaveComment": "Leave Comment",
- "ReadMore": "Read more",
"ShowMore": "Show More",
"NoPublishedPostsYet": "No published posts yet.",
"Name": "Name",
@@ -184,6 +183,7 @@
"Post_Index_Page_MetaDescription": "ABP Community's purpose is to create a contribution environment for developers who use the ABP framework.",
"Layout_Title": "{0} | ABP Community",
"Layout_MetaDescription": "ABP Community is an environment where people can share posts about ABP framework and follows the projects.",
- "Index_Page_CommunityIntroduction": "This is a hub for ABP Framework, .NET and software development. You can read the articles, watch the video tutorials, get informed about ABP’s development progress and ABP-related events, help other developers and share your expertise with the ABP community."
+ "Index_Page_CommunityIntroduction": "This is a hub for ABP Framework, .NET and software development. You can read the articles, watch the video tutorials, get informed about ABP’s development progress and ABP-related events, help other developers and share your expertise with the ABP community.",
+ "TagsInArticle": "Tags in article"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
index b5d9d65c82..8196d567a1 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
@@ -29,14 +29,12 @@
"ContributionGuide": "贡献指南",
"BugReport": "Bug报告",
"SeeAllPosts": "查看所有的文章",
- "WelcomeToABPCommunity!": "欢迎来到ABP社区!",
- "MyProfile": "我的资料",
- "MyOrganizations": "我的组织",
+ "WelcomeToABP": "欢迎来到ABP",
"EmailNotValid": "请输入有效的电子邮箱地址.",
"FeatureRequest": "功能请求",
"CreatePostTitleInfo": "文章标题显示在文章列表中.",
"CreatePostSummaryInfo": "文章的简短摘要将显示在文章列表中.",
- "CreatePostCoverInfo": "为了创建有效的文章,请添加封面图. 仅支持16:9的图片!",
+ "CreatePostCoverInfo": "要创建一个有效的帖子,需要添加封面图片. 上传16:9的图片获取最佳视觉效果. 文件最大支持: 1MB",
"ThisExtensionIsNotAllowed": "不允许此扩展名.",
"TheFileIsTooLarge": "文件过大.",
"GoToThePost": "转到文章",
@@ -45,7 +43,7 @@
"Done": "完成",
"Open": "打开",
"Closed": "关闭",
- "LatestQuestionOnThe": "有关的最新问题",
+ "RecentQuestionFrom": "最近的问题来自",
"Stackoverflow": "Stackoverflow",
"Votes": "票数",
"Answer": "回答",
@@ -59,7 +57,7 @@
"QuestionItemErrorMessage": "无法从Stackoverflow获取最新的问题详细信息.",
"Oops": "哎呀!",
"CreatePostSuccessMessage": "文章提交成功. 网站管理员审核通过后将被发布.",
- "ChooseCoverImage": "选项一张封面图片",
+ "Browse": "浏览",
"CoverImage": "封面图片",
"ShareYourExperiencesWithTheABPFramework": "分享你的ABP Framework经验!",
"Optional": "可选的",
@@ -88,6 +86,8 @@
"PostRequestFromGithubIssue": "现在没有任何文章请求.",
"LatestPosts": "最新的帖子",
"ArticleRequests": "文章请求",
+ "ArticleRequestsDescription": "想在这里查看具体内容吗? 您可以要求社区创建它!",
+ "LatestContentRequests": "最新内容请求",
"AllPostRequests": "查看所有文章请求",
"SubscribeToTheNewsletter": "订阅简讯",
"NewsletterEmailDefinition": "获取有关ABP发生的信息,例如新版本,免费资源,文章等.",
@@ -115,7 +115,6 @@
"VideoUrl": "视频Url",
"GithubPostUrl": "Github文章Url",
"ExternalPostUrl": "外部文章Url",
- "CreatePostCoverInfo": "要创建一个有效的帖子,需要添加封面图片. 上传16:9的图片获取最佳视觉效果. 文件最大支持: 1MB",
"ThankYouForContribution": "感谢你对ABP社区的贡献",
"GithubPost": "Github文章",
"GithubPostSubmitStepOne": "1. 用Markdown格式在GitHub的任何公共存储库上写一篇文章. 示例",
@@ -143,6 +142,47 @@
"Volo.AbpIo.Domain:060001": "源 URL(\"{PostUrl}\") 不是 Github URL",
"Volo.AbpIo.Domain:060002": "文章内容无法从 Github(\"{PostUrl}\") 资源中获得。",
"Volo.AbpIo.Domain:060003": "没有找到文章内容!",
- "SeeMore": "查看更多"
+ "SeeMore": "查看更多",
+ "JoinTheABPCommunity": "加入 ABP 社区",
+ "ABPCommunityTalks": "ABP 社区会谈",
+ "LiveDemo": "现场演示",
+ "GetLicense": "获得许可证",
+ "GetStarted": "开始使用",
+ "SourceCode": "源代码",
+ "LeaveComment": "发表评论",
+ "ShowMore": "展示更多",
+ "NoPublishedPostsYet": "还没有发布的帖子。",
+ "Name": "名字",
+ "Surname": "姓氏",
+ "WebSite": "网站",
+ "FullURL": "完整网址",
+ "JobTitle": "职称",
+ "Prev": "上一页",
+ "Previous": "前面的",
+ "Next": "下一页",
+ "Share": "分享",
+ "SortBy": "排序方式",
+ "NoPublishedEventsYet": "尚未发布活动。",
+ "SubscribeYoutubeChannel": "订阅 Youtube 频道",
+ "Enum:EventType:0": "会谈",
+ "MemberNotPublishedPostYet": "该成员尚未发布任何帖子。",
+ "TimeAgo": "{0} 前",
+ "Discord_Page_JoinCommunityMessage": "加入 ABP Discord 社区",
+ "Discord_Page_Announce": "我们很高兴地宣布 ABP 社区 Discord 服务器!",
+ "Discord_Page_Description_1": "ABP 社区从第一天起就一直在壮大。 我们希望通过创建一个官方的 ABP Discord 服务器将其带入下一步,这样 ABP 社区就可以使用即时消息的功能彼此进行互动。",
+ "Discord_Page_Description_2": "ABP Community Discord Server 是您可以使用 ABP 框架来展示您的创作、分享对您有用的技巧、了解有关 ABP 框架的最新消息和公告、与社区成员聊天交流想法并玩得开心的地方!",
+ "Discord_Page_Description_3": "此 ABP 社区 Discord 服务器是 ABP 核心团队的官方服务器,存在于服务器上进行监控。",
+ "Discord_Page_JoinToServer": "加入 ABP Discord 服务器",
+ "Events_Page_MetaTitle": "ABP 社区活动",
+ "Events_Page_MetaDescription": "现场活动由 ABP 团队主持,是充满社区内容、演示、问答和围绕 ABP 正在发生的事情的讨论的休闲会议。",
+ "Events_Page_Title": "ABP会谈",
+ "Events_Page_WritingFromUser": "阅读来自 ABP 社区的 {0} 的文章。",
+ "Post_Create_Page_MetaTitle": "最新帖子",
+ "Post_Create_Page_MetaDescription": "创建您的帖子以分享您对 ABP 框架的经验并为 ABP 社区做出贡献。",
+ "Post_Create_Page_CreateNewPost": "创建新帖子",
+ "Post_Index_Page_MetaDescription": "ABP 社区的目的是为使用 ABP 框架的开发人员创建一个贡献环境。",
+ "Layout_Title": "{0} | ABP 社区",
+ "Layout_MetaDescription": "ABP 社区是一个人们可以分享有关 ABP 框架的帖子并关注项目的环境。",
+ "Index_Page_CommunityIntroduction": "这是 ABP 框架、.NET 和软件开发的中心。 您可以阅读文章,观看视频教程,了解 ABP 的开发进度和 ABP 相关事件,帮助其他开发人员并与 ABP 社区分享您的专业知识。"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/AbpIoWwwResource.cs b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/AbpIoWwwResource.cs
index 552b5949e1..f64552be30 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/AbpIoWwwResource.cs
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/AbpIoWwwResource.cs
@@ -1,5 +1,8 @@
-namespace AbpIoLocalization.Www
+using Volo.Abp.Localization;
+
+namespace AbpIoLocalization.Www
{
+ [LocalizationResourceName("AbpIoWww")]
public class AbpIoWwwResource
{
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
index 41eda60de6..0b9dfab886 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
@@ -293,7 +293,6 @@
"ExploreDocumentationAndGuides": "Explore the comprehensive documentation and guides.",
"Documentations": "Documentation",
"Views": "Views",
- "ReadMore": "Read More",
"EnterYouEmailToGetNews": "Enter your email to get the latest news about the ABP Framework",
"Tiered": "Tiered",
"SeparateIdentityServer": "Separate Identity Server",
@@ -372,6 +371,27 @@
"MasteringAbpFramework_Book_What_You_Will_Learn_8": "Write unit, integration, and UI tests using ABP Framework.",
"MasteringAbpFramework_Book_WhoIsThisBookFor": "Who's this book for",
"MasteringAbpFramework_Book_WhoIsThisBookFor_Description": "This book is for web developers who want to learn software architectures and best practices for building\n maintainable web-based solutions using Microsoft technologies and ABP Framework. Basic knowledge of C#\n and ASP.NET Core is necessary to get started with this book.",
- "ComputersAndTechnology": "Computers & Technology"
+ "ComputersAndTechnology": "Computers & Technology",
+ "BuildingMicroserviceSolutions": "Building Microservice Solutions",
+ "MicroserviceBookPracticalGuide": "This book is a reference guide for developing and managing microservice-based applications using the ABP Framework. It references the .NET Microservice Sample Reference Application: eShopOnContainers and discusses the architectural design and implementation approaches using the ABP Framework. By the end of this book, you'll learn how ABP approaches the common microservice complexities such as authorization, distributed transactions, inter-microservice communications, deployment, etc.",
+ "IntroducingTheSolution": "Introducing the eShopOnAbp Solution",
+ "RunningTheSolution": "Running the Solution",
+ "UnderstandingTheAuthenticationSystem": "Understanding the Authentication System",
+ "ExploringTheApplications": "Exploring the Applications",
+ "UnderstandingTheAPIGateways": "Understanding the API Gateways",
+ "DevelopingTheMicroservices": "Developing the Microservices",
+ "UnderstandingTheInfrastructure": "Understanding the Infrastructure",
+ "DiggingInTheUseCases": "Digging in the Use Cases",
+ "DeployingTheSolution": "Deploying the Solution",
+ "ThisBookIsInDraftStageAndIsNotCompletedYet": "This book is in draft stage and is not completed yet.",
+ "Authors": "Authors",
+ "MicroserviceEBook": "Microservice E-Book",
+ "SelectUITheme": "Select UI Theme",
+ "LeptonXLiteTheme": "LeptonX Lite Theme",
+ "BasicTheme": "Basic Theme",
+ "LeptonXLiteThemeInfo": " A modern and stylish Bootstrap UI theme. Ideal if you want to have a production ready UI theme. This is the newest theme and is the default.",
+ "BasicThemeInfo": "Minimalist UI theme with plain Bootstrap colors and styles. Ideal if you will build your own UI theme.",
+ "SeeDocumentation": "See documentation.",
+ "SeeFullScreen": "🖼️ See the screenshot"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ro-RO.json
index bd04ba7f49..a1ff5f58ad 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ro-RO.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/ro-RO.json
@@ -253,18 +253,18 @@
"Or": "Sau",
"TellUsAboutYourself": "Spuneţi-ne un pic despre dumneavoastră",
"Name": "Nume",
- "Surname": "Nume",
+ "Surname": "Nume de familie",
"CompanyName": "Nume companie",
"DoYouAgreePrivacyPolicy": "Sunt de acord cu Termenii & condiţiile şi Politica de confidenţialitate.",
"Free": "Gratuit",
"DDDEBook": "E-book DDD",
"PracticalGuideForImplementingDDD": "Această carte este un ghid practic pentru implementarea Domain Driven Design în framework-ul ABP.",
"IntroducingDDD": "Introducere în Domain Driven Design",
- "DDDLayersAndCleanArchitecture": "Straturile DDD & Arhitectură curată",
+ "DDDLayersAndCleanArchitecture": "Straturile DDD şi Arhitectură curată",
"LayeringOfADotnetSolution": "Stratificarea unei soluţii .NET",
"ImplementingDDDBuildingBlocks": "Implementând DDD Building Blocks",
"DomainVsApplicationLogic": "Domain Logic vs Application Logic",
- "SamplesAndDiscussions": "Exemple & Discuţii",
+ "SamplesAndDiscussions": "Exemple şi Discuţii",
"EmailNotValid": "Vă rugăm să introduceţi o adresa de email validă.",
"WeWillSendYouADownloadLink": "Un link care conţine e-book-ul a fost trimis către {0}. Verificaţi-vă folderele de inbox, junk sau spam!",
"GoHome": "Pagina principală",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
index 01fe9f8b7b..a4a6e142a9 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
@@ -279,6 +279,7 @@
"SubscribeToNewsletter": "ABP.IO Platform'u ile ilgili yeni haberler, makaleler, teklifler ve daha fazlası gibi gelişmeler hakkında bilgi almak için bültene abone olun.",
"FirstEdition": "İlk Baskı",
"ThankYou": "Teşekkürler!",
- "CheckboxMandatory": "Devam etmek için bunu kontrol etmeniz gerekiyor!"
+ "CheckboxMandatory": "Devam etmek için bunu kontrol etmeniz gerekiyor!",
+ "ThisBookIsInDraftStageAndIsNotCompletedYet": "Bu kitap taslak aşamasındadır ve henüz tamamlanmamıştır."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
index dd91379201..7826f00ca2 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
@@ -174,6 +174,7 @@
"CreateProjectWizard": "此向导让你从启动模板创建一个新项目,该启动模板已正确配置为可以快速启动你的项目.",
"TieredOption": "创建一个分层解决方案,其中Web和Http API层在物理上是分离的. 如果没有选中则创建一个不那么复杂且适合大多数场景的分层解决方案.",
"SeparateIdentityServerOption": "将服务器端分离为两个应用程序:第一个应用程序用于身份服务器,第二个应用程序用于服务器端HTTP API.",
+ "ProgressiveWebApplicationOption": "将项目指定为渐进式 Web 应用程序",
"UseslatestPreVersion": "使用最新的预发布版本",
"ReadTheDocumentation": "阅读文档",
"Documentation": "文档",
@@ -214,7 +215,11 @@
"SeeDocs": "查看文档",
"None": "空",
"Application": "应用程序",
+ "ApplicationExplanation": "基于领域驱动设计实践创建一个完全分层的解决方案。 推荐用于需要可维护和可扩展代码库的长期项目。",
+ "ApplicationNoLayer": "应用程序(单层)",
+ "ApplicationNoLayerExplanation": "创建单层 Web 应用程序。 推荐用于构建具有更简单且易于理解的架构的应用程序。",
"Module": "模块",
+ "ModuleExplanation": "创建可重用、完全分层的应用程序模块解决方案。 您可以使用此选项为您的模块化应用程序创建模块。",
"PackageName": "包名称",
"LicenseURL": "许可URL",
"License": "许可",
@@ -256,7 +261,7 @@
"Surname": "姓",
"CompanyName": "公司名",
"DoYouAgreePrivacyPolicy": "我同意条款和条件和隐私政策。",
- "Free": "自由",
+ "Free": "免费",
"DDDEBook": "DDD电子书",
"PracticalGuideForImplementingDDD": "本书是使用 ABP 框架实现领域驱动设计的实用指南。",
"IntroducingDDD": "介绍领域驱动设计",
@@ -273,6 +278,100 @@
"SubscribeToNewsletter": "订阅时事通讯以获取有关 ABP.IO 平台中发生的事件的信息,例如新版本、文章、优惠等。",
"FirstEdition": "第一版",
"ThankYou": "谢谢!",
- "CheckboxMandatory": "你需要检查这个才能继续!"
+ "CheckboxMandatory": "你需要检查这个才能继续!",
+ "UserInterface": "用户界面",
+ "APIGateway": "API 网关",
+ "Database": "数据库",
+ "Saas": "Saas",
+ "OpenSourceWebApp": "开源
Web 应用程序",
+ "Framework": "框架",
+ "AuditLoggingExplanation": "自动跟踪系统中的所有操作和数据更改。",
+ "AbpNewCommandExplanation": "使用 ABP 启动模板创建新的解决方案。",
+ "AbpAddModuleCommandExplanation": "将预构建的应用程序模块安装到您的解决方案中",
+ "AbpUpdateCommandExplanation": "自动更新解决方案中所有与 ABP 相关的 NuGet 和 NPM 包。",
+ "ExploreAllCLICommands": "探索所有 CLI 命令",
+ "ExploreDocumentationAndGuides": "探索全面的文档和指南。",
+ "Documentations": "文档",
+ "Views": "意见",
+ "EnterYouEmailToGetNews": "输入您的电子邮件以获取有关 ABP 框架的最新消息",
+ "Tiered": "分层",
+ "SeparateIdentityServer": "独立的身份服务器",
+ "ProgressiveWebApplication": "渐进式 Web 应用程序",
+ "Preview": "预览",
+ "CreateANewSolution": "创建一个新的解决方案",
+ "ABPFrameworkFeatures": "ABP 框架 功能",
+ "Commercial": "商业版",
+ "ThirdPartyTools": "第三方工具",
+ "Back": "后退",
+ "Community": "社区",
+ "SeeMore": "查看更多",
+ "DetailsOfTheEBook": "电子书详情",
+ "JoinOurMarketingNewsletter": "加入我们的市场推广时事通讯",
+ "FrameworkNewsletterConfirmationMessage": "我同意条款和条件 和 隐私政策。",
+ "GetYourFreeEBook": "获取您的 免费 DDD 电子书",
+ "EverythingYouNeedToKnow": "您需要了解的一切。",
+ "PreOrderNow": "立即预订",
+ "UITheming": "用户界面主题",
+ "UIThemingExplanation": "创建可重用的 UI 主题和布局,或使用预构建的 UI 主题之一。",
+ "DataFilteringExplanation2": "自动过滤来自数据库的查询,以轻松实现软删除和多租户等模式。",
+ "NeedHelp": "您需要帮助吗?",
+ "GiveYourProjectAName": "给您的项目命名",
+ "SelectProjectType": "选择项目类型",
+ "SelectUIFramework": "选择 UI 框架",
+ "SelectDatabaseProvider": "选择数据库提供者",
+ "SelectDatabaseManagementSystem": "选择数据库管理系统",
+ "InstallingTheABPCLI": "安装 ABP CLI",
+ "CreateYourProjectNow": "立即创建您的项目",
+ "OrderOn": "在 {0} 订购",
+ "DownloadFreeDDDBook": "下载免费的 DDD 书",
+ "WhatIsABPFramework": "什么是 ABP 框架?",
+ "TenantDatabase": "租户 {0} 数据库",
+ "SharedDatabase": "共享数据库",
+ "ConnectionResolver": "连接解析器",
+ "TenantBasedDataFilter": "基于租户的数据过滤器",
+ "ApplicationCode": "申请代码",
+ "TenantResolution": "租户决议",
+ "TenantUser": "租户 {0} 用户",
+ "CardTitle": "卡片标题",
+ "View": "查看",
+ "Model": "模型",
+ "Email": "电子邮箱",
+ "Password": "密码",
+ "Address": "地址",
+ "Gender": "性别",
+ "Male": "男",
+ "Female": "女",
+ "Submit": "提交",
+ "Unspecified": "未指定",
+ "StaticFileMiddleware": "静态文件中间件",
+ "RazorViewEngine": "Razor 视图引擎",
+ "PhysicalFiles": "物理文件 (wwwroot)",
+ "EmbeddedFiles": "嵌入式文件(DDL) ",
+ "DynamicFiles": "动态文件(内存)",
+ "BuildSolutionsWithAbp": "遵循使用 ABP 的软件开发最佳实践,构建可维护的 .NET 解决方案。",
+ "BuyOnAmazon": "在亚马逊上购买",
+ "BuyOnPackt": "在 Packt 上购买",
+ "Discounted": "打折",
+ "MasteringAbpFramework_Book_KeyFeatures": "主要特性",
+ "MasteringAbpFramework_Book_Key_Features_Description_1": "使用 ABP 框架构建强大、可维护、模块化和可扩展的软件解决方案。",
+ "MasteringAbpFramework_Book_Key_Features_Description_2": "了解如何在您的 Web 应用程序中实施 SOLID 原则和领域驱动设计。",
+ "MasteringAbpFramework_Book_Key_Features_Description_3": "了解 ABP 框架如何通过自动执行重复性任务来加快您的开发周期。",
+ "MasteringAbpFramework_Book_Description": "书籍说明",
+ "MasteringAbpFramework_Book_Description_Details_1": "ABP 框架是一个完整的基础架构,用于通过遵循软件 \n 开发最佳实践和约定来创建现代 Web 应用程序。 借助 ABP 的高级框架和生态系统,您可以 \n 实现 Don't Repeat Yourself (DRY) 原则并专注于您的业务代码。",
+ "MasteringAbpFramework_Book_Description_Details_2": "本书由 ABP 框架的创建者撰写,将帮助您全面了解该框架和现代 Web 应用程序开发技术。 通过对基本概念和实际示例的逐步解释,您将了解现代 Web 解决方案的要求以及 ABP\n 框架如何使开发您自己的解决方案变得轻松愉快。 您将发现\n 企业 Web 应用程序开发的常见需求,并探索 ABP 提供的基础架构。 在整本书中,您将掌握构建可维护和模块化 Web 解决方案的软件开发最佳实践。",
+ "MasteringAbpFramework_Book_Description_Details_3": "在本书结束时,您将能够创建一个易于开发、\n 维护和测试的完整 Web 解决方案。",
+ "MasteringAbpFramework_Book_WhatYouWillLearn": "你将会学到什么",
+ "MasteringAbpFramework_Book_What_You_Will_Learn_1": "设置开发环境并开始使用 ABP 框架。",
+ "MasteringAbpFramework_Book_What_You_Will_Learn_2": "使用 Entity Framework Core 和 MongoDB 开发您的数据访问层。",
+ "MasteringAbpFramework_Book_What_You_Will_Learn_3": "了解横切关注点以及 ABP 如何自动执行重复性任务。",
+ "MasteringAbpFramework_Book_What_You_Will_Learn_4": "掌握使用 ABP 框架实施领域驱动设计。",
+ "MasteringAbpFramework_Book_What_You_Will_Learn_5": "使用 ASP.NET Core MVC (Razor Pages) 和 Blazor 构建 UI 页面和组件。",
+ "MasteringAbpFramework_Book_What_You_Will_Learn_6": "使用多租户创建模块化 Web 应用程序。",
+ "MasteringAbpFramework_Book_What_You_Will_Learn_7": "了解模块化并创建可重用的应用程序模块。",
+ "MasteringAbpFramework_Book_What_You_Will_Learn_8": "使用 ABP 框架编写单元、集成和 UI 测试。",
+ "MasteringAbpFramework_Book_WhoIsThisBookFor": "这本书是给谁看的",
+ "MasteringAbpFramework_Book_WhoIsThisBookFor_Description": "本书适用于希望学习软件架构和最佳实践的 Web 开发人员,以使用 Microsoft 技术和 ABP 框架构建\n 可维护的基于 Web 的解决方案。 C#\n 和 ASP.NET Core 的基本知识是开始阅读本书所必需的。",
+ "ComputersAndTechnology": "计算机与技术",
+ "ThisBookIsInDraftStageAndIsNotCompletedYet": "这本书正在草案阶段,还没有完成。"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json
index c8d31d2002..62a941951e 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json
@@ -256,7 +256,7 @@
"Surname": "姓",
"CompanyName": "公司名",
"DoYouAgreePrivacyPolicy": "我同意條款和條件和隱私政策。",
- "Free": "自由",
+ "Free": "免費",
"DDDEBook": "DDD電子書",
"PracticalGuideForImplementingDDD": "本書是使用 ABP 框架實現領域驅動設計的實用指南。",
"IntroducingDDD": "介紹領域驅動設計",
diff --git a/common.DotSettings b/common.DotSettings
index 5c1cda48fd..f2cc0339ae 100644
--- a/common.DotSettings
+++ b/common.DotSettings
@@ -38,5 +38,6 @@
False
False
False
+ True
True
\ No newline at end of file
diff --git a/common.props b/common.props
index e6c9c40c28..f8b7c620c2 100644
--- a/common.props
+++ b/common.props
@@ -1,7 +1,7 @@
latest
- 6.0.0
+ 7.0.0
$(NoWarn);CS1591;CS0436
https://abp.io/assets/abp_nupkg.png
https://abp.io/
diff --git a/docs/en/Apps/VoloDocs.md b/docs/en/Apps/VoloDocs.md
index f85aa78bbd..9fe8ff2507 100644
--- a/docs/en/Apps/VoloDocs.md
+++ b/docs/en/Apps/VoloDocs.md
@@ -23,13 +23,13 @@ https://github.com/abpframework/abp/tree/master/modules/docs
You can download the VoloDocs release from the following links:
-http://apps.abp.io/VoloDocs/VoloDocs.win-x64.zip - **Windows 64 bit**
+https://apps.abp.io/VoloDocs/VoloDocs.win-x64.zip - **Windows 64 bit**
-http://apps.abp.io/VoloDocs/VoloDocs.win-x86.zip - **Windows 32 bit**
+https://apps.abp.io/VoloDocs/VoloDocs.win-x86.zip - **Windows 32 bit**
-http://apps.abp.io/VoloDocs/VoloDocs.osx-x64.zip - **MacOS**
+https://apps.abp.io/VoloDocs/VoloDocs.osx-x64.zip - **MacOS**
-http://apps.abp.io/VoloDocs/VoloDocs.linux-x64.zip - **Linux**
+https://apps.abp.io/VoloDocs/VoloDocs.linux-x64.zip - **Linux**
Notice that, all installations are self-contained deployments. It means all the required third-party dependencies along with the version of .NET Core is included. So you don't need to install any .NET Core SDK / Runtime.
diff --git a/docs/en/Authorization.md b/docs/en/Authorization.md
index 869c49a52a..063af84708 100644
--- a/docs/en/Authorization.md
+++ b/docs/en/Authorization.md
@@ -459,6 +459,15 @@ public static class CurrentUserExtensions
}
```
+> If you use Identity Server please add your claims to `RequestedClaims` of `AbpClaimsServiceOptions`.
+
+```csharp
+Configure(options =>
+{
+ options.RequestedClaims.AddRange(new[]{ "SocialSecurityNumber" });
+});
+```
+
## See Also
* [Permission Management Module](Modules/Permission-Management.md)
diff --git a/docs/en/Background-Jobs-Hangfire.md b/docs/en/Background-Jobs-Hangfire.md
index 4ee58d84ef..869a8075af 100644
--- a/docs/en/Background-Jobs-Hangfire.md
+++ b/docs/en/Background-Jobs-Hangfire.md
@@ -80,6 +80,41 @@ After you have installed these NuGet packages, you need to configure your projec
}
````
+### Specifying Queue
+
+You can use the [`QueueAttribute`](https://docs.hangfire.io/en/latest/background-processing/configuring-queues.html) to specify the queue.
+
+````csharp
+using System.Threading.Tasks;
+using Volo.Abp.BackgroundJobs;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Emailing;
+
+namespace MyProject
+{
+ [Queue("alpha")]
+ public class EmailSendingJob
+ : AsyncBackgroundJob, ITransientDependency
+ {
+ private readonly IEmailSender _emailSender;
+
+ public EmailSendingJob(IEmailSender emailSender)
+ {
+ _emailSender = emailSender;
+ }
+
+ public override async Task ExecuteAsync(EmailSendingArgs args)
+ {
+ await _emailSender.SendAsync(
+ args.EmailAddress,
+ args.Subject,
+ args.Body
+ );
+ }
+ }
+}
+````
+
### Dashboard Authorization
Hangfire Dashboard provides information about your background jobs, including method names and serialized arguments as well as gives you an opportunity to manage them by performing different actions – retry, delete, trigger, etc. So it is important to restrict access to the Dashboard.
diff --git a/docs/en/Background-Jobs-RabbitMq.md b/docs/en/Background-Jobs-RabbitMq.md
index 16b8b0981a..8eec3733fb 100644
--- a/docs/en/Background-Jobs-RabbitMq.md
+++ b/docs/en/Background-Jobs-RabbitMq.md
@@ -126,25 +126,31 @@ By default, all the job types use the `Default` RabbitMQ connection.
Configure(options =>
{
options.DefaultQueueNamePrefix = "my_app_jobs.";
+ options.DefaultDelayedQueueNamePrefix = "my_app_jobs.delayed"
+ options.PrefetchCount = 1;
options.JobQueues[typeof(EmailSendingArgs)] =
new JobQueueConfiguration(
typeof(EmailSendingArgs),
queueName: "my_app_jobs.emails",
- connectionName: "SecondConnection"
+ connectionName: "SecondConnection",
+ delayedQueueName:"my_app_jobs.emails.delayed"
);
});
````
-* This example sets the default queue name prefix to `my_app_jobs.`. If different applications use the same RabbitMQ server, it would be important to use different prefixes for each application to not consume jobs of each other.
+* This example sets the default queue name prefix to `my_app_jobs.` and default delayed queue name prefix to `my_app_jobs.delayed`. If different applications use the same RabbitMQ server, it would be important to use different prefixes for each application to not consume jobs of each other.
+* Sets `PrefetchCount` for all queues.
* Also specifies a different connection string for the `EmailSendingArgs`.
`JobQueueConfiguration` class has some additional options in its constructor;
* `queueName`: The queue name that is used for this job. The prefix is not added, so you need to specify the full name of the queue.
+* `DelayedQueueName`: The delayed queue name that is used for delayed execution of job. The prefix is not added, so you need to specify the full name of the queue.
* `connectionName`: The RabbitMQ connection name (see the connection configuration above). This is optional and the default value is `Default`.
* `durable` (optional, default: `true`).
* `exclusive` (optional, default: `false`).
-* `autoDelete` (optional, default: `false`)
+* `autoDelete` (optional, default: `false`).
+* `PrefetchCount` (optional, default: null)
See the RabbitMQ documentation if you want to understand the `durable`, `exclusive` and `autoDelete` options better, while most of the times the default configuration is what you want.
diff --git a/docs/en/Background-Workers.md b/docs/en/Background-Workers.md
index 286d6ab7b0..6206e2fbd1 100644
--- a/docs/en/Background-Workers.md
+++ b/docs/en/Background-Workers.md
@@ -128,7 +128,7 @@ Be careful if you run multiple instances of your application simultaneously in a
If that's a problem for your workers, you have the following options:
-* Implement your background workers so that they work in a clustered environment without any problem. Using the [distributed lock](../Distributed-Locking.md) to ensure concurrency control is a way of doing that. A background worker in an application instance may handle a distributed lock, so the workers in other application instances will wait for the lock. In this way, only one worker does the actual work, while others wait in idle. If you implement this, your workers run safely without caring about how the application is deployed.
+* Implement your background workers so that they work in a clustered environment without any problem. Using the [distributed lock](Distributed-Locking.md) to ensure concurrency control is a way of doing that. A background worker in an application instance may handle a distributed lock, so the workers in other application instances will wait for the lock. In this way, only one worker does the actual work, while others wait in idle. If you implement this, your workers run safely without caring about how the application is deployed.
* Stop the background workers (set `AbpBackgroundWorkerOptions.IsEnabled` to `false`) in all application instances except one of them, so only the single instance runs the workers.
* Stop the background workers (set `AbpBackgroundWorkerOptions.IsEnabled` to `false`) in all application instances and create a dedicated application (maybe a console application running in its own container or a Windows Service running in the background) to execute all the background tasks. This can be a good option if your background workers consume high system resources (CPU, RAM or Disk), so you can deploy that background application to a dedicated server and your background tasks don't affect your application's performance.
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/POST.md b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/POST.md
new file mode 100644
index 0000000000..2b756f2958
--- /dev/null
+++ b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/POST.md
@@ -0,0 +1,380 @@
+# ABP.IO Platform 6.0 RC Has Been Released
+
+Today, we are happy to release the [ABP Framework](https://abp.io/) and [ABP Commercial](https://commercial.abp.io/) version **6.0 RC** (release candidate). This blog post introduces the new features and important changes in this new version.
+
+> **The planned release date for the [6.0.0 Stable](https://github.com/abpframework/abp/milestone/71) version is September 06, 2022**.
+
+Try this version and provide feedback for the stable ABP v6.0! Thank you to all.
+
+## Get Started with the 6.0 RC
+
+Follow the steps below to try version 6.0.0 RC today:
+
+1) **Upgrade** the ABP CLI to version `6.0.0-rc.1` using a command line terminal:
+
+````bash
+dotnet tool update Volo.Abp.Cli -g --version 6.0.0-rc.1
+````
+
+**or install** it if you haven't before:
+
+````bash
+dotnet tool install Volo.Abp.Cli -g --version 6.0.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/latest/CLI) for all the available options.
+
+> You can also use the *Direct Download* tab on the [Get Started](https://abp.io/get-started) page by selecting the **Preview checkbox**.
+
+You can use any IDE that supports .NET 6.x, like **[Visual Studio 2022](https://visualstudio.microsoft.com/downloads/)**.
+
+## Migration Guides
+
+There are breaking changes in this version that may affect your application.
+Please see the following migration documents, if you are upgrading from v5.3.0:
+
+* [ABP Framework 5.3 to 6.0 Migration Guide](https://docs.abp.io/en/abp/6.0/Migration-Guides/Abp-6_0)
+* [ABP Commercial 5.3 to 6.0 Migration Guide](https://docs.abp.io/en/commercial/6.0/migration-guides/v6_0)
+
+## What's New with ABP Framework 6.0?
+
+In this section, I will introduce some major features released in this version. Here is a brief list of titles explained in the next sections:
+
+* **LeptonX Lite** is now the **default theme** for startup templates.
+* Optional PWA support is added to [*Get Started*](https://abp.io/get-started) page.
+* Introducing the **OpenIddict Module** and switching to OpenIddict for the startup templates.
+* New **.NET MAUI** Startup Template.
+* Introducing the `ITransientCachedServiceProvider` interface.
+* Introducing the dynamic components for Blazor UI.
+* Improvements on ABP CLI.
+* Introducing the `Volo.Abp.RemoteServices` package.
+* Create/Update user accounts for external logins.
+* Sending test email in the setting page for MVC and Blazor user interfaces.
+* Improvements on the **eShopOnAbp** project.
+* Other news...
+
+### LeptonX Lite Theme on Startup Templates
+
+
+
+With this version, startup templates (`app` and `app-nolayers` templates) use the **LeptonX Lite** as the default theme. However, it's still possible to create a project with **Basic Theme** either using the **ABP CLI** or downloading the project via [*Get Started*](https://abp.io/get-started) page on the [abp.io](https://abp.io/) website.
+
+#### via ABP CLI
+
+To create a new project with **Basic Theme**, you can use the `--theme` option as below:
+
+```bash
+abp new Acme.BookStore --theme basic --preview
+```
+
+#### via Get Started page
+
+Also, you can create a new project with **LeptonX Lite** or **Basic Theme** on *Get Started* page.
+
+
+
+> The "Preview" checkbox should be checked to be able to see the theme selection section on the *Get Started* page.
+
+
+
+### Optional PWA Support is Added to the Get Started Page
+
+We've introduced the PWA (Progressive Web Application) support for the startup templates for Angular & Blazor WASM UIs in **v5.3**. In this version, we also added this PWA support to the [*Get Started*](https://abp.io/get-started) page on the [abp.io](https://abp.io/) website.
+
+
+
+If you check the "Progressive Web Application" checkbox while creating an application, the all required configurations will be done for you and you will get the benefit of PWA features in your application.
+
+
+
+### Introducing the **OpenIddict Module** and Switching to OpenIddict in the Startup Templates
+
+We already [announced the plan of replacing the IdentityServer with OpenIddict](https://github.com/abpframework/abp/issues/11989).
+
+Therefore, we have created the `OpenIddict` module in this version and switched to **OpenIddict** in the startup templates. The ABP Framework uses this module to add **OAuth** features to the applications. We created documentation for the **OpenIddict Module**.
+
+- You can see the following document to **learn about the OpenIddict Module**:
+ [https://docs.abp.io/en/abp/6.0/Modules/OpenIddict](https://docs.abp.io/en/abp/6.0/Modules/OpenIddict)
+- You can check out the following migration guide to learn **how to migrate to OpenIddict**:
+ [https://docs.abp.io/en/abp/6.0/Migration-Guides/IdentityServer_To_OpenIddict](https://docs.abp.io/en/abp/6.0/Migration-Guides/IdentityServer_To_OpenIddict)
+
+
+
+> We will continue to ship Identity Server packages for a while but in the long term, you may need to replace it, because Identity Server support ends at the end of 2022. Please see the [announcement]((https://github.com/abpframework/abp/issues/11989)) for more info.
+
+
+
+### New .NET MAUI Startup Template
+
+
+
+ABP Framework provides .NET MAUI startup templates with **v6.0.0**. You can create a new .NET MAUI project with the command below:
+
+```bash
+abp new Acme.BookStore -t maui
+```
+
+
+
+### Introducing the `ITransientCachedServiceProvider`
+
+`ICachedServiceProvider` interface is used to resolve the cached services within a new scope. We created a new interface to resolve cached services **without creating scopes**. It's called `ITransientCachedServiceProvider`. The difference between `ICachedServiceProvider` and `ITransientCachedServiceProvider` is; `ITransientCachedServiceProvider` is transient. Check out [this issue](https://github.com/abpframework/abp/issues/12918) for more information.
+
+
+
+### Introducing the dynamic layout components for Blazor UI
+
+ABP Framework provides different ways of customizing the UI and one of them is to use [Layout Hooks](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Layout-Hooks) in MVC. The **Layout Hook System** allows you to add code to some specific parts of the layout and all layouts of the themes provided by the ABP Framework implement these hooks.
+
+However, Blazor UI doesn't have such a system yet and we are planning to implement [Layout Hooks for the Blazor UI](https://github.com/abpframework/abp/issues/6261) in version 7.0.
+
+We are introducing the dynamic layout components for the Blazor UI to be able to add components to the Blazor layouts.
+
+You can configure the `AbpDynamicLayoutComponentOptions` to render your components in the layout, as below:
+
+```csharp
+Configure(options =>
+{
+ options.Components.Add(typeof(MyBlazorComponent), null);
+});
+```
+
+
+
+### Improvements in ABP CLI
+
+There are some enhancements in [ABP CLI](https://docs.abp.io/en/abp/6.0/CLI). You can see the brief list of some of these improvements below:
+
+* You can list all available templates by using the `abp list-templates` command with v6.0. See [#13083](https://github.com/abpframework/abp/pull/13083).
+* You can select the theme when creating a new project by specifying the `--theme` option. You can see the *LeptonX Lite Theme on the Startup Templates* section above for an example.
+* `abp update` command has been updating the version of the main application until now. With v6.0.0, this command updates all package versions **inside all solutions in the sub-folders**. Checkout the issue [#12735](https://github.com/abpframework/abp/pull/12738) for more information.
+
+
+
+### Introducing the `Volo.Abp.RemoteService` Package
+
+A new `Volo.Abp.RemoteService` package has been added to the framework. Some of the classes that are related to the remote service configurations such as `AbpRemoteServiceOptions` class moved from `Volo.Abp.Http.Client` to this package. In this way, it became more reusable for further usages.
+
+
+
+### Create/Update User Accounts For External Logins
+
+If a user authenticates from an external provider like `Keycloak`, the user is being redirected to this external provider, and comes back to the main application. In this process, the user's data is not being saved in the main application's database. With this version, ABP saves the user information and lists in the users page. And this fixes permission management, user information mismatches and other issues. For more info, see [the related issue](https://github.com/abpframework/abp/issues/12203).
+
+
+
+### Sending test email in the setting page for MVC and Blazor UIs
+
+"Sending Test Email" feature is added to the [Setting Management](https://docs.abp.io/en/abp/6.0/Modules/Setting-Management) module, which allows checking the email settings are configured properly and sending emails successfully to the target email address.
+
+
+
+After configuring the email settings such as the target email address, you can click the "Send" button to send a test email to see if everything went well.
+
+> Note that this feature will be implemented for the Angular UI in the stable v6.0.
+
+
+
+### Improvements on eShopOnAbp Project
+
+The following improvements have been made on [eShopOnAbp project](https://github.com/abpframework/eShopOnAbp) with this version:
+
+* Some improvements have been made on the Admin Application for Order Management for Angular UI. See [#110](https://github.com/abpframework/eShopOnAbp/pull/110).
+* `SignalR` error on Kubernetes & Docker Compose has been fixed. See [#113](https://github.com/abpframework/eShopOnAbp/pull/113).
+* eShopOnAbp project has been deployed to Azure Kubernetes Service. See [#114](https://github.com/abpframework/eShopOnAbp/pull/114). The live demo can be seen from [eshoponabp.com](https://eshoponabp.com/).
+* Configurations have been made for some services on the `docker-compose.yml` file. See [#112](https://github.com/abpframework/eShopOnAbp/pull/112).
+* Gateway Redirect Loop problem on Kubernetes has been fixed. See [the commit](https://github.com/abpframework/eShopOnAbp/commit/6413ef15c91cd8a5309050b63bb4dbca23587607).
+
+
+
+### Other News
+
+* Autofac library has been upgraded to **v6.4.0**. Please see [#12816](https://github.com/abpframework/abp/pull/12816) for more info.
+* Performance Improvements have been made in the **Settings Module** and tabs on the *Settings* page are lazy loading now.
+* Some improvements have been made in the CMS Kit Module. You can see the improvements from [here](https://github.com/abpframework/abp/issues/11965).
+
+If you want to see more details, you can check [the release on GitHub](https://github.com/abpframework/abp/releases/tag/6.0.0-rc.1), which contains a list of all the issues and pull requests closed in this version.
+
+
+
+## What's New with ABP Commercial 6.0?
+
+
+
+### LeptonX Theme is the Default Theme
+
+With this version, the startup templates (`app-pro`, `app-nolayers-pro` and `microservice-pro` templates) use the **LeptonX Theme** as the default theme. However, it's still possible to create a new project with **Lepton Theme** or **Basic Theme**, either using the **ABP CLI** or **ABP Suite**.
+
+#### via ABP CLI
+
+To create a new project with **Lepton Theme** or **Basic Theme**, you can use the `--theme` option as below. For "Basic Theme" specify the theme name as `--theme basic`.
+
+```bash
+abp new Acme.BookStore --theme lepton --preview
+```
+
+
+
+#### via ABP Suite
+
+Also, you can create a new project with **Lepton Theme** or **Basic Theme** from ABP Suite.
+
+
+
+### Switching to OpenIddict in the Startup Templates
+
+We have also switched to the **OpenIddict** for the startup templates for ABP Commercial as explained above.
+
+
+
+### New .NET MAUI Mobile
+
+
+
+ABP Commercial has been providing a [React Native](https://docs.abp.io/en/commercial/latest/getting-started-react-native) mobile app since with the very early versions. Alternative to this application, we created a new .NET MAUI mobile app. To create a new `app-pro` ABP project with the .NET MAUI mobile app, you can use the command below:
+
+```bash
+abp new Acme.BookStore -t app-pro --mobile maui
+```
+
+> Note that, when Microsoft supports `WebAuthenticator` on Windows, we'll also support it to work on Windows OS.
+
+
+
+### GDPR: Cookie Consent
+
+
+
+With this version, the **Cookie Consent** feature has been added to the **GDPR** module. It's enabled by default for the new startup templates. There are two pages in the templates: "Cookie Policy" page and "Privacy Policy" page.
+
+If you want to disable/hide the "Cookie Consent", you can simply open the startup project module class and set the `IsEnabled` property as **false** for the **AddAbpCookieConsent** method as below:
+
+```csharp
+context.Services.AddAbpCookieConsent(options =>
+{
+ options.IsEnabled = false; //disabled
+ options.CookiePolicyUrl = "/CookiePolicy";
+ options.PrivacyPolicyUrl = "/PrivacyPolicy";
+});
+```
+
+> These pages are used to build up the cookie consent text and you can change the content or url of these pages by your needs.
+
+If you want to use the Cookie Consent feature of the GDPR module in your existing project, please see the [GDPR Module](https://docs.abp.io/en/commercial/6.0/modules/gdpr) documentation for configurations.
+
+### Improvements/Developments on CMS Kit Poll
+
+Some improvements have been made on the Poll System of CMS Kit module as listed below:
+
+* The Widget rendering and Admin side for the Blazor UI improvements.
+* A Widget can be picked from the editor as seen in the image below.
+
+
+
+
+
+### Blazor UI for the Chat Module
+
+Chat Module is now also available for the Blazor UI after the MVC and Angular UIs. You can read the [Chat Module](https://docs.abp.io/en/commercial/6.0/modules/chat) documentation to get the overall knowledge about the module and add to your application.
+
+
+
+
+
+
+### Blazor Admin UI for CMS Kit Module
+
+All admin side **CMS Kit** and **CMS Kit Pro** features have been implemented for the Blazor UI. Blazor UI will only be available to ABP Commercial customers.
+
+
+
+
+
+
+### Suite: Excel Export
+
+With v6.0, now it's possible to export the records as Excel for Blazor & MVC UIs. Angular UI is still in-progress, and we will implement it with the stable v6.0 release. Check the "Excel export" checkbox to add this feature.
+
+
+
+
+
+A new Excel Export button is being located at the top of the generated page as seen below:
+
+
+
+Then, you can download the records as `.xlsx` format by clicking the "Excel Export" button. Note that the exported Excel list is the filtered list.
+
+
+
+### ABP Suite: Optional PWA Support
+
+With this version, it's possible to add the [PWA (Progressive Web App)](https://web.dev/progressive-web-apps/?gclid=Cj0KCQjwxIOXBhCrARIsAL1QFCY0IB-W5k-lsXmRCbm00sl4nyBIYynAX3IdJkjyizyNUjuCE8zeu24aApxtEALw_wcB) support for Blazor & Angular UIs while creating the application via Suite.
+
+
+
+You just need to check the "Progressive web application" checkbox, when creating a new application. Then, ABP Suite will add the PWA support to your application. When you publish your application, you get the full benefits of PWA features such as offline support.
+
+
+
+### Other News
+
+#### Explainer Videos
+
+We are creating explainer videos for the ABP Commercial Modules to provide an overview. Within this milestone, we've created four new explainer videos:
+
+* [Audit Logging Module](https://www.youtube.com/watch?v=NzSuFBpqfsc)
+* [Identity Module](https://www.youtube.com/watch?v=W87jA_GBE54)
+* [SaaS Module](https://www.youtube.com/watch?v=xXlaaXP6qqQ)
+* [Forms Module](https://www.youtube.com/watch?v=MousWEPfrA8)
+
+You can subscribe to [Volosoft's YouTube channel](https://www.youtube.com/channel/UCO3XKlpvq8CA5MQNVS6b3dQ) to be informed about the future ABP events and videos.
+
+
+
+### Trial License is now available!
+
+
+
+If you are considering purchasing a new ABP Commercial license, and you want to see ABP in action then, check out https://commercial.abp.io/pricing and click FREE TRIAL button.
+
+
+
+## Community News
+
+### New ABP Community Posts
+
+* [Alper Ebicoglu](https://twitter.com/alperebicoglu) has created a new community article to give a full overview of .NET MAUI. You can read it [here](https://community.abp.io/posts/all-about-.net-maui-gb4gkdg5).
+* [Anto Subash](https://twitter.com/antosubash) has created a new video content to show "State Management in Blazor with Fluxor". You can read it [here](https://community.abp.io/posts/blazor-state-management-with-fluxor-raskpv19).
+* [Learn ABP Framework](https://community.abp.io/members/learnabp) has also created a new video content to show "How to install LeptonX Lite Theme for ABP Framework 5.3 MVC UI". You can read it [here](https://community.abp.io/posts/how-to-install-leptonx-lite-theme-on-abp-framework-5.3-mvc-ui-epzng137).
+* [Kirti Kulkarni](https://twitter.com/kirtimkulkarni) has created three new community articles. You can use the links below to read the articles:
+ * [Integrating the file management module with ABP Commercial application](https://community.abp.io/posts/integrating-the-file-management-module-with-abp-commercial-application-qd6v4dsr)
+ * [Work with PDF's in ABP Commercial Project using PDFTron](https://community.abp.io/posts/work-with-pdfs-in-abp-commercial-project-using-pdftron-tjw0hlgu)
+ * [Create a custom login page in ABP Commercial Angular app](https://community.abp.io/posts/create-a-custom-login-page-in-abp-commercial-angular-app-r2huidx7)
+* [Don Boutwell](https://community.abp.io/members/dboutwell) has created his first ABP Community article. You can read it from [here](https://community.abp.io/posts/password-required-redis-with-abp-framework-and-docker-94old5rm).
+
+
+
+### Volosoft Has Attended the DNF Summit 2022
+
+
+
+Core team members of ABP Framework, [Halil Ibrahim Kalkan](https://twitter.com/hibrahimkalkan) and [Alper Ebicoglu](https://twitter.com/alperebicoglu) have attended the [DNF Summit](https://t.co/ngWnBLiAn5) on the 20th of July. Halil Ibrahim Kalkan talked about the creation of the ABP Framework and Alper Ebicoglu showed how easy to create a project with ABP Framework within 15 minutes.
+
+Watch DNF Summit session 👉 https://www.youtube.com/embed/VL0ewZ-0ruo
+
+
+
+
+
+## Conclusion
+
+This version comes with some features and enhancements to the existing features. You can see the [Road Map](https://docs.abp.io/en/abp/6.0/Road-Map) documentation to learn about the release schedule and planned features for the next releases. The planned release date for the [6.0.0 Stable](https://github.com/abpframework/abp/milestone/71) version is September 06, 2022. Please try the ABP v6.0 RC and provide feedback to us.
+
+Thanks for being a part of this community!
\ No newline at end of file
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/blazor-chat-module-1.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/blazor-chat-module-1.png
new file mode 100644
index 0000000000..6d847c9065
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/blazor-chat-module-1.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/blazor-chat-module-2.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/blazor-chat-module-2.png
new file mode 100644
index 0000000000..24f0688319
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/blazor-chat-module-2.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/cms-blog-blazor.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/cms-blog-blazor.png
new file mode 100644
index 0000000000..5d169aa322
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/cms-blog-blazor.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/cms-blog-post-blazor.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/cms-blog-post-blazor.png
new file mode 100644
index 0000000000..1722a85b10
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/cms-blog-post-blazor.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/cookie-banner.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/cookie-banner.png
new file mode 100644
index 0000000000..cbfafbc907
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/cookie-banner.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/cover-image.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/cover-image.png
new file mode 100644
index 0000000000..1a6e267b86
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/cover-image.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/dnf-summit-attendees.jpg b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/dnf-summit-attendees.jpg
new file mode 100644
index 0000000000..42df8aaf4e
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/dnf-summit-attendees.jpg differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/dnf-summit.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/dnf-summit.png
new file mode 100644
index 0000000000..dff3609c20
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/dnf-summit.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/excel-export.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/excel-export.png
new file mode 100644
index 0000000000..393ea33ada
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/excel-export.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/export-excel-page.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/export-excel-page.png
new file mode 100644
index 0000000000..243752969e
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/export-excel-page.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/get-started-page.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/get-started-page.png
new file mode 100644
index 0000000000..5ae76b1398
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/get-started-page.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/leptonx-lite-theme.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/leptonx-lite-theme.png
new file mode 100644
index 0000000000..e87a06f4fb
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/leptonx-lite-theme.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/maui-mobile-option.gif b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/maui-mobile-option.gif
new file mode 100644
index 0000000000..645346abc6
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/maui-mobile-option.gif differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/maui-template.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/maui-template.png
new file mode 100644
index 0000000000..0d9df0e63f
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/maui-template.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/poll-add-widget.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/poll-add-widget.png
new file mode 100644
index 0000000000..51cd34b9bf
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/poll-add-widget.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/pricing-page.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/pricing-page.png
new file mode 100644
index 0000000000..21b19b4ed7
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/pricing-page.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/pwa-support-get-started-page.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/pwa-support-get-started-page.png
new file mode 100644
index 0000000000..e91e4e5223
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/pwa-support-get-started-page.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/setting-management-emailing.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/setting-management-emailing.png
new file mode 100644
index 0000000000..f2c5475655
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/setting-management-emailing.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/suite-create-new-solution.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/suite-create-new-solution.png
new file mode 100644
index 0000000000..5756a65ad0
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/suite-create-new-solution.png differ
diff --git a/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/suite-pwa-support.png b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/suite-pwa-support.png
new file mode 100644
index 0000000000..bf5982b68a
Binary files /dev/null and b/docs/en/Blog-Posts/2022-07-26 v6_0_Preview/suite-pwa-support.png differ
diff --git a/docs/en/CLI-New-Command-Samples.md b/docs/en/CLI-New-Command-Samples.md
index 1a7a8a551a..26d098c98e 100644
--- a/docs/en/CLI-New-Command-Samples.md
+++ b/docs/en/CLI-New-Command-Samples.md
@@ -1,6 +1,6 @@
# ABP CLI - New Solution Sample Commands
-The `abp new` command creates an ABP solution or other artifacts based on an ABP template. [ABP CLI](CLI.md) 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`.
+The `abp new` command creates an ABP solution or other artifacts based on an ABP template. [ABP CLI](CLI.md) 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 available mobile projects are `React Native` and `MAUI` mobile app. Available database providers are `Entity Framework Core` and `MongoDB`. All the commands starts with `abp new`.
## Angular
@@ -64,6 +64,14 @@ The following commands are for creating MVC UI projects:
abp new Acme.BookStore -u mvc --tiered --database-provider mongodb -csf
```
+* **Public Website**, Entity Framework Core, no mobile app, creates the project in a new folder:
+
+ ```bash
+ abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef -csf --with-public-website
+ ```
+
+ _Note that Public Website is only included in PRO templates._
+
## Blazor
diff --git a/docs/en/CLI.md b/docs/en/CLI.md
index cc85f0e573..7a5e59a62a 100644
--- a/docs/en/CLI.md
+++ b/docs/en/CLI.md
@@ -34,6 +34,7 @@ Here, is the list of all available commands before explaining their details:
* **`add-package`**: Adds an ABP package to a project.
* **`add-module`**: Adds a [multi-package application module](https://docs.abp.io/en/abp/latest/Modules/Index) to a solution.
* **`list-modules`**: Lists names of open-source application modules.
+* **`list-templates`**: Lists the names of available templates to create a solution.
* **`get-source`**: Downloads the source code of a module.
* **`generate-proxy`**: Generates client side proxies to use HTTP API endpoints.
* **`remove-proxy`**: Removes previously generated client side proxies.
@@ -123,6 +124,7 @@ For more samples, go to [ABP CLI Create Solution Samples](CLI-New-Command-Sample
* `--separate-auth-server`: The Identity Server project comes as a separate project and runs at a different endpoint. It separates the Identity Server from the API Host application. If not specified, you will have a single endpoint in the server side.
* `--mobile` or `-m`: Specifies the mobile application framework. If not specified, no mobile application will be created. Available options:
* `react-native`: React Native.
+ * `maui`: MAUI. This mobile option is only available for ABP Commercial.
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
@@ -143,7 +145,8 @@ For more samples, go to [ABP CLI Create Solution Samples](CLI-New-Command-Sample
* `mongodb`: MongoDB.
* `--theme`: Specifes the theme. Default theme is `leptonx-lite`. Available themes:
* `leptonx-lite`: [LeptonX Lite Theme](/Themes/LeptonXLite/mvc.md).
- * `basic`: [Basic Theme](/UI/AspNetCore/Basic-Theme.md).
+ * `basic`: [Basic Theme](/UI/AspNetCore/Basic-Theme.md).
+ * **`maui`**: .NET MAUI. A minimalist .NET MAUI application will be created if you specify this option.
* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
* `--version` or `-v`: Specifies the ABP & template version. It can be a [release tag](https://github.com/abpframework/abp/releases) or a [branch name](https://github.com/abpframework/abp/branches). Uses the latest release if not specified. Most of the times, you will want to use the latest version.
* `--preview`: Use latest preview version.
@@ -159,6 +162,7 @@ For more samples, go to [ABP CLI Create Solution Samples](CLI-New-Command-Sample
* `PostgreSQL`
* `--local-framework-ref --abp-path`: Uses local projects references to the ABP framework instead of using the NuGet packages. This can be useful if you download the ABP Framework source code and have a local reference to the framework from your application.
* `--no-random-port`: Uses template's default ports.
+* `--skip-installing-libs` or `-sib`: Skip installing client side packages.
See some [examples for the new command](CLI-New-Command-Samples.md) here.
@@ -242,7 +246,7 @@ It can also create a new module for your solution and add it to your solution. S
> A business module generally consists of several packages (because of layering, different database provider options or other reasons). Using `add-module` command dramatically simplifies adding a module to a solution. However, each module may require some additional configurations which is generally indicated in the documentation of the related module.
-Usage
+Usage:
````bash
abp add-module [options]
@@ -276,7 +280,7 @@ abp add-module ProductManagement --new --add-to-solution-file
Lists names of open-source application modules.
-Usage
+Usage:
````bash
abp list-modules [options]
@@ -292,11 +296,21 @@ abp list-modules
* `--include-pro-modules`: Includes commercial (pro) modules in the output.
+### list-templates
+
+Lists all available templates to create a solution.
+
+Usage:
+
+```bash
+abp list-templates
+```
+
### get-source
Downloads the source code of a module to your computer.
-Usage
+Usage:
````bash
abp get-source [options]
diff --git a/docs/en/Community-Articles/15-08-2022-How-to-Design-Multi-Lingual-Entity/How-to-Design-Multi-Lingual-Entity.md b/docs/en/Community-Articles/15-08-2022-How-to-Design-Multi-Lingual-Entity/How-to-Design-Multi-Lingual-Entity.md
new file mode 100644
index 0000000000..2c4b860c95
--- /dev/null
+++ b/docs/en/Community-Articles/15-08-2022-How-to-Design-Multi-Lingual-Entity/How-to-Design-Multi-Lingual-Entity.md
@@ -0,0 +1,690 @@
+# How to Design Multi-Lingual Entity
+
+## Introduction
+
+If you want to open up to the global market these days, end-to-end localization is a must. ABP provides an already established infrastructure for static texts. However, this may not be sufficient for many applications. You may need to fully customize your app for a particular language and region.
+
+Let's take a look at a few quotes from Christian Arno's article "[How Foreign-Language Internet Strategies Boost Sales](https://www.mediapost.com/publications/article/155250/how-foreign-language-internet-strategies-boost-sal.html)" to better understand the impact of this:
+
+- 82% of European consumers are less likely to buy online if the site is not in their native tongue ([Eurobarometer survey](http://europa.eu/rapid/pressReleasesAction.do?reference=IP/11/556)).
+- 72.4% of global consumers are more likely to buy a product if the information is available in their own language ([Common Sense Advisory](http://www.commonsenseadvisory.com/)).
+- The English language currently only accounts for 31% of all online use, and more than half of all searches are in languages other than English.
+- Today, 42% of all Internet users are in Asia, while almost one-quarter are in Europe and just over 10% are in Latin America.
+
+- Foreign languages have experienced exponential growth in online usage in the past decade -- with Chinese now officially the [second-most-prominent-language](http://english.peopledaily.com.cn/90001/90776/90882/7438489.html) on the Web. [Arabic](http://www.internetworldstats.com/stats7.htm) has increased by a whopping 2500%, while English has only risen by 204%
+
+If you are looking for ways to expand your market share by fully customizing your application for a particular language and region, in this article I will explain how you can do it with ABP framework.
+
+### Source Code
+
+You can find the source code of the application at [abpframework/abp-samples](https://github.com/abpframework/abp-samples/tree/master/AcmeBookStoreMultiLingual).
+
+### Demo of the Final Application
+
+At the end of this article, we will have created an application same as in the gif below.
+
+
+
+## Development
+
+In order to keep the article short and get rid of unrelated information in the article (like defining entities etc.), we'll be using the [BookStore](https://github.com/abpframework/abp-samples/tree/master/BookStore-Mvc-EfCore) example, which is used in the "[Web Application Development Tutorial](https://docs.abp.io/en/abp/latest/Tutorials/Part-1?UI=MVC&DB=EF)" documentation of ABP Framework and we will make the Book entity as multi-lingual. If you do not want to finish this tutorial, you can find the application [here](https://github.com/abpframework/abp-samples/tree/master/BookStore-Mvc-EfCore).
+
+### Determining the data model
+
+We need a robust, maintainable, and efficient data model to store content in multiple languages.
+
+> I read many articles to determine the data model correctly, and as a result, I decided to use one of the many approaches that suit us.
+> However, as in everything, there is a trade-off here. If you are wondering about the advantages and disadvantages of the model we will implement compared to other models, I recommend you to read [this article](https://vertabelo.com/blog/data-modeling-for-multiple-languages-how-to-design-a-localization-ready-system/).
+
+
+
+As a result of the tutorial, we already have the `Book` and `Author` entities, as an extra, we will just add the `BookTranslation`.
+
+> In the article, we will make the Name property of the Book entity multi-lingual, but the article is independent of the Book entity, you can make the entity you want multi-lingual with similar codes according to your requirements.
+
+#### Acme.BookStore.Domain.Shared
+
+Create a folder named `MultiLingualObjects` and create the following interfaces in its contents.
+
+We will use the `IObjectTranslation` interface to mark the translation of a multi-lingual entity:
+
+```csharp
+public interface IObjectTranslation
+{
+ string Language { get; set; }
+}
+```
+
+We will use the `IMultiLingualObject` interface to mark multi-lingual entities:
+
+```csharp
+public interface IMultiLingualObject
+ where TTranslation : class, IObjectTranslation
+{
+ ICollection Translations { get; set; }
+}
+```
+
+#### Acme.BookStore.Domain
+
+In the `Books` folder, create the `BookTranslation` class as follows:
+
+```csharp
+public class BookTranslation : Entity, IObjectTranslation
+{
+ public Guid BookId { get; set; }
+
+ public string Name { get; set; }
+
+ public string Language { get; set; }
+
+ public override object[] GetKeys()
+ {
+ return new object[] {BookId, Language};
+ }
+}
+```
+
+`BookTranslation` contains the `Language` property, which contains a language code for translation and a reference to the multi-lingual entity. We also have the `BookId` foreign key to help us know which book is translated.
+
+Implement `IMultiLingualObject` in the `Book` class as follows:
+
+```csharp
+public class Book : AuditedAggregateRoot, IMultiLingualObject
+{
+ public Guid AuthorId { get; set; }
+
+ public string Name { get; set; }
+
+ public BookType Type { get; set; }
+
+ public DateTime PublishDate { get; set; }
+
+ public float Price { get; set; }
+
+ public ICollection Translations { get; set; }
+}
+```
+
+Create a folder named `MultiLingualObjects` and add the following class inside of this folder:
+
+```csharp
+public class MultiLingualObjectManager : ITransientDependency
+{
+ protected const int MaxCultureFallbackDepth = 5;
+
+ public async Task FindTranslationAsync(
+ TMultiLingual multiLingual,
+ string culture = null,
+ bool fallbackToParentCultures = true)
+ where TMultiLingual : IMultiLingualObject
+ where TTranslation : class, IObjectTranslation
+ {
+ culture ??= CultureInfo.CurrentUICulture.Name;
+
+ if (multiLingual.Translations.IsNullOrEmpty())
+ {
+ return null;
+ }
+
+ var translation = multiLingual.Translations.FirstOrDefault(pt => pt.Language == culture);
+ if (translation != null)
+ {
+ return translation;
+ }
+
+ if (fallbackToParentCultures)
+ {
+ translation = GetTranslationBasedOnCulturalRecursive(
+ CultureInfo.CurrentUICulture.Parent,
+ multiLingual.Translations,
+ 0
+ );
+
+ if (translation != null)
+ {
+ return translation;
+ }
+ }
+
+ return null;
+ }
+
+ protected TTranslation GetTranslationBasedOnCulturalRecursive(
+ CultureInfo culture, ICollection translations, int currentDepth)
+ where TTranslation : class, IObjectTranslation
+ {
+ if (culture == null ||
+ culture.Name.IsNullOrWhiteSpace() ||
+ translations.IsNullOrEmpty() ||
+ currentDepth > MaxCultureFallbackDepth)
+ {
+ return null;
+ }
+
+ var translation = translations.FirstOrDefault(pt => pt.Language.Equals(culture.Name, StringComparison.OrdinalIgnoreCase));
+ return translation ?? GetTranslationBasedOnCulturalRecursive(culture.Parent, translations, currentDepth + 1);
+ }
+}
+```
+
+With `MultiLingualObjectManager`'s `FindTranslationAsync` method, we get the translated version of the book according to `CurrentUICulture`. If no translation of culture is found, we return null.
+
+> Every thread in .NET has `CurrentCulture` and `CurrentUICulture` objects.
+
+#### Acme.BookStore.EntityFrameworkCore
+
+In the `OnModelCreating` method of the `BookStoreDbContext` class, configure the `BookTranslation` as follows:
+
+```csharp
+builder.Entity(b =>
+{
+ b.ToTable(BookStoreConsts.DbTablePrefix + "BookTranslations",
+ BookStoreConsts.DbSchema);
+
+ b.ConfigureByConvention();
+
+ b.HasKey(x => new {x.BookId, x.Language});
+});
+```
+
+> I haven't explicitly set up a one-to-many relationship between `Book` and `BookTranslation` here, but the entity framework will do it for us.
+
+After that, you can just run the following command in a command-line terminal to add a new database migration (in the directory of the `EntityFrameworkCore` project):
+
+```bash
+dotnet ef migrations add Added_BookTranslation
+```
+
+This will add a new migration class to your project. You can then run the following command (or run the `.DbMigrator` application) to apply changes to the database:
+
+```bash
+dotnet ef database update
+```
+
+Add the following code to the `ConfigureServices` method of the `BookStoreEntityFrameworkCoreModule`:
+
+```csharp
+ Configure(options =>
+ {
+ options.Entity(bookOptions =>
+ {
+ bookOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Translations);
+ });
+});
+```
+
+Now we can use `WithDetailsAsync` without any parameters on `BookAppService` knowing that `Translations` will be included.
+
+#### Acme.BookStore.Application.Contracts
+
+Implement `IObjectTranslation` in the `BookDto` class as follows:
+
+```csharp
+public class BookDto : AuditedEntityDto, IObjectTranslation
+{
+ public Guid AuthorId { get; set; }
+
+ public string AuthorName { get; set; }
+
+ public string Name { get; set; }
+
+ public BookType Type { get; set; }
+
+ public DateTime PublishDate { get; set; }
+
+ public float Price { get; set; }
+
+ public string Language { get; set; }
+}
+```
+
+`Language` property is required to understand which language the translated book name belongs to in the UI.
+
+Create the `AddBookTranslationDto` class in the `Books` folder as follows:
+
+```csharp
+public class AddBookTranslationDto : IObjectTranslation
+{
+ [Required]
+ public string Language { get; set; }
+
+ [Required]
+ public string Name { get; set; }
+}
+```
+
+Add the `AddTranslationsAsync` method to the `IBookAppService` as follows:
+
+```csharp
+public interface IBookAppService :
+ ICrudAppService<
+ BookDto,
+ Guid,
+ PagedAndSortedResultRequestDto,
+ CreateUpdateBookDto>
+{
+ Task> GetAuthorLookupAsync();
+
+ Task AddTranslationsAsync(Guid id, AddBookTranslationDto input); // added this line
+}
+```
+
+#### Acme.BookStore.Application
+
+Now, we need to implement the `AddTranslationsAsync` method in `BookAppService` and include `Translations` in the `Book` entity, for this you can change the `BookAppService` as follows:
+
+```csharp
+[Authorize(BookStorePermissions.Books.Default)]
+public class BookAppService :
+ CrudAppService<
+ Book, //The Book entity
+ BookDto, //Used to show books
+ Guid, //Primary key of the book entity
+ PagedAndSortedResultRequestDto, //Used for paging/sorting
+ CreateUpdateBookDto>, //Used to create/update a book
+ IBookAppService //implement the IBookAppService
+{
+ private readonly IAuthorRepository _authorRepository;
+
+ public BookAppService(
+ IRepository repository,
+ IAuthorRepository authorRepository)
+ : base(repository)
+ {
+ _authorRepository = authorRepository;
+ GetPolicyName = BookStorePermissions.Books.Default;
+ GetListPolicyName = BookStorePermissions.Books.Default;
+ CreatePolicyName = BookStorePermissions.Books.Create;
+ UpdatePolicyName = BookStorePermissions.Books.Edit;
+ DeletePolicyName = BookStorePermissions.Books.Create;
+ }
+
+ public override async Task GetAsync(Guid id)
+ {
+ //Get the IQueryable from the repository
+ var queryable = await Repository.WithDetailsAsync(); // this line changed
+
+ //Prepare a query to join books and authors
+ var query = from book in queryable
+ join author in await _authorRepository.GetQueryableAsync() on book.AuthorId equals author.Id
+ where book.Id == id
+ select new { book, author };
+
+ //Execute the query and get the book with author
+ var queryResult = await AsyncExecuter.FirstOrDefaultAsync(query);
+ if (queryResult == null)
+ {
+ throw new EntityNotFoundException(typeof(Book), id);
+ }
+
+ var bookDto = ObjectMapper.Map(queryResult.book);
+ bookDto.AuthorName = queryResult.author.Name;
+ return bookDto;
+ }
+
+ public override async Task> GetListAsync(PagedAndSortedResultRequestDto input)
+ {
+ //Get the IQueryable from the repository
+ var queryable = await Repository.WithDetailsAsync(); // this line changed
+
+ //Prepare a query to join books and authors
+ var query = from book in queryable
+ join author in await _authorRepository.GetQueryableAsync() on book.AuthorId equals author.Id
+ select new {book, author};
+
+ //Paging
+ query = query
+ .OrderBy(NormalizeSorting(input.Sorting))
+ .Skip(input.SkipCount)
+ .Take(input.MaxResultCount);
+
+ //Execute the query and get a list
+ var queryResult = await AsyncExecuter.ToListAsync(query);
+
+ //Convert the query result to a list of BookDto objects
+ var bookDtos = queryResult.Select(x =>
+ {
+ var bookDto = ObjectMapper.Map(x.book);
+ bookDto.AuthorName = x.author.Name;
+ return bookDto;
+ }).ToList();
+
+ //Get the total count with another query
+ var totalCount = await Repository.GetCountAsync();
+
+ return new PagedResultDto(
+ totalCount,
+ bookDtos
+ );
+ }
+
+ public async Task> GetAuthorLookupAsync()
+ {
+ var authors = await _authorRepository.GetListAsync();
+
+ return new ListResultDto(
+ ObjectMapper.Map, List>(authors)
+ );
+ }
+
+ public async Task AddTranslationsAsync(Guid id, AddBookTranslationDto input)
+ {
+ var queryable = await Repository.WithDetailsAsync();
+
+ var book = await AsyncExecuter.FirstOrDefaultAsync(queryable, x => x.Id == id);
+
+ if (book.Translations.Any(x => x.Language == input.Language))
+ {
+ throw new UserFriendlyException($"Translation already available for {input.Language}");
+ }
+
+ book.Translations.Add(new BookTranslation
+ {
+ BookId = book.Id,
+ Name = input.Name,
+ Language = input.Language
+ });
+
+ await Repository.UpdateAsync(book);
+ }
+
+ 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}";
+ }
+}
+```
+
+Create the `MultiLingualBookObjectMapper` class as follows:
+
+```csharp
+public class MultiLingualBookObjectMapper : IObjectMapper, ITransientDependency
+{
+ private readonly MultiLingualObjectManager _multiLingualObjectManager;
+
+ private readonly ISettingProvider _settingProvider;
+
+ public MultiLingualBookObjectMapper(
+ MultiLingualObjectManager multiLingualObjectManager,
+ ISettingProvider settingProvider)
+ {
+ _multiLingualObjectManager = multiLingualObjectManager;
+ _settingProvider = settingProvider;
+ }
+
+ public BookDto Map(Book source)
+ {
+ var translation = AsyncHelper.RunSync(() =>
+ _multiLingualObjectManager.FindTranslationAsync(source));
+
+ return new BookDto
+ {
+ Id = source.Id,
+ AuthorId = source.AuthorId,
+ Type = source.Type,
+ Name = translation?.Name ?? source.Name,
+ PublishDate = source.PublishDate,
+ Price = source.Price,
+ Language = translation?.Language ?? AsyncHelper.RunSync(() => _settingProvider.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage)),
+ CreationTime = source.CreationTime,
+ CreatorId = source.CreatorId,
+ LastModificationTime = source.LastModificationTime,
+ LastModifierId = source.LastModifierId
+ };
+ }
+
+ public BookDto Map(Book source, BookDto destination)
+ {
+ return default;
+ }
+}
+```
+
+To map the multi-lingual `Book` entity to `BookDto`, we implement custom mapping using the `IObjectMapper` interface. If no translation is found, default values are returned.
+
+So far we have created the entire infrastructure. We don't need to change anything in the UI, if there is a translation according to the language chosen by the user, the list view will change. However, I want to create a simple modal where we can add new translations to an existing book in order to see what we have done.
+
+#### Acme.BookStore.Web
+
+Create a new razor page named `AddTranslationModal` in the `Books` folder as below.
+
+**View**
+
+```html
+@page
+@using Microsoft.AspNetCore.Mvc.TagHelpers
+@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
+@model Acme.BookStore.Web.Pages.Books.AddTranslationModal
+
+@{
+ Layout = null;
+}
+
+
+```
+
+**Model**
+
+```csharp
+public class AddTranslationModal : BookStorePageModel
+{
+ [HiddenInput]
+ [BindProperty(SupportsGet = true)]
+ public Guid Id { get; set; }
+
+ public List Languages { get; set; }
+
+ [BindProperty]
+ public BookTranslationViewModel TranslationViewModel { get; set; }
+
+ private readonly IBookAppService _bookAppService;
+ private readonly ILanguageProvider _languageProvider;
+
+ public AddTranslationModal(
+ IBookAppService bookAppService,
+ ILanguageProvider languageProvider)
+ {
+ _bookAppService = bookAppService;
+ _languageProvider = languageProvider;
+ }
+
+ public async Task OnGetAsync()
+ {
+ Languages = await GetLanguagesSelectItem();
+
+ TranslationViewModel = new BookTranslationViewModel();
+ }
+
+ public async Task OnPostAsync()
+ {
+ await _bookAppService.AddTranslationsAsync(Id, ObjectMapper.Map(TranslationViewModel));
+
+ return NoContent();
+ }
+
+ private async Task> GetLanguagesSelectItem()
+ {
+ var result = await _languageProvider.GetLanguagesAsync();
+
+ return result.Select(
+ languageInfo => new SelectListItem
+ {
+ Value = languageInfo.CultureName,
+ Text = languageInfo.DisplayName + " (" + languageInfo.CultureName + ")"
+ }
+ ).ToList();
+ }
+
+ public class BookTranslationViewModel
+ {
+ [Required]
+ [SelectItems(nameof(Languages))]
+ public string Language { get; set; }
+
+ [Required]
+ public string Name { get; set; }
+
+ }
+}
+```
+
+Then, we can open the `BookStoreWebAutoMapperProfile` class and define the required mapping as follows:
+
+```csharp
+CreateMap();
+```
+
+Finally, change the content of `index.js` in the `Books` folder as follows:
+
+```javascript
+$(function () {
+ var l = abp.localization.getResource('BookStore');
+ var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal');
+ var editModal = new abp.ModalManager(abp.appPath + 'Books/EditModal');
+ var addTranslationModal = new abp.ModalManager(abp.appPath + 'Books/AddTranslationModal'); // added this line
+
+ var dataTable = $('#BooksTable').DataTable(
+ abp.libs.datatables.normalizeConfiguration({
+ serverSide: true,
+ paging: true,
+ order: [[1, "asc"]],
+ searching: false,
+ scrollX: true,
+ ajax: abp.libs.datatables.createAjax(acme.bookStore.books.book.getList),
+ columnDefs: [
+ {
+ title: l('Actions'),
+ rowAction: {
+ items:
+ [
+ {
+ text: l('Edit'),
+ visible: abp.auth.isGranted('BookStore.Books.Edit'),
+ action: function (data) {
+ editModal.open({ id: data.record.id });
+ }
+ },
+ {
+ text: l('Add Translation'), // added this action
+ visible: abp.auth.isGranted('BookStore.Books.Edit'),
+ action: function (data) {
+ addTranslationModal.open({ id: data.record.id });
+ }
+ },
+ {
+ text: l('Delete'),
+ visible: abp.auth.isGranted('BookStore.Books.Delete'),
+ confirmMessage: function (data) {
+ return l(
+ 'BookDeletionConfirmationMessage',
+ data.record.name
+ );
+ },
+ action: function (data) {
+ acme.bookStore.books.book
+ .delete(data.record.id)
+ .then(function() {
+ abp.notify.info(
+ l('SuccessfullyDeleted')
+ );
+ dataTable.ajax.reload();
+ });
+ }
+ }
+ ]
+ }
+ },
+ {
+ title: l('Name'),
+ data: "name"
+ },
+ {
+ title: l('Author'),
+ data: "authorName"
+ },
+ {
+ title: l('Type'),
+ data: "type",
+ render: function (data) {
+ return l('Enum:BookType:' + data);
+ }
+ },
+ {
+ title: l('PublishDate'),
+ data: "publishDate",
+ render: function (data) {
+ return luxon
+ .DateTime
+ .fromISO(data, {
+ locale: abp.localization.currentCulture.name
+ }).toLocaleString();
+ }
+ },
+ {
+ title: l('Price'),
+ data: "price"
+ },
+ {
+ title: l('CreationTime'),
+ data: "creationTime",
+ render: function (data) {
+ return luxon
+ .DateTime
+ .fromISO(data, {
+ locale: abp.localization.currentCulture.name
+ }).toLocaleString(luxon.DateTime.DATETIME_SHORT);
+ }
+ }
+ ]
+ })
+ );
+
+ createModal.onResult(function () {
+ dataTable.ajax.reload();
+ });
+
+ editModal.onResult(function () {
+ dataTable.ajax.reload();
+ });
+
+ $('#NewBookButton').click(function (e) {
+ e.preventDefault();
+ createModal.open();
+ });
+});
+```
+
+## Conclusion
+
+With a multi-lingual application, you can expand your market share, but if not designed well, may your application will be unusable. So, I've tried to explain how to design a sustainable multi-lingual entity in this article.
+
+### Source Code
+
+You can find source code of the example solution used in this article [here](https://github.com/abpframework/abp-samples/tree/master/AcmeBookStoreMultiLingual).
diff --git a/docs/en/Community-Articles/15-08-2022-How-to-Design-Multi-Lingual-Entity/data-model.png b/docs/en/Community-Articles/15-08-2022-How-to-Design-Multi-Lingual-Entity/data-model.png
new file mode 100644
index 0000000000..c7e02bc2cd
Binary files /dev/null and b/docs/en/Community-Articles/15-08-2022-How-to-Design-Multi-Lingual-Entity/data-model.png differ
diff --git a/docs/en/Community-Articles/15-08-2022-How-to-Design-Multi-Lingual-Entity/result.gif b/docs/en/Community-Articles/15-08-2022-How-to-Design-Multi-Lingual-Entity/result.gif
new file mode 100644
index 0000000000..0bc41cb8f1
Binary files /dev/null and b/docs/en/Community-Articles/15-08-2022-How-to-Design-Multi-Lingual-Entity/result.gif differ
diff --git a/docs/en/Community-Articles/2020-09-09-Replacing-Email-Template-and-Sending-Emails/POST.md b/docs/en/Community-Articles/2020-09-09-Replacing-Email-Template-and-Sending-Emails/POST.md
index 049171731b..f412ca3170 100644
--- a/docs/en/Community-Articles/2020-09-09-Replacing-Email-Template-and-Sending-Emails/POST.md
+++ b/docs/en/Community-Articles/2020-09-09-Replacing-Email-Template-and-Sending-Emails/POST.md
@@ -335,7 +335,7 @@ After sending the email we should see the template like below.
-
Share your experiences with the ABP Framework!
ABP is an open source and community driven project. This guide is aims to help anyone wants to contribute to the project.
+
Share your experiences with the ABP Framework!
ABP is an open source and community driven project. This guide is aimed to help anyone who wants to contribute to the project.
If you want to write articles or "how to" guides related to the ABP Framework and ASP.NET Core, please submit your article to the community.abp.io web site.
diff --git a/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 b/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
index 308358bb67..8e46bd6944 100644
--- a/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
+++ b/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
@@ -1,9 +1,13 @@
# How to Add Custom Properties to the User Entity
+> **Note:** If your application is greater than version 4.3.3, please follow [this article](../2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/How-To-Add-Custom-Property-To-The-User-Entity.md).
+
## Introduction
In this step-by-step article, I will explain how you can customize the user entity class, which is available in every web application you create using the ABP framework, according to your needs. When you read this article, you will learn how to override the services of built-in modules, extend the entities, extend data transfer objects and customize the user interface in the applications you develop using the ABP framework.
+> **Note:** This article is not about customizing the `Login` page. If you have such a need, please follow [this article](../2020-05-09-Customize-the-Login-Page-for-MVC-Razor-Page-Applications/POST.md).
+
You can see the screenshots below which we will reach at the end of the article.

diff --git a/docs/en/Community-Articles/2022-02-06-How-to-Hide-ABP-Related-Endpoints-on-Swagger-UI/POST.md b/docs/en/Community-Articles/2022-02-06-How-to-Hide-ABP-Related-Endpoints-on-Swagger-UI/POST.md
index 056c14c6e7..a6ad7596d4 100644
--- a/docs/en/Community-Articles/2022-02-06-How-to-Hide-ABP-Related-Endpoints-on-Swagger-UI/POST.md
+++ b/docs/en/Community-Articles/2022-02-06-How-to-Hide-ABP-Related-Endpoints-on-Swagger-UI/POST.md
@@ -425,4 +425,26 @@ That's it. Now we can open the Setting Management page and enable/disable the sw

-Thanks for reading.
+---
+
+## July 2022 Update
+
+With ABP v5.2+, there is a built-in option to hide/show ABP related endpoints on runtime. To hide ABP's default endpoints, call the `HideAbpEndpoints` method in your Swagger configuration as below:
+
+```csharp
+services.AddAbpSwaggerGen(
+ options =>
+ {
+ //... other options
+
+ //Hides ABP Related endpoints on Swagger UI
+ options.HideAbpEndpoints();
+ }
+)
+```
+
+> For more info, please see the [Swagger Integration](https://docs.abp.io/en/abp/latest/API/Swagger-Integration#hide-abp-endpoints-on-swagger-ui) docs.
+
+---
+
+Thanks for reading.
\ No newline at end of file
diff --git a/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/How-To-Add-Custom-Property-To-The-User-Entity.md b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/How-To-Add-Custom-Property-To-The-User-Entity.md
new file mode 100644
index 0000000000..7c119c6e66
--- /dev/null
+++ b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/How-To-Add-Custom-Property-To-The-User-Entity.md
@@ -0,0 +1,154 @@
+# How to Add Custom Properties to the User Entity
+
+> **Note:** If your application is less than version 4.4.x, please follow [this article](../2020-10-08-How-To-Add-Custom-Property-To-The-User-Entity/How-To-Add-Custom-Property-To-The-User-Entity.md).
+
+## Introduction
+
+In this step-by-step article, I will explain how you can customize the user entity class, which is available in every web application you create using the ABP framework, according to your needs. When you read this article, you will learn how to override the services of built-in modules, extend the entities, extend data transfer objects and customize the user interface in the applications you develop using the ABP framework.
+
+> **Note:** This article is not about customizing the `Login` page. If you have such a need, please follow [this article](../2020-05-09-Customize-the-Login-Page-for-MVC-Razor-Page-Applications/POST.md).
+
+You can see the screenshots below which we will reach at the end of the article.
+
+
+
+
+
+## Preparing the Project
+
+### Startup template and the initial run
+
+Abp Framework offers startup templates to get into the work faster. We can create a new startup template using Abp CLI:
+
+`abp new CustomizeUserDemo`
+
+> In this article, I will go through the MVC application, but it will work also in the [Angular](https://docs.abp.io/en/abp/latest/Getting-Started?UI=NG&DB=EF&Tiered=No), [Blazor Server](https://docs.abp.io/en/abp/latest/Getting-Started?UI=BlazorServer&DB=EF&Tiered=No), and [Blazor WebAssembly](https://docs.abp.io/en/abp/latest/Getting-Started?UI=Blazor&DB=EF&Tiered=No) application.
+
+After the download is finished, we can run **CustomizeUserDemo.DbMigrator** project to create the database migrations and seed the initial data (admin user, role, etc). Then we can run `CustomizeUserDemo.Web` to see that our application is working.
+
+> Default admin username is **admin** and password is **1q2w3E\***
+
+
+
+In this article, we will go through a scenario together and find the solutions to our questions through this scenario. However, since the scenario is not a real-life scenario, it may be strange, please don't get too about this issue :)
+
+## Step-1
+
+Create the Users folder in the **CustomizeUserDemo.Domain.Shared** project, create the class `UserConsts` inside the folder and update the class you created as below:
+
+```csharp
+public static class UserConsts
+{
+ public const string TitlePropertyName = "Title";
+
+ public const string ReputationPropertyName = "Reputation";
+
+ public const int MaxTitleLength = 64;
+
+ public const double MaxReputationValue = 1_000;
+
+ public const double MinReputationValue = 1;
+}
+```
+
+## Step-2
+
+Update the `CustomizeUserDemoEfCoreEntityExtensionMappings` class in the **CustomizeUserDemo.EntityFramework** project in the EntityFrameworkCore folder as below:
+
+```csharp
+public static class CustomizeUserDemoEfCoreEntityExtensionMappings
+{
+ private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
+
+ public static void Configure()
+ {
+ CustomizeUserDemoGlobalFeatureConfigurator.Configure();
+ CustomizeUserDemoModuleExtensionConfigurator.Configure();
+
+ OneTimeRunner.Run(() =>
+ {
+ ObjectExtensionManager.Instance
+ .MapEfCoreProperty(
+ UserConsts.TitlePropertyName,
+ (_, propertyBuilder) =>
+ {
+ propertyBuilder.HasDefaultValue("");
+ propertyBuilder.HasMaxLength(UserConsts.MaxTitleLength);
+ }
+ ).MapEfCoreProperty(
+ UserConsts.ReputationPropertyName,
+ (_, propertyBuilder) =>
+ {
+ propertyBuilder.HasDefaultValue(UserConsts.MinReputationValue);
+ }
+ );
+ });
+ }
+}
+```
+
+This class can be used to map these extra properties to table fields in the database. Please read [this](https://docs.abp.io/en/abp/latest/Customizing-Application-Modules-Extending-Entities) article to improve your understanding of what we are doing.
+
+So far, we have added our extra features to the `User` entity and matched these features with the `ef core`.
+
+Now we need to add migration to see what has changed in our database. This for, open the Package Manager Console (PMC) under the menu Tools > NuGet Package Manager.
+
+
+
+Select the **CustomizeUserDemo.EntityFramework** as the **default project** and execute the following command:
+
+```bash
+Add-Migration "Updated-User-Entity"
+```
+
+
+
+This will create a new migration class inside the `Migrations` folder of the **CustomizeUserDemo.EntityFrameworkCore** project.
+
+> If you are using another IDE than the Visual Studio, you can use `dotnet-ef` tool as [documented here](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli#create-a-migration).
+
+Finally, run the **CustomizeUserDemo.DbMigrator** project to update the database.
+
+When we updated the database, you can see that the `Title` and `Reputation` columns are added to the `Users` table.
+
+
+
+## Step-3
+Open the `CustomizeUserDemoModuleExtensionConfigurator` in the **CustomizeUserDemo.Domain.Shared** project, and change the contents of the `ConfigureExtraProperties` method as shown below:
+```csharp
+private static void ConfigureExtraProperties()
+{
+ ObjectExtensionManager.Instance.Modules().ConfigureIdentity(identity =>
+ {
+ identity.ConfigureUser(user =>
+ {
+ user.AddOrUpdateProperty(
+ UserConsts.TitlePropertyName,
+ options =>
+ {
+ options.Attributes.Add(new RequiredAttribute());
+ options.Attributes.Add(
+ new StringLengthAttribute(UserConsts.MaxTitleLength)
+ );
+ }
+ );
+ user.AddOrUpdateProperty(
+ UserConsts.ReputationPropertyName,
+ options =>
+ {
+ options.DefaultValue = UserConsts.MinReputationValue;
+ options.Attributes.Add(
+ new RangeAttribute(UserConsts.MinReputationValue, UserConsts.MaxReputationValue)
+ );
+ }
+ );
+ });
+ });
+}
+```
+
+That's it. Now let's run the application and look at the Identity user page. You can also try to edit and recreate a record if you want, it will work even though we haven't done anything extra. Here is the magic code behind ABP framework.
+
+If there is a situation you want to add, you can click the contribute button or make a comment. Also, if you like the article, don't forget to share it :)
+
+Happy coding :)
diff --git a/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/added-new-migration.png b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/added-new-migration.png
new file mode 100755
index 0000000000..d459fdeed2
Binary files /dev/null and b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/added-new-migration.png differ
diff --git a/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/custom-identity-user-list.png b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/custom-identity-user-list.png
new file mode 100644
index 0000000000..896ed947aa
Binary files /dev/null and b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/custom-identity-user-list.png differ
diff --git a/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/initial-project.png b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/initial-project.png
new file mode 100755
index 0000000000..b64e93a99f
Binary files /dev/null and b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/initial-project.png differ
diff --git a/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/new-user.png b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/new-user.png
new file mode 100644
index 0000000000..d3a5c66198
Binary files /dev/null and b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/new-user.png differ
diff --git a/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/nuget-package-manager.png b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/nuget-package-manager.png
new file mode 100755
index 0000000000..680bc9d2e7
Binary files /dev/null and b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/nuget-package-manager.png differ
diff --git a/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/user-table.png b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/user-table.png
new file mode 100755
index 0000000000..5bb71b8325
Binary files /dev/null and b/docs/en/Community-Articles/2022-07-19-How-To-Add-Custom-Property-To-The-User-Entity/user-table.png differ
diff --git a/docs/en/Dependency-Injection.md b/docs/en/Dependency-Injection.md
index 668eac6644..a0ad342c4c 100644
--- a/docs/en/Dependency-Injection.md
+++ b/docs/en/Dependency-Injection.md
@@ -244,25 +244,35 @@ One restriction of property injection is that you cannot use the dependency in y
Property injection is also useful when you want to design a base class that has some common services injected by default. If you're going to use constructor injection, all derived classes should also inject depended services into their own constructors which makes development harder. However, be very careful using property injection for non-optional services as it makes it harder to clearly see the requirements of a class.
-### Resolve Service from IServiceProvider
+#### DisablePropertyInjectionAttribute
-You may want to resolve a service directly from ``IServiceProvider``. In that case, you can inject IServiceProvider into your class and use ``GetService`` method as shown below:
+You can use `[DisablePropertyInjection]` attribute on class or properties to disable property injection for the whole class or some specific properties.
````C#
+[DisablePropertyInjection]
public class MyService : ITransientDependency
{
- private readonly IServiceProvider _serviceProvider;
+ public ITaxCalculator TaxCalculator { get; set; }
+}
- public MyService(IServiceProvider serviceProvider)
- {
- _serviceProvider = serviceProvider;
- }
+public class MyService : ITransientDependency
+{
+ public ILogger Logger { get; set; }
- public void DoSomething()
- {
- var taxCalculator = _serviceProvider.GetService();
- //...
- }
+ [DisablePropertyInjection]
+ public ITaxCalculator TaxCalculator { get; set; }
+}
+
+````
+
+### Resolve Service from IServiceProvider
+
+You may want to resolve a service directly from ``IServiceProvider``. In that case, you can inject IServiceProvider into your class and use ``GetService`` method as shown below:
+
+````C#
+public class MyService : ITransientDependency
+{
+ public ILogger Logger { get; set; }
}
````
diff --git a/docs/en/Deploy-azure-app-service.md b/docs/en/Deploy-azure-app-service.md
new file mode 100644
index 0000000000..9e0309f3b9
--- /dev/null
+++ b/docs/en/Deploy-azure-app-service.md
@@ -0,0 +1,452 @@
+# Deploying ABP Project to Azure App Service
+
+In this document, you will learn how to create and deploy your first ABP web app to [Azure App Service](https://docs.microsoft.com/en-us/azure/app-service/overview). The App Service supports various versions of .NET apps, and provides a highly scalable, self-patching web hosting service. ABP web apps are cross-platform and can be hosted on Linux, Windows or MacOS.
+
+****Prerequisites****
+
+- An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/dotnet).
+- A GitHub account [Create an account for free](http://github.com/).
+
+
+
+## Creating a new ABP application
+
+Create a repository on [GitHub.com](https://github.com/) (keep all settings as default).
+
+Open the command prompt and clone the repository into a folder on your computer
+
+```bash
+git clone https://github.com/your-username/your-repository-name.git
+```
+
+Check your dotnet version. It should be at least 3.1.x
+
+```bash
+dotnet --version
+```
+
+Install or update the [ABP CLI](https://docs.abp.io/en/abp/latest/cli) with the following command:
+
+```bash
+dotnet tool install -g Volo.Abp.Cli || dotnet tool update -g Volo.Abp.Cli
+```
+
+Open the command prompt in the *GitHub repository folder* and create a new ABP Blazor solution with the command below:
+
+```bash
+abp new YourAppName -u blazor
+```
+
+
+
+## Running the application
+
+Open the command prompt in the *[YourAppName].DbMigrator* project and enter the command below to apply the database migrations:
+
+```bash
+dotnet run
+```
+
+Open the command prompt in the *[YourAppName].HttpApi.Host* project to run the API project:
+
+```bash
+dotnet run
+```
+
+Navigate to the *applicationUrl* specified in *the launchSettings.json* file of the *[YourAppName].HttpApi.Host project*. You should get the *Swagger window*
+
+Open the command prompt in the *[YourAppName].Blazor* folder and enter the command below to run the Blazor project:
+
+```bash
+dotnet run
+```
+
+Navigate to the *applicationUrl* specified in the *launchSettings.json* file of the *[YourAppName].Blazor* project and you should see the landing page.
+
+Stop both the *API* and the *Blazor* project by pressing **CTRL+C**
+
+
+
+## Committing to GitHub
+
+Before the GitHub commit, you have to delete the line "**/wwwroot/libs/*" at *.gitignore* file.
+
+
+
+Open the command prompt in the root folder of your project and *add, commit and push* all your changes to your GitHub repository:
+
+```bash
+git add .
+git commit -m initialcommit
+git push
+```
+
+
+
+## Configuring Azure database connection string
+
+Create a SQL database on Azure and change the connection string in all the *appsettings.json* files.
+
+* Login into [Azure Portal](https://portal.azure.com/)
+
+* Click **Create a resource**
+
+* Search for *SQL Database*
+
+* Click the **Create** button in the *SQL Database window*
+
+* Create a new resource group. Name it *rg[YourAppName]*
+
+* Enter *[YourAppName]Db* as database name
+
+* Create a new Server and name it *[yourappname]server*
+
+* Enter a serveradmin login and passwords. Click the **OK** button
+
+* Select your *Location*
+
+* Check *Allow Azure services to access server*
+
+* Click **Configure database**. Go to the *Basic* version and click the **Apply** button
+
+* Click the **Review + create** button. Click **Create**
+
+* Click **Go to resource** and click **SQL server** when the SQL Database is created
+
+* Click **Networking** under Security left side menu
+
+* Select **Selected networks** and click **Add your client IP$ address** at the Firewall rules
+
+* Select **Allow Azure and resources to access this seerver** and save
+
+* Go to your **SQL database**, click **Connection strings** and copy the connection string
+
+* Copy/paste the *appsettings.json* files of the *[YourAppName].HttpApi.Host* and the *[YourAppName].DbMigrator* project
+
+* Do not forget to replace {your_password} with the correct server password you entered in Azure SQL Database
+
+
+
+## Running DB Migrations
+
+Open the command prompt in the *[YourAppName].DbMigrator* project again and enter the command below to apply the database migrations:
+
+```bash
+dotnet run
+```
+
+Open the command prompt in the *[YourAppName].HttpApi.Host* project and enter the command below to check your API is working:
+
+```bash
+dotnet run
+```
+
+Stop the *[YourAppName].HttpApi.Host* by pressing CTRL+C.
+
+
+
+## Committing to GitHub
+
+Open the command prompt in the root folder of your project and add, commit and push all your changes to your GitHub repository
+
+```bash
+git add .
+git commit -m initialcommit
+git push
+```
+
+
+
+## Setting up the Build pipeline in AzureDevops and publish the Build Artifacts
+
+* Sign in Azure DevOps
+
+* Click **New organization** and follow the steps to create a new organisation. Name it [YourAppName]org
+
+* Enter [YourAppName]Proj as project name in the ***Create a project to get started*** window
+
+* Select **Public visibility** and click the **Create project** button
+
+* Click the **Pipelines** button to continue
+
+* Click the **Create Pipeline** button
+
+ Select GitHub in the Select your repository window
+
+
+
+* Enter the Connection name. *[YourAppName]GitHubConnection* and click **Authorize using OAuth**
+
+* Select your **GitHub** [YourAppName]repo and click Continue
+
+* Search for **ASP.NET** in the ***Select a template*** window
+
+
+
+* Select the ASP.NET Core template and click the **Apply** button
+
+* Add the below commands block as a first step in the pipeline
+
+ ```
+ - task: UseDotNet@2
+ inputs:
+ packageType: 'sdk'
+ version: '6.0.106'
+ ```
+
+
+
+* Select **Settings** on the second task(Nugetcommand@2) in the pipeline
+
+* Select **Feeds in my Nuget.config** and type **Nuget.config** in the text box
+
+
+
+* Add the below commands block to the end of the pipeline
+
+ ```
+ - task: PublishBuildArtifacts@1
+ displayName: 'Publish Artifact'
+ inputs:
+ PathtoPublish: '$(build.artifactstagingdirectory)'
+ ArtifactName: '$(Parameters.ArtifactName)'
+ condition: succeededOrFailed()
+ ```
+
+ 
+
+```
+# ASP.NET
+# Build and test ASP.NET projects.
+# Add steps that publish symbols, save build artifacts, deploy, and more:
+# https://docs.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4
+
+trigger:
+- main
+
+pool:
+ vmImage: 'windows-latest'
+
+variables:
+ solution: '**/*.sln'
+ buildPlatform: 'Any CPU'
+ buildConfiguration: 'Release'
+
+steps:
+- task: UseDotNet@2
+ inputs:
+ packageType: 'sdk'
+ version: '6.0.106'
+
+- task: NuGetToolInstaller@1
+
+- task: NuGetCommand@2
+ inputs:
+ command: 'restore'
+ restoreSolution: '$(solution)'
+ feedsToUse: 'config'
+ nugetConfigPath: 'NuGet.config'
+
+- task: VSBuild@1
+ inputs:
+ solution: '$(solution)'
+ msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"'
+ platform: '$(buildPlatform)'
+ configuration: '$(buildConfiguration)'
+
+- task: VSTest@2
+ inputs:
+ platform: '$(buildPlatform)'
+ configuration: '$(buildConfiguration)'
+
+- task: PublishBuildArtifacts@1
+ displayName: 'Publish Artifact'
+ inputs:
+ PathtoPublish: '$(build.artifactstagingdirectory)'
+ ArtifactName: '$(Parameters.ArtifactName)'
+ publishLocation: 'Container'
+ condition: succeededOrFailed()
+```
+
+* Click **Save & queue** in the top menu. Click **Save & queue** again and click **Save and run** to run the Build pipeline
+
+* When the Build pipeline has finished. Click **1 published; 1 consumed**
+
+
+
+## Creating a Web App in the Azure Portal to deploy [YourAppName].HttpApi.Host project
+
+* Search for Web App in the *Search the Marketplace* field
+
+* Click the **Create** button in the Web App window
+
+* Select rg[YourAppName] in the *Resource Group* dropdown
+
+* Enter [YourAppName]API in the *Name input* field
+
+* Select code, .NET Core 3.1 (LTS) and windows as *Operating System*
+
+* Enter [YourAppName]API in the *Name input* field
+
+* Select .NET Core 3.1 (LTS) in the *Runtime stack* dropdown
+
+* Select Windows as *Operating System*
+
+* Select the same *Region* as in the SQL server you created in Part 3
+
+
+
+* Click **Create new** in the Windows Plan. Name it [YourAppName]ApiWinPlan
+
+* Click **Change size** in Sku and size. Go to the Dev/Test Free F1 version and click the **Apply** button
+
+
+
+* Click the **Review + create** button. Click the **Create** button
+
+* Click **Go to resource** when the Web App has been created
+
+
+
+## Creating a release pipeline in the AzureDevops and deploy [YourAppName].HttpApi.Host project
+
+* Sign in into [Azure DevOps](https://azure.microsoft.com/en-us/services/devops/)
+
+* Click [YourAppName]Proj and click **Releases** in the *Pipelines* menu
+
+* Click the **New pipeline** button in the *No release pipelines found* window
+
+* Select *Azure App Service deployment* and click the **Apply** button
+
+
+
+* Enter *[YourAppName]staging* in the *Stage name* field in the *Stage* window. And close the window
+
+* Click **+ Add an artifact** in the *Pipeline* tab
+
+* Select the **Build** icon as *Source type* in the *Add an artifact* window
+
+* Select Build pipeline in the *Source (build pipeline)* dropdown and click the **Add** button
+
+
+
+* Click the **Continuous deployment trigger (thunderbolt icon)**
+
+* Set the toggle to **Enabled** in the the *Continuous deployment trigger* window
+
+* Click **+ Add** in *No filters added*. Select **Include** in the *Type* dropdown. Select your branch in the *Build branch* dropdown and close the window
+
+
+
+* Click **the little red circle with the exclamation mark** in the *Tasks* tab menu
+
+* Select your subscription in the *Azure subscription* dropdown.
+
+
+
+* Click **Authorize** and enter your credentials in the next screens
+
+* After Authorization, select the **[YourAppName]API** in the *App service name* dropdown
+
+* Click the **Deploy Azure App Service** task
+
+* Select **[YourAppName].HttpApi.Host.zip** in the *Package or folder* input field
+
+
+
+* Click the **Save** icon in the top menu and click **OK**
+
+* Click **Create release** in the top menu. Click **Create** to create a release
+
+* Click the *Pipeline* tab and wait until the Deployment succeeds
+
+
+
+* Open a browser and navigate to the URL of your Web App
+
+```
+https://[YourAppName]api.azurewebsites.net
+```
+
+
+
+
+
+## Creating a Web App in Azure Portal to deploy [YourAppName].Blazor project
+
+* Login into [Azure Portal](https://portal.azure.com/)
+
+* Click **Create a resource**
+
+* Search for *Web App* in the *Search the Marketplace* field
+
+* Click the **Create** button in the *Web App* window
+
+* Select *rg[YourAppName]* in the *Resource Group* dropdown
+
+* Enter *[YourAppName]Blazor* in the *Name* input field
+
+* Select *.NET Core 3.1 (LTS)* in the *Runtime stack* dropdown
+
+* Select *Windows* as *Operating System*
+
+* Select the same region as the SQL server you created in Part 3
+
+* Select the [YourAppName]ApiWinPlan in the *Windows Plan* dropdown
+
+
+
+* Click the **Review + create** button. Click **Create** button
+
+* Click **Go to resource** when the Web App has been created
+
+* Copy the URL of the Blazor Web App for later use
+
+```
+https://[YourAppName]blazor.azurewebsites.net
+```
+
+
+## Changing the Web App configuration for the Azure App Service
+
+Copy the URL of the Api Host and Blazor Web App. Change appsettings.json files in the Web App as follows images.
+
+
+
+
+
+
+
+
+
+## Adding an extra Stage in the Release pipeline in the AzureDevops to deploy [YourAppName].Blazor project
+
+* Go to the *Release* pipeline in [Azure DevOps](https://azure.microsoft.com/en-us/services/devops/) and click **Edit**
+
+* Click the **+ Add** link and add a **New Stage**
+
+
+
+* Select *Azure App Service deployment* and click the **Apply** button
+
+* Enter *BlazorDeployment* in the *Stage name* input field and close the *Stage* window
+
+* Click the **little red circle with the exclamation mark** in the BlazorDeployment stage
+
+* Select your subscription in the *Azure subscription* dropdown
+
+* Select your Blazor Web App in the *App service name* dropdown
+
+* Click the **Deploy Azure App Service task**
+
+* Select *[YourAppName].Blazor.zip* in the *Package or folder* input field
+
+
+
+* Click **Save** in the top menu and click the **OK** button after
+
+* Click **Create release** in the top menu and click the **Create** button
+
+
+
+
diff --git a/docs/en/Deployment/Index.md b/docs/en/Deployment/Index.md
index dc1cca300e..6503f8b664 100644
--- a/docs/en/Deployment/Index.md
+++ b/docs/en/Deployment/Index.md
@@ -6,4 +6,4 @@ However, there are some topics that you should care about when you are deploying
## Guides
-* [Deploying to a clustered environment](Clustered-Environment.md): Explains how to configure your application when you want to run multiple instances of your application concurrently.
\ No newline at end of file
+* [Deploying to a clustered environment](Clustered-Environment.md): Explains how to configure your application when you want to run multiple instances of your application concurrently.
diff --git a/docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md b/docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md
index 3d99e1e3cf..4823cbaae9 100644
--- a/docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md
+++ b/docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md
@@ -86,7 +86,7 @@ Defining multiple connections is allowed. In this case, you can specify the conn
This allows you to use multiple RabbitMQ server in your application, but select one of them for the event bus.
-You can use any of the [ConnectionFactry](http://rabbitmq.github.io/rabbitmq-dotnet-client/api/RabbitMQ.Client.ConnectionFactory.html#properties) properties as the connection properties.
+You can use any of the [ConnectionFactory](http://rabbitmq.github.io/rabbitmq-dotnet-client/api/RabbitMQ.Client.ConnectionFactory.html#properties) properties as the connection properties.
**Example: Specify the connection port**
@@ -141,14 +141,15 @@ Configure(options =>
});
````
-**Example: Configure the client and exchange names**
+**Example: Configure the client, exchange names and prefetchCount**
````csharp
Configure(options =>
{
options.ClientName = "TestApp1";
options.ExchangeName = "TestMessages";
+ options.PrefetchCount = 1;
});
````
-Using these options classes can be combined with the `appsettings.json` way. Configuring an option property in the code overrides the value in the configuration file.
\ No newline at end of file
+Using these options classes can be combined with the `appsettings.json` way. Configuring an option property in the code overrides the value in the configuration file.
diff --git a/docs/en/Distributed-Event-Bus.md b/docs/en/Distributed-Event-Bus.md
index 5fe85a468d..21b1b07256 100644
--- a/docs/en/Distributed-Event-Bus.md
+++ b/docs/en/Distributed-Event-Bus.md
@@ -228,7 +228,7 @@ namespace AbpDemo
````
* `MyHandler` implements the `IDistributedEventHandler>`.
-* It is required to register your handler class to the [dependency injection](Dependency-Injection.md) system. Implementing `ITransient` like in this example is an easy way.
+* It is required to register your handler class to the [dependency injection](Dependency-Injection.md) system. Implementing `ITransientDependency` like in this example is an easy way.
### Configuration
diff --git a/docs/en/Entities.md b/docs/en/Entities.md
index c57af27457..ef8f52a04f 100644
--- a/docs/en/Entities.md
+++ b/docs/en/Entities.md
@@ -112,6 +112,21 @@ For the example above, the composite key is composed of `UserId` and `RoleId`. F
> Also note that Entities with Composite Primary Keys cannot utilize the `IRepository` interface since it requires a single Id property. However, you can always use `IRepository`. See [repositories documentation](Repositories.md) for more.
+### EntityEquals
+
+`Entity.EntityEquals(...)` method is used to check if two Entity Objects are equals.
+
+Example:
+
+```csharp
+Book book1 = ...
+Book book2 = ...
+
+if (book1.EntityEquals(book2)) //Check equality
+{
+ ...
+}
+```
## AggregateRoot Class
diff --git a/docs/en/Getting-Started-AspNetCore-Application.md b/docs/en/Getting-Started-AspNetCore-Application.md
index 0ccd900b1f..c7f329878c 100644
--- a/docs/en/Getting-Started-AspNetCore-Application.md
+++ b/docs/en/Getting-Started-AspNetCore-Application.md
@@ -77,7 +77,7 @@ using BasicAspNetCoreApplication;
var builder = WebApplication.CreateBuilder(args);
-await builder.Services.AddApplicationAsync();
+await builder.AddApplicationAsync();
var app = builder.Build();
@@ -85,7 +85,7 @@ await app.InitializeApplicationAsync();
await app.RunAsync();
````
-``builder.Services.AddApplicationAsync();`` adds all services defined in all modules starting from the ``AppModule``.
+``builder.AddApplicationAsync();`` adds all services defined in all modules starting from the ``AppModule``.
``app.InitializeApplicationAsync()`` initializes and starts the application.
@@ -125,7 +125,7 @@ var builder = WebApplication.CreateBuilder(args);
builder.Host.UseAutofac(); //Add this line
-await builder.Services.AddApplicationAsync();
+await builder.AddApplicationAsync();
var app = builder.Build();
diff --git a/docs/en/Getting-Started-Running-Solution.md b/docs/en/Getting-Started-Running-Solution.md
index 66230c7aef..44fbd3eb03 100644
--- a/docs/en/Getting-Started-Running-Solution.md
+++ b/docs/en/Getting-Started-Running-Solution.md
@@ -163,6 +163,8 @@ You can see the application APIs and test them here. Get [more info](https://swa
### Running the Blazor Application (Client Side)
+Go to the Blazor project folder, open a command line terminal, type the `abp bundle -f` command (If the project was created by ABP Cli tool, you don't need to do this).
+
Ensure that the `.Blazor` project is the startup project and run the application.
> 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.
diff --git a/docs/en/Migration-Guides/Abp-6_0.md b/docs/en/Migration-Guides/Abp-6_0.md
new file mode 100644
index 0000000000..1436990e56
--- /dev/null
+++ b/docs/en/Migration-Guides/Abp-6_0.md
@@ -0,0 +1,29 @@
+# ABP Version 6.0 Migration Guide
+
+This document is a guide for upgrading ABP v5.3 solutions to ABP v6.0. There is a change in this version that may affect your applications, please read it carefully and apply the necessary changes to your application.
+
+## Added IsActive property
+
+`IsActive` property is added to `IUserData`. This property is set to **true** by default. **Cmskit** and **Blog** modules are affected by this change. You need to add new migration to your existing application if you are using any of these modules. Please see [#11417](https://github.com/abpframework/abp/pull/11417) for more info.
+
+## Default behavior change in MultiTenancyMiddlewareErrorPageBuilder
+
+If you have customized the `MultiTenancyMiddlewareErrorPageBuilder` of `AbpMultiTenancyOptions`, the pipeline now returns **true** to stop the pipeline as the default behavior. See [AbpMultiTenancyOptions: Handle inactive and non-existent tenants](https://github.com/abpframework/abp/blob/dev/docs/en/Multi-Tenancy.md#abpmultitenancyoptions-handle-inactive-and-non-existent-tenants) for more info.
+
+## Migrating to LeptonX Lite
+
+LeptonX Lite is now being introduced and you can follow the guides below to migrate your existing applications:
+
+- [Migrating to LeptonX MVC UI](../themes/LeptonXLite/AspNetCore.md)
+- [Migrating to LeptonX Angular UI](../themes/LeptonXLite/angular.md)
+- [Migrating to LeptonX Blazor UI](../themes/LeptonXLite/blazor.md)
+
+## Migrating to OpenIddict
+
+After the [announcement of plan to replace the IdentityServer](https://github.com/abpframework/abp/issues/11989), we have successfully implemented [Openiddict](https://github.com/openiddict/openiddict-core) as a replacement for IdentityServer4 as an OpenID-Provider.
+
+You can follow the [IdentityServer to OpenIddict Step by Step Guide](OpenIddict-Step-by-Step.md) for migrating your existing application in detail with a sample projects.
+
+## See Also
+
+* [Official blog post for the 6.0 release](https://blog.abp.io/abp/ABP.IO-Platform-6.0-RC-Has-Been-Published)
diff --git a/docs/en/Migration-Guides/IdentityServer_To_OpenIddict.md b/docs/en/Migration-Guides/IdentityServer_To_OpenIddict.md
new file mode 100644
index 0000000000..a4baa79d9f
--- /dev/null
+++ b/docs/en/Migration-Guides/IdentityServer_To_OpenIddict.md
@@ -0,0 +1,78 @@
+# Migration Identity Server to OpenIddict Guide
+
+This document explains how to migrate to [OpenIddict](https://github.com/openiddict/openiddict-core) from Identity Server. From now on the ABP startup templates uses `OpenIddict` as the auth server by default since version v6.0.0.
+
+## History
+We are not removing Identity Server packages and we will continue to release new versions of Identity Server related NuGet/NPM packages. That means you won't have an issue while upgrading to v6.0 when the stable version releases. We will continue to fix bugs in our packages for a while. ABP 7.0 will be based on .NET 7. If Identity Server continues to work with .NET 7, we will also continue to ship NuGet packages for our IDS integration.
+
+On the other hand, Identity Server ends support for the open-source Identity Server in the end of 2022. The Identity Server team has decided to move to Duende IDS and ABP will not be migrated to the commercial Duende IDS. You can see the Duende Identity Server announcement from [this link](https://blog.duendesoftware.com/posts/20220111_fair_trade).
+
+## OpenIddict Migration Steps
+
+* Update all `Volo's` packages to `6.x`.
+* Replace all `Volo's` `IdentityServer.*` packages with corresponding `OpenIddict.*` packages. eg `Volo.Abp.IdentityServer.Domain` to `Volo.Abp.OpenIddict.Domain`, `Volo.Abp.Account.Web.IdentityServer` to `Volo.Abp.Account.Web.OpenIddict`.
+* Replace all `IdentityServer` modules with corresponding `OpenIddict` modules. eg `AbpIdentityServerDomainModule` to `AbpOpenIddictDomainModule`, `AbpAccountWebIdentityServerModule` to `AbpAccountWebOpenIddictModule`.
+* Rename the `ConfigureIdentityServer` to `ConfigureOpenIddict` in your `ProjectNameDbContext` class.
+* Remove the `UseIdentityServer` and add `UseAbpOpenIddictValidation` after `UseAuthentication`.
+* Add follow code to your startup module.
+
+```cs
+public override void PreConfigureServices(ServiceConfigurationContext context)
+{
+ PreConfigure(builder =>
+ {
+ builder.AddValidation(options =>
+ {
+ options.AddAudiences("ProjectName"); // Change ProjectName to your project name.
+ options.UseLocalServer();
+ options.UseAspNetCore();
+ });
+ });
+}
+```
+
+* If your project is not separate AuthServer please also add `ForwardIdentityAuthenticationForBearer`
+
+```cs
+private void ConfigureAuthentication(ServiceConfigurationContext context)
+{
+ context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
+}
+```
+
+* Remove the `IdentityServerDataSeedContributor` from the `Domain` project.
+* Create a new version of the project, with the same name as your existing project.
+* Copy the `ProjectName.Domain\OpenIddict\OpenIddictDataSeedContributor.cs` of new project into your project and update `appsettings.json` base on `ProjectName.DbMigrator\appsettings.json`, Be careful to change the port number.
+* Copy the `Index.cshtml.cs` and `Index.cs` of new project to your project if you're using `IClientRepository` in `IndexModel`.
+* Update the scope name from `role` to `roles` in `AddAbpOpenIdConnect` method.
+* Remove `options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]);` from `HttpApi.Host` project.
+* AuthServer no longer requires `JWT bearer authentication`. Please remove it. eg `AddJwtBearer` and `UseJwtTokenMiddleware`.
+* Try compiling the project in the IDE and following the errors to remove and reference the code and namespaces.
+* Add migrations and update the database if you are using EF Core as the database provider.
+
+## Module packages
+### Open source side
+* Volo.Abp.OpenIddict.Domain (`AbpOpenIddictDomainModule`)
+* Volo.Abp.OpenIddict.Domain.Shared (`AbpOpenIddictDomainSharedModule`)
+* Volo.Abp.OpenIddict.EntityFrameworkCore (`AbpOpenIddictEntityFrameworkCoreModule`)
+* Volo.Abp.OpenIddict.AspNetCore (`AbpOpenIddictAspNetCoreModule`)
+* Volo.Abp.OpenIddict.MongoDB (`AbpOpenIddictMongoDbModule`)
+* Volo.Abp.Account.Web.OpenIddict (`AbpAccountWebOpenIddictModule`)
+* Volo.Abp.PermissionManagement.Domain.OpenIddict (`AbpPermissionManagementDomainOpenIddictModule`)
+
+### Commercial side
+* Volo.Abp.OpenIddict.Pro.Application.Contracts (`AbpOpenIddictProApplicationContractsModule`)
+* Volo.Abp.OpenIddict.Pro.Application (`AbpOpenIddictProApplicationModule`)
+* Volo.Abp.OpenIddict.Pro.HttpApi.Client (`AbpOpenIddictProHttpApiClientModule`)
+* Volo.Abp.OpenIddict.Pro.HttpApi (`AbpOpenIddictProHttpApiModule`)
+* Volo.Abp.OpenIddict.Pro.Blazor(`AbpOpenIddictProBlazorModule`)
+* Volo.Abp.OpenIddict.Pro.Blazor.Server (`AbpOpenIddictProBlazorServerModule`)
+* Volo.Abp.OpenIddict.Pro.Blazor.WebAssembly (`AbpOpenIddictProBlazorWebAssemblyModule`)
+* Volo.Abp.OpenIddict.Pro.Web (`AbpOpenIddictProWebModule`)
+
+## Source code of samples and module
+
+* [Open source tiered & separate auth server application migrate Identity Server to OpenIddct](https://github.com/abpframework/abp-samples/tree/master/Ids2OpenId)
+* [Commercial tiered & separate auth server application migrate Identity Server to OpenIddct](https://abp.io/Account/Login?returnUrl=/api/download/samples/Ids2OpenId)
+* [OpenIddict module document](https://docs.abp.io/en/abp/6.0/Modules/OpenIddict)
+* [OpenIddict module source code](https://github.com/abpframework/abp/tree/rel-6.0/modules/openiddict)
diff --git a/docs/en/Migration-Guides/Index.md b/docs/en/Migration-Guides/Index.md
index c24ac09eee..e3ea77db1f 100644
--- a/docs/en/Migration-Guides/Index.md
+++ b/docs/en/Migration-Guides/Index.md
@@ -2,6 +2,7 @@
The following documents explain how to migrate your existing ABP applications. We write migration documents only if you need to take an action while upgrading your solution. Otherwise, you can easily upgrade your solution using the [abp update command](../Upgrading.md).
+- [5.3 to 6.0](Abp-6_0.md)
- [5.2 to 5.3](Abp-5_3.md)
- [5.1 to 5.2](Abp-5_2.md)
- [4.x to 5.0](Abp-5_0.md)
diff --git a/docs/en/Migration-Guides/OpenIddict-Angular.md b/docs/en/Migration-Guides/OpenIddict-Angular.md
new file mode 100644
index 0000000000..e8d34cb5fc
--- /dev/null
+++ b/docs/en/Migration-Guides/OpenIddict-Angular.md
@@ -0,0 +1,170 @@
+# OpenIddict Angular UI Migration Guide
+
+## Angular Project
+
+- In `environment.ts` and `environment.prod.ts` **add a trailing slash at the end of the issuer**:
+
+ ```typescript
+ oAuthConfig: {
+ issuer: 'https://localhost:44377/',
+ ...
+ },
+ ```
+
+## Http.Api.Host (Non-Separated IdentityServer)
+
+- In **MyApplication.HttpApi.Host.csproj** replace **project references**:
+
+ ```csharp
+
+
+ ```
+
+ with
+
+ ```csharp
+
+ ```
+
+- In the **MyApplicationHttpApiHostModule.cs** replace usings and **module dependencies**:
+
+ ```csharp
+ using Volo.Abp.AspNetCore.Authentication.JwtBearer;
+ ...
+ typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
+ typeof(AbpAccountWebIdentityServerModule),
+ ```
+
+ with
+
+ ```csharp
+ using OpenIddict.Validation.AspNetCore;
+ ...
+ typeof(AbpAccountWebOpenIddictModule),
+ ```
+
+- In the **MyApplicationHttpApiHostModule.cs** add `PreConfigureServices` like below with your application name as the audience:
+
+ ```csharp
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(builder =>
+ {
+ builder.AddValidation(options =>
+ {
+ options.AddAudiences("MyApplication"); // Replace with your application name
+ options.UseLocalServer();
+ options.UseAspNetCore();
+ });
+ });
+ }
+ ```
+
+- In the **MyApplicationHttpApiHostModule.cs** `ConfigureServices` method, **replace the method call**:
+
+ From `ConfigureAuthentication(context, configuration);` to `ConfigureAuthentication(context);` and update the method as:
+
+ ```csharp
+ private void ConfigureAuthentication(ServiceConfigurationContext context)
+ {
+ context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
+ }
+ ```
+
+- In the **MyApplicationHttpApiHostModule.cs** `OnApplicationInitialization` method, **replace the midware**:
+
+ ```csharp
+ app.UseJwtTokenMiddleware();
+ app.UseIdentityServer();
+ ```
+
+ with
+
+ ```csharp
+ app.UseAbpOpenIddictValidation();
+ ```
+
+- In the **MyApplicationHttpApiHostModule.cs** `OnApplicationInitialization` method, delete `c.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]);` in `app.UseAbpSwaggerUI` options configurations which is no longer needed.
+
+- In `appsettings.json` delete **SwaggerClientSecret** from the *AuthServer* section like below:
+
+ ```json
+ "AuthServer": {
+ "Authority": "https://localhost:44345",
+ "RequireHttpsMetadata": "false",
+ "SwaggerClientId": "MyApplication_Swagger"
+ },
+ ```
+
+## Http.Api.Host (Separated IdentityServer)
+
+- In the **MyApplicationHttpApiHostModule.cs** `OnApplicationInitialization` method, delete `c.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]);` in `app.UseAbpSwaggerUI` options configurations which is no longer needed.
+
+- In `appsettings.json` delete **SwaggerClientSecret** from the *AuthServer* section like below:
+
+ ```json
+ "AuthServer": {
+ "Authority": "https://localhost:44345",
+ "RequireHttpsMetadata": "false",
+ "SwaggerClientId": "MyApplication_Swagger"
+ },
+ ```
+
+## IdentityServer
+
+This project is renamed to **AuthServer** after v6.0.0-rc1. You can also refactor and rename your project to *AuthServer* for easier updates in the future.
+
+- In **MyApplication.IdentityServer.csproj** replace **project references**:
+
+ ```csharp
+
+ ```
+
+ with
+
+ ```csharp
+
+ ```
+
+- In the **MyApplicationIdentityServerModule.cs** replace usings and **module dependencies**:
+
+ ```csharp
+ typeof(AbpAccountWebIdentityServerModule),
+ ```
+
+ with
+
+ ```csharp
+ typeof(AbpAccountWebOpenIddictModule),
+ ```
+
+- In the **MyApplicationIdentityServerModule.cs** add `PreConfigureServices` like below with your application name as the audience:
+
+ ```csharp
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(builder =>
+ {
+ builder.AddValidation(options =>
+ {
+ options.AddAudiences("MyApplication"); // Replace with your application name
+ options.UseLocalServer();
+ options.UseAspNetCore();
+ });
+ });
+ }
+ ```
+
+- In the **MyApplicationIdentityServerModule.cs** `OnApplicationInitialization` method, **remove the midware**:
+
+ ```csharp
+ app.UseIdentityServer();
+ ```
+
+- To use the new AuthServer page, replace **Index.cshtml.cs** with [AuthServer Index.cshtml.cs](https://github.com/abpframework/abp-samples/blob/master/Ids2OpenId/src/Ids2OpenId.IdentityServer/Pages/Index.cshtml) and **Index.cshtml** file with [AuthServer Index.cshtml](https://github.com/abpframework/abp-samples/blob/master/Ids2OpenId/src/Ids2OpenId.IdentityServer/Pages/Index.cshtml.cs) and rename **Ids2OpenId** with your application namespace.
+
+ > Note: It can be found under the *Pages* folder.
+
+## See Also
+
+* [OpenIddict Step-by-Step Guide](OpenIddict-Step-by-Step.md)
diff --git a/docs/en/Migration-Guides/OpenIddict-Blazor-Server.md b/docs/en/Migration-Guides/OpenIddict-Blazor-Server.md
new file mode 100644
index 0000000000..4db4556479
--- /dev/null
+++ b/docs/en/Migration-Guides/OpenIddict-Blazor-Server.md
@@ -0,0 +1,175 @@
+# OpenIddict Blazor-Server UI Migration Guide
+
+## Blazor Project (Non-Tiered Solution)
+
+- In the **MyApplication.Blazor.csproj** replace **project references**:
+
+ ```csharp
+
+
+ ```
+
+ with
+
+ ```csharp
+
+ ```
+
+- In the **MyApplicationBlazorModule.cs** replace usings and **module dependencies**:
+
+ ```csharp
+ using System;
+ using System.Net.Http;
+ using Volo.Abp.AspNetCore.Authentication.JwtBearer;
+ ...
+ typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
+ typeof(AbpAccountWebIdentityServerModule),
+ ```
+
+ with
+
+ ```csharp
+ using OpenIddict.Validation.AspNetCore;
+ ...
+ typeof(AbpAccountWebOpenIddictModule),
+ ```
+
+- In the **MyApplicationBlazorModule.cs** add `PreConfigureServices` like below with your application name as the audience:
+
+ ```csharp
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(builder =>
+ {
+ builder.AddValidation(options =>
+ {
+ options.AddAudiences("MyApplication"); // Replace with your application name
+ options.UseLocalServer();
+ options.UseAspNetCore();
+ });
+ });
+ }
+ ```
+
+- In the **MyApplicationBlazorModule.cs** `ConfigureServices` method, **replace the method call**:
+
+ From `ConfigureAuthentication(context, configuration);` to `ConfigureAuthentication(context);` and update the method as:
+
+ ```csharp
+ private void ConfigureAuthentication(ServiceConfigurationContext context)
+ {
+ context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
+ }
+ ```
+
+- In the **MyApplicationBlazorModule.cs** `OnApplicationInitialization` method, **replace the midware**:
+
+ ```csharp
+ app.UseJwtTokenMiddleware();
+ app.UseIdentityServer();
+ ```
+
+ with
+
+ ```csharp
+ app.UseAbpOpenIddictValidation();
+ ```
+
+## Blazor Project (Tiered Solution)
+
+- In the **MyApplicationWebModule.cs** update the `AddAbpOpenIdConnect` configurations:
+
+ ```csharp
+ .AddAbpOpenIdConnect("oidc", options =>
+ {
+ options.Authority = configuration["AuthServer:Authority"];
+ options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
+ options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
+
+ options.ClientId = configuration["AuthServer:ClientId"];
+ options.ClientSecret = configuration["AuthServer:ClientSecret"];
+
+ options.SaveTokens = true;
+ options.GetClaimsFromUserInfoEndpoint = true;
+
+ options.Scope.Add("roles"); // Replace "role" with "roles"
+ options.Scope.Add("email");
+ options.Scope.Add("phone");
+ options.Scope.Add("MyApplication");
+ });
+ ```
+
+ Replace **role** scope with **roles**.
+
+## IdentityServer
+
+This project is renamed to **AuthServer** after v6.0.0-rc1. You can also refactor and rename your project to *AuthServer* for easier updates in the future.
+
+- In **MyApplication.IdentityServer.csproj** replace **project references**:
+
+ ```csharp
+
+ ```
+
+ with
+
+ ```csharp
+
+ ```
+
+- In **MyApplicationIdentityServerModule.cs** replace usings and **module dependencies**:
+
+ ```csharp
+ typeof(AbpAccountWebIdentityServerModule),
+ ```
+
+ with
+
+ ```csharp
+ typeof(AbpAccountWebOpenIddictModule),
+ ```
+
+- In the **MyApplicationIdentityServerModule.cs** add `PreConfigureServices` like below with your application name as the audience:
+
+ ```csharp
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(builder =>
+ {
+ builder.AddValidation(options =>
+ {
+ options.AddAudiences("MyApplication"); // Replace with your application name
+ options.UseLocalServer();
+ options.UseAspNetCore();
+ });
+ });
+ }
+ ```
+
+- In **MyApplicationIdentityServerModule.cs** `OnApplicationInitialization` method **remove IdentityServer midware**:
+
+ ```csharp
+ app.UseIdentityServer();
+ ```
+
+## Http.Api.Host
+
+- In the **MyApplicationHttpApiHostModule.cs** `OnApplicationInitialization` method, delete `c.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]);` in `app.UseAbpSwaggerUI` options configurations which is no longer needed.
+
+- In `appsettings.json` delete **SwaggerClientSecret** from the *AuthServer* section like below:
+
+```json
+"AuthServer": {
+ "Authority": "https://localhost:44345",
+ "RequireHttpsMetadata": "false",
+ "SwaggerClientId": "MyApplication_Swagger"
+},
+```
+
+- To use the new AuthServer page, replace **Index.cshtml.cs** with [AuthServer Index.cshtml.cs](https://github.com/abpframework/abp-samples/blob/master/Ids2OpenId/src/Ids2OpenId.IdentityServer/Pages/Index.cshtml) and **Index.cshtml** file with [AuthServer Index.cshtml](https://github.com/abpframework/abp-samples/blob/master/Ids2OpenId/src/Ids2OpenId.IdentityServer/Pages/Index.cshtml.cs) and rename **Ids2OpenId** with your application namespace.
+
+ > Note: It can be found under the *Pages* folder.
+
+## See Also
+
+* [OpenIddict Step-by-Step Guide](OpenIddict-Step-by-Step.md)
diff --git a/docs/en/Migration-Guides/OpenIddict-Blazor.md b/docs/en/Migration-Guides/OpenIddict-Blazor.md
new file mode 100644
index 0000000000..0dc1c0f123
--- /dev/null
+++ b/docs/en/Migration-Guides/OpenIddict-Blazor.md
@@ -0,0 +1,189 @@
+# OpenIddict Blazor Wasm UI Migration Guide
+
+## Blazor Project
+
+- In the **MyApplicationBlazorModule.cs** update the `ConfigureAuthentication` method:
+
+ ```csharp
+ builder.Services.AddOidcAuthentication(options =>
+ {
+ ...
+ options.UserOptions.RoleClaim = JwtClaimTypes.Role;
+
+ options.ProviderOptions.DefaultScopes.Add("role");
+ ...
+ });
+ ```
+
+ Update **UserOptions** and **role scope** as below
+
+ ```csharp
+ builder.Services.AddOidcAuthentication(options =>
+ {
+ ...
+ options.UserOptions.NameClaim = OpenIddictConstants.Claims.Name;
+ options.UserOptions.RoleClaim = OpenIddictConstants.Claims.Role;
+
+ options.ProviderOptions.DefaultScopes.Add("roles");
+ ...
+ });
+ ```
+
+## Http.Api.Host (Non-Separated IdentityServer)
+
+- In the **MyApplication.HttpApi.Host.csproj** replace **project references**:
+
+ ```csharp
+
+
+ ```
+
+ with
+
+ ```csharp
+
+ ```
+
+- In the **MyApplicationHttpApiHostModule.cs** replace usings and **module dependencies**:
+
+ ```csharp
+ using System.Net.Http;
+ using Volo.Abp.AspNetCore.Authentication.JwtBearer;
+ ...
+ typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
+ typeof(AbpAccountWebIdentityServerModule),
+ ```
+
+ with
+
+ ```csharp
+ using OpenIddict.Validation.AspNetCore;
+ ...
+ typeof(AbpAccountWebOpenIddictModule),
+ ```
+
+- In the **MyApplicationBlazorModule.cs** add `PreConfigureServices` like below with your application name as the audience:
+
+ ```csharp
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(builder =>
+ {
+ builder.AddValidation(options =>
+ {
+ options.AddAudiences("MyApplication"); // Replace with your application name
+ options.UseLocalServer();
+ options.UseAspNetCore();
+ });
+ });
+ }
+ ```
+
+- In the **MyApplicationBlazorModule.cs** `ConfigureServices` method, **replace the method call**:
+
+ From `ConfigureAuthentication(context, configuration);` to `ConfigureAuthentication(context);` and update the method as:
+
+ ```csharp
+ private void ConfigureAuthentication(ServiceConfigurationContext context)
+ {
+ context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
+ }
+ ```
+
+- In the **MyApplicationBlazorModule.cs** `OnApplicationInitialization` method, **replace the midware**:
+
+ ```csharp
+ app.UseJwtTokenMiddleware();
+ app.UseIdentityServer();
+ ```
+
+ with
+
+ ```csharp
+ app.UseAbpOpenIddictValidation();
+ ```
+
+- Delete `c.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]);` in `app.UseAbpSwaggerUI` options configurations which is no longer needed.
+
+- In `appsettings.json` delete **SwaggerClientSecret** from the *AuthServer* section like below:
+
+ ```json
+ "AuthServer": {
+ "Authority": "https://localhost:44345",
+ "RequireHttpsMetadata": "false",
+ "SwaggerClientId": "MyApplication_Swagger"
+ },
+ ```
+
+## Http.Api.Host (Separated IdentityServer)
+
+- In the **MyApplicationHttpApiHostModule.cs** `OnApplicationInitialization` method, delete `c.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]);` in `app.UseAbpSwaggerUI` options configurations which is no longer needed.
+
+- In `appsettings.json` delete **SwaggerClientSecret** from the *AuthServer* section like below:
+
+ ```json
+ "AuthServer": {
+ "Authority": "https://localhost:44345",
+ "RequireHttpsMetadata": "false",
+ "SwaggerClientId": "MyApplication_Swagger"
+ },
+ ```
+
+## IdentityServer
+
+This project is renamed to **AuthServer** after v6.0.0-rc1. You can also refactor and rename your project to *AuthServer* for easier updates in the future.
+
+- In **MyApplication.IdentityServer.csproj** replace **project references**:
+
+ ```csharp
+
+ ```
+
+ with
+
+ ```csharp
+
+ ```
+
+- In the **MyApplicationIdentityServerModule.cs** replace usings and **module dependencies**:
+
+ ```csharp
+ typeof(AbpAccountWebIdentityServerModule),
+ ```
+
+ with
+
+ ```csharp
+ typeof(AbpAccountWebOpenIddictModule),
+ ```
+
+- In the **MyApplicationIdentityServerModule.cs** add `PreConfigureServices` like below with your application name as the audience:
+
+ ```csharp
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(builder =>
+ {
+ builder.AddValidation(options =>
+ {
+ options.AddAudiences("MyApplication"); // Replace with your application name
+ options.UseLocalServer();
+ options.UseAspNetCore();
+ });
+ });
+ }
+ ```
+
+- In the **MyApplicationIdentityServerModule.cs** `OnApplicationInitialization` method, **remove the midware**:
+
+ ```csharp
+ app.UseIdentityServer();
+ ```
+
+- To use the new AuthServer page, replace **Index.cshtml.cs** with [AuthServer Index.cshtml.cs](https://github.com/abpframework/abp-samples/blob/master/Ids2OpenId/src/Ids2OpenId.IdentityServer/Pages/Index.cshtml) and **Index.cshtml** file with [AuthServer Index.cshtml](https://github.com/abpframework/abp-samples/blob/master/Ids2OpenId/src/Ids2OpenId.IdentityServer/Pages/Index.cshtml.cs) and rename **Ids2OpenId** with your application namespace.
+
+ > Note: It can be found under the *Pages* folder.
+
+## See Also
+
+* [OpenIddict Step-by-Step Guide](OpenIddict-Step-by-Step.md)
diff --git a/docs/en/Migration-Guides/OpenIddict-Mvc.md b/docs/en/Migration-Guides/OpenIddict-Mvc.md
new file mode 100644
index 0000000000..e772de272c
--- /dev/null
+++ b/docs/en/Migration-Guides/OpenIddict-Mvc.md
@@ -0,0 +1,166 @@
+# OpenIddict MVC/Razor UI Migration Guide
+
+## Web Project (Non-Tiered Solution)
+
+- In **MyApplication.Web.csproj** replace **project references**:
+
+ ```csharp
+
+
+ ```
+
+ with
+
+ ```csharp
+
+ ```
+
+- In **MyApplicationWebModule.cs** replace usings and **module dependencies**:
+
+ ```csharp
+ using Volo.Abp.AspNetCore.Authentication.JwtBearer;
+ ...
+ typeof(AbpAccountWebIdentityServerModule),
+ typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
+ ```
+
+ with
+
+ ```csharp
+ typeof(AbpAccountWebModule),
+ ```
+
+- In **MyApplicationWebModule.cs** `ConfigureServices` method **update authentication configuration**:
+
+ ```csharp
+ ConfigureAuthentication(context, configuration);
+ ```
+
+ with
+
+ ```csharp
+ ConfigureAuthentication(context);
+ ```
+
+ and update the `ConfigureAuthentication` private method to:
+
+ ```csharp
+ private void ConfigureAuthentication(ServiceConfigurationContext context)
+ {
+ context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
+ }
+ ```
+
+- In **MyApplicationWebModule.cs** `OnApplicationInitialization` method **replace IdentityServer and JwtToken midwares**:
+
+ ```csharp
+ app.UseJwtTokenMiddleware();
+ app.UseIdentityServer();
+ ```
+
+ with
+
+ ```csharp
+ app.UseAbpOpenIddictValidation();
+ ```
+
+
+## Web Project (Tiered Solution)
+
+- In the **MyApplicationWebModule.cs** update the `AddAbpOpenIdConnect` configurations:
+
+ ```csharp
+ .AddAbpOpenIdConnect("oidc", options =>
+ {
+ options.Authority = configuration["AuthServer:Authority"];
+ options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
+ options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
+
+ options.ClientId = configuration["AuthServer:ClientId"];
+ options.ClientSecret = configuration["AuthServer:ClientSecret"];
+
+ options.UsePkce = true; // Add this line
+ options.SaveTokens = true;
+ options.GetClaimsFromUserInfoEndpoint = true
+
+ options.Scope.Add("roles"); // Replace "role" with "roles"
+ options.Scope.Add("email");
+ options.Scope.Add("phone");
+ options.Scope.Add("MyApplication");
+ });
+ ```
+
+Replace role scope to **roles** and add **UsePkce** and **SignoutScheme** options.
+
+## IdentityServer
+
+This project is renamed to **AuthServer** after v6.0.0-rc1. You can also refactor and rename your project to *AuthServer* for easier updates in the future.
+
+- In **MyApplication.IdentityServer.csproj** replace **project references**:
+
+ ```csharp
+
+ ```
+
+ with
+
+ ```csharp
+
+ ```
+
+- In **MyApplicationIdentityServerModule.cs** replace usings and **module dependencies**:
+
+ ```csharp
+ typeof(AbpAccountWebIdentityServerModule),
+ ```
+
+ with
+
+ ```csharp
+ typeof(AbpAccountWebOpenIddictModule),
+ ```
+
+- In the **MyApplicationIdentityServerModule.cs** add `PreConfigureServices` like below with your application name as the audience:
+
+ ```csharp
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(builder =>
+ {
+ builder.AddValidation(options =>
+ {
+ options.AddAudiences("MyApplication"); // Replace with your application name
+ options.UseLocalServer();
+ options.UseAspNetCore();
+ });
+ });
+ }
+ ```
+
+- In **MyApplicationIdentityServerModule.cs** `OnApplicationInitialization` method **remove IdentityServer midware**:
+
+ ```csharp
+ app.UseIdentityServer();
+ ```
+
+- To use the new AuthServer page, replace **Index.cshtml.cs** with [AuthServer Index.cshtml.cs](https://github.com/abpframework/abp-samples/blob/master/Ids2OpenId/src/Ids2OpenId.IdentityServer/Pages/Index.cshtml) and **Index.cshtml** file with [AuthServer Index.cshtml](https://github.com/abpframework/abp-samples/blob/master/Ids2OpenId/src/Ids2OpenId.IdentityServer/Pages/Index.cshtml.cs) and rename **Ids2OpenId** with your application namespace.
+
+ > Note: It can be found under the *Pages* folder.
+
+## Http.Api.Host
+
+- In the **MyApplicationHttpApiHostModule.cs** `OnApplicationInitialization` method, delete `c.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]);` in `app.UseAbpSwaggerUI` options configurations which is no longer needed.
+
+- In `appsettings.json` delete **SwaggerClientSecret** from the *AuthServer* section like below:
+
+ ```json
+ "AuthServer": {
+ "Authority": "https://localhost:44345",
+ "RequireHttpsMetadata": "false",
+ "SwaggerClientId": "MyApplication_Swagger"
+ },
+ ```
+
+## See Also
+
+* [OpenIddict Step-by-Step Guide](OpenIddict-Step-by-Step.md)
diff --git a/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md b/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md
new file mode 100644
index 0000000000..3567ea5c06
--- /dev/null
+++ b/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md
@@ -0,0 +1,231 @@
+# Migrating from IdentityServer to OpenIddict Step by Step Guide
+
+This guide provides layer-by-layer guidance for migrating your existing application to [OpenIddict](https://github.com/openiddict/openiddict-core) from IdentityServer. ABP startup templates use `OpenIddict` OpenId provider from v6.0.0-rc1 by default and `IdentityServer` projects are renamed to `AuthServer` in tiered/separated solutions. Since OpenIddict is only available with ABP v6.0, you will need to update your existing application in order to apply OpenIddict changes.
+
+## History
+We are not removing Identity Server packages and we will continue to release new versions of IdentityServer-related NuGet/NPM packages. That means you won't have an issue while upgrading to v6.0 when the stable version releases. We will continue to fix bugs in our packages for a while. ABP 7.0 will be based on .NET 7. If Identity Server continues to work with .NET 7, we will also continue to ship NuGet packages for our IDS integration.
+
+On the other hand, Identity Server ends support for the open-source Identity Server at the end of 2022. The Identity Server team has decided to move to Duende IDS and ABP will not be migrated to the commercial Duende IDS. You can see the Duende Identity Server announcement from [this link](https://blog.duendesoftware.com/posts/20220111_fair_trade).
+
+## OpenIddict Migration Steps
+
+Use the `abp update` command to update your existing application. See [Upgrading docs](../Upgrading.md) for more info. Apply required migrations by following the [Migration Guides](Index.md) based on your application version.
+
+### Domain.Shared Layer
+
+- In **MyApplication.Domain.Shared.csproj** replace **project reference**:
+ ```csharp
+
+ ```
+ with
+ ```csharp
+
+ ```
+
+- In **MyApplicationDomainSharedModule.cs** replace usings and **module dependencies:**
+
+ ```csharp
+ using Volo.Abp.IdentityServer;
+ ...
+ typeof(AbpIdentityServerDomainSharedModule)
+ ```
+ with
+ ```csharp
+ using Volo.Abp.OpenIddict;
+ ...
+ typeof(AbpOpenIddictDomainSharedModule)
+
+### Domain Layer
+
+- In **MyApplication.Domain.csproj** replace **project references**:
+
+ ```csharp
+
+
+ ```
+
+ with
+
+ ```csharp
+
+
+ ```
+
+- In **MyApplicationDomainModule.cs** replace usings and **module dependencies**:
+
+ ```csharp
+ using Volo.Abp.IdentityServer;
+ using Volo.Abp.PermissionManagement.IdentityServer;
+ ...
+ typeof(AbpIdentityServerDomainModule),
+ typeof(AbpPermissionManagementDomainIdentityServerModule),
+ ```
+
+ with
+
+ ```csharp
+ using Volo.Abp.OpenIddict;
+ using Volo.Abp.PermissionManagement.OpenIddict;
+ ...
+ typeof(AbpOpenIddictDomainModule),
+ typeof(AbpPermissionManagementDomainOpenIddictModule),
+ ```
+
+#### OpenIddictDataSeedContributor
+
+- Create a folder named *OpenIddict* under the Domain project and copy the [OpenIddictDataSeedContributor.cs](https://github.com/abpframework/abp-samples/blob/master/Ids2OpenId/src/Ids2OpenId.Domain/OpenIddict/OpenIddictDataSeedContributor.cs) under this folder. Rename all the `Ids2OpenId` with your project name.
+- Delete *IdentityServer* folder that contains `IdentityServerDataSeedContributor.cs` which is no longer needed.
+
+You can also create a project with the same name and copy the `OpenIddict` folder of the new project into your project.
+
+### EntityFrameworkCore Layer
+
+If you are using MongoDB, skip this step and check the *MongoDB* layer section.
+
+- In **MyApplication.EntityFrameworkCore.csproj** replace **project reference**:
+
+ ```csharp
+
+ ```
+
+ with
+
+ ```csharp
+
+ ```
+
+- In **MyApplicationEntityFrameworkCoreModule.cs** replace usings and **module dependencies**:
+
+ ```csharp
+ using Volo.Abp.IdentityServer.EntityFrameworkCore;
+ ...
+ typeof(AbpIdentityServerEntityFrameworkCoreModule),
+ ```
+
+ with
+
+ ```csharp
+ using Volo.Abp.OpenIddict.EntityFrameworkCore;
+ ...
+ typeof(AbpOpenIddictEntityFrameworkCoreModule),
+ ```
+
+- In **MyApplicationDbContext.cs** replace usings and **fluent api configurations**:
+
+ ```csharp
+ using Volo.Abp.IdentityServer.EntityFrameworkCore;
+ ...
+ using Volo.Abp.OpenIddict.EntityFrameworkCore;
+ ...
+ protected override void OnModelCreating(ModelBuilder builder)
+ {
+ base.OnModelCreating(builder);
+
+ /* Include modules to your migration db context */
+
+ ...
+ builder.ConfigureIdentityServer();
+ ```
+
+ with
+
+ ```csharp
+ using Volo.Abp.OpenIddict.EntityFrameworkCore;
+ ...
+ protected override void OnModelCreating(ModelBuilder builder)
+ {
+ base.OnModelCreating(builder);
+
+ /* Include modules to your migration db context */
+
+ ...
+ builder.ConfigureOpenIddict();
+ ```
+
+### MongoDB Layer
+
+If you are using EntityFrameworkCore, skip this step and check the *EntityFrameworkCore* layer section.
+
+- In **MyApplication.MongoDB.csproj** replace **project reference**:
+
+ ```csharp
+
+ ```
+
+ with
+
+ ```csharp
+
+ ```
+
+- In **MyApplicationMongoDbModule.cs** replace usings and **module dependencies**:
+
+ ```csharp
+ using Volo.Abp.IdentityServer.MongoDB;
+ ...
+ typeof(AbpIdentityServerMongoDbModule),
+ ```
+
+ with
+
+ ```csharp
+ using Volo.Abp.OpenIddict.MongoDB;
+ ...
+ typeof(AbpOpenIddictMongoDbModule),
+ ```
+
+### DbMigrator Project
+
+- In **MyApplication.DbMigrator.csproj** **add project reference**:
+
+ ```csharp
+
+ ```
+
+for creating the host builder.
+
+- In `appsettings.json` **replace IdentityServer section with OpenIddict:**
+
+ ```json
+ "OpenIddict": {
+ "Applications": {
+ "MyApplication_Web": {
+ "ClientId": "MyApplication_Web",
+ "ClientSecret": "1q2w3e*",
+ "RootUrl": "https://localhost:44384"
+ },
+ "MyApplication_App": {
+ "ClientId": "MyApplication_App",
+ "RootUrl": "http://localhost:4200"
+ },
+ "MyApplication_BlazorServerTiered": {
+ "ClientId": "MyApplication_BlazorServerTiered",
+ "ClientSecret": "1q2w3e*",
+ "RootUrl": "https://localhost:44346"
+ },
+ "MyApplication_Swagger": {
+ "ClientId": "MyApplication_Swagger",
+ "RootUrl": "https://localhost:44391"
+ }
+ }
+ }
+ ```
+
+ Replace **MyApplication** with your application name.
+
+### UI Layer
+
+- [Angular UI Migration](OpenIddict-Angular.md)
+- [MVC/Razor UI Migration](OpenIddict-Mvc.md)
+- [Blazor-Server UI Migration](OpenIddict-Blazor-Server.md)
+- [Blazor-Wasm UI Migration](OpenIddict-Blazor.md)
+
+## Source code of samples and module
+
+* [Open source tiered & separate auth server application migrate Identity Server to OpenIddct](https://github.com/abpframework/abp-samples/tree/master/Ids2OpenId)
+* [OpenIddict module document](https://docs.abp.io/en/abp/6.0/Modules/OpenIddict)
+* [OpenIddict module source code](https://github.com/abpframework/abp/tree/rel-6.0/modules/openiddict)
+
+## See Also
+
+* [ABP Version 6.0 Migration Guide](Abp-6_0.md)
diff --git a/docs/en/Modules/Cms-Kit/Dynamic-Widget.md b/docs/en/Modules/Cms-Kit/Dynamic-Widget.md
new file mode 100644
index 0000000000..88c0be6750
--- /dev/null
+++ b/docs/en/Modules/Cms-Kit/Dynamic-Widget.md
@@ -0,0 +1,137 @@
+# Dynamic Widget
+
+CMS kit provides a dynamic [widget](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Widgets) used to render the components previously developed by the software in the content of the pages and blog posts. Its means, that in static content you can use dynamic content. We will mention how you can do it. You have two choices to define the widget in the system: Writing and UI.
+
+### Adding the widget
+Firstly we will show how to use the widget system via writing manually in the page and blogpost contents.
+
+Let's define the view component
+
+```csharp
+[Widget]
+[ViewComponent(Name = "CmsToday")]
+public class TodayViewComponent : AbpViewComponent
+{
+ public IViewComponentResult Invoke()
+ {
+ return View("~/ViewComponents/Today.cshtml",
+ new TodayViewComponent());
+ }
+}
+```
+
+```html
+@model Volo.CmsKit.ViewComponents.TodayViewComponent
+
+Welcome Today Component
+@DateTime.Now.ToString()
+
+```
+
+Now configuration time on YourModule.cs
+```csharp
+Configure(options =>
+ {
+ options.AddWidget("Today","CmsToday");
+ });
+```
+
+Now you're ready to add your widget by writing.
+[Widget Type="Today"]
+
+After completing the above steps, you can see the output at the right of the below screenshot.
+
+
+### Adding by using UI
+Now we will mention the second option, using UI.
+Once writing these definitions can make some mistakes hence we added a new feature to use the widget system easily. To the right of the editor, you will see the customized `W` button to add a dynamic widget like the below image. Don't forget please this is design mode and you need to view your page in view mode after saving. Also `Preview` tab on the editor will be ready to check your output easily for widget configurations in the next features.
+
+
+
+### Adding by using UI with parameters
+Let's improve the above example by adding a new parameter named format. Via this feature, we can use the widget system with many different scenarios but not prolong the document. Also, these examples can be expandable with dependency injection and getting values from the database, but we will use a basic example. We will add the format parameter to customize the date.
+
+```csharp
+[Widget]
+[ViewComponent(Name = "CmsToday")]
+public class TodayViewComponent : AbpViewComponent
+{
+ public string Format { get; set; }
+
+ public IViewComponentResult Invoke(string format)
+ {
+ return View("~/ViewComponents/Today.cshtml",
+ new TodayViewComponent() { Format = format });
+ }
+}
+```
+
+```html
+@model Volo.CmsKit.ViewComponents.TodayViewComponent
+
+Welcome Today Component
+@DateTime.Now.ToString(Format)
+
+```
+
+Let's define the format component.
+```csharp
+[Widget]
+[ViewComponent(Name = "Format")]
+public class FormatViewComponent : AbpViewComponent
+{
+ public IViewComponentResult Invoke()
+ {
+ return View("~/ViewComponents/Format.cshtml",
+ new FormatViewModel());
+ }
+}
+
+public class FormatViewModel
+{
+ [DisplayName("Format your date in the component")]
+ public string Format { get; set; }
+}
+```
+> Important Note: To get properties properly you should set the `name` property on the razor page or you may use the ABP component. ABP handles that automatically.
+
+```html
+@using Volo.CmsKit.ViewComponents
+@model FormatViewModel
+
+
+```
+
+```csharp
+Configure(options =>
+ {
+ options.AddWidget("Today", "CmsToday", "Format");
+ });
+```
+
+
+
+In this image, after choosing your widget (on the other case, it changes automatically up to your configuration, mine is `Today`. Its parameter name `parameterWidgetName` and its value is `Format`) you will see the next widget. Enter input values or choose them and click `Add`. You will see the underlined output in the editor. Right of the image, also you can see its previewed output.
+
+You can edit this output manually if do any wrong coding for that (wrong value or typo) you won't see the widget, even so, your page will be viewed successfully.
+
+## Options
+To configure the widget, you should define the below code in YourModule.cs
+
+```csharp
+Configure(options =>
+ {
+ options.AddWidget(widgetType: "Today", widgetName: "CmsToday", parameterWidgetName: "Format");
+ });
+```
+
+Let's look at these parameters in detail
+* `widgetType` is used for end-user and more readable names. The following bold word represents widgetType.
+[Widget Type="**Today**" Format="yyyy-dd-mm HH:mm:ss"].
+
+* `widgetName` is used for your widget name used in code for the name of the `ViewComponent`.
+
+* `parameterWidgetName` is used the for editor component side to see on the `Add Widget` modal.
+After choosing the widget type from listbox (now just defined `Format`) and renders this widget automatically. It's required only to see UI once using parameters
\ No newline at end of file
diff --git a/docs/en/Modules/Cms-Kit/Index.md b/docs/en/Modules/Cms-Kit/Index.md
index 072f196f10..b8cbe89d20 100644
--- a/docs/en/Modules/Cms-Kit/Index.md
+++ b/docs/en/Modules/Cms-Kit/Index.md
@@ -14,6 +14,7 @@ The following features are currently available:
* Provides a [**rating**](Ratings.md) system to add rating feature to any kind of resource.
* Provides a [**menu**](Menus.md) system to manage public menus dynamically.
* Provides a [**global resources**](Global-Resources.md) system to add global styles and scripts dynamically.
+* Provides a [**Dynamic Widget**](Dynamic-Widget.md) system to create dynamic widgets for page and blog posts.
Click to a feature to understand and learn how to use it.
diff --git a/docs/en/Modules/OpenIddict.md b/docs/en/Modules/OpenIddict.md
index ed25147be2..22cb22bf55 100644
--- a/docs/en/Modules/OpenIddict.md
+++ b/docs/en/Modules/OpenIddict.md
@@ -1,98 +1,268 @@
-## ABP OpenIddict Modules
+## ABP OpenIddict Module
+
+OpenIddict module provides an integration with the [OpenIddict](https://github.com/openiddict/openiddict-core) which provides advanced authentication features like single sign-on, single log-out, and API access control. This module persists applications, scopes, and other OpenIddict-related objects to the database.
## How to Install
-TODO:
+This module comes as pre-installed (as NuGet/NPM packages) when you [create a new solution](https://abp.io/get-started) with the ABP Framework. You can continue to use it as a package and get updates easily, or you can include its source code into your solution (see `get-source` [CLI](../CLI.md) command) to develop your custom module.
+
+### The Source Code
+
+The source code of this module can be accessed [here](https://github.com/abpframework/abp/tree/dev/modules/openiddict). The source code is licensed by [MIT](https://choosealicense.com/licenses/mit/), so you can freely use and customize it.
## User Interface
-This module implements the domain logic and database integrations, but not provides any UI. Management UI is useful if you need to add applications and scopes on the fly. In this case, you may build the management UI yourself or consider to purchase the [ABP Commercial](https://commercial.abp.io/) which provides the management UI for this module.
+This module implements the domain logic and database integrations but does not provide any UI. Management UI is useful if you need to add applications and scopes on the fly. In this case, you may build the management UI yourself or consider purchasing the [ABP Commercial](https://commercial.abp.io/) which provides the management UI for this module.
## Relations to Other Modules
-This module is based on the [Identity Module](Identity.md) and have an [integration package](https://www.nuget.org/packages/Volo.Abp.Account.Web.OpenIddict) with the [Account Module](Account.md).
+This module is based on the [Identity Module](Identity.md) and has an [integration package](https://www.nuget.org/packages/Volo.Abp.Account.Web.OpenIddict) with the [Account Module](Account.md).
-## The module
+## Options
-### Demo projects
+### OpenIddictBuilder
-In the module's `app` directory there are six projects(including `angular`)
+`OpenIddictBuilder` can be configured in the `PreConfigureServices` method of your OpenIddict [module](https://docs.abp.io/en/abp/latest/Module-Development-Basics).
-* `OpenIddict.Demo.Server`: An abp application with integrated modules (has two `clients` and a `scope`).
-* `OpenIddict.Demo.API`: ASP NET Core API application using JwtBearer authentication
-* `OpenIddict.Demo.Client.Mvc`: ASP NET Core MVC application using `OpenIdConnect` for authentication
-* `OpenIddict.Demo.Client.Console`: Use `IdentityModel` to test OpenIddict's various endpoints, and call the api of `OpenIddict.Demo.API`
-* `OpenIddict.Demo.Client.BlazorWASM:` ASP NET Core Blazor application using `OidcAuthentication` for authentication
-* `angular`: An angular application that integrates the abp ng modules and uses oauth for authentication
+Example:
-#### How to run?
-
-Confirm the connection string of `appsettings.json` in the `OpenIddict.Demo.Server` project. Running the project will automatically create the database and initialize the data.
-After running the `OpenIddict.Demo.API` project, then you can run the rest of the projects to test.
+```csharp
+public override void PreConfigureServices(ServiceConfigurationContext context)
+{
+ PreConfigure(builder =>
+ {
+ //Set options here...
+ });
+}
+```
-### Domain module
+`OpenIddictBuilder` contains various extension methods to configure the OpenIddict services:
-There are four main entities included in this module.
+- `AddServer()` registers the OpenIddict token server services in the DI container. Contains `OpenIddictServerBuilder` configurations.
+- `AddCore()` registers the OpenIddict core services in the DI container. Contains `OpenIddictCoreBuilder` configurations.
+- `AddValidation()` registers the OpenIddict token validation services in the DI container. Contains `OpenIddictValidationBuilder` configurations.
-* OpenIddictApplication: **Represents applications(client)**
-* OpenIddictScope: **Represents scopes**
-* OpenIddictAuthorization: **Represents authorizations, Track of logical chains of tokens and user consent..**
-* OpenIddictToken: **Represents various tokens.**
+### OpenIddictCoreBuilder
-Domain also implements four store interfaces in OpenIddict, OpenIddict uses store to manage entities, corresponding to the above four entities, Custom entity repository is used in the store.
+`OpenIddictCoreBuilder` contains extension methods to configure the OpenIddict core services.
+Example:
-```cs
-//Manager
-OpenIddictApplicationManager
-OpenIddictScopeManager
-OpenIddictAuthorizationManager
-OpenIddictTokenManager
-
-//Store
-IOpenIddictApplicationStore
-IOpenIddictScopeStore
-IOpenIddictAuthorizationStore
-IOpenIddictTokenStore
-
-//Repository
-IOpenIddictApplicationRepository
-IOpenIddictScopeRepository
-IOpenIddictAuthorizationRepository
-IOpenIddictTokenRepository
+```csharp
+public override void PreConfigureServices(ServiceConfigurationContext context)
+{
+ PreConfigure(builder =>
+ {
+ //Set options here...
+ });
+}
```
-We enabled most of OpenIddict's features in the `AddOpenIddict` method, You can change OpenIddict's related builder options via `PreConfigure`.
+These services contain:
-```cs
-PreConfigure(builder =>
-{
- //builder
-});
+- Adding `ApplicationStore`, `AuthorizationStore`, `ScopeStore`, `TokenStore`.
+- Replacing `ApplicationManager`, `AuthorizationManager`, `ScopeManager`, `TokenManager`.
+- Replacing `ApplicationStoreResolver`, `AuthorizationStoreResolver`, `ScopeStoreResolver`, `TokenStoreResolver`.
+- Setting `DefaultApplicationEntity`, `DefaultAuthorizationEntity`, `DefaultScopeEntity`, `DefaultTokenEntity`.
+
+### OpenIddictServerBuilder
+
+`OpenIddictServerBuilder` contains extension methods to configure OpenIddict server services.
+
+Example:
-PreConfigure(builder =>
+```csharp
+public override void PreConfigureServices(ServiceConfigurationContext context)
{
- //builder
-});
+ PreConfigure(builder =>
+ {
+ //Set options here...
+ });
+}
+```
-PreConfigure(builder =>
+These services contain:
+
+- Registering claims, scopes.
+- Setting the `Issuer` URI that is used as the base address for the endpoint URIs returned from the discovery endpoint.
+- Adding development signing keys, encryption/signing keys, credentials, and certificates.
+- Adding/removing event handlers.
+- Enabling/disabling grant types.
+- Setting authentication server endpoint URIs.
+
+### OpenIddictValidationBuilder
+
+`OpenIddictValidationBuilder` contains extension methods to configure OpenIddict validation services.
+
+Example:
+
+```csharp
+public override void PreConfigureServices(ServiceConfigurationContext context)
{
- //builder
-});
+ PreConfigure(builder =>
+ {
+ //Set options here...
+ });
+}
```
-#### AbpOpenIddictAspNetCoreOptions
+These services contain:
+
+- `AddAudiances()` for resource servers.
+- `SetIssuer()` URI that is used to determine the actual location of the OAuth 2.0/OpenID Connect configuration document when using provider discovery.
+- `SetConfiguration()` to configure `OpenIdConnectConfiguration`.
+- `UseIntrospection()` to use introspection instead of local/direct validation.
+- Adding encryption key, credentials, and certificates.
+- Adding/removing event handlers.
+- `SetClientId() ` to set the client identifier `client_id ` when communicating with the remote authorization server (e.g for introspection).
+- `SetClientSecret()` to set the identifier `client_secret` when communicating with the remote authorization server (e.g for introspection).
+- `EnableAuthorizationEntryValidation()` to enable authorization validation to ensure the `access token` is still valid by making a database call for each API request. *Note:* This may have a negative impact on performance and can only be used with an OpenIddict-based authorization server.
+- `EnableTokenEntryValidation()` to enable authorization validation to ensure the `access token` is still valid by making a database call for each API request. *Note:* This may have a negative impact on performance and it is required when the OpenIddict server is configured to use reference tokens.
+- `UseLocalServer()` to register the OpenIddict validation/server integration services.
+- `UseAspNetCore()` to register the OpenIddict validation services for ASP.NET Core in the DI container.
+
+## Internals
+
+### Domain Layer
+
+#### Aggregates
+
+##### OpenIddictApplication
+
+OpenIddictApplications represent the applications that can request tokens from your OpenIddict Server.
+
+- `OpenIddictApplications` (aggregate root): Represents an OpenIddict application.
+ - `ClientId` (string): The client identifier associated with the current application.
+ - `ClientSecret` (string): The client secret associated with the current application. Maybe hashed or encrypted for security reasons.
+ - `ConsentType` (string): The consent type associated with the current application.
+ - `DisplayName` (string): The display name associated with the current application.
+ - `DisplayNames` (string): The localized display names associated with the current application serialized as a JSON object.
+ - `Permissions` (string): The permissions associated with the current application, serialized as a JSON array.
+ - `PostLogoutRedirectUris` (string): The logout callback URLs associated with the current application, serialized as a JSON array.
+ - `Properties` (string): The additional properties associated with the current application serialized as a JSON object or null.
+ - `RedirectUris` (string): The callback URLs associated with the current application, serialized as a JSON array.
+ - `Requirements` (string): The requirements associated with the current application
+ - `Type` (string): The application type associated with the current application.
+ - `ClientUri` (string): URI to further information about client.
+ - `LogoUri` (string): URI to client logo.
+
+##### OpenIddictAuthorization
+
+OpenIddictAuthorizations are used to keep the allowed scopes, authorization flow types.
+
+- `OpenIddictAuthorization` (aggregate root): Represents an OpenIddict authorization.
+
+ - `ApplicationId` (Guid?): The application associated with the current authorization.
+
+ - `Properties` (string): The additional properties associated with the current authorization serialized as a JSON object or null.
+
+ - `Scopes` (string): The scopes associated with the current authorization, serialized as a JSON array.
+
+ - `Status` (string): The status of the current authorization.
+
+ - `Subject` (string): The subject associated with the current authorization.
+
+ - `Type` (string): The type of the current authorization.
+
+##### OpenIddictScope
+
+OpenIddictScopes are used to keep the scopes of resources.
+
+- `OpenIddictScope` (aggregate root): Represents an OpenIddict scope.
+
+ - `Description` (string): The public description associated with the current scope.
+
+ - `Descriptions` (string): The localized public descriptions associated with the current scope, serialized as a JSON object.
+
+ - `DisplayName` (string): The display name associated with the current scope.
+
+ - `DisplayNames` (string): The localized display names associated with the current scope serialized as a JSON object.
+
+ - `Name` (string): The unique name associated with the current scope.
+ - `Properties` (string): The additional properties associated with the current scope serialized as a JSON object or null.
+ - `Resources` (string): The resources associated with the current scope, serialized as a JSON array.
+
+##### OpenIddictToken
+
+OpenIddictTokens are used to persist the application tokens.
+
+- `OpenIddictToken` (aggregate root): Represents an OpenIddict token.
+
+ - `ApplicationId` (Guid?): The application associated with the current token.
+ - `AuthorizationId` (Guid?): The application associated with the current token.
+ - `CreationDate` (DateTime?): The UTC creation date of the current token.
+ - `ExpirationDate` (DateTime?): The UTC expiration date of the current token.
+ - `Payload` (string): The payload of the current token, if applicable. Only used for reference tokens and may be encrypted for security reasons.
+
+ - `Properties` (string): The additional properties associated with the current token serialized as a JSON object or null.
+ - `RedemptionDate` (DateTime?): The UTC redemption date of the current token.
+ - `Status` (string): The status of the current authorization.
+
+ - `ReferenceId` (string): The reference identifier associated with the current token, if applicable. Only used for reference tokens and may be hashed or encrypted for security reasons.
+
+ - `Status` (string): The status of the current token.
+
+ - `Subject` (string): The subject associated with the current token.
+
+ - `Type` (string): The type of the current token.
-`UpdateAbpClaimTypes(default: true)`: Updates AbpClaimTypes to be compatible with identity server claims.
-`AddDevelopmentEncryptionAndSigningCertificate(default: true)`: Registers (and generates if necessary) a user-specific development encryption/development signing certificate.
+#### Stores
-You can also change this options via `PreConfigure`.
+This module implements OpenIddict stores:
-#### Automatically removing orphaned tokens/authorizations
+- `IAbpOpenIdApplicationStore`
+- `IOpenIddictAuthorizationStore`
+- `IOpenIddictScopeStore`
+- `IOpenIddictTokenStore`
-There is a background task in the `Domain` module (`enabled by default`) that automatically removes orphaned tokens/authorizations, you can configure `TokenCleanupOptions` to manage it.
+##### Repositories
-### ASP NET Core module
+The following custom repositories are defined in this module:
+
+- `IOpenIddictApplicationRepository`
+- `IOpenIddictAuthorizationRepository`
+- `IOpenIddictScopeRepository`
+- `IOpenIddictTokenRepository`
+
+##### Domain Services
+
+This module doesn't contain any domain service but overrides the service below:
+
+- `AbpApplicationManager` used to populate/get `AbpApplicationDescriptor` information that contains `ClientUri` and `LogoUri`.
+
+### Database Providers
+
+#### Common
+
+##### Table/Collection Prefix & Schema
+
+All tables/collections use the `OpenIddict` prefix by default. Set static properties on the `AbpOpenIddictDbProperties` class if you need to change the table prefix or set a schema name (if supported by your database provider).
+
+##### Connection String
+
+This module uses `AbpOpenIddict` for the connection string name. If you don't define a connection string with this name, it fallbacks to the `Default` connection string.
+
+See the [connection strings](https://docs.abp.io/en/abp/latest/Connection-Strings) documentation for details.
+
+#### Entity Framework Core
+
+##### Tables
+
+- **OpenIddictApplications**
+- **OpenIddictAuthorizations**
+- **OpenIddictScopes**
+- **OpenIddictTokens**
+
+#### MongoDB
+
+##### Collections
+
+- **OpenIddictApplications**
+- **OpenIddictAuthorizations**
+- **OpenIddictScopes**
+- **OpenIddictTokens**
+
+## ASP.NET Core Module
This module integrates ASP NET Core, with built-in MVC controllers for four protocols. It uses OpenIddict's [Pass-through mode](https://documentation.openiddict.com/guides/index.html#pass-through-mode).
@@ -103,22 +273,76 @@ LogoutController -> connect/logout
UserInfoController -> connect/userinfo
```
-> We will implement the related functions of **device flow** in the PRO module..
+> **Device flow** implementation will be done in the commercial module.
-#### How to control claims in access_token and id_token
+#### AbpOpenIddictAspNetCoreOptions
+
+`AbpOpenIddictAspNetCoreOptions` can be configured in the `PreConfigureServices` method of your OpenIddict [module](https://docs.abp.io/en/abp/latest/Module-Development-Basics).
+
+Example:
+
+```csharp
+PreConfigure(options =>
+{
+ //Set options here...
+});
+```
+
+`AbpOpenIddictAspNetCoreOptions` properties:
+
+- `UpdateAbpClaimTypes(default: true)`: Updates `AbpClaimTypes` to be compatible with the Openiddict claims.
+- `AddDevelopmentEncryptionAndSigningCertificate(default: true)`: Registers (and generates if necessary) a user-specific development encryption/development signing certificate.
+
+#### Automatically Removing Orphaned Tokens/Authorizations
+
+The background task that automatically removes orphaned tokens/authorizations. This can be configured by `TokenCleanupOptions` to manage it.
+
+`TokenCleanupOptions` can be configured in the `PreConfigureServices` method of your OpenIddict [module](https://docs.abp.io/en/abp/latest/Module-Development-Basics).
+
+Example:
+
+```csharp
+PreConfigure(options =>
+{
+ //Set options here...
+});
+```
-You can use the [Claims Principal Factory](https://docs.abp.io/en/abp/latest/Authorization#claims-principal-factory) to add/remove claims to the `ClaimsPrincipal`.
+`TokenCleanupOptions` properties:
-The `AbpDefaultOpenIddictClaimDestinationsProvider` service will add `Name`, `Email` and `Role` types of Claims to `access_token` and `id_token`, other claims are only added to `access_token` by default, and remove the `SecurityStampClaimType` secret claim of `Identity`.
+- `IsCleanupEnabled` (default: true): Enable/disable token clean up.
+- `CleanupPeriod` (default: 3,600,000 ms): Setting clean up period.
+- `DisableAuthorizationPruning`: Setting a boolean indicating whether authorizations pruning should be disabled.
+- `DisableTokenPruning`: Setting a boolean indicating whether token pruning should be disabled.
+- `MinimumAuthorizationLifespan` (default: 14 days): Setting the minimum lifespan authorizations must have to be pruned. Cannot be less than 10 minutes.
+- `MinimumTokenLifespan` (default: 14 days): Setting the minimum lifespan tokens must have to be pruned. Cannot be less than 10 minutes.
-You can create a service that inherits from `IAbpOpenIddictClaimDestinationsProvider` and add it to DI to fully control the destinations of claims
+#### Updating Claims In Access_token and Id_token
+
+[Claims Principal Factory](https://docs.abp.io/en/abp/latest/Authorization#claims-principal-factory) can be used to add/remove claims to the `ClaimsPrincipal`.
+
+The `AbpDefaultOpenIddictClaimDestinationsProvider` service will add `Name`, `Email,` and `Role` types of Claims to `access_token` and `id_token`, other claims are only added to `access_token` by default, and remove the `SecurityStampClaimType` secret claim of `Identity`.
+
+Create a service that inherits from `IAbpOpenIddictClaimDestinationsProvider` and add it to DI to fully control the destinations of claims.
```cs
public class MyClaimDestinationsProvider : IAbpOpenIddictClaimDestinationsProvider, ITransientDependency
{
public virtual Task SetDestinationsAsync(AbpOpenIddictClaimDestinationsProviderContext context)
{
- // ...
+ foreach (var claim in context.Claims)
+ {
+ if (claim.Type == MyClaims.MyClaimsType)
+ {
+ claim.SetDestinations(OpenIddictConstants.Destinations.AccessToken, OpenIddictConstants.Destinations.IdentityToken);
+ }
+
+ if (claim.Type == MyClaims.MyClaimsType2)
+ {
+ claim.SetDestinations(OpenIddictConstants.Destinations.AccessToken);
+ }
+ }
+
return Task.CompletedTask;
}
}
@@ -129,30 +353,11 @@ Configure(options =>
});
```
-For detailed information, please refer to: [OpenIddict claim destinations](https://documentation.openiddict.com/configuration/claim-destinations.html)
-
-### EF Core module
-
-Implements the above four repository interfaces.
-
-### MongoDB module
-
-Implements the above four repository interfaces.
-
+For detailed information, please refer to: [OpenIddict claim destinations](https://documentation.openiddict.com/configuration/claim-destinations.html)
-## OpenIddict
+#### Disable AccessToken Encryption
-### Documentation
-
-For more details about OpenIddict, please refer to its official documentation and Github.
-
-https://documentation.openiddict.com
-
-https://github.com/openiddict/openiddict-core#resources
-
-### Disable AccessToken Encryption
-
-ABP disables the `access token encryption` by default for compatibility, you can manually enable it if needed.
+ABP disables the `access token encryption` by default for compatibility, it can be enabled manually if needed.
```cs
public override void PreConfigureServices(ServiceConfigurationContext context)
@@ -166,22 +371,15 @@ public override void PreConfigureServices(ServiceConfigurationContext context)
https://documentation.openiddict.com/configuration/token-formats.html#disabling-jwt-access-token-encryption
-
-### PKCE
-
-https://documentation.openiddict.com/configuration/proof-key-for-code-exchange.html
-
-### Request/Response process
-
-I will briefly introduce the principle of OpenIddict so that everyone can quickly understand it.
+### Request/Response Process
The `OpenIddict.Server.AspNetCore` adds an authentication scheme(`Name: OpenIddict.Server.AspNetCore, handler: OpenIddictServerAspNetCoreHandler`) and implements the `IAuthenticationRequestHandler` interface.
It will be executed first in `AuthenticationMiddleware` and can short-circuit the current request. Otherwise, `DefaultAuthenticateScheme` will be called and continue to execute the pipeline.
-`OpenIddictServerAspNetCoreHandler` will call various built-in handlers(Handling requests and responses), And the handler will process according to the context or skip logic that has nothing to do with it.
+`OpenIddictServerAspNetCoreHandler` will call various built-in handlers (handling requests and responses), And the handler will process according to the context or skip logic that has nothing to do with it.
-Example a token request:
+Example of a token request:
```
POST /connect/token HTTP/1.1
@@ -195,11 +393,11 @@ Content-Type: application/x-www-form-urlencoded
scope=AbpAPI offline_access
```
-This request will be processed by various handlers. They will confirm the endpoint type of the request, check `http/https`, verify that the request parameters (`client. scope etc`) are valid and exist in the database, etc. Various protocol checks. And build a `OpenIddictRequest` object, If there are any errors, the response content may be set and directly short-circuit the current request.
+This request will be processed by various handlers. They will confirm the endpoint type of the request, check `HTTP/HTTPS`, verify that the request parameters (`client. scope, etc`) are valid and exist in the database, etc. Various protocol checks. And build a `OpenIddictRequest` object, If there are any errors, the response content may be set and directly short-circuit the current request.
-If everything is ok, the request will go to our processing controller(eg `TokenController`), we can get an `OpenIddictRequest` from the http request at this time. The rest of our work will be based on this object.
+If everything is ok, the request will go to our processing controller(eg `TokenController`), we can get an `OpenIddictRequest` from the HTTP request at this time. The rest will be based on this object.
-We may check the `username` and `password` in the request. If it is correct we create a `ClaimsPrincipal` object and return a `SignInResult`, which uses the `OpenIddict.Validation.AspNetCore` authentication scheme name, will calls `OpenIddictServerAspNetCoreHandler` for processing.
+Check the `username` and `password` in the request. If it is correct create a `ClaimsPrincipal` object and return a `SignInResult`, which uses the `OpenIddict.Validation.AspNetCore` authentication scheme name, will calls `OpenIddictServerAspNetCoreHandler` for processing.
`OpenIddictServerAspNetCoreHandler` do some checks to generate json and replace the http response content.
@@ -210,6 +408,26 @@ If you need to customize OpenIddict, you need to replace/delete/add new handlers
Please refer to:
https://documentation.openiddict.com/guides/index.html#events-model
-## Sponsor
+### PKCE
+
+https://documentation.openiddict.com/configuration/proof-key-for-code-exchange.html
+
+## Demo projects
+
+In the module's `app` directory there are six projects(including `angular`)
+
+* `OpenIddict.Demo.Server`: An abp application with integrated modules (has two `clients` and a `scope`).
+* `OpenIddict.Demo.API`: ASP NET Core API application using JwtBearer authentication.
+* `OpenIddict.Demo.Client.Mvc`: ASP NET Core MVC application using `OpenIdConnect` for authentication.
+* `OpenIddict.Demo.Client.Console`: Use `IdentityModel` to test OpenIddict's various endpoints, and call the api of `OpenIddict.Demo.API`.
+* `OpenIddict.Demo.Client.BlazorWASM:` ASP NET Core Blazor application using `OidcAuthentication` for authentication.
+* `angular`: An angular application that integrates the abp ng modules and uses oauth for authentication.
+
+#### How to run?
+
+Confirm the connection string of `appsettings.json` in the `OpenIddict.Demo.Server` project. Running the project will automatically create the database and initialize the data.
+After running the `OpenIddict.Demo.API` project, then you can run the rest of the projects to test.
+
+## Migrating Guide
-Please consider sponsoring this project: https://github.com/sponsors/kevinchalet
+[Migrating from IdentityServer to OpenIddict Step by Step Guide ](../Migration-Guides/OpenIddict-Step-by-Step.md)
diff --git a/docs/en/Modules/Setting-Management.md b/docs/en/Modules/Setting-Management.md
index e54993cf79..354fbdd539 100644
--- a/docs/en/Modules/Setting-Management.md
+++ b/docs/en/Modules/Setting-Management.md
@@ -118,7 +118,13 @@ The order of the providers are important. Providers are executed in the reverse
## Setting Management UI
-Setting Mangement module provided the email setting UI by default, and it is extensible; You can add your tabs to this page for your application settings.
+Setting Mangement module provided the email setting UI by default.
+
+
+
+> You can click the Send test email button to send a test email to check your email settings.
+
+Setting it is extensible; You can add your tabs to this page for your application settings.
### MVC UI
@@ -302,5 +308,4 @@ export class AppComponent {
Navigate to `/setting-management` route to see the changes:
-
-
+
\ No newline at end of file
diff --git a/docs/en/Multi-Tenancy.md b/docs/en/Multi-Tenancy.md
index 2603cb0436..7dac3762aa 100644
--- a/docs/en/Multi-Tenancy.md
+++ b/docs/en/Multi-Tenancy.md
@@ -32,6 +32,25 @@ Configure(options =>
> Multi-Tenancy is disabled in the ABP Framework by default. However, it is **enabled by default** when you create a new solution using the [startup template](Startup-Templates/Application.md). `MultiTenancyConsts` class in the solution has a constant to control it in a single place.
+### AbpMultiTenancyOptions: Handle inactive and non-existent tenants.
+
+The `MultiTenancyMiddlewareErrorPageBuilder` of `AbpMultiTenancyOptions` is used to handle inactive and non-existent tenants.
+
+It will respond to an error page by default, you can change it if you want, eg: only output the error log and continue ASP NET Core's request pipeline.
+
+```csharp
+Configure(options =>
+{
+ options.MultiTenancyMiddlewareErrorPageBuilder = async (context, exception) =>
+ {
+ // Handle the exception.
+
+ // Return true to stop the pipeline, false to continue.
+ return true;
+ };
+});
+```
+
### Database Architecture
ABP Framework supports all the following approaches to store the tenant data in the database;
@@ -203,7 +222,6 @@ The following resolvers are provided and configured by default;
* `CurrentUserTenantResolveContributor`: Gets the tenant id from claims of the current user, if the current user has logged in. **This should always be the first contributor for the security**.
* `QueryStringTenantResolveContributor`: Tries to find current tenant id from query string parameters. The parameter name is `__tenant` by default.
-* `FormTenantResolveContributor`:Tries to find current tenant id from form parameters. The parameter name is `__tenant` by default.
* `RouteTenantResolveContributor`: Tries to find current tenant id from route (URL path). The variable name is `__tenant` by default. If you defined a route with this variable, then it can determine the current tenant from the route.
* `HeaderTenantResolveContributor`: Tries to find current tenant id from HTTP headers. The header name is `__tenant` by default.
* `CookieTenantResolveContributor`: Tries to find current tenant id from cookie values. The cookie name is `__tenant` by default.
diff --git a/docs/en/Nightly-Builds.md b/docs/en/Nightly-Builds.md
index f835dcda9e..cf44b51045 100644
--- a/docs/en/Nightly-Builds.md
+++ b/docs/en/Nightly-Builds.md
@@ -1,19 +1,27 @@
# Nightly Builds
-All framework & module packages are deployed to MyGet every night in weekdays. So, you can use or test the latest code without waiting the next release.
+All framework & module packages are deployed to MyGet every night in weekdays. So, you can install the latest dev-brach builds to try out functionality prior to release.
## Install & Uninstall Nightly Preview Packages
-The latest version of nightly preview packages can be installed by the running below command in the root folder of application:
+The latest version of nightly preview packages can be installed by the running below command in the root folder of the application:
```bash
abp switch-to-nightly
```
+> Note that this command doesn't create a project with nightly preview packages. Instead, it switches package versions of a project with the nightly preview packages.
+
+After this command, a new NuGet feed will be added to the `NuGet.Config` file of your project. Then, you can get the latest code of ABP Framework without waiting for the next release.
+
+> You can check the [abp-nightly gallery](https://www.myget.org/gallery/abp-nightly) to see the all nightly preview packages.
+
If you're using the ABP Framework nightly preview packages, you can switch back to stable version using this command:
```bash
abp switch-to-stable
```
+ABP nightly NuGet feed is [https://www.myget.org/F/abp-nightly/api/v3/index.json](https://www.myget.org/F/abp-nightly/api/v3/index.json).
+
See the [ABP CLI documentation](./CLI.md) for more information.
diff --git a/docs/en/Object-To-Object-Mapping.md b/docs/en/Object-To-Object-Mapping.md
index f5ca805611..c12b260921 100644
--- a/docs/en/Object-To-Object-Mapping.md
+++ b/docs/en/Object-To-Object-Mapping.md
@@ -12,7 +12,7 @@ public class UserAppService : ApplicationService
_userRepository = userRepository;
}
- public void CreateUser(CreateUserInput input)
+ public async Task CreateUser(CreateUserInput input)
{
//Manually creating a User object from the CreateUserInput object
var user = new User
@@ -23,7 +23,7 @@ public class UserAppService : ApplicationService
Password = input.Password
};
- _userRepository.Insert(user);
+ await _userRepository.InsertAsync(user);
}
}
```
@@ -46,12 +46,12 @@ public class UserAppService : ApplicationService
_userRepository = userRepository;
}
- public void CreateUser(CreateUserInput input)
+ public async Task CreateUser(CreateUserInput input)
{
//Automatically creating a new User object using the CreateUserInput object
var user = ObjectMapper.Map(input);
- _userRepository.Insert(user);
+ await _userRepository.InsertAsync(user);
}
}
````
diff --git a/docs/en/Road-Map.md b/docs/en/Road-Map.md
index d7fb13a9a8..ec9b8fac01 100644
--- a/docs/en/Road-Map.md
+++ b/docs/en/Road-Map.md
@@ -4,18 +4,18 @@ This document provides a road map, release schedule and planned features for the
## Next Versions
-### v6.0
+### v7.0
-In [6.0 milestone](https://github.com/abpframework/abp/milestone/61), we will be mostly working on the following topics:
+In the [7.0 milestone](https://github.com/abpframework/abp/milestone/75), we will be mostly working on the following topics:
-* Providing an OpenIddict integration to replace current IdentityServer4 integration.
+* Dapr integration ([#13337](https://github.com/abpframework/abp/issues/13337))
+* Upgrade to .NET 7.0 ([#13336](https://github.com/abpframework/abp/issues/13336))
+* Integration Services ([#12470](https://github.com/abpframework/abp/issues/12470))
* Maturing and documenting the [eShopOnAbp](https://github.com/abpframework/eShopOnAbp) project, writing a free e-book that explains the solution.
-* Working on the [LeptonX](https://blog.abp.io/abp/LeptonX-Theme-for-ABP-Framework-Alpha-Release) theme and making it as the default theme for the ABP Framework UI options.
+* Working on the [LeptonX](https://blog.abp.io/abp/LeptonX-Theme-for-ABP-Framework-Alpha-Release) theme.
* Improvements on the existing features and providing more guides.
-The planned stable release date for v6.0 is **July, 2022**.
-
-> After the version 6.0, we will be working for ABP 7.0 which will be released in the end of 2022 based on .NET 7.0.
+The planned stable release date for v7.0 is **December, 2022**. We will be publishing more than one pre-release versions before that date.
## Backlog Items
@@ -23,7 +23,6 @@ The *Next Versions* section above shows the main focus of the planned versions.
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
* [#6655](https://github.com/abpframework/abp/pull/6655) / Use Typescript for the MVC UI
* [#236](https://github.com/abpframework/abp/issues/236) / Resource based authorization system
* [#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))
diff --git a/docs/en/SMS-Sending.md b/docs/en/SMS-Sending.md
index 0dca487a69..efe63c3c91 100644
--- a/docs/en/SMS-Sending.md
+++ b/docs/en/SMS-Sending.md
@@ -80,7 +80,7 @@ The given `SendAsync` method in the example is an extension method to send an SM
## NullSmsSender
-`NullSmsSender` is a the default implementation of the `ISmsSender`. It writes SMS content to the [standard logler](Logging.md), rather than actually sending the SMS.
+`NullSmsSender` is a the default implementation of the `ISmsSender`. It writes SMS content to the [standard logger](Logging.md), rather than actually sending the SMS.
This class can be useful especially in development time where you generally don't want to send real SMS. **However, if you want to actually send SMS, you should implement the `ISmsSender` in your application code.**
diff --git a/docs/en/Startup-Templates/Application.md b/docs/en/Startup-Templates/Application.md
index ec89f479ab..6a47363e8c 100644
--- a/docs/en/Startup-Templates/Application.md
+++ b/docs/en/Startup-Templates/Application.md
@@ -78,7 +78,7 @@ Based on the options you've specified, you will get a slightly different solutio
If you don't specify any additional options, you will have a solution as shown below:
-
+
Projects are organized in `src` and `test` folders. `src` folder contains the actual application which is layered based on [DDD](../Domain-Driven-Design.md) principles as mentioned before.
@@ -225,7 +225,7 @@ So, the resulting solution allows a 4-tiered deployment, by comparing to 3-tiere
The solution structure is shown below:
-
+
As different from the default structure, two new projects come into play: `.AuthServer` & `.HttpApi.Host`.
@@ -233,9 +233,9 @@ As different from the default structure, two new projects come into play: `.Auth
This project is used as an authentication server for other projects. `.Web` project uses OpenId Connect Authentication to get identity and access tokens for the current user from the AuthServer. Then uses the access token to call the HTTP API server. HTTP API server uses bearer token authentication to obtain claims from the access token to authorize the current user.
-
+
-ABP uses the open source [OpenIddcit](https://github.com/openiddict/openiddict-core) framework for the authentication between applications. See [OpenIddcit documentation](https://documentation.openiddict.com/) for details about the OpenIddict and OpenID Connect protocol.
+ABP uses the [OpenIddict Module](../Modules/OpenIddict.md) that uses the open-source [OpenIddict-core](https://github.com/openiddict/openiddict-core) library for the authentication between applications. See [OpenIddict documentation](https://documentation.openiddict.com/) for details about the OpenIddict and OpenID Connect protocol.
It has its own `appsettings.json` that contains database connection and other configurations.
diff --git a/docs/en/Themes/LeptonXLite/angular.md b/docs/en/Themes/LeptonXLite/Angular.md
similarity index 91%
rename from docs/en/Themes/LeptonXLite/angular.md
rename to docs/en/Themes/LeptonXLite/Angular.md
index 805ababd69..506ffaf753 100644
--- a/docs/en/Themes/LeptonXLite/angular.md
+++ b/docs/en/Themes/LeptonXLite/Angular.md
@@ -7,6 +7,8 @@ LeptonX Lite has implementation for the ABP Framework Angular Client. It's a sim
## Installation
+This theme is **already installed** when you create a new solution using the startup templates. If you are using any other template, you can install this theme by following the steps below:
+
To add `LeptonX-lite` into your project,
* Install `@abp/ng.theme.lepton-x`
@@ -79,4 +81,4 @@ To change the logos and brand color of `LeptonX`, simply add the following CSS t
### Server Side
-In order to migrate to LeptonX on your server side projects (Host and/or AuthServer projects), please follow the [Server Side Migration](mvc.md) document.
+In order to migrate to LeptonX on your server side projects (Host and/or AuthServer projects), please follow the [Server Side Migration](AspNetCore.md) document.
diff --git a/docs/en/Themes/LeptonXLite/AspNetCore.md b/docs/en/Themes/LeptonXLite/AspNetCore.md
new file mode 100644
index 0000000000..f480141120
--- /dev/null
+++ b/docs/en/Themes/LeptonXLite/AspNetCore.md
@@ -0,0 +1,215 @@
+# LeptonX Lite MVC UI
+LeptonX Lite has implementation for the ABP Framework Razor Pages. It's a simplified variation of the [LeptonX Theme](https://x.leptontheme.com/).
+
+> If you are looking for a professional, enterprise ready theme, you can check the [LeptonX Theme](https://x.leptontheme.com/), which is a part of [ABP Commercial](https://commercial.abp.io/).
+
+> See the [Theming document](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Theming) to learn about themes.
+
+## Installation
+
+This theme is **already installed** when you create a new solution using the startup templates. If you are using any other template, you can install this theme by following the steps below:
+
+- Add the **Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite** package to your **Web** application.
+
+```bash
+dotnet add package Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite --prerelease
+```
+
+- Remove the **Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic** reference from the project since it's not necessary after switching to LeptonX Lite.
+
+- Make sure the old theme is removed and LeptonX is added in your Module class.
+
+```diff
+[DependsOn(
+ // Remove the BasicTheme module from DependsOn attribute
+- typeof(AbpAspNetCoreMvcUiBasicThemeModule),
+
+ // Add the LeptonX Lite module to DependsOn attribute
++ typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule),
+)]
+```
+
+- Replace `BasicThemeBundles` with `LeptonXLiteThemeBundles` in AbpBundlingOptions
+
+```diff
+Configure(options =>
+{
+ options.StyleBundles.Configure(
+ // Remove the following line
+- BasicThemeBundles.Styles.Global,
+ // Add the following line instead
++ LeptonXLiteThemeBundles.Styles.Global
+ bundle =>
+ {
+ bundle.AddFiles("/global-styles.css");
+ }
+ );
+});
+```
+
+## Customization
+
+### Layouts
+
+LeptonX Lite Mvc provides **layouts** for your **user interface** based [ABP Framework Theming](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Theming). You can use **layouts** to **organize your user interface**.
+
+The main responsibility of a theme is to **provide** the layouts. There are **three pre-defined layouts that must be implemented by all the themes:**
+
+* **Application:** The **default** layout which is used by the **main** application pages.
+
+* **Account:** Mostly used by the **account module** for **login**, **register**, **forgot password**... pages.
+
+* **Empty:** The **Minimal** layout that **has no layout components** at all.
+
+**Layout names** are **constants** defined in the `LeptonXLiteTheme` class in the **Mvc** project **root**.
+
+> The layout pages define under the `Themes/LeptonXLite/Layouts` folder and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+### Toolbars
+LeptonX Lite includes separeted toolbars for desktop & mobile. You can manage toolbars independently. Toolbar names can be accessible in the **LeptonXLiteToolbars** class.
+
+- `LeptonXLiteToolbars.Main`
+- `LeptonXLiteToolbars.MainMobile`
+
+```csharp
+public class MyProjectNameMainToolbarContributor : IToolbarContributor
+{
+ public async Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
+ {
+ if (context.Toolbar.Name == LeptonXLiteToolbars.Main)
+ {
+ context.Toolbar.Items.Add(new ToolbarItem(typeof(MyDesktopComponent)));
+ }
+
+ if (context.Toolbar.Name == LeptonXLiteToolbars.MainMobile)
+ {
+ context.Toolbar.Items.Add(new ToolbarItem(typeof(MyMobileComponent)));
+ }
+ }
+}
+```
+# LeptonX Lite Mvc Components
+
+Abp **helps** you make **highly customizable UI**. You can easily **customize** your themes to fit your needs. **The Virtual File System** makes it possible to **manage files** that **do not physically** exist on the **file system** (disk). It's mainly used to embed **(js, css, image..)** files into assemblies and **use them like** physical files at runtime. An application (or another module) can **override** a **virtual file of a module** just like placing a file with the **same name** and **extension** into the **same folder** of the **virtual file**.
+
+LeptonX Lite is built on the [Abp Framework](https://abp.io/), so you can **easily** customize your Asp.Net Core Mvc user interface by following [Abp Mvc UI Customization](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Customization-xUser-Interface).
+
+## Brand Component
+
+The **brand component** is a simple component that can be used to display your brand. It contains a **logo** and a **company name**.
+
+
+
+### How to override the Brand Component in LeptonX Lite Mvc
+
+* The **brand component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/Brand/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+* The **brand component (C# file)** is defined in the `Themes/LeptonXLite/Components/Brand/MainNavbarBrandViewComponent.cs` file and you can **override it** by creating a file with the **same name** and under the **same folder**.
+
+## Breadcrumb Component
+
+On websites that have a lot of pages, **breadcrumb navigation** can greatly **enhance the way users find their way** around. In terms of **usability**, breadcrumbs reduce the number of actions a website **visitor** needs to take in order to get to a **higher-level page**, and they **improve** the **findability** of **website sections** and **pages**.
+
+
+
+### How to override the Breadcrumb Component in LeptonX Lite Mvc
+
+* The **breadcrumb component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/Breadcrumbs/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+* The **breadcrumb component (C# file)** is defined in the `Themes/LeptonXLite/Components/Breadcrumbs/BreadcrumbsViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+## Sidebar Menu Component
+
+Sidebar menus have been used as **a directory for Related Pages** to a **Service** offering, **Navigation** items to a **specific service** or topic and even just as **Links** the user may be interested in.
+
+
+
+### How to override the Sidebar Menu Component in LeptonX Lite Mvc
+
+* **Sidebar menu page (.cshtml)** is defined in the `Themes/LeptonXLite/Components/Menu/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+* If you want to **override the menu component (C#)** you can override the `Themes/LeptonXLite/Components/Menu/MainMenuViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+> The **sidebar menu** renders menu items **dynamically**. The **menu item** is a **partial view** and is defined in the `Themes/LeptonXLite/Components/Menu/_MenuItem.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+## Page Alerts Component
+
+Provides contextual **feedback messages** for typical user actions with the handful of **available** and **flexible** **alert messages**. Alerts are available for any length of text, as well as an **optional dismiss button**.
+
+
+
+### How to override the Page Alerts Component in LeptonX Lite Mvc
+
+* The **page alerts component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/PageAlerts/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+* The **page alerts component (C#)** is defined in the `Themes/LeptonXLite/Components/PageAlerts/PageAlertsViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+## Toolbar Component
+
+Toolbar items are used to add **extra functionality to the toolbar**. The toolbar is a **horizontal bar** that **contains** a group of **toolbar items**.
+
+### How to override the Toolbar Component in LeptonX Lite Mvc
+
+* The **toolbar component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/Toolbar/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+* The **toolbar component (C#)** is defined in the `Themes/LeptonXLite/Components/Toolbar/ToolbarViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+## Toolbar Item Component
+
+The toolbar item is a **single item** that **contains** a **link**, an **icon**, a **label** etc..
+
+### How to override the Toolbar Item Component in LeptonX Lite Mvc
+
+* The **toolbar item component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/ToolbarItems/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+* The **toolbar item component (C#)** is defined in the `Themes/LeptonXLite/Components/ToolbarItems/ToolbarItemsViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+You can find the toolbar components below:
+
+## Language Switch Component
+
+Think about a **multi-lingual** website and the first thing that could **hit your mind** is **the language switch component**. A **navigation bar** is a **great place** to **embed a language switch**. By embedding the language switch in the navigation bar of your website, you would **make it simpler** for users to **find it** and **easily** switch the **language** **without trying to locate it across the website.**
+
+
+
+### How to override the Language Switch Component in LeptonX Lite Mvc
+
+* The **language switch component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/LanguageSwitch/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+* The **language switch component (C#)** is defined in the `Themes/LeptonXLite/Components/LanguageSwitch/LanguageSwitchViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+## Mobile Language Switch Component
+
+The **mobile** **language switch component** is used to switch the language of the website **on mobile devices**. The mobile language switch component is a **dropdown menu** that **contains all the languages** of the website.
+
+
+
+### How to override the Mobile Language Switch Component in LeptonX Lite Mvc
+
+* The **mobile language switch component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/MobileLanguageSwitch/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+* The **mobile language switch component (C#)** is defined in the `Themes/LeptonXLite/Components/MobileLanguageSwitch/MobileLanguageSwitchViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+## User Menu Component
+
+The **User Menu** is the **menu** that **drops down** when you **click your name** or **profile picture** in the **upper right corner** of your page (**in the toolbar**). It drops down options such as **Settings**, **Logout**, etc.
+
+
+
+### How to override the User Menu Component in LeptonX Lite Mvc
+
+* The **user menu component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/UserMenu/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+* The **user menu component (C#)** is defined in the `Themes/LeptonXLite/Components/UserMenu/UserMenuViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+## Mobile User Menu Component
+
+The **mobile user menu component** is used to display the **user menu on mobile devices**. The mobile user menu component is a **dropdown menu** that contains all the **options** of the **user menu**.
+
+
+
+### How to override the Mobile User Menu Component in LeptonX Lite Mvc
+
+* The **mobile user menu component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/MobileUserMenu/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
+
+* The **mobile user menu component (C#)** is defined in the `Themes/LeptonLite/Components/MobileUserMenu/MobileUserMenuViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**.
diff --git a/docs/en/Themes/LeptonXLite/blazor.md b/docs/en/Themes/LeptonXLite/Blazor.md
similarity index 87%
rename from docs/en/Themes/LeptonXLite/blazor.md
rename to docs/en/Themes/LeptonXLite/Blazor.md
index f443336e7c..636c33ef28 100644
--- a/docs/en/Themes/LeptonXLite/blazor.md
+++ b/docs/en/Themes/LeptonXLite/Blazor.md
@@ -15,8 +15,11 @@ LeptonX Lite has implementation for the ABP Framework Blazor WebAssembly & Blazo
## Installation
+This theme is **already installed** when you create a new solution using the startup templates. If you are using any other template, you can install this theme by following the steps below:
+
{{if UI == "Blazor"}}
-- Complete the [MVC Razor Pages Installation](mvc.md#installation) for the **HttpApi.Host** application first. _If the solution is tiered/micro-service, complete the MVC steps for all MVC applications such as **HttpApi.Host** and if identity server is separated, install to the **OpenIddict**_.
+- Complete the [MVC Razor Pages Installation](AspNetCore.md#installation) for the **HttpApi.Host** application first. _If the solution is tiered/micro-service, complete the MVC steps for all MVC applications such as **HttpApi.Host** and if identity server is separated, install to the **OpenIddict**_.
+
- Add **Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme** package to your **Blazor WebAssembly** application with the following command:
@@ -52,7 +55,7 @@ builder.RootComponents.Add("#ApplicationContainer");
{{if UI == "BlazorServer"}}
-- Complete the [MVC Razor Pages Installation](mvc.md#installation) first. _If the solution is tiered/micro-service, complete the MVC steps for all MVC applications such as **HttpApi.Host** and **AuthServer**_.
+- Complete the [MVC Razor Pages Installation](AspNetCore.md#installation) first. _If the solution is tiered/micro-service, complete the MVC steps for all MVC applications such as **HttpApi.Host** and **AuthServer**_.
- Add **Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme** package to your **Blazor server** application with the following command:
diff --git a/docs/en/Themes/LeptonXLite/mvc.md b/docs/en/Themes/LeptonXLite/mvc.md
deleted file mode 100644
index 5c2c515613..0000000000
--- a/docs/en/Themes/LeptonXLite/mvc.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# LeptonX Lite MVC UI
-LeptonX Lite has implementation for the ABP Framework Razor Pages. It's a simplified variation of the [LeptonX Theme](https://x.leptontheme.com/).
-
-> If you are looking for a professional, enterprise ready theme, you can check the [LeptonX Theme](https://x.leptontheme.com/), which is a part of [ABP Commercial](https://commercial.abp.io/).
-
-> See the [Theming document](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Theming) to learn about themes.
-
-## Installation
-
-- Add **Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite** package to your **Web** application.
-
-```bash
-dotnet add package Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite --prerelease
-```
-
-- Remove **Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic** reference from the project since it's not necessary after switching to LeptonX Lite.
-
-- Make sure the old theme is removed and LeptonX is added in your Module class.
-
-```diff
-[DependsOn(
- // Remove BasicTheme module from DependsOn attribute
-- typeof(AbpAspNetCoreMvcUiBasicThemeModule),
-
- // Add LeptonX Lite module to DependsOn attribute
-+ typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule),
-)]
-```
-
-- Replace `BasicThemeBundles` with `LeptonXLiteThemeBundles` in AbpBundlingOptions
-
-```diff
-Configure(options =>
-{
- options.StyleBundles.Configure(
- // Remove following line
-- BasicThemeBundles.Styles.Global,
- // Add following line instead
-+ LeptonXLiteThemeBundles.Styles.Global
- bundle =>
- {
- bundle.AddFiles("/global-styles.css");
- }
- );
-});
-```
-
----
-
-## Customization
-
-### Toolbars
-LeptonX Lite includes separeted toolbars for desktop & mobile. You can manage toolbars independently. Toolbar names can be accessible in the **LeptonXLiteToolbars** class.
-
-- `LeptonXLiteToolbars.Main`
-- `LeptonXLiteToolbars.MainMobile`
-
-```csharp
-public class MyProjectNameMainToolbarContributor : IToolbarContributor
-{
- public async Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
- {
- if (context.Toolbar.Name == LeptonXLiteToolbars.Main)
- {
- context.Toolbar.Items.Add(new ToolbarItem(typeof(MyDesktopComponent)));
- }
-
- if (context.Toolbar.Name == LeptonXLiteToolbars.MainMobile)
- {
- context.Toolbar.Items.Add(new ToolbarItem(typeof(MyMobileComponent)));
- }
- }
-}
-```
diff --git a/docs/en/Tutorials/Part-2.md b/docs/en/Tutorials/Part-2.md
index 50b90b516d..3e7a1bc735 100644
--- a/docs/en/Tutorials/Part-2.md
+++ b/docs/en/Tutorials/Part-2.md
@@ -135,22 +135,22 @@ Open the `en.json` (*the English translations*) file and change the content as s
"CreationTime": "Creation time",
"AreYouSure": "Are you sure?",
"AreYouSureToDelete": "Are you sure you want to delete this item?",
- "Enum:BookType:0": "Undefined",
- "Enum:BookType:1": "Adventure",
- "Enum:BookType:2": "Biography",
- "Enum:BookType:3": "Dystopia",
- "Enum:BookType:4": "Fantastic",
- "Enum:BookType:5": "Horror",
- "Enum:BookType:6": "Science",
- "Enum:BookType:7": "Science fiction",
- "Enum:BookType:8": "Poetry"
+ "Enum:BookType.Undefined": "Undefined",
+ "Enum:BookType.Adventure": "Adventure",
+ "Enum:BookType.Biography": "Biography",
+ "Enum:BookType.Dystopia": "Dystopia",
+ "Enum:BookType.Fantastic": "Fantastic",
+ "Enum:BookType.Horror": "Horror",
+ "Enum:BookType.Science": "Science",
+ "Enum:BookType.ScienceFiction": "Science fiction",
+ "Enum:BookType.Poetry": "Poetry"
}
}
````
* Localization key names are arbitrary. You can set any name. We prefer some conventions for specific text types;
* Add `Menu:` prefix for menu items.
- * Use `Enum::` naming convention to localize the enum members. When you do it like that, ABP can automatically localize the enums in some proper cases.
+ * Use `Enum:.` or `.` or `` naming convention to localize the enum members. When you do it like that, ABP can automatically localize the enums in some proper cases.
If a text is not defined in the localization file, it **falls back** to the localization key (as ASP.NET Core's standard behavior).
@@ -624,7 +624,7 @@ Open the `Books.razor` and replace the content as the following:
Field="@nameof(BookDto.Type)"
Caption="@L["Type"]">
- @L[$"Enum:BookType:{(int)context.Type}"]
+ @L[$"Enum:BookType.{Enum.GetName(context.Type)}"]
- @L[$"Enum:BookType:{bookTypeValue}"]
+ @L[$"Enum:BookType.{Enum.GetName((BookType)bookTypeValue)}"]
}
@@ -1322,7 +1322,7 @@ We can now define a modal to edit the book. Add the following code to the end of
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
- @L[$"Enum:BookType:{bookTypeValue}"]
+ @L[$"Enum:BookType.{Enum.GetName((BookType)bookTypeValue)}"]
}
@@ -1459,7 +1459,7 @@ Here's the complete code to create the book management CRUD page, that has been
Field="@nameof(BookDto.Type)"
Caption="@L["Type"]">
- @L[$"Enum:BookType:{(int) context.Type}"]
+ @L[$"Enum:BookType.{Enum.GetName(context.Type)}"]
- @L[$"Enum:BookType:{bookTypeValue}"]
+ @L[$"Enum:BookType.{Enum.GetName((BookType)bookTypeValue)}"]
}
@@ -1564,7 +1564,7 @@ Here's the complete code to create the book management CRUD page, that has been
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
- @L[$"Enum:BookType:{bookTypeValue}"]
+ @L[$"Enum:BookType.{Enum.GetName((BookType)bookTypeValue)}"]
}
diff --git a/docs/en/Tutorials/Todo/Index.md b/docs/en/Tutorials/Todo/Index.md
index 5ecee2074b..e373871183 100644
--- a/docs/en/Tutorials/Todo/Index.md
+++ b/docs/en/Tutorials/Todo/Index.md
@@ -25,15 +25,17 @@ You can find the source code of the completed application [here](https://github.
{{end}}
-## Creating a New Solution
+## Install ABP CLI Tool
-We will use the [ABP CLI](../../CLI.md) to create new solutions with the ABP Framework. You can run the following command in a command-line terminal to install it:
+We will use the [ABP CLI](../../CLI.md) to create new ABP solutions. You can run the following command on a terminal window to install this dotnet tool:
````bash
dotnet tool install -g Volo.Abp.Cli
````
-Then create an empty folder, open a command-line terminal and execute the following command in the terminal:
+## Create Your ABP Solution
+
+Create an empty folder, open a command-line terminal and execute the following command in the terminal:
````bash
abp new TodoApp{{if UI=="Blazor"}} -u blazor{{else if UI=="BlazorServer"}} -u blazor-server{{else if UI=="NG"}} -u angular{{end}}{{if DB=="Mongo"}} -d mongodb{{end}}
diff --git a/docs/en/UI/Angular/Basic-Theme.md b/docs/en/UI/Angular/Basic-Theme.md
index 7b6c98fdcc..6b9ffcfeb1 100644
--- a/docs/en/UI/Angular/Basic-Theme.md
+++ b/docs/en/UI/Angular/Basic-Theme.md
@@ -8,7 +8,7 @@ The Basic Theme is a theme implementation for the Angular UI. It is a minimalist
## Installation
-**This theme is already installed** when you create a new solution using the [startup templates](../../Startup-Templates/Index.md). If you need to manually install it, follow the steps below:
+If you need to manually this theme, follow the steps below:
* Install the [@abp/ng.theme.basic](https://www.npmjs.com/package/@abp/ng.theme.basic) NPM package to your Angular project.
* Open the `src/app/app.module.ts` file, import `ThemeBasicModule` (it can be imported from `@abp/ng.theme.basic` package), and add `ThemeBasicModule.forRoot()` to the `imports` array.
diff --git a/docs/en/UI/Angular/Config-State-Service.md b/docs/en/UI/Angular/Config-State-Service.md
index b3884f65e1..c457184fc2 100644
--- a/docs/en/UI/Angular/Config-State-Service.md
+++ b/docs/en/UI/Angular/Config-State-Service.md
@@ -120,10 +120,10 @@ Please refer to `ApplicationConfigurationDto` type for all the properties you ca
You can get the application configuration response and set the `ConfigStateService` state value as shown below:
```js
-import {ApplicationConfigurationService, ConfigStateService} from '@abp/ng.core';
+import {AbpApplicationConfigurationService, ConfigStateService} from '@abp/ng.core';
-constructor(private applicationConfigurationService: ApplicationConfigurationService, private config: ConfigStateService) {
- this.applicationConfigurationService.getConfiguration().subscribe(config => {
+constructor(private abpApplicationConfigurationService: AbpApplicationConfigurationService, private config: ConfigStateService) {
+ this.abpApplicationConfigurationService.get().subscribe(config => {
this.config.setState(config);
})
}
diff --git a/docs/en/UI/Angular/Current-User.md b/docs/en/UI/Angular/Current-User.md
new file mode 100644
index 0000000000..820a787b5c
--- /dev/null
+++ b/docs/en/UI/Angular/Current-User.md
@@ -0,0 +1,20 @@
+# Angular UI: Current User
+
+The current user information stored in Config State.
+
+### How to Get a Current User Information Configuration
+
+You can use the `getOne` or `getOne$` method of `ConfigStateService` to get a specific configuration property. For that, the property name should be passed to the method as parameter.
+
+```js
+// this.config is an instance of ConfigStateService
+
+const currentUser = this.config.getOne("currentUser");
+
+// or
+this.config.getOne$("currentUser").subscribe(currentUser => {
+ // use currentUser here
+})
+```
+
+> See the [ConfigStateService](./Config-State-Service) for more information.
diff --git a/docs/en/UI/Angular/Theming.md b/docs/en/UI/Angular/Theming.md
index c7f303763d..435acc6930 100644
--- a/docs/en/UI/Angular/Theming.md
+++ b/docs/en/UI/Angular/Theming.md
@@ -16,10 +16,11 @@ In order to accomplish these goals, ABP Framework;
### Current Themes
-Currently, two themes are **officially provided**:
+Currently, three themes are **officially provided**:
* The [Basic Theme](Basic-Theme.md) is the minimalist theme with the plain Bootstrap style. It is **open source and free**.
* The [Lepton Theme](https://commercial.abp.io/themes) is a **commercial** theme developed by the core ABP team and is a part of the [ABP Commercial](https://commercial.abp.io/) license.
+* The [LeptonX Theme](https://x.leptontheme.com/) is a theme that has both [commercial](https://docs.abp.io/en/commercial/latest/themes/lepton-x/commercial/angular) and [lite](../../Themes/LeptonXLite/Angular.md) choices.
## Overall
diff --git a/docs/en/UI/AspNetCore/Basic-Theme.md b/docs/en/UI/AspNetCore/Basic-Theme.md
index e74799a423..903231a20a 100644
--- a/docs/en/UI/AspNetCore/Basic-Theme.md
+++ b/docs/en/UI/AspNetCore/Basic-Theme.md
@@ -10,7 +10,7 @@ The Basic Theme has RTL (Right-to-Left language) support.
## Installation
-**This theme is already installed** when you create a new solution using the [startup templates](../../Startup-Templates/Index.md). If you need to manually install it, follow the steps below:
+If you need to manually this theme, follow the steps below:
* Install the [Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic) NuGet package to your web project.
* Add `AbpAspNetCoreMvcUiBasicThemeModule` into the `[DependsOn(...)]` attribute for your [module class](../../Module-Development-Basics.md) in the web project.
diff --git a/docs/en/UI/AspNetCore/Modals.md b/docs/en/UI/AspNetCore/Modals.md
index 3824c45983..b0a0ba922e 100644
--- a/docs/en/UI/AspNetCore/Modals.md
+++ b/docs/en/UI/AspNetCore/Modals.md
@@ -9,7 +9,7 @@ While you can continue to use the standard [Bootstrap way](https://getbootstrap.
ABP Framework provides the following benefits for such a modal with a form inside it;
* **Lazy loads** the modal HTML into the page and **removes** it from the DOM once its closed. This makes easy to consume a reusable modal dialog. Also, every time you open the modal, it will be a fresh new modal, so you don't have to deal with resetting the modal content.
-* **Auto-focuses** the first input of the form once the modal has been opened.
+* **Auto-focuses** the first input of the form once the modal has been opened. You can also specify it using a `function` or `jquery selector`.
* Automatically determines the **form** inside a modal and posts the form via **AJAX** instead of normal page post.
* Automatically checks if the form inside the modal **has changed, but not saved**. It warns the user in this case.
* Automatically **disables the modal buttons** (save & cancel) until the AJAX operation completes.
@@ -429,6 +429,7 @@ Here, the list of all available options;
* `viewUrl` (required, `string`): The URL to lazy load the HTML of the modal.
* `scriptUrl` (optional, `string`): A URL to lazy load a JavaScript file. It is loaded only once, when the modal first opened.
* `modalClass` (optional, `string`): A JavaScript class defined in the `abp.modals` namespace that can be used to execute code related to the modal.
+* `focusElement` (optional, `function or string`): Specifies the element that gets focus.
### Functions
diff --git a/docs/en/UI/AspNetCore/Overall.md b/docs/en/UI/AspNetCore/Overall.md
index 8cd9dd3f5e..bc24c56fb8 100644
--- a/docs/en/UI/AspNetCore/Overall.md
+++ b/docs/en/UI/AspNetCore/Overall.md
@@ -32,10 +32,11 @@ ABP Framework provides a complete [Theming](Theming.md) system with the followin
### Current Themes
-Currently, two themes are **officially provided**:
+Currently, three themes are **officially provided**:
* The [Basic Theme](Basic-Theme.md) is the minimalist theme with the plain Bootstrap style. It is **open source and free**.
* The [Lepton Theme](https://commercial.abp.io/themes) is a **commercial** theme developed by the core ABP team and is a part of the [ABP Commercial](https://commercial.abp.io/) license.
+* The [LeptonX Theme](https://x.leptontheme.com/) is a theme that has both [commercial](https://docs.abp.io/en/commercial/latest/themes/lepton-x/commercial/mvc) and [lite](../../Themes/LeptonXLite/AspNetCore.md) choices.
There are also some community-driven themes for the ABP Framework (you can search on the web).
diff --git a/docs/en/UI/AspNetCore/Page-Header.md b/docs/en/UI/AspNetCore/Page-Header.md
index f6ec3074de..8b045c89ab 100644
--- a/docs/en/UI/AspNetCore/Page-Header.md
+++ b/docs/en/UI/AspNetCore/Page-Header.md
@@ -23,6 +23,8 @@ Page Title can be set as shown in the example below:
### Breadcrumb
> **The [Basic Theme](Basic-Theme.md) currently doesn't implement the breadcrumbs.**
+>
+> The [LeptonX Lite Theme](../../Themes/LeptonXLite/AspNetCore.md) supports breadcrumbs.
Breadcrumb items can be added to the `PageLayout.Content.BreadCrumb`.
@@ -48,11 +50,13 @@ Any item that you add is inserted between Home and Current Page items. You can a
### The Selected Menu Item
> **The [Basic Theme](Basic-Theme.md) currently doesn't implement the selected menu item since it is not applicable to the top menu which is the only option for the Basic Theme for now.**
+>
+> The [LeptonX Lite Theme](../../Themes/LeptonXLite/AspNetCore.md) supports selected menu item.
You can set the Menu Item name related to this page:
-````csharp
+```csharp
PageLayout.Content.MenuItemName = "BookStore.Books";
-````
+```
Menu item name should match a unique menu item name defined using the [Navigation / Menu](Navigation-Menu.md) system. In this case, it is expected from the theme to make the menu item "active" in the main menu.
\ No newline at end of file
diff --git a/docs/en/UI/AspNetCore/Theming.md b/docs/en/UI/AspNetCore/Theming.md
index fd2e7312de..050228de2d 100644
--- a/docs/en/UI/AspNetCore/Theming.md
+++ b/docs/en/UI/AspNetCore/Theming.md
@@ -16,10 +16,12 @@ In order to accomplish these goals, ABP Framework;
### Current Themes
-Currently, two themes are **officially provided**:
+Currently, four themes are **officially provided**:
* The [Basic Theme](Basic-Theme.md) is the minimalist theme with the plain Bootstrap style. It is **open source and free**.
+* The [LeptonX Lite Theme](../../Themes/LeptonXLite/AspNetCore.md) is modern and stylish Bootstrap UI theme. It is ideal if you want to have a production ready UI theme. It is also **open source and free**.
* The [Lepton Theme](https://commercial.abp.io/themes) is a **commercial** theme developed by the core ABP team and is a part of the [ABP Commercial](https://commercial.abp.io/) license.
+* The [LeptonX Theme](https://docs.abp.io/en/commercial/6.0/themes/leptonx) is also a **commercial** theme developed by the core ABP theme and is a part of the [ABP Commercial](https://commercial.abp.io/) license. This is the default theme after ABP v6.0.0.
There are also some community-driven themes for the ABP Framework (you can search on the web).
diff --git a/docs/en/UI/AspNetCore/Toolbars.md b/docs/en/UI/AspNetCore/Toolbars.md
index d82150b47e..975157151f 100644
--- a/docs/en/UI/AspNetCore/Toolbars.md
+++ b/docs/en/UI/AspNetCore/Toolbars.md
@@ -8,6 +8,12 @@ There is only one **standard toolbar** named "Main" (defined as a constant: `Sta
In the screenshot above, there are two items added to the main toolbar: Language switch component & user menu. You can add your own items here.
+Also, [LeptonX Lite Theme](../../Themes/LeptonXLite/AspNetCore.md) has 2 different toolbars for desktop and mobile views which defined as constants: `LeptonXLiteToolbars.Main`, `LeptonXLiteToolbars.MainMobile`.
+
+| LeptonXLiteToolbars.Main | LeptonXLiteToolbars.MainMobile |
+| :---: | :---: |
+|  |  |
+
## Example: Add a Notification Icon
In this example, we will add a **notification (bell) icon** to the left of the language switch item. A item in the toolbar should be a **view component**. So, first, create a new view component in your project:
diff --git a/docs/en/UI/Blazor/Basic-Theme.md b/docs/en/UI/Blazor/Basic-Theme.md
index 2cd0914e2f..4060f097ba 100644
--- a/docs/en/UI/Blazor/Basic-Theme.md
+++ b/docs/en/UI/Blazor/Basic-Theme.md
@@ -15,7 +15,7 @@ The Basic Theme is a theme implementation for the Blazor UI. It is a minimalist
## Installation
-**This theme is already installed** when you create a new solution using the [startup templates](../../Startup-Templates/Index.md). If you need to manually install it, follow the steps below:
+If you need to manually this theme, follow the steps below:
{{if UI == "Blazor"}}
diff --git a/docs/en/UI/Blazor/Overall.md b/docs/en/UI/Blazor/Overall.md
index ff361d6784..402d61acb0 100644
--- a/docs/en/UI/Blazor/Overall.md
+++ b/docs/en/UI/Blazor/Overall.md
@@ -75,10 +75,11 @@ ABP Framework provides a complete [Theming](Theming.md) system with the followin
### Current Themes
-Currently, two themes are **officially provided**:
+Currently, three themes are **officially provided**:
* The [Basic Theme](Basic-Theme.md) is the minimalist theme with the plain Bootstrap style. It is **open source and free**.
* The [Lepton Theme](https://commercial.abp.io/themes) is a **commercial** theme developed by the core ABP team and is a part of the [ABP Commercial](https://commercial.abp.io/) license.
+* The [LeptonX Theme](https://x.leptontheme.com/) is a theme that has both [commercial](https://docs.abp.io/en/commercial/latest/themes/lepton-x/commercial/blazor) and [lite](../../Themes/LeptonXLite/Blazor.md) choices.
### Base Libraries
diff --git a/docs/en/UI/Blazor/Page-Header.md b/docs/en/UI/Blazor/Page-Header.md
index 29cb006bd3..1bdc9c93c0 100644
--- a/docs/en/UI/Blazor/Page-Header.md
+++ b/docs/en/UI/Blazor/Page-Header.md
@@ -16,6 +16,8 @@ Once you add the `PageHeader` component to your page, you can control the relate
## Breadcrumb
> **The [Basic Theme](Basic-Theme.md) currently doesn't implement the breadcrumbs.**
+>
+> The [LeptonX Lite Theme](../../Themes/LeptonXLite/Blazor.md) supports breadcrumbs.
Breadcrumbs can be added using the `BreadcrumbItems` property.
diff --git a/docs/en/UI/Blazor/Page-Layout.md b/docs/en/UI/Blazor/Page-Layout.md
index 49ed1659f4..c6f3d62000 100644
--- a/docs/en/UI/Blazor/Page-Layout.md
+++ b/docs/en/UI/Blazor/Page-Layout.md
@@ -42,6 +42,10 @@ Menu item name can be set on runtime too.
}
```
+
+
+
+
> Be aware, The [Basic Theme](../Blazor/Basic-Theme.md) currently doesn't support the selected menu item since it is not applicable to the top menu.
## BreadCrumbs
diff --git a/docs/en/UI/Blazor/Theming.md b/docs/en/UI/Blazor/Theming.md
index c7f92189de..d8cec07cb3 100644
--- a/docs/en/UI/Blazor/Theming.md
+++ b/docs/en/UI/Blazor/Theming.md
@@ -27,7 +27,7 @@ Currently, three themes are **officially provided**:
* The [Basic Theme](Basic-Theme.md) is the minimalist theme with the plain Bootstrap style. It is **open source and free**.
* The [Lepton Theme](https://commercial.abp.io/themes) is a **commercial** theme developed by the core ABP team and is a part of the [ABP Commercial](https://commercial.abp.io/) license.
-* The [LeptonX Theme](https://x.leptontheme.com/) is a theme that has a [commercial](https://docs.abp.io/en/commercial/latest/themes/lepton-x/commercial/blazor) and a [lite](../../Themes/LeptonXLite/blazor.md) version.
+* The [LeptonX Theme](https://x.leptontheme.com/) is a theme that has a [commercial](https://docs.abp.io/en/commercial/latest/themes/lepton-x/commercial/blazor) and a [lite](../../Themes/LeptonXLite/Blazor.md) version.
## Overall
diff --git a/docs/en/UI/Blazor/Toolbars.md b/docs/en/UI/Blazor/Toolbars.md
index 3ff1b7f135..c0878f080a 100644
--- a/docs/en/UI/Blazor/Toolbars.md
+++ b/docs/en/UI/Blazor/Toolbars.md
@@ -8,6 +8,12 @@ There is only one **standard toolbar** named "Main" (defined as a constant: `Sta
In the screenshot above, there are two items added to the main toolbar: Language switch component & user menu. You can add your own items here.
+Also, [LeptonX Lite Theme](../../Themes/LeptonXLite/Blazor.md) has 2 different toolbars for desktop and mobile views which defined as constants: `LeptonXLiteToolbars.Main`, `LeptonXLiteToolbars.MainMobile`.
+
+| LeptonXLiteToolbars.Main | LeptonXLiteToolbars.MainMobile |
+| :---: | :---: |
+|  |  |
+
## Example: Add a Notification Icon
In this example, we will add a **notification (bell) icon** to the left of the language switch item. A item in the toolbar should be a **Razor Component**. So, first, create a new razor component in your project (the location of the component doesn't matter):
diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json
index 7950313217..14c584d376 100644
--- a/docs/en/docs-nav.json
+++ b/docs/en/docs-nav.json
@@ -43,6 +43,10 @@
"text": "WPF Application",
"path": "Startup-Templates/WPF.md"
},
+ {
+ "text": "MAUI",
+ "path": "Startup-Templates/MAUI.md"
+ },
{
"text": "Empty Web Project",
"path": "Getting-Started-AspNetCore-Application.md"
@@ -721,7 +725,7 @@
},
{
"text": "LeptonX Lite",
- "path": "Themes/LeptonXLite/mvc.md"
+ "path": "Themes/LeptonXLite/AspNetCore.md"
}
]
},
@@ -837,7 +841,7 @@
},
{
"text": "LeptonX Lite",
- "path": "Themes/LeptonXLite/blazor.md"
+ "path": "Themes/LeptonXLite/Blazor.md"
},
{
"text": "Branding",
@@ -847,6 +851,10 @@
"text": "Page Header",
"path": "UI/Blazor/Page-Header.md"
},
+ {
+ "text": "Page Layout",
+ "path": "UI/Blazor/Page-Layout.md"
+ },
{
"text": "Toolbars",
"path": "UI/Blazor/Toolbars.md"
@@ -977,6 +985,10 @@
"text": "Authorization",
"path": "UI/Angular/Authorization.md"
},
+ {
+ "text": "Current User",
+ "path": "UI/Angular/Current-User.md"
+ },
{
"text": "HTTP Requests",
"path": "UI/Angular/HTTP-Requests.md"
@@ -1112,7 +1124,7 @@
},
{
"text": "LeptonX Lite",
- "path": "Themes/LeptonXLite/angular.md"
+ "path": "Themes/LeptonXLite/Angular.md"
}
]
},
@@ -1322,6 +1334,12 @@
},
{
"text": "OpenIddict",
+ "items": [
+ {
+ "text": "OpenIddict Migration Guide",
+ "path": "Migration-Guides/OpenIddict-Step-by-Step.md"
+ }
+ ],
"path": "Modules/OpenIddict.md"
},
{
diff --git a/docs/en/images/bookstore-rider-solution-tiered.png b/docs/en/images/bookstore-rider-solution-tiered.png
new file mode 100644
index 0000000000..25114bc51c
Binary files /dev/null and b/docs/en/images/bookstore-rider-solution-tiered.png differ
diff --git a/docs/en/images/breadcrumbs-example.png b/docs/en/images/breadcrumbs-example.png
index 17ae5f8ba5..8b4bbc62d7 100644
Binary files a/docs/en/images/breadcrumbs-example.png and b/docs/en/images/breadcrumbs-example.png differ
diff --git a/docs/en/images/cms-kit-page-editor.png b/docs/en/images/cms-kit-page-editor.png
new file mode 100644
index 0000000000..2906da8663
Binary files /dev/null and b/docs/en/images/cms-kit-page-editor.png differ
diff --git a/docs/en/images/cms-kit-widget-preview.png b/docs/en/images/cms-kit-widget-preview.png
new file mode 100644
index 0000000000..df071adc65
Binary files /dev/null and b/docs/en/images/cms-kit-widget-preview.png differ
diff --git a/docs/en/images/cmskit-module-editor-parameter.png b/docs/en/images/cmskit-module-editor-parameter.png
new file mode 100644
index 0000000000..1424716591
Binary files /dev/null and b/docs/en/images/cmskit-module-editor-parameter.png differ
diff --git a/docs/en/images/cmskit-without-parameter.png b/docs/en/images/cmskit-without-parameter.png
new file mode 100644
index 0000000000..49ec3b754f
Binary files /dev/null and b/docs/en/images/cmskit-without-parameter.png differ
diff --git a/docs/en/images/leptonx-selected-menu-item-example.gif b/docs/en/images/leptonx-selected-menu-item-example.gif
new file mode 100644
index 0000000000..8f1170cd55
Binary files /dev/null and b/docs/en/images/leptonx-selected-menu-item-example.gif differ
diff --git a/docs/en/images/leptonxlite-brand-component.png b/docs/en/images/leptonxlite-brand-component.png
new file mode 100644
index 0000000000..c06a51612f
Binary files /dev/null and b/docs/en/images/leptonxlite-brand-component.png differ
diff --git a/docs/en/images/leptonxlite-breadcrumb-component.png b/docs/en/images/leptonxlite-breadcrumb-component.png
new file mode 100644
index 0000000000..9026ca4c52
Binary files /dev/null and b/docs/en/images/leptonxlite-breadcrumb-component.png differ
diff --git a/docs/en/images/leptonxlite-language-switch-component.png b/docs/en/images/leptonxlite-language-switch-component.png
new file mode 100644
index 0000000000..027910c23b
Binary files /dev/null and b/docs/en/images/leptonxlite-language-switch-component.png differ
diff --git a/docs/en/images/leptonxlite-mobile-language-switch-component.png b/docs/en/images/leptonxlite-mobile-language-switch-component.png
new file mode 100644
index 0000000000..a058820743
Binary files /dev/null and b/docs/en/images/leptonxlite-mobile-language-switch-component.png differ
diff --git a/docs/en/images/leptonxlite-mobile-user-menu-component.png b/docs/en/images/leptonxlite-mobile-user-menu-component.png
new file mode 100644
index 0000000000..1a51c341d7
Binary files /dev/null and b/docs/en/images/leptonxlite-mobile-user-menu-component.png differ
diff --git a/docs/en/images/leptonxlite-page-alerts-component.png b/docs/en/images/leptonxlite-page-alerts-component.png
new file mode 100644
index 0000000000..7976412fb2
Binary files /dev/null and b/docs/en/images/leptonxlite-page-alerts-component.png differ
diff --git a/docs/en/images/leptonxlite-sidebar-menu-component.png b/docs/en/images/leptonxlite-sidebar-menu-component.png
new file mode 100644
index 0000000000..6afe4029e8
Binary files /dev/null and b/docs/en/images/leptonxlite-sidebar-menu-component.png differ
diff --git a/docs/en/images/leptonxlite-toolbar-main-example.png b/docs/en/images/leptonxlite-toolbar-main-example.png
new file mode 100644
index 0000000000..30edcf547b
Binary files /dev/null and b/docs/en/images/leptonxlite-toolbar-main-example.png differ
diff --git a/docs/en/images/leptonxlite-toolbar-mainmobile-example.png b/docs/en/images/leptonxlite-toolbar-mainmobile-example.png
new file mode 100644
index 0000000000..95815b5843
Binary files /dev/null and b/docs/en/images/leptonxlite-toolbar-mainmobile-example.png differ
diff --git a/docs/en/images/leptonxlite-user-menu-component.png b/docs/en/images/leptonxlite-user-menu-component.png
new file mode 100644
index 0000000000..a0039e996c
Binary files /dev/null and b/docs/en/images/leptonxlite-user-menu-component.png differ
diff --git a/docs/en/images/setting-management-email-ui.png b/docs/en/images/setting-management-email-ui.png
new file mode 100644
index 0000000000..f8f1270c15
Binary files /dev/null and b/docs/en/images/setting-management-email-ui.png differ
diff --git a/docs/en/images/solution-structure-solution-explorer-rider.png b/docs/en/images/solution-structure-solution-explorer-rider.png
new file mode 100644
index 0000000000..8a09cec74e
Binary files /dev/null and b/docs/en/images/solution-structure-solution-explorer-rider.png differ
diff --git a/docs/en/images/tiered-solution-applications-authserver.png b/docs/en/images/tiered-solution-applications-authserver.png
new file mode 100644
index 0000000000..6d96bf31b4
Binary files /dev/null and b/docs/en/images/tiered-solution-applications-authserver.png differ
diff --git a/docs/es/Getting-Started-AspNetCore-Application.md b/docs/es/Getting-Started-AspNetCore-Application.md
new file mode 100644
index 0000000000..c4d124d827
--- /dev/null
+++ b/docs/es/Getting-Started-AspNetCore-Application.md
@@ -0,0 +1,140 @@
+# Empezando con ABP y una Aplicacion AspNet Core MVC Web
+
+Este tutorial explica como empezar una aplicacion ABP desde cero usando las dependencias minimas. Uno generalmente desea
+empezar con la **[plantilla de inicio](Getting-Started-AspNetCore-MVC-Template.md)**.
+
+## Crea un Proyecto Nuevo
+
+1. Crea una Aplicacion Web AspNet Core nueva usando Visual Studio 2022 (17.0.0+):
+
+
+
+2. Configura el nuevo proyecto:
+
+
+
+3. Presione el boton Create:
+
+
+
+## Instale el paquete Volo.Abp.AspNetCore.Mvc
+
+Volo.Abp.AspNetCore.Mvc es el paquete de integracion con AspNet Core MVC para ABP. Siendo asi, instalalo en su proyecto:
+
+````
+Install-Package Volo.Abp.AspNetCore.Mvc
+````
+
+## Crea el primer modulo ABP
+
+ABP es un marco de referencia modular y require una clase de **inicio (raíz) tipo modulo** derivada de ``AbpModule``:
+
+````C#
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.Hosting;
+using Volo.Abp;
+using Volo.Abp.AspNetCore.Mvc;
+using Volo.Abp.Modularity;
+
+namespace BasicAspNetCoreApplication
+{
+ [DependsOn(typeof(AbpAspNetCoreMvcModule))]
+ public class AppModule : AbpModule
+ {
+ public override void OnApplicationInitialization(ApplicationInitializationContext context)
+ {
+ var app = context.GetApplicationBuilder();
+ var env = context.GetEnvironment();
+
+ // Configura la canalización de peticiones HTTP.
+ if (env.IsDevelopment())
+ {
+ app.UseExceptionHandler("/Error");
+ // El valor por defecto de HSTS es 30 dias. Debes cambiar esto en ambientes productivos. Referencia https://aka.ms/aspnetcore-hsts.
+ app.UseHsts();
+ }
+
+ app.UseHttpsRedirection();
+ app.UseStaticFiles();
+ app.UseRouting();
+ app.UseConfiguredEndpoints();
+ }
+ }
+}
+````
+
+``AppModule`` es un buen nombre para el modulo de inicio de una aplicacion.
+
+Los paquetes de ABP definen clases de tipo modulo y cada modulo puede depender de otro.
+En el codigo anterior, el ``AppModule`` depende de el modulo ``AbpAspNetCoreMvcModule`` (definido por el paquete [Volo.Abp.AspNetCore.Mvc](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Mvc)). Es comun agregar el atributo ``DependsOn`` despues de instalar un paquete ABP nuevo.
+
+En vez de la clase de inicion Startup, estamos configurando una canalizacion de ASP.NET Core en este modulo.
+
+## La clase Program
+
+El proximo paso es modificar la clase Program para integrate el sistema de modulos ABP:
+
+````C#
+using BasicAspNetCoreApplication;
+
+var builder = WebApplication.CreateBuilder(args);
+
+await builder.Services.AddApplicationAsync();
+
+var app = builder.Build();
+
+await app.InitializeApplicationAsync();
+await app.RunAsync();
+````
+
+``builder.Services.AddApplicationAsync();`` Agrega todos los servicios definidos en todos los modulos empezando desde ``AppModule``.
+
+``app.InitializeApplicationAsync()`` inicializa y empieza la aplicacion.
+
+## Ejecutar la Aplicación
+
+Es todo! Ejecuta la aplicación, debe funcionar como esperado.
+
+## Uso de Autofac como Marco de Inyección de Dependencia
+
+Mientras el sistema de Inyección de Dependencia de ASP.NET Core es suficiente para requerimientos basico, [Autofac](https://autofac.org/) proporciona características avanzadas como Inyección de Propiedades e Intercepcion de Metodos, los cuales son necesarios para que ABP pueda llevar a cabo funciones avanzadas.
+
+El acto de remplazar el sistema DI de ASP.NET Core por Autofac e integrarlo con ABP es facil.
+
+1. Instala el paquete [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac)
+
+````
+Install-Package Volo.Abp.Autofac
+````
+
+2. Agrega la dependencia sobre el modulo ``AbpAutofacModule``
+
+````C#
+[DependsOn(typeof(AbpAspNetCoreMvcModule))]
+[DependsOn(typeof(AbpAutofacModule))] //Agrega la dependencia sobre el modulo ABP Autofac
+public class AppModule : AbpModule
+{
+ ...
+}
+````
+
+3. Actualiza `Program.cs` para que use Autofac:
+
+````C#
+using BasicAspNetCoreApplication;
+
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Host.UseAutofac(); //Agrega esta linea
+
+await builder.Services.AddApplicationAsync();
+
+var app = builder.Build();
+
+await app.InitializeApplicationAsync();
+await app.RunAsync();
+````
+
+## Codigo fuente
+
+ Obten el codigo fuente del ejemplo creado en este tutorial de [aqui](https://github.com/abpframework/abp-samples/tree/master/BasicAspNetCoreApplication).
diff --git a/docs/es/images/create-aspnet-core-application.png b/docs/es/images/create-aspnet-core-application.png
new file mode 100644
index 0000000000..b8b98f5c32
Binary files /dev/null and b/docs/es/images/create-aspnet-core-application.png differ
diff --git a/docs/es/images/create-new-aspnet-core-application-v2.png b/docs/es/images/create-new-aspnet-core-application-v2.png
new file mode 100644
index 0000000000..f8274ae2a4
Binary files /dev/null and b/docs/es/images/create-new-aspnet-core-application-v2.png differ
diff --git a/docs/es/images/select-empty-web-application-v2.png b/docs/es/images/select-empty-web-application-v2.png
new file mode 100644
index 0000000000..da32f71857
Binary files /dev/null and b/docs/es/images/select-empty-web-application-v2.png differ
diff --git a/docs/pt-BR/Validation.md b/docs/pt-BR/Validation.md
index 5818566cdd..662235431a 100644
--- a/docs/pt-BR/Validation.md
+++ b/docs/pt-BR/Validation.md
@@ -1,3 +1,182 @@
-## Validation
+# Validação
-Façam
\ No newline at end of file
+O sistema de validação é utilizado para validar a entrada do usuário ou a requisição do cliente para uma ação de um controller ou por um serviço.
+
+O ABP é compatível com o sistema de Validação de Modelos do ASP.NET Core e tudo escrito na [sua documentação](https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation) é válido para aplicações baseadas no ABP. Logo, esse documento foca nas funcionalidades do ABP ao invés de repetir a documentação da Microsoft.
+
+Além disso, o ABP adiciona os seguintes benefícios:
+
+* Define `IValidationEnabled` para adicionar validação automática para uma classe qualquer. Como todos os [serviços de aplicação](Application-Services.md) já o implementam, eles também são validados automaticamente.
+* Automaticamente traduz os erros de validação para os atributos de anotação de dados.
+* Provê serviços extensíveis para validar a chamada de um método ou o estado de um objeto.
+* Provê integração com o [FluentValidation](https://fluentvalidation.net/)
+
+## Validando DTOs
+
+Essa seção introduz brevemente o sistema de validação. Para mais detalhes, veja a [Documentação da Validação de Modelo em ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation).
+
+### Atributos de anotação de dados
+
+Utilizar anotações de dados é uma maneira simples de implementar uma validação formal para um [DTO](Data-Transfer-Objects.md) de uma forma declarativa. Exemplo:
+
+````csharp
+public class CreateBookDto
+{
+ [Required]
+ [StringLength(100)]
+ public string Name { get; set; }
+
+ [Required]
+ [StringLength(1000)]
+ public string Description { get; set; }
+
+ [Range(0, 999.99)]
+ public decimal Price { get; set; }
+}
+````
+Quando você utilizar essa classe como parâmetro para um [serviço da aplicação](Application-Services.md) ou um controller, ele será automaticamente validado e a validação traduzida será lançada ([e tratada](Exception-Handling.md) pelo ABP framework).
+
+### IValidatableObject
+
+`IValidatableObject` pode ser implementado por um DTO para executar uma lógica customizada de validação. O `CreateBookDto` no exemplo a seguir implementa essa interface e verifica se o `Name` é igual a `Description` e retorna um erro de validação nesse caso.
+
+````csharp
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+
+namespace Acme.BookStore
+{
+ public class CreateBookDto : IValidatableObject
+ {
+ [Required]
+ [StringLength(100)]
+ public string Name { get; set; }
+
+ [Required]
+ [StringLength(1000)]
+ public string Description { get; set; }
+
+ [Range(0, 999.99)]
+ public decimal Price { get; set; }
+
+ public IEnumerable Validate(
+ ValidationContext validationContext)
+ {
+ if (Name == Description)
+ {
+ yield return new ValidationResult(
+ "Name and Description can not be the same!",
+ new[] { "Name", "Description" }
+ );
+ }
+ }
+ }
+}
+````
+
+#### Resolvendo um serviço.
+
+Se você precisar resolver um serviço do [sistema de injeção de dependências](Dependency-Injection.md), você pode utilizar o objeto `ValidationContext`.
+
+````csharp
+var myService = validationContext.GetRequiredService();
+````
+
+> Enquanto resolver os serviços no método `Validate` permite várias possibilidades, não é um boa prática implementar sua lógica de validação do domínio nos DTOs. Mantenha os DTOs simples. Seu propósito é transferir dados (DTO: Data Transfer Object, ou Objeto de Transferência de Dados).
+
+## Infraestrutura de Validação.
+
+Essa seção explica alguns serviços adicionais fornecidos pelo ABP Framework.
+
+### Interface IValidationEnabled
+
+`IValidationEnabled` é um marcador vazio de interface que pode ser implementado por qualquer classe (registrada e resolvida a partir do [DI](Dependency-Injection.md)) para permitir que o ABP framework realize o sistema de validação para os métodos da classe. Por exemplo:
+
+````csharp
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Validation;
+
+namespace Acme.BookStore
+{
+ public class MyService : ITransientDependency, IValidationEnabled
+ {
+ public virtual async Task DoItAsync(MyInput input)
+ {
+ //...
+ }
+ }
+}
+````
+
+> O ABP framework utiliza o sistema de [Proxying Dinâmico / Interceptadores](Dynamic-Proxying-Interceptors.md) para realizar a validação. Para fazê-lo funcionar, seu método deve ser **virtual** ou seu serviço deve ser injetado e utilizado através de uma **interface** (como `IMyService`).
+
+#### Habilitando e Desabilitando Validações
+
+Você pode utilizar o `[DisableValidation]` e desabilitar a validação para métodos, classes e propriedades.
+
+````csharp
+[DisableValidation]
+public Void MyMethod()
+{
+}
+
+[DisableValidation]
+public class InputClass
+{
+ public string MyProperty { get; set; }
+}
+
+public class InputClass
+{
+ [DisableValidation]
+ public string MyProperty { get; set; }
+}
+````
+
+### AbpValidationException
+
+Uma vez que o ABP determina um erro de validação, é lançada uma validação do tipo `AbpValidationException`. O código da sua aplicação poderá lançar o `AbpValidationException`, mas na maioria das vezes não será necessário.
+
+* A propriedade `ValidationErrors` do `AbpValidationException` contem a lista com os erros de validação.
+* O nível de log do `AbpValidationException` é definido como `Warning`. Todos os erros de validação são logados no [Sistema de Logging](Logging.md).
+* `AbpValidationException` é tratado automaticamente pelo ABP framework e é convertido em um erro utilizável com o código de status HTTP 400. Veja a documentação de [Manipulação de Exceção](Exception-Handling.md) para mais informações.
+
+## Tópicos Avançados
+
+### IObjectValidator
+
+Além da validação automática, você pode querer validar um objeto manualmente. Nesse caso, [injete](Dependency-Injection.md) e use o serviço `IObjectValidator`:
+
+* O método `ValidateAsync` valida o objeto informado baseado nas regras de validação e lança uma `AbpValidationException` se não estiver em um estado válido.
+
+* `GetErrorsAsync` não lança uma exceção, somente retorna os erros de validação.
+
+`IObjectValidator` é implementado pelo `ObjectValidator` por padrão. `ObjectValidator` é extensível; você pode implementar a interface `IObjectValidationContributor` para contribuir com uma lógica customizada. Exemplo:
+
+````csharp
+public class MyObjectValidationContributor
+ : IObjectValidationContributor, ITransientDependency
+{
+ public Task AddErrorsAsync(ObjectValidationContext context)
+ {
+ //Get the validating object
+ var obj = context.ValidatingObject;
+
+ //Add the validation errors if available
+ context.Errors.Add(...);
+ return Task.CompletedTask;
+ }
+}
+````
+
+* Lembre-se de registrar sua classe no [DI](Dependency-Injection.md) (implementar `ITransientDependency` faz isso no exemplo anterior)
+* ABP vai automaticamente descobrir sua classe e utilizá-la em qualquer tipo de validação de objetos (incluindo chamadas de métodos de validação automáticas).
+
+### IMethodInvocationValidator
+
+`IMethodInvocationValidator` é utilizado para validar a chamada de um método. Ele utiliza internamente o `IObjectValidator` para validar os objetos passados na chamada do método. Você normalmente não precisa deste serviço, já que ele é utilizado automaticamente pelo framework, mas você pode querer reutilizar ou substituir na sua aplicação em alguns casos raros.
+
+## Integração com FluentValidation
+
+O pacote Volo.Abp.FluentValidation integra a biblioteca FluentValidation com o sistema de validação (implementando o `IObjectValidationContributor`). Veja o [documento de Integração com o FluentValidation](FluentValidation.md) para mais informações.
diff --git a/docs/zh-Hans/Authorization.md b/docs/zh-Hans/Authorization.md
index db0dfdb654..39c64c0905 100644
--- a/docs/zh-Hans/Authorization.md
+++ b/docs/zh-Hans/Authorization.md
@@ -392,6 +392,45 @@ public override void ConfigureServices(ServiceConfigurationContext context)
启动模板的集成测试已经禁用了授权服务.
+### Claims Principal Factory
+
+声明是认证和授权的重要组成部分. ABP 使用 `IAbpClaimsPrincipalFactory` 来服务创建身份认证声明. 该服务被设计为可扩展的. 如果你需要将自定义声明添加到身份认证票证中, 可以在你的应用程序中实现 `IAbpClaimsPrincipalContributor`.
+
+**示例:添加一个 `SocialSecurityNumber ` 声明并获取它:**
+
+```csharp
+public class SocialSecurityNumberClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency
+{
+ public async Task ContributeAsync(AbpClaimsPrincipalContributorContext context)
+ {
+ var identity = context.ClaimsPrincipal.Identities.FirstOrDefault();
+ var userId = identity?.FindUserId();
+ if (userId.HasValue)
+ {
+ var userService = context.ServiceProvider.GetRequiredService(); //Your custom service
+ var socialSecurityNumber = await userService.GetSocialSecurityNumberAsync(userId.Value);
+ if (socialSecurityNumber != null)
+ {
+ identity.AddClaim(new Claim("SocialSecurityNumber", socialSecurityNumber));
+ }
+ }
+ }
+}
+
+Configure(options=>
+{
+ options.RequestedClaims.Add("SocialSecurityNumber")
+})
+
+public static class CurrentUserExtensions
+{
+ public static string GetSocialSecurityNumber(this ICurrentUser currentUser)
+ {
+ return currentUser.FindClaimValue("SocialSecurityNumber");
+ }
+}
+```
+
## 接下来
* [权限管理模块](Modules/Permission-Management.md)
diff --git a/docs/zh-Hans/Background-Jobs-Hangfire.md b/docs/zh-Hans/Background-Jobs-Hangfire.md
index b1bf7b8c79..fb899758cc 100644
--- a/docs/zh-Hans/Background-Jobs-Hangfire.md
+++ b/docs/zh-Hans/Background-Jobs-Hangfire.md
@@ -66,6 +66,41 @@ public class YourModule : AbpModule
}
````
+### 指定队列
+
+你可以使用 [`QueueAttribute`](https://docs.hangfire.io/en/latest/background-processing/configuring-queues.html) 来指定队列.
+
+````csharp
+using System.Threading.Tasks;
+using Volo.Abp.BackgroundJobs;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Emailing;
+
+namespace MyProject
+{
+ [Queue("alpha")]
+ public class EmailSendingJob
+ : AsyncBackgroundJob, ITransientDependency
+ {
+ private readonly IEmailSender _emailSender;
+
+ public EmailSendingJob(IEmailSender emailSender)
+ {
+ _emailSender = emailSender;
+ }
+
+ public override async Task ExecuteAsync(EmailSendingArgs args)
+ {
+ await _emailSender.SendAsync(
+ args.EmailAddress,
+ args.Subject,
+ args.Body
+ );
+ }
+ }
+}
+````
+
1. 如果你想要使用Hangfire的面板,你可以在 `Module` 类的 `OnApplicationInitialization` 方法添加: `UseHangfireDashboard`
````csharp
diff --git a/docs/zh-Hans/Background-Jobs-RabbitMq.md b/docs/zh-Hans/Background-Jobs-RabbitMq.md
index 0f9fb21d8a..8bf61846e7 100644
--- a/docs/zh-Hans/Background-Jobs-RabbitMq.md
+++ b/docs/zh-Hans/Background-Jobs-RabbitMq.md
@@ -126,25 +126,31 @@ Configure(options =>
Configure(options =>
{
options.DefaultQueueNamePrefix = "my_app_jobs.";
+ options.DefaultDelayedQueueNamePrefix = "my_app_jobs.delayed"
+ options.PrefetchCount = 1;
options.JobQueues[typeof(EmailSendingArgs)] =
new JobQueueConfiguration(
typeof(EmailSendingArgs),
queueName: "my_app_jobs.emails",
- connectionName: "SecondConnection"
+ connectionName: "SecondConnection",
+ delayedQueueName:"my_app_jobs.emails.delayed"
);
});
```
-- 这个示例将默认的队列名前缀设置为 `my_app_jobs.`,如果多个项目都使用的同一个 RabbitMQ 服务,设置不同的前缀可以避免执行其他项目的后台作业.
+- 这个示例将默认的队列名前缀设置为 `my_app_jobs.`并且设置默认的延迟队列名为 `my_app_jobs.delayed`,如果多个项目都使用的同一个 RabbitMQ 服务,设置不同的前缀可以避免执行其他项目的后台作业.
+- 设置了预取数量, 用于所有队列.
- 这里还设置了 `EmailSendingArgs` 绑定的 RabbitMQ 连接.
`JobQueueConfiguration` 类的构造函数中,还有一些其他的可选参数.
- `queueName`: 指定后台作业对应的队列名称(全名).
+* `DelayedQueueName`: 指定后台延迟执行的作业对于的队列名称(全名).
- `connectionName`: 后台作业对应的 RabbitMQ 连接名称,默认是 `Default`.
- `durable`: 可选参数,默认为 `true`.
- `exclusive`: 可选参数,默认为 `false`.
- `autoDelete`: 可选参数,默认为 `false`.
+* `PrefetchCount` (可选参数, 默认为: null)
如果你想要更多地了解 `durable`,`exclusive`,`autoDelete` 的用法,请阅读 RabbitMQ 提供的文档.
diff --git a/docs/zh-Hans/CLI.md b/docs/zh-Hans/CLI.md
index f890534795..f108bbcfec 100644
--- a/docs/zh-Hans/CLI.md
+++ b/docs/zh-Hans/CLI.md
@@ -123,6 +123,7 @@ abp new Acme.BookStore
* `module`: [Module template](Startup-Templates/Module.md). 其他选项:
* `--no-ui`: 不包含UI.仅创建服务模块(也称为微服务 - 没有UI).
* **`console`**: [Console template](Startup-Templates/Console.md).
+ * **`maui`**: [Maui template](Startup-Templates/MAUI.md).
* **`app-nolayers`**: 应用程序单层模板
* `--ui` 或者 `-u`: 指定ui框架.默认`mvc`框架.其他选项:
* `mvc`: ASP.NET Core MVC.
diff --git a/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md b/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md
index 1cd6b5b9dd..f45d4d90bf 100644
--- a/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md
+++ b/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md
@@ -141,13 +141,14 @@ Configure(options =>
});
````
-**示例: 配置客户端和交换机名称**
+**示例: 配置客户端,交换机名称和预取数量**
````csharp
Configure(options =>
{
options.ClientName = "TestApp1";
options.ExchangeName = "TestMessages";
+ options.PrefetchCount = 1;
});
````
diff --git a/docs/zh-Hans/Entities.md b/docs/zh-Hans/Entities.md
index 8fbf16ddd3..b9c236e346 100644
--- a/docs/zh-Hans/Entities.md
+++ b/docs/zh-Hans/Entities.md
@@ -105,6 +105,22 @@ public class UserRole : Entity
> 需要注意,复合主键实体不可以使用 `IRepository` 接口,因为它需要一个唯一的Id属性. 但你可以使用 `IRepository`.更多信息请参见[仓储](Repositories.md)的文档.
+### EntityEquals
+
+`Entity.EntityEquals(...)` 方法用于检查两个实体对象是否相等.
+
+示例:
+
+```csharp
+Book book1 = ...
+Book book2 = ...
+
+if (book1.EntityEquals(book2)) //Check equality
+{
+ ...
+}
+```
+
## 聚合根
"*聚合是域驱动设计中的一种模式.DDD的聚合是一组可以作为一个单元处理的域对象.例如,订单及订单系列的商品,这些是独立的对象,但将订单(连同订单系列的商品)视为一个聚合通常是很有用的*"( [查看详细介绍](http://martinfowler.com/bliki/DDD_Aggregate.html))
diff --git a/docs/zh-Hans/Modules/Cms-Kit/Dynamic-Widget.md b/docs/zh-Hans/Modules/Cms-Kit/Dynamic-Widget.md
new file mode 100644
index 0000000000..14e861b204
--- /dev/null
+++ b/docs/zh-Hans/Modules/Cms-Kit/Dynamic-Widget.md
@@ -0,0 +1,47 @@
+# 动态部件
+
+CMS kit提供了组件系统在页面和博客文章和生成动态部件. 这是一个在 `Page` 端的示例投票部件截图
+
+> 重要提示: 投票部件是ABP Commercial实现的唯一部件
+
+
+> 你也可以对其他小部件执行相同的操作.这只是一个例子.
+要添加部件,你应该去页面或博客创建或更新, 然后单击 `W` 按钮添加一个动态部件, 如下图所示. 不要忘了这是设计模态框,你需要在保存后查看你的页面. 此外 `预览` 选项卡可以轻松的查看部件配置的部件输出.
+
+
+
+在这张图中, 选择投票后(在其他情况下,它根据你的配置自动改变, 这里是投票组件,它的参数名是 `editorWidgetName`),你看到下一个部件, 输入值或选择值或选择并单击 `添加`. 你将看到以下输出
+
+> [Widget Type="Poll" Code="SelectedValue"]
+如果编码有任何错误(错误的值或拼写错误)你可以手动修改输出.
+
+## 选项
+
+使添加的部件工作,你必须在模块类中进行配置:
+
+```csharp
+Configure(options =>
+{
+ options.AddWidget("widgetKey", "widgetName", "editorWidgetName");
+});
+```
+
+* `widgetKey` 用于最终用户更具有可读性的名称.
+ [Widget Type="**Poll**" Code="SelectedValue"]
+* `widgetName` 用于代码中通过 `[widget]` Attribute使用的小部件名称
+
+```csharp
+[Widget]
+public class WidgetNameViewComponent : AbpViewComponent
+{
+ public IViewComponentResult Invoke()
+ {
+ return View();
+ }
+}
+
+```
+
+* `editorWidgetName` 用于编辑器组件端,在 `添加部件` 模态框中查看.
+
+另请参阅[部件](https://docs.abp.io/zh-Hans/abp/latest/UI/AspNetCore/Widgets).
\ No newline at end of file
diff --git a/docs/zh-Hans/Modules/Cms-Kit/Index.md b/docs/zh-Hans/Modules/Cms-Kit/Index.md
index 0751eb0ad0..2409a98156 100644
--- a/docs/zh-Hans/Modules/Cms-Kit/Index.md
+++ b/docs/zh-Hans/Modules/Cms-Kit/Index.md
@@ -13,6 +13,7 @@
* 提供 [**反应**](Reactions.md) 系统来添加对任何资源的反应 (表情符号) 功能, 如博客文章或评论.
* 提供 [**评级**](Ratings.md) 系统来添加对任何资源的评级功能.
* 提供 [**菜单**](Menus.md) 系统来动态管理公共菜单.
+* 提供 [**动态部件**](Dynamic-Widget.md) 系统在页面和博客文章中创建动态部件.
点击功能以了解和学习如何去使用它.
diff --git a/docs/zh-Hans/Modules/Setting-Management.md b/docs/zh-Hans/Modules/Setting-Management.md
index c99397e4b4..242553c2c9 100644
--- a/docs/zh-Hans/Modules/Setting-Management.md
+++ b/docs/zh-Hans/Modules/Setting-Management.md
@@ -87,7 +87,13 @@ namespace Demo
## Setting Management UI.
-设置管理模块默认提供了邮件设置页面并且它是可扩展的; 你可以为你的应用程序设置添加设置标签到设置页面.
+设置管理模块默认提供了邮件设置页面.
+
+
+
+> 你可以点击发送测试邮件按钮发送一封测试邮件来检查你的邮件设置.
+
+设置UI是可扩展的; 你可以为你的应用程序设置添加设置标签到设置页面.
### MVC UI
diff --git a/docs/zh-Hans/Multi-Tenancy.md b/docs/zh-Hans/Multi-Tenancy.md
index 8e92d10673..6db625e7d9 100644
--- a/docs/zh-Hans/Multi-Tenancy.md
+++ b/docs/zh-Hans/Multi-Tenancy.md
@@ -34,6 +34,22 @@ namespace MyCompany.MyProject
> 随着"Multi-tenancy ready"的概念,我们打算开发我们的代码和多租户方法兼容.然后它可以被用于多租户和非多租户的程序中,这取决于最终程序的需求.
+### AbpMultiTenancyOptions: 处理不活跃或不存在的租户
+
+`MultiTenancyMiddlewareErrorPageBuilder` 或 `AbpMultiTenancyOptions` 用于 处理不活跃或不存在的租户.
+
+默认情况下会响应错误页面, 你可以根据自己的需要更改它, 比如: 只输出错误日志并继续ASP NET Core的请求管道
+
+```csharp
+Configure(options =>
+{
+ options.MultiTenancyMiddlewareErrorPageBuilder = async (context, exception) =>
+ {
+ // Handle the exception.
+ };
+});
+```
+
#### 定义实体
你可以在你的实体中实现 **IMultiTenant** 接口来实现多租户,例如:
@@ -306,7 +322,6 @@ Volo.Abp.AspNetCore.MultiTenancy 添加了下面这些租户解析器,从当前W
* **CurrentUserTenantResolveContributor**: 如果当前用户已登录,从当前用户的声明中获取租户Id. **出于安全考虑,应该始终将其做为第一个Contributor**.
* **QueryStringTenantResolveContributor**: 尝试从query string参数中获取当前租户,默认参数名为"__tenant".
-* **FormTenantResolveContributor**: 尝试从form参数中获取当前租户,默认参数名为"__tenant".
* **RouteTenantResolveContributor**:尝试从当前路由中获取(URL路径),默认是变量名是"__tenant".所以,如果你的路由中定义了这个变量,就可以从路由中确定当前租户.
* **HeaderTenantResolveContributor**: 尝试从HTTP header中获取当前租户,默认的header名称是"__tenant".
* **CookieTenantResolveContributor**: 尝试从当前cookie中获取当前租户.默认的Cookie名称是"__tenant".
diff --git a/docs/zh-Hans/Object-To-Object-Mapping.md b/docs/zh-Hans/Object-To-Object-Mapping.md
index 402acdc4f6..62c1d17add 100644
--- a/docs/zh-Hans/Object-To-Object-Mapping.md
+++ b/docs/zh-Hans/Object-To-Object-Mapping.md
@@ -12,7 +12,7 @@ public class UserAppService : ApplicationService
_userRepository = userRepository;
}
- public void CreateUser(CreateUserInput input)
+ public async Task CreateUser(CreateUserInput input)
{
//Manually creating a User object from the CreateUserInput object
var user = new User
@@ -23,7 +23,7 @@ public class UserAppService : ApplicationService
Password = input.Password
};
- _userRepository.Insert(user);
+ await _userRepository.InsertAsync(user);
}
}
```
@@ -46,12 +46,12 @@ public class UserAppService : ApplicationService
_userRepository = userRepository;
}
- public void CreateUser(CreateUserInput input)
+ public async Task CreateUser(CreateUserInput input)
{
//Automatically creating a new User object using the CreateUserInput object
var user = ObjectMapper.Map(input);
- _userRepository.Insert(user);
+ await _userRepository.InsertAsync(user);
}
}
````
diff --git a/docs/zh-Hans/Tutorials/Part-2.md b/docs/zh-Hans/Tutorials/Part-2.md
index 346927acbe..dc8d804d5e 100644
--- a/docs/zh-Hans/Tutorials/Part-2.md
+++ b/docs/zh-Hans/Tutorials/Part-2.md
@@ -135,15 +135,15 @@ successfully created the book with id: 439b0ea8-923e-8e1e-5d97-39f2c7ac4246
"CreationTime": "Creation time",
"AreYouSure": "Are you sure?",
"AreYouSureToDelete": "Are you sure you want to delete this item?",
- "Enum:BookType:0": "Undefined",
- "Enum:BookType:1": "Adventure",
- "Enum:BookType:2": "Biography",
- "Enum:BookType:3": "Dystopia",
- "Enum:BookType:4": "Fantastic",
- "Enum:BookType:5": "Horror",
- "Enum:BookType:6": "Science",
- "Enum:BookType:7": "Science fiction",
- "Enum:BookType:8": "Poetry"
+ "Enum:BookType.Undefined": "Undefined",
+ "Enum:BookType.Adventure": "Adventure",
+ "Enum:BookType.Biography": "Biography",
+ "Enum:BookType.Dystopia": "Dystopia",
+ "Enum:BookType.Fantastic": "Fantastic",
+ "Enum:BookType.Horror": "Horror",
+ "Enum:BookType.Science": "Science",
+ "Enum:BookType.ScienceFiction": "Science fiction",
+ "Enum:BookType.Poetry": "Poetry"
}
}
````
@@ -152,7 +152,7 @@ successfully created the book with id: 439b0ea8-923e-8e1e-5d97-39f2c7ac4246
* 本地化关键字名称是任意的. 你可以设置任何名称. 对于特定的文本类型,我们更喜欢遵循一些约定:
* 为按钮项添加 `Menu:` 前缀.
- * 使用 `Enum::` 命名约定来本地化枚举成员. 当您这样做时ABP可以在某些适当的情况下自动将枚举本地化.
+ * 使用 `Enum::` 或 `.` 或 `` 命名约定来本地化枚举成员. 当您这样做时ABP可以在某些适当的情况下自动将枚举本地化.
如果未在本地化文件中定义文本,则文本将**回退**到本地化键(ASP.NET Core的标准行为).
@@ -626,7 +626,7 @@ ABP提供了一个通用的基类,`AbpCrudPageBase<...>`,用来创建CRUD风格
Field="@nameof(BookDto.Type)"
Caption="@L["Type"]">
- @L[$"Enum:BookType:{(int)context.Type}"]
+ @L[$"Enum:BookType.{Enum.GetName(context.Type)}"]
- @L[$"Enum:BookType:{bookTypeValue}"]
+ @L[$"Enum:BookType.{Enum.GetName((BookType)bookTypeValue)}"]
}
@@ -1323,7 +1323,7 @@ delete(id: string) {
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
- @L[$"Enum:BookType:{bookTypeValue}"]
+ @L[$"Enum:BookType.{Enum.GetName((BookType)bookTypeValue)}"]
}
@@ -1460,7 +1460,7 @@ namespace Acme.BookStore.Blazor
Field="@nameof(BookDto.Type)"
Caption="@L["Type"]">
- @L[$"Enum:BookType:{(int) context.Type}"]
+ @L[$"Enum:BookType.{Enum.GetName(context.Type)}"]
- @L[$"Enum:BookType:{bookTypeValue}"]
+ @L[$"Enum:BookType.{Enum.GetName((BookType)bookTypeValue)}"]
}
@@ -1565,7 +1565,7 @@ namespace Acme.BookStore.Blazor
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
- @L[$"Enum:BookType:{bookTypeValue}"]
+ @L[$"Enum:BookType.{Enum.GetName((BookType)bookTypeValue)}"]
}
diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json
index 203000c6c6..be30753fb3 100644
--- a/docs/zh-Hans/docs-nav.json
+++ b/docs/zh-Hans/docs-nav.json
@@ -61,6 +61,10 @@
{
"text": "WPF",
"path": "Startup-Templates/WPF.md"
+ },
+ {
+ "text": "MAUI",
+ "path": "Startup-Templates/MAUI.md"
}
]
},
diff --git a/docs/zh-Hans/images/cmskit-add-widget-on-page.png b/docs/zh-Hans/images/cmskit-add-widget-on-page.png
new file mode 100644
index 0000000000..8e03964477
Binary files /dev/null and b/docs/zh-Hans/images/cmskit-add-widget-on-page.png differ
diff --git a/docs/zh-Hans/images/cmskit-example-output-on-page.png b/docs/zh-Hans/images/cmskit-example-output-on-page.png
new file mode 100644
index 0000000000..bdc5c52278
Binary files /dev/null and b/docs/zh-Hans/images/cmskit-example-output-on-page.png differ
diff --git a/docs/zh-Hans/images/setting-management-email-ui.png b/docs/zh-Hans/images/setting-management-email-ui.png
new file mode 100644
index 0000000000..f8f1270c15
Binary files /dev/null and b/docs/zh-Hans/images/setting-management-email-ui.png differ
diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln
index fadd40bcc5..4ce47bdbc8 100644
--- a/framework/Volo.Abp.sln
+++ b/framework/Volo.Abp.sln
@@ -409,6 +409,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.RemoteServices", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Mvc.PlugIn", "test\Volo.Abp.AspNetCore.Mvc.PlugIn\Volo.Abp.AspNetCore.Mvc.PlugIn.csproj", "{C6D6D878-208A-4FD2-822E-365545D8681B}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Dapr", "src\Volo.Abp.Dapr\Volo.Abp.Dapr.csproj", "{192A829F-D608-4E41-8DE0-058E943E453F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.EventBus.Dapr", "src\Volo.Abp.EventBus.Dapr\Volo.Abp.EventBus.Dapr.csproj", "{DCC41E99-EBC7-4F19-BA0D-A6F770D8E431}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Http.Client.Dapr", "src\Volo.Abp.Http.Client.Dapr\Volo.Abp.Http.Client.Dapr.csproj", "{18B796D2-D45D-41AE-9A42-75C9B14B20DF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Mvc.Dapr", "src\Volo.Abp.AspNetCore.Mvc.Dapr\Volo.Abp.AspNetCore.Mvc.Dapr.csproj", "{5EED625D-8D86-492A-BCB8-F6C8CD8D4AA1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Mvc.Dapr.EventBus", "src\Volo.Abp.AspNetCore.Mvc.Dapr.EventBus\Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.csproj", "{B02EF042-C39E-45C4-A92D-BF7554E1889D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.DistributedLocking.Dapr", "src\Volo.Abp.DistributedLocking.Dapr\Volo.Abp.DistributedLocking.Dapr.csproj", "{CAE48068-233C-47A9-BEAB-DDF521730E7A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1219,6 +1231,30 @@ Global
{C6D6D878-208A-4FD2-822E-365545D8681B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C6D6D878-208A-4FD2-822E-365545D8681B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C6D6D878-208A-4FD2-822E-365545D8681B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {192A829F-D608-4E41-8DE0-058E943E453F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {192A829F-D608-4E41-8DE0-058E943E453F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {192A829F-D608-4E41-8DE0-058E943E453F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {192A829F-D608-4E41-8DE0-058E943E453F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DCC41E99-EBC7-4F19-BA0D-A6F770D8E431}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DCC41E99-EBC7-4F19-BA0D-A6F770D8E431}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DCC41E99-EBC7-4F19-BA0D-A6F770D8E431}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DCC41E99-EBC7-4F19-BA0D-A6F770D8E431}.Release|Any CPU.Build.0 = Release|Any CPU
+ {18B796D2-D45D-41AE-9A42-75C9B14B20DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {18B796D2-D45D-41AE-9A42-75C9B14B20DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18B796D2-D45D-41AE-9A42-75C9B14B20DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {18B796D2-D45D-41AE-9A42-75C9B14B20DF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5EED625D-8D86-492A-BCB8-F6C8CD8D4AA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5EED625D-8D86-492A-BCB8-F6C8CD8D4AA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5EED625D-8D86-492A-BCB8-F6C8CD8D4AA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5EED625D-8D86-492A-BCB8-F6C8CD8D4AA1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B02EF042-C39E-45C4-A92D-BF7554E1889D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B02EF042-C39E-45C4-A92D-BF7554E1889D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B02EF042-C39E-45C4-A92D-BF7554E1889D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B02EF042-C39E-45C4-A92D-BF7554E1889D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CAE48068-233C-47A9-BEAB-DDF521730E7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CAE48068-233C-47A9-BEAB-DDF521730E7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CAE48068-233C-47A9-BEAB-DDF521730E7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CAE48068-233C-47A9-BEAB-DDF521730E7A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1425,6 +1461,12 @@ Global
{3683340D-92F5-4B14-B77B-34A163333309} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{EDFFDA74-090D-439C-A58D-06CCF86D4423} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{C6D6D878-208A-4FD2-822E-365545D8681B} = {447C8A77-E5F0-4538-8687-7383196D04EA}
+ {192A829F-D608-4E41-8DE0-058E943E453F} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {DCC41E99-EBC7-4F19-BA0D-A6F770D8E431} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {18B796D2-D45D-41AE-9A42-75C9B14B20DF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {5EED625D-8D86-492A-BCB8-F6C8CD8D4AA1} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {B02EF042-C39E-45C4-A92D-BF7554E1889D} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {CAE48068-233C-47A9-BEAB-DDF521730E7A} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/AbpDynamicLayoutComponentOptions.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/AbpDynamicLayoutComponentOptions.cs
new file mode 100644
index 0000000000..5bba550eff
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/AbpDynamicLayoutComponentOptions.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using JetBrains.Annotations;
+
+namespace Volo.Abp.AspNetCore.Components.Web.Theming;
+
+public class AbpDynamicLayoutComponentOptions
+{
+ ///
+ /// Used to define components that renders in the layout
+ ///
+ [NotNull]
+ public Dictionary?> Components { get; set; }
+
+ public AbpDynamicLayoutComponentOptions()
+ {
+ Components = new Dictionary?>();
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/DynamicLayoutComponent.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/DynamicLayoutComponent.razor
new file mode 100644
index 0000000000..8354c02889
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/DynamicLayoutComponent.razor
@@ -0,0 +1,7 @@
+@if (AbpDynamicLayoutComponentOptions.Value.Components.Any())
+{
+ foreach (var (componentType, parameters) in AbpDynamicLayoutComponentOptions.Value.Components)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/DynamicLayoutComponent.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/DynamicLayoutComponent.razor.cs
new file mode 100644
index 0000000000..3c4d68178e
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/DynamicLayoutComponent.razor.cs
@@ -0,0 +1,10 @@
+using Microsoft.AspNetCore.Components;
+using Microsoft.Extensions.Options;
+
+namespace Volo.Abp.AspNetCore.Components.Web.Theming.Components;
+
+public partial class DynamicLayoutComponent : ComponentBase
+{
+ [Inject]
+ protected IOptions AbpDynamicLayoutComponentOptions { get; set; }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor
new file mode 100644
index 0000000000..f512232b86
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor
@@ -0,0 +1,7 @@
+@if (LayoutHookViewModel.Hooks.Any())
+{
+ foreach (var hook in LayoutHookViewModel.Hooks)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs
new file mode 100644
index 0000000000..18fbcd89c2
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Components;
+using Microsoft.Extensions.Options;
+using Volo.Abp.Ui.LayoutHooks;
+
+namespace Volo.Abp.AspNetCore.Components.Web.Theming.Components.LayoutHooks;
+
+public partial class LayoutHook : ComponentBase
+{
+ [Parameter]
+ public string Name { get; set; }
+
+ [Parameter]
+ public string Layout { get; set; }
+
+ [Inject]
+ protected IOptions LayoutHookOptions { get; set; }
+
+ protected LayoutHookViewModel LayoutHookViewModel { get; private set; }
+
+ protected override Task OnInitializedAsync()
+ {
+ if (LayoutHookOptions.Value.Hooks.TryGetValue(Name, out var layoutHooks))
+ {
+ layoutHooks = layoutHooks
+ .WhereIf(string.IsNullOrWhiteSpace(Layout), x => x.Layout == Layout)
+ .ToList();
+ }
+
+ layoutHooks ??= new List();
+
+ LayoutHookViewModel = new LayoutHookViewModel(layoutHooks.ToArray(), Layout);
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/StandardLayouts.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/StandardLayouts.cs
new file mode 100644
index 0000000000..ea73a5673f
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/StandardLayouts.cs
@@ -0,0 +1,6 @@
+namespace Volo.Abp.AspNetCore.Components.Web.Theming.Layout;
+
+public static class StandardLayouts
+{
+ public const string Application = "Application";
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarManager.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarManager.cs
index 05531096d4..00f7f5da23 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarManager.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarManager.cs
@@ -3,16 +3,17 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public class PageToolbarManager : IPageToolbarManager, ITransientDependency
{
- protected IHybridServiceScopeFactory ServiceScopeFactory { get; }
+ protected IServiceScopeFactory ServiceScopeFactory { get; }
public PageToolbarManager(
- IHybridServiceScopeFactory serviceScopeFactory)
+ IServiceScopeFactory serviceScopeFactory)
{
ServiceScopeFactory = serviceScopeFactory;
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs
index 33716d8383..229831141e 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs
@@ -7,6 +7,7 @@ using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.AspNetCore.Components.Web.ExceptionHandling;
using Volo.Abp.AspNetCore.Components.Web.Security;
using Volo.Abp.AspNetCore.Mvc.Client;
+using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
using Volo.Abp.Threading;
@@ -46,8 +47,8 @@ public class AbpAspNetCoreComponentsWebAssemblyModule : AbpModule
public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{
- await context.ServiceProvider.GetRequiredService().InitializeAsync();
- await context.ServiceProvider.GetRequiredService().InitializeAsync();
+ await context.ServiceProvider.GetRequiredService().ServiceProvider.GetRequiredService().InitializeAsync();
+ await context.ServiceProvider.GetRequiredService().ServiceProvider.GetRequiredService().InitializeAsync();
await SetCurrentLanguageAsync(context.ServiceProvider);
}
diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs
index ad36cf0f11..e0d8ecd806 100644
--- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs
+++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs
@@ -15,7 +15,6 @@ public class AbpAspNetCoreMultiTenancyModule : AbpModule
Configure(options =>
{
options.TenantResolvers.Add(new QueryStringTenantResolveContributor());
- options.TenantResolvers.Add(new FormTenantResolveContributor());
options.TenantResolvers.Add(new RouteTenantResolveContributor());
options.TenantResolvers.Add(new HeaderTenantResolveContributor());
options.TenantResolvers.Add(new CookieTenantResolveContributor());
diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs
index 4f89ef7b97..aa0f62a699 100644
--- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs
+++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs
@@ -3,6 +3,8 @@ using System.Globalization;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.MultiTenancy;
@@ -14,13 +16,25 @@ public class AbpAspNetCoreMultiTenancyOptions
///
public string TenantKey { get; set; }
- public Func MultiTenancyMiddlewareErrorPageBuilder { get; set; }
+ ///
+ /// Return true to stop the pipeline, false to continue.
+ ///
+ public Func> MultiTenancyMiddlewareErrorPageBuilder { get; set; }
public AbpAspNetCoreMultiTenancyOptions()
{
TenantKey = TenantResolverConsts.DefaultTenantKey;
MultiTenancyMiddlewareErrorPageBuilder = async (context, exception) =>
{
+ // Try to delete the tenant's cookie if it does not exist or is inactive.
+ var tenantResolveResult = context.RequestServices.GetRequiredService().Result;
+ if (tenantResolveResult != null &&
+ tenantResolveResult.AppliedResolvers.Contains(CookieTenantResolveContributor.ContributorName))
+ {
+ var options = context.RequestServices.GetRequiredService>().Value;
+ AbpMultiTenancyCookieHelper.SetTenantCookie(context, null, options.TenantKey);
+ }
+
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; ;
context.Response.ContentType = "text/html";
@@ -31,8 +45,10 @@ public class AbpAspNetCoreMultiTenancyOptions
await context.Response.WriteAsync($"{message}
{details}
\r\n");
await context.Response.WriteAsync("