Browse Source

Merge branch 'dev' into auto-merge/rel-7-3/2068

pull/17088/head
maliming 3 years ago
committed by GitHub
parent
commit
a65ae4ec1e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .github/scripts/update_versions.py
  2. 3
      Directory.Build.props
  3. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
  4. 1
      abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/ar.json
  5. 8
      abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
  6. 1
      abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/fi.json
  7. 1
      abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/hu.json
  8. 1
      abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json
  9. 1
      abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json
  10. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json
  11. 57
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
  12. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
  13. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json
  14. 10
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
  15. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
  16. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Docs/Localization/Resources/en.json
  17. 2
      common.props
  18. 267
      docs/en/Blog-Posts/2023-06-05 v7_3_Preview/POST.md
  19. BIN
      docs/en/Blog-Posts/2023-06-05 v7_3_Preview/abp-conf.png
  20. BIN
      docs/en/Blog-Posts/2023-06-05 v7_3_Preview/community-talks-2023-4.png
  21. BIN
      docs/en/Blog-Posts/2023-06-05 v7_3_Preview/cover-image.png
  22. BIN
      docs/en/Blog-Posts/2023-06-05 v7_3_Preview/devnot-conference.png
  23. BIN
      docs/en/Blog-Posts/2023-06-05 v7_3_Preview/devnot-talk.png
  24. BIN
      docs/en/Blog-Posts/2023-06-05 v7_3_Preview/leptonx-account-layout.png
  25. BIN
      docs/en/Blog-Posts/2023-06-05 v7_3_Preview/reset-authenticator.png
  26. BIN
      docs/en/Blog-Posts/2023-06-05 v7_3_Preview/two-factor-auth-1.png
  27. BIN
      docs/en/Blog-Posts/2023-06-05 v7_3_Preview/two-factor-auth-2.png
  28. BIN
      docs/en/Blog-Posts/2023-06-05 v7_3_Preview/two-factor-auth-3.png
  29. 4
      docs/en/Community-Articles/2023-06-05-Kubernetes-Integration-Abp-Studio/POST.md
  30. 293
      docs/en/Community-Articles/2023-07-03-Image-Compression-And-Resize/POST.md
  31. BIN
      docs/en/Community-Articles/2023-07-03-Image-Compression-And-Resize/image-manipulation.gif
  32. BIN
      docs/en/Community-Articles/2023-07-03-Image-Compression-And-Resize/image-upload-ui.png
  33. 40
      docs/en/Integration-Services.md
  34. 8
      docs/en/Migration-Guides/docs/en/Migration-Guides/Abp-7_4.md
  35. 23
      docs/en/Module-Development-Basics.md
  36. 14
      docs/en/Module-Entity-Extensions.md
  37. 2
      framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo.Abp.ApiVersioning.Abstractions.csproj
  38. 2
      framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/IRequestedApiVersion.cs
  39. 2
      framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/NullRequestedApiVersion.cs
  40. 2
      framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj
  41. 2
      framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj
  42. 4
      framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/MultipleClaimAction.cs
  43. 15
      framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs
  44. 2
      framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj
  45. 2
      framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming.csproj
  46. 2
      framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo.Abp.AspNetCore.Components.MauiBlazor.csproj
  47. 2
      framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/AbpAspNetCoreComponentsMauiBlazorModule.cs
  48. 2
      framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/AbpMauiBlazorClientHttpMessageHandler.cs
  49. 6
      framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/ApplicationConfigurationCache.cs
  50. 2
      framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/IMauiBlazorSelectedLanguageProvider.cs
  51. 2
      framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorCurrentTenantAccessor.cs
  52. 18
      framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs
  53. 2
      framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorServerUrlProvider.cs
  54. 4
      framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/NullMauiBlazorSelectedLanguageProvider.cs
  55. 2
      framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Volo.Abp.AspNetCore.Components.Server.Theming.csproj
  56. 2
      framework/src/Volo.Abp.AspNetCore.Components.Server/Microsoft/AspNetCore/Authentication/Cookies/CookieAuthenticationOptionsExtensions.cs
  57. 2
      framework/src/Volo.Abp.AspNetCore.Components.Server/Volo.Abp.AspNetCore.Components.Server.csproj
  58. 2
      framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/Extensibility/BlazorServerLookupApiRequestService.cs
  59. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/DynamicLayoutComponent.razor.cs
  60. 8
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs
  61. 10
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor.cs
  62. 12
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageLayout.cs
  63. 16
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarExtensions.cs
  64. 5
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarItem.cs
  65. 8
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/SimplePageToolbarContributor.cs
  66. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Routing/AbpRouterOptions.cs
  67. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/AbpThemingOptions.cs
  68. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/DefaultThemeManager.cs
  69. 3
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/IToolbarConfigurationContext.cs
  70. 3
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/ToolbarConfigurationContext.cs
  71. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/ToolbarItem.cs
  72. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Volo.Abp.AspNetCore.Components.Web.Theming.csproj
  73. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo.Abp.AspNetCore.Components.Web.csproj
  74. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpBlazorClientHttpMessageHandler.cs
  75. 4
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpBlazorMessageLocalizerHelper.cs
  76. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/CookieOptions.cs
  77. 4
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/CookieService.cs
  78. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/DefaultServerUrlProvider.cs
  79. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/DependencyInjection/ComponentsClientScopeServiceProviderAccessor.cs
  80. 6
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/AbpExceptionHandlingLogger.cs
  81. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/AbpExceptionHandlingLoggerProvider.cs
  82. 8
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/UserExceptionInformer.cs
  83. 14
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/EntityActions/EntityAction.cs
  84. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/EntityActions/EntityActionDictionary.cs
  85. 15
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/TableColumns/TableColumn.cs
  86. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/TableColumns/TableColumnDictionary.cs
  87. 4
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ICookieService.cs
  88. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/IServerUrlProvider.cs
  89. 10
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Messages/SimpleUiMessageService.cs
  90. 5
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs
  91. 2
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/ApplicationConfigurationChangedService.cs
  92. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj
  93. 4
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/EmptyWebAssemblyHostEnvironment.cs
  94. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo.Abp.AspNetCore.Components.WebAssembly.csproj
  95. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs
  96. 4
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ApplicationConfigurationCache.cs
  97. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCurrentTenantAccessor.cs
  98. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyServerUrlProvider.cs
  99. 2
      framework/src/Volo.Abp.AspNetCore.Components/Volo.Abp.AspNetCore.Components.csproj
  100. 75
      framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs

3
.github/scripts/update_versions.py

@ -51,5 +51,4 @@ def create_pr():
if __name__ == "__main__":
should_create_pr = update_latest_versions()
if should_create_pr:
create_pr()
create_pr()

3
Directory.Build.props

@ -42,6 +42,9 @@
<IsTestProject Condition="$(MSBuildProjectFullPath.Contains('test')) and ($(MSBuildProjectName.EndsWith('.Tests')) or $(MSBuildProjectName.EndsWith('.TestBase')))">true</IsTestProject>
<!-- OpenIddict https://www.nuget.org/packages/OpenIddict.Core -->
<OpenIddictPackageVersion>4.5.0</OpenIddictPackageVersion>
</PropertyGroup>
<ItemGroup>

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

@ -463,6 +463,7 @@
"DiscountAmount": "Discount Amount",
"FullChangeHistory": "Full Change History",
"Permission:RefreshReleaseLogs": "Refresh Release Logs",
"ReleaseLogs": "Release Logs"
"ReleaseLogs": "Release Logs",
"AuthorUserName": "Author User Name"
}
}

1
abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/ar.json

@ -137,6 +137,7 @@
"Address": "العنوان",
"Homepage": "الصفحة الرئيسية",
"Year": "السنة",
"Year_Plural": "سنوات",
"Copyright": "حقوق النشر © <a href=\"{0}\" target=\"_blank\">{1}</a>",
"DomainDrivenDesign": "التصميم المُقاد بالنطاق DDD",
"CrossCuttingConcerns": "اهتمامات مشتركة",

8
abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json

@ -141,6 +141,7 @@
"Address": "Address",
"Homepage": "Homepage",
"Year": "Year",
"Year_Plural": "Years",
"Copyright": "Copyright © <a href=\"{0}\" target=\"_blank\">{1}</a>",
"DomainDrivenDesign": "Domain Driven Design",
"CrossCuttingConcerns": "Cross Cutting Concerns",
@ -211,6 +212,11 @@
"RecentActivities": "Recent Activities",
"SpringCampaign": "Welcome <br>Spring Sale!",
"SpringCampaign2": "<span>Limited <br> Time Offer!</span>",
"AboutUs": "About Us"
"AboutUs": "About Us",
"HowItWorks": "How it works?",
"ReleaseNotes": "Release Notes",
"DetailedChangeNotes" : "Detailed Change Notes",
"SeeTrainings": "See Trainings",
"NoContent": "No content"
}
}

1
abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/fi.json

@ -140,6 +140,7 @@
"Address": "Osoite",
"Homepage": "Kotisivu",
"Year": "vuosi",
"Year_Plural": "vuotta",
"Copyright": "Tekijänoikeus © <a href=\"{0}\" target=\"_blank\">{1}</a>",
"DomainDrivenDesign": "Domain Driven Design",
"CrossCuttingConcerns": "Cross Cutting Concerns",

1
abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/hu.json

@ -138,6 +138,7 @@
"Address": "Cím",
"Homepage": "Kezdőlap",
"Year": "Év",
"Year_Plural": "Év",
"Copyright": "Copyright © <a href=\"{0}\" target=\"_blank\">{1}</a>",
"DomainDrivenDesign": "Domainvezérelt tervezés",
"CrossCuttingConcerns": "Cross Cutting Concerns",

1
abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json

@ -132,6 +132,7 @@
"Address": "Adres",
"Homepage": "Anasayfa",
"Year": "Yıl",
"Year_Plural": "Yıl",
"Copyright": "Telif hakkı © <a href=\"{0}\" target=\"_blank\">{1}</a>",
"DomainDrivenDesign": "Alan Odaklı Tasarım",
"CrossCuttingConcerns": "Cross Cutting Concerns",

1
abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json

@ -140,6 +140,7 @@
"Address": "地址",
"Homepage": "主页",
"Year": "年份",
"Year_Plural": "年份",
"Copyright": "版权所有 © <a href=\"{0}\" target=\"_blank\">{1}</a>",
"DomainDrivenDesign": "领域驱动设计",
"CrossCuttingConcerns": "横切关注点",

2
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json

@ -454,7 +454,7 @@
"MultipleUIOptionsExplanation": "نحن نحب طرقًا مختلفة لإنشاء واجهة المستخدم. يوفر حل بدء التشغيل هذا ثلاثة خيارات مختلفة لإطار عمل واجهة المستخدم لتطبيق عملك.",
"MultipleDatabaseOptions": "خيارات قاعدة بيانات متعددة",
"MultipleDatabaseOptionsExplanation": "لديك خياران لموفر قاعدة البيانات (بالإضافة إلى استخدام كليهما في تطبيق واحد). استخدم Entity Framework Core للعمل مع أي قاعدة بيانات علائقية واستخدم Dapper اختياريًا عندما تحتاج إلى كتابة استعلامات منخفضة المستوى للحصول على أداء أفضل. يعد MongoDB خيارًا آخر إذا كنت بحاجة إلى استخدام قاعدة بيانات NoSQL قائمة على المستندات. في حين أن هؤلاء الموفرين مدمجون جيدًا وملخصون ومهيئون مسبقًا ، يمكنك في الواقع التفاعل مع أي نظام قاعدة بيانات يمكنك استخدامه مع .NET.",
"ModularArchitectureExplanation2": "النمطية هي مواطن من الدرجة الأولى في منصة ABP.IO. يتم تقسيم جميع وظائف التطبيق إلى وحدات اختيارية معزولة جيدًا. يأتي حل بدء التشغيل بالفعل مع وحدات <a href=\"@Url.Page(\"/Modules\")\" class=\"text-primary\">ABP Commercial الأساسية </a> المثبتة مسبقًا. يمكنك أيضًا إنشاء الوحدات النمطية الخاصة بك لبناء نظام معياري لتطبيقك الخاص.",
"ModularArchitectureExplanation2": "النمطية هي مواطن من الدرجة الأولى في منصة ABP.IO. يتم تقسيم جميع وظائف التطبيق إلى وحدات اختيارية معزولة جيدًا. يأتي حل بدء التشغيل بالفعل مع وحدات <a href=\"/modules\" class=\"text-primary\">ABP Commercial الأساسية </a> المثبتة مسبقًا. يمكنك أيضًا إنشاء الوحدات النمطية الخاصة بك لبناء نظام معياري لتطبيقك الخاص.",
"MultiTenancyForSaasBusiness": "متعدد الإيجارات لأعمال SaaS الخاصة بك",
"MultiTenancyForSaasBusinessExplanation": "توفر ABP Commercial نظامًا كاملاً ومتعدد الإيجارات لإنشاء أنظمة SaaS (البرمجيات كخدمة). يسمح للمستأجرين بمشاركة قواعد البيانات الخاصة بهم أو الحصول عليها من خلال إنشاء قاعدة بيانات سريعة ونظام الهجرة.",
"MicroserviceStartupSolution": "حل بدء تشغيل الخدمات المصغرة",

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

@ -476,7 +476,7 @@
"MultipleUIOptionsExplanation": "We love different ways to create the User Interface. This startup solution provides three different UI framework options for your business application.",
"MultipleDatabaseOptions": "Multiple Database Options",
"MultipleDatabaseOptionsExplanation": "You have two database provider options (in addition to use both in a single application). Use Entity Framework Core to work with any relational database and optionally use Dapper when you need to write low-level queries for a better performance. MongoDB is another option if you need to use a document based NoSQL database. While these providers are well-integrated, abstracted and pre-configured, you can actually interact to any database system that you can use with .NET.",
"ModularArchitectureExplanation2": "Modularity is a first-class citizen in the ABP.IO platform. All the application functionalities are split into well-isolated optional modules. The startup solution already comes with the fundamental <a href=\"@Url.Page(\"/Modules\")\" class=\"text-primary\">ABP Commercial modules</a> pre-installed. You can also create your own modules to build a modular system for your own application.",
"ModularArchitectureExplanation2": "Modularity is a first-class citizen in the ABP.IO platform. All the application functionalities are split into well-isolated optional modules. The startup solution already comes with the fundamental <a href=\"/modules\" class=\"text-primary\">ABP Commercial modules</a> pre-installed. You can also create your own modules to build a modular system for your own application.",
"MultiTenancyForSaasBusiness": "Multi-Tenancy for your SaaS Business",
"MultiTenancyForSaasBusinessExplanation": "ABP Commercial provides a complete, end-to-end multi-tenancy system to create your SaaS (Software-as-a-Service) systems. It allows the tenants to share or have their own databases with on-the-fly database creation and migration system.",
"MicroserviceStartupSolution": "Microservice Startup Solution",
@ -844,7 +844,7 @@
"BlazoriseSupportExplanation5": "You can post your questions on the support website and generate a product token for your application.",
"AbpLiveTrainingPackages": "ABP Live Training Packages",
"Releases": "Releases",
"ReleasesDescription": "ABP Commercial releases and their changelogs.",
"ReleasesDescription": "Release logs of ABP Commercial.",
"ReleaseDate": "Release Date",
"Labels": "Labels",
"PreRelease": "Pre-release",
@ -852,7 +852,56 @@
"Enhancement": "Enhancement",
"Bug": "Bug",
"Feature": "Feature",
"AllUIs": "All UI's",
"MVC": "MVC"
"AllUIs": "All UIs",
"MVC": "MVC",
"BlazorServer": "Blazor Server",
"MAUI": "MAUI",
"HowItWorks_Page_Title": "How it works?",
"HowItWorks_Page_Description": "ABP Framework extends the .NET platform. So, anything you can do with a plain .NET solution is already possible with the ABP Framework. That makes it easy to get started with a low learning curve.",
"HowItWorks_Description1": "ABP Framework extends the .NET platform. So, anything you can do with a plain .NET solution is already possible with the ABP Framework. That makes it easy to get started with a low learning curve.",
"HowItWorks_Description2": "Once you start learning and using the ABP Framework features, developing your software will be much more enjoyable than ever.",
"HowItWorks_Description3": "This page basically explains how you use the ABP.IO Platform as a .NET developer.",
"CreateANewSolution": "Create a New .NET Solution",
"CreateANewSolution_Description1": "Everything starts by creating a new ABP integrated .NET solution.",
"StartWithStartupTemplates": "Start one of the pre-built <a href=\"/startup-templates\">startup solution templates</a>",
"SimpleMonolithApplicationTemplate": "Simple monolith application template",
"LayeredApplicationTemplate": "Layered application template",
"MicroserviceSolutionTemplate": "Microservice solution template",
"CreateEmptySolutionAndUseAbp": "Or create a new empty .NET solution and install ABP NuGet & NPM <a href=\"https://abp.io/packages\" target=\"_blank\">packages</a> yourself.",
"CreatingSolutionWithMultipleOptions": "There are multiple User Interface and Database options while creating a new solution.",
"UIFrameworkOptions": "UI Framework Options",
"DotnetSolutionWithoutDependency": "Now, you have a regular .NET solution in your local computer that has no dependency to a cloud platform or external service.",
"CheckTheDocumentForDetails": "You can check the <a href=\"{0}\" target=\"_blank\">{1}</a> document for details.",
"UIAndDatabaseIndependent": "ABP can work with any UI and any database provider supported by .NET. \n However, these UI and database providers are pre-integrated and well documented.",
"InstallAbpModules": "Install ABP Modules",
"DevelopYourSolution": "Develop Your Solution",
"DeployAnywhere": "Deploy Anywhere",
"InstallAbpModule_Description1": "ABP is a modular application development framework. Startup solution templates already come with the essential modules installed. \n But there are more application modules you may want to use in your solution.",
"InstallAbpModule_Description2": "Every module consists of a few NuGet and NPM packages and has an installation document. <a href=\"/tools/suite\">ABP Suite</a> does most of the work automatically, then you manually configure or fine tune the module based on its documentation.",
"DevelopYourSolution_Description1": "ABP’s infrastructure makes you <b class=\"text-white\">focus on your own business code</b> by automating the repetitive work and providing pre-built infrastructure and application <a href=\"https://abp.io/features\" target=\"_blank\">features</a>.",
"DevelopYourSolution_Description2": "In the following code block, you can see how the ABP Framework seamlessly integrates into your code and automates the repetitive tasks for you.",
"DevelopYourSolution_Description3": "Even in this short code block, ABP does a lot of things for you.",
"DevelopYourSolution_Description4": "It provides base classes to apply conventions, like \n <a href=\"https://docs.abp.io/en/abp/latest/Dependency-Injection\" target=\"_blank\">dependency injection</a>. Generic \n <a href=\"https://docs.abp.io/en/abp/latest/Repositories\" target=\"_blank\">repository</a> services provide a convenient \n way to interact with the database. Declarative \n <a href=\"https://docs.abp.io/en/abp/latest/Authorization\" target=\"_blank\">authorization</a> works with a fine-tuned permission system.",
"DevelopYourSolution_Description5": "ABP completely automates \n <a href=\"https://docs.abp.io/en/abp/latest/Unit-Of-Work\" target=\"_blank\">unit of work</a> (for database connection and transaction management), \n <a href=\"https://docs.abp.io/en/abp/latest/Exception-Handling\" target=\"_blank\">exception handling</a>, \n <a href=\"https://docs.abp.io/en/abp/latest/Validation\" target=\"_blank\">validation</a>\n and <a href=\"https://docs.abp.io/en/abp/latest/Audit-Logging\" target=\"_blank\">audit logging</a>. It provides many more building blocks to simplify your daily development tasks and focus on your own code while creating production ready \n applications.",
"DevelopYourSolution_Description6": "You can imagine how much that code block can be long and complicated if you would do it all manually.",
"SuiteCrudGenerationInFewSeconds": "In addition to hand coding your solution, you can create fully working advanced CRUD pages in a few minutes using the ABP Suite tooling. It generates the code into your solution, so you can fine tune it based on your custom requirements.",
"DeployAnywhere_Description1": "At the end of the day, you have a pure .NET solution. You can deploy your solution to your own server, to a cloud platform, kubernetes or anywhere you want. You can deploy to as many servers as you want. ABP is a deployment environment agnostic tool.",
"ExpertiseAbpFramework": "Expertise the ABP Framework",
"ExpertiseAbpFramework_Description1": "Want to go beyond basics and get expertise with the ABP.IO Platform?",
"FreeDownload": "Free Download",
"Read": "Read",
"HavingTrouble": "Having Trouble?",
"HavingTrouble_Description1": "Do you have problems with developing your solution? We are here! Use the ABP Support platform \n or send an email to get help directly from the Core ABP Framework team members.",
"WeAreHereToHelp_Description1": "You can browse our help topics or search in the frequently asked questions, \n or you can ask us a question by using the contact form.",
"OtherModules": "Other Modules",
"OtherModules_Description1": "Account, Audit Logging, Chat , CMS Kit,File Management , Forms, GDPR, Identity, Language Management, Payment , Saas and more...",
"HowItWorks_DatabaseProviderOptions": "Database provider options",
"SeeFAQ" : "See FAQ",
"ReleaseLogs": "Release Logs",
"ReleaseLogs_Tag": "{0} Release Logs",
"ReleaseLogs_Pr": "Pull Request #{0} - {1}",
"NoLabels": "No labels",
"DoesTheSubscriptionRenewAutomatically": "Does the subscription renew automatically?",
"DoesTheSubscriptionRenewAutomaticallyExplanation": "The ABP Commercial does not have an auto-renewal billing model. Therefore <strong>your subscription will not be automatically renewed</strong> at the end of your license period. If you want to continue to have the benefits of ABP Commercial, you can manually renew it at the <a href=\"/my-organizations\">organization management page</a>. If you have multiple organizations, click the \"Manage\" button at your expiring organization and then click the \"Extend Now\" button to renew your license. You may also want to take a look at the <a href=\"/faq#what-happens-when-license-ends\">What Happens When My License Ends?</a> section."
}
}

2
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json

@ -476,7 +476,7 @@
"MultipleUIOptionsExplanation": "Rakastamme erilaisia tapoja luoda käyttöliittymä. Tämä käynnistysratkaisu tarjoaa kolme erilaista käyttöliittymäkehysvaihtoehtoa yrityssovelluksellesi.",
"MultipleDatabaseOptions": "Useita tietokantavaihtoehtoja",
"MultipleDatabaseOptionsExplanation": "Sinulla on kaksi tietokannan tarjoajavaihtoehtoa (sen lisäksi, että voit käyttää molempia yhdessä sovelluksessa). Käytä Entity Framework Corea työskennelläksesi minkä tahansa relaatiotietokannan kanssa ja käytä valinnaisesti Dapperia, kun sinun on kirjoitettava matalan tason kyselyitä parantaaksesi suorituskykyä. MongoDB on toinen vaihtoehto, jos haluat käyttää dokumenttipohjaista NoSQL-tietokantaa. Vaikka nämä palveluntarjoajat ovat hyvin integroituja, abstrakteja ja esikonfiguroituja, voit itse asiassa olla vuorovaikutuksessa minkä tahansa tietokantajärjestelmän kanssa, jota voit käyttää .NET:n kanssa.",
"ModularArchitectureExplanation2": "Modulaarisuus on ensiluokkainen kansalainen ABP.IO-alustalla. Kaikki sovelluksen toiminnot on jaettu hyvin eristettyihin valinnaisiin moduuleihin. Käynnistysratkaisussa on valmiiksi asennettuna perus <a href=\"@Url.Page(\"/Modules\")\" class=\"text-primary\">ABP Commercial -moduulit</a>. Voit myös luoda omia moduuleita rakentaaksesi modulaarisen järjestelmän omalle sovelluksellesi.",
"ModularArchitectureExplanation2": "Modulaarisuus on ensiluokkainen kansalainen ABP.IO-alustalla. Kaikki sovelluksen toiminnot on jaettu hyvin eristettyihin valinnaisiin moduuleihin. Käynnistysratkaisussa on valmiiksi asennettuna perus <a href=\"/modules\" class=\"text-primary\">ABP Commercial -moduulit</a>. Voit myös luoda omia moduuleita rakentaaksesi modulaarisen järjestelmän omalle sovelluksellesi.",
"MultiTenancyForSaasBusiness": "Monivuokraus SaaS-yrityksellesi",
"MultiTenancyForSaasBusinessExplanation": "ABP Commercial tarjoaa täydellisen, päästä-päähän usean vuokrausjärjestelmän SaaS-järjestelmien (Software-as-a-Service) luomiseen. Sen avulla vuokralaiset voivat jakaa tai käyttää omia tietokantojaan tietokantojen luonti- ja siirtojärjestelmässä.",
"MicroserviceStartupSolution": "Mikropalvelun käynnistysratkaisu",

2
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json

@ -477,7 +477,7 @@
"MultipleUIOptionsExplanation": "Szeretjük a felhasználói felület létrehozásának különböző módjait. Ez az indítási megoldás három különböző felhasználói felületi keretrendszert biztosít az üzleti alkalmazás számára.",
"MultipleDatabaseOptions": "Több adatbázis-beállítás",
"MultipleDatabaseOptionsExplanation": "Két adatbázis-szolgáltató lehetősége van (amellett, hogy mindkettőt egyetlen alkalmazásban használhatja). Az Entity Framework Core segítségével bármilyen relációs adatbázissal dolgozhat, és opcionálisan használja a Dappert, ha alacsony szintű lekérdezéseket kell írnia a jobb teljesítmény érdekében. A MongoDB egy másik lehetőség, ha dokumentum alapú NoSQL adatbázist kell használnia. Noha ezek a szolgáltatók jól integráltak, absztraktáltak és előre konfiguráltak, valójában bármilyen adatbázis-rendszerrel kapcsolatba léphet, amelyet a .NET-tel használhat.",
"ModularArchitectureExplanation2": "A a legfőbb szempont az ABP.IO platformon. Az alkalmazás összes funkciója jól elkülönített opcionális modulokra van felosztva. Az indítási megoldás már előre telepítve tartalmazza az alapvető <a href=\"@Url.Page(\"/Modules\")\" class=\"text-primary\">ABP Commercial modulokat</a> . Saját modulokat is létrehozhat, hogy moduláris rendszert építsen fel saját alkalmazásához.",
"ModularArchitectureExplanation2": "A a legfőbb szempont az ABP.IO platformon. Az alkalmazás összes funkciója jól elkülönített opcionális modulokra van felosztva. Az indítási megoldás már előre telepítve tartalmazza az alapvető <a href=\"/modules\" class=\"text-primary\">ABP Commercial modulokat</a> . Saját modulokat is létrehozhat, hogy moduláris rendszert építsen fel saját alkalmazásához.",
"MultiTenancyForSaasBusiness": "Többérlős felépítés az Ön SaaS-üzleteihez",
"MultiTenancyForSaasBusinessExplanation": "Az ABP Commercial teljes körű, többbérlős rendszert biztosít SaaS (Software-as-a-Service) rendszereinek létrehozásához. Lehetővé teszi a bérlők számára, hogy megosszák vagy rendelkezzenek saját adatbázisokkal az on-the-fly adatbázis-létrehozó és migrációs rendszerrel.",
"MicroserviceStartupSolution": "Mikroszolgáltatás indítási megoldás",

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

@ -21,7 +21,7 @@
"SetDefault": "Varsayılan olarak ayarla",
"DefaultOrganization": "Varsayılan",
"StartDate": "Başlangıç tarihi",
"EndDate": "bitiş tarihi",
"EndDate": "Bitiş tarihi",
"Modules": "Modüller",
"LicenseExtendMessage": "Lisans bitiş tarihiniz {0} tarihine kadar uzatıldı",
"LicenseUpgradeMessage": "Lisansınız {0} lisansa yükseltildi",
@ -129,8 +129,8 @@
"TellUsWhatYouNeed": "Bize neye ihtiyacın olduğunu söyle.",
"YourMessage": "Mesajın",
"YourFullName": "Tam adınız",
"EmailField": "E",
"YourEmailAddress": "E",
"EmailField": "E-posta Adresi",
"YourEmailAddress": "E-posta adresiniz",
"HowMayWeHelpYou": "Size nasıl yardımcı olabiliriz?",
"SendMessage": "Mesaj gönder",
"Success": "Başarı",
@ -486,7 +486,7 @@
"MultipleUIOptionsExplanation": "Kullanıcı Arayüzü oluşturmanın farklı yollarını seviyoruz. Bu başlangıç çözümü, iş uygulamanız için üç farklı UI çerçeve seçeneği sunuyor.",
"MultipleDatabaseOptions": "Çoklu Veritabanı Seçenekleri",
"MultipleDatabaseOptionsExplanation": "İki veritabanı sağlayıcısı seçeneğiniz var (her ikisini de tek bir uygulamada kullanmanın yanı sıra). Herhangi bir ilişkisel veritabanıyla çalışmak için Entity Framework Core'u kullanın ve daha iyi bir performans için düşük seviyeli sorgular yazmanız gerektiğinde isteğe bağlı olarak Dapper'ı kullanın. Belge tabanlı bir NoSQL veritabanı kullanmanız gerekiyorsa MongoDB başka bir seçenektir. Bu sağlayıcılar iyi entegre edilmiş, soyutlanmış ve önceden yapılandırılmış olsa da, .NET ile kullanabileceğiniz herhangi bir veritabanı sistemiyle etkileşime girebilirsiniz. ",
"ModularArchitectureExplanation2": "Modülerlik, ABP.IO platformunda birinci sınıf bir vatandaştır. Uygulamalardaki tüm işlevler iyi izole edilmiş opsiyonel modüllere ayrılmıştır. Başlangıç çözümü zaten temel <a href=\"@Url.Page(\"/Modules\")\" class=\"text-primary\">ABP Ticari modülleri</a> önceden yüklenmiş olarak gelir. Kendi uygulamanız için modüler bir sistem oluşturmak üzere kendi modüllerinizi de oluşturabilirsiniz.",
"ModularArchitectureExplanation2": "Modülerlik, ABP.IO platformunda birinci sınıf bir vatandaştır. Uygulamalardaki tüm işlevler iyi izole edilmiş opsiyonel modüllere ayrılmıştır. Başlangıç çözümü zaten temel <a href=\"/modules\" class=\"text-primary\">ABP Ticari modülleri</a> önceden yüklenmiş olarak gelir. Kendi uygulamanız için modüler bir sistem oluşturmak üzere kendi modüllerinizi de oluşturabilirsiniz.",
"MultiTenancyForSaasBusiness": "Saas İşletmeleri için Çoklu Kiralama",
"MultiTenancyForSaasBusinessExplanation": "ABP Commercial, SaaS (Hizmet Olarak Yazılım) sistemlerinizi oluşturmak için eksiksiz, uçtan uca çoklu kiracılık sistemi sağlar. Anında veritabanı oluşturma ve taşıma sistemi ile kiracıların kendi veritabanlarını paylaşmalarına veya sahip olmalarına olanak tanır.",
"MicroserviceStartupSolution": "Mikro Hizmet Başlangıç Çözümü",
@ -808,4 +808,4 @@
"BlazoriseLicense": "Blazorise lisansı satın almamız gerekiyor mu?",
"BlazoriseLicenseExplanation": "Volosoft ve Megabit arasında bir anlaşmamız var, bu anlaşma ile Blazorise lisansı ABP Ticari ürünleri ile birlikte geliyor, bu nedenle müşterilerimizin ekstra bir Blazorise lisansı satın almasına gerek kalmıyor."
}
}
}

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

@ -476,7 +476,7 @@
"MultipleUIOptionsExplanation": "我们喜欢不同的方式来创建用户界面。 此启动解决方案为您的业务应用程序提供了三种不同的 UI 框架选项。",
"MultipleDatabaseOptions": "多个数据库选项",
"MultipleDatabaseOptionsExplanation": "您有两个数据库提供程序选项(除了在单个应用程序中使用两者)。 使用 Entity Framework Core 处理任何关系数据库,当您需要编写低级查询以获得更好的性能时,可以选择使用 Dapper。 如果您需要使用基于文档的 NoSQL 数据库,MongoDB 是另一种选择。 虽然这些提供程序是良好集成、抽象和预配置的,但您实际上可以与任何可与 .NET 一起使用的数据库系统进行交互。",
"ModularArchitectureExplanation2": "模块化是 ABP.IO 平台的一等公民。 所有应用程序功能都被拆分为隔离良好的可选模块。 启动解决方案已经预装了基本的 <a href=\"@Url.Page(\"/Modules\")\" class=\"text-primary\">ABP 商业模块</a>。 您还可以创建自己的模块来为自己的应用程序构建模块化系统。",
"ModularArchitectureExplanation2": "模块化是 ABP.IO 平台的一等公民。 所有应用程序功能都被拆分为隔离良好的可选模块。 启动解决方案已经预装了基本的 <a href=\"/modules\" class=\"text-primary\">ABP 商业模块</a>。 您还可以创建自己的模块来为自己的应用程序构建模块化系统。",
"MultiTenancyForSaasBusiness": "SaaS 业务的多租户",
"MultiTenancyForSaasBusinessExplanation": "ABP 商业版 提供完整的端到端多租户系统来创建您的 SaaS(软件即服务)系统。 它允许租户通过动态数据库创建和迁移系统共享或拥有自己的数据库。",
"MicroserviceStartupSolution": "微服务启动解决方案",
@ -827,6 +827,15 @@
"PrivacyPolicyPageTitle": "隐私政策 - Cookies政策",
"TermsConditionsPageTitle": "条款和条件",
"TrainingsPageTitle": "ABP培训套餐",
"ModulesPageTitle": "ABP内置的应用模块"
"ModulesPageTitle": "ABP内置的应用模块",
"DoesTheSubscriptionRenewAutomatically": "订阅会自动续订吗?",
"DoesTheSubscriptionRenewAutomaticallyExplanation": "ABP 商业版没有自动续订计费模式。因此,在您的许可期结束时,<strong>您的订阅将不会自动续订</strong>。如果您希望继续享受 ABP 商业版的好处,您可以在<a href=\"/my-organizations\">组织管理</a>页面手动续订。如果您有多个组织,请点击即将到期的组织上的“管理”按钮,然后点击“立即续订”按钮来续订您的许可证。您还可以查看<a href=\"/faq#what-happens-when-license-ends\">许可证到期后会发生什么?</a>部分。",
"BlazoriseSupport": "如何获取Blazorise许可密钥并获得Blazorise团队的支持?",
"BlazoriseSupportExplanation": "请按照以下步骤获取Blazorise团队的支持并获得您的Blazorise许可密钥:",
"BlazoriseSupportExplanation1": "使用与您的abp.io账户相同的电子邮件地址在<a href=\"https://blazorise.com/support/register\" rel=\"nofollow\">blazorise.com/support/register</a>上注册一个新账户。请将“许可密钥”一栏留空,<strong>并确保该电子邮件地址与您在abp.io上的电子邮件账户相同</strong>。",
"BlazoriseSupportExplanation2": "通过查看您的电子邮件信箱来验证您的电子邮件地址。如果在收件箱中没有看到电子邮件,请检查您的垃圾邮件箱!",
"BlazoriseSupportExplanation3": "在<a href=\"https://blazorise.com/support/login\" rel=\"nofollow\">blazorise.com/support/login</a>上登录Blazorise支持网站。",
"BlazoriseSupportExplanation4": "如果您有有效的ABP商业版许可证,您还将拥有Blazorise PRO许可证。您可以在<a href=\"https://blazorise.com/support/user/manage/license\" rel=\"nofollow\">blazorise.com/support/user/manage/license</a>获取您的Blazorise许可密钥。",
"BlazoriseSupportExplanation5": "您可以在support网站上发布您的问题,并为您的应用程序生成一个产品令牌。"
}
}

4
abp_io/AbpIoLocalization/AbpIoLocalization/Docs/Localization/Resources/en.json

@ -1,6 +1,8 @@
{
"culture": "en",
"texts": {
"Buy": "Buy"
"Buy": "Buy",
"SeeBookDetails": "See Book Details",
"MasteringAbpFrameworkEBookDescription": "This book will help you gain a complete understanding of the framework and modern web application development techniques."
}
}

2
common.props

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

267
docs/en/Blog-Posts/2023-06-05 v7_3_Preview/POST.md

@ -0,0 +1,267 @@
# ABP.IO Platform 7.3 RC Has Been Released
Today, we are happy to release the [ABP Framework](https://abp.io/) and [ABP Commercial](https://commercial.abp.io/) version **7.3 RC** (Release Candidate). This blog post introduces the new features and important changes in this new version.
Try this version and provide feedback for a more stable version of ABP v7.3! Thanks to all of you.
## Get Started with the 7.3 RC
Follow the steps below to try version 7.3.0 RC today:
1) **Upgrade** the ABP CLI to version `7.3.0-rc.1` using a command line terminal:
````bash
dotnet tool update Volo.Abp.Cli -g --version 7.3.0-rc.1
````
**or install** it if you haven't before:
````bash
dotnet tool install Volo.Abp.Cli -g --version 7.3.0-rc.1
````
2) Create a **new application** with the `--preview` option:
````bash
abp new BookStore --preview
````
See the [ABP CLI documentation](https://docs.abp.io/en/abp/latest/CLI) for all the available options.
> You can also use the [Get Started](https://abp.io/get-started) page to generate a CLI command to create a new application.
You can use any IDE that supports .NET 7.x, like [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/).
## Migration Guides
There are a few breaking changes in this version that may affect your application.
Please see the following migration documents, if you are upgrading from v7.2:
* [ABP Framework 7.2 to 7.3 Migration Guide](https://docs.abp.io/en/abp/7.3/Migration-Guides/Abp-7_3)
> If you are using the CMS Kit or CMS Kit Pro module, please don't forget to create a new migration and apply it to your database.
## What's New with ABP Framework 7.3?
In this section, I will introduce some major features released in this version. Here is a brief list of the titles that will be explained in the next sections:
* Introducing the Volo.Abp.Imaging packages
* ABP CLI: switch-to-local command
* Monitoring Distributed Events
* Ordering of the Local Event Handlers
* Nonce attribute support for Content Security Policy (CSP)
* Other News
### Introducing the Volo.Abp.Imaging packages
ABP Framework provides some packages to compress and resize images. Currently, there are four official packages:
* `Volo.Abp.Imaging.Abstractions`: Provides common services for compression and resizing purposes.
* `Volo.Abp.Imaging.AspNetCore`: Provides some attributes for controller actions that can automatically compress and/or resize uploaded files.
* `Volo.Abp.Imaging.ImageSharp`: Implements the image compression & resize operations using the [ImageSharp](https://github.com/SixLabors/ImageSharp) library.
* `Volo.Abp.Imaging.MagickNet`: Implements the image compression & resize operations using the [Magick.NET](https://github.com/dlemstra/Magick.NET) library.
You can use one of these official providers (`ImageSharp` or `Magick.NET`) or implement your own image resizer/compressor contributor and use it in your application.
> See the [Image Manipulation](https://docs.abp.io/en/abp/7.3/Image-Manipulation) documentation to learn more and see the required configurations.
### ABP CLI: switch-to-local command
In this version, ABP CLI introduces a new CLI command: **"switch-to-local"**. The `switch-to-local` command changes all NuGet package references on a solution to local project references for all the `.csproj` files in the specified folder (and all its subfolders with any depth).
**Usage:**
```bash
abp switch-to-local --paths "C:\Github\abp"
```
### Monitoring Distributed Events
ABP Framework allows you to stay informed when your application **receives** or **sends** a distributed event. This enables you to track the event flow within your application and take appropriate actions based on the received or sent distributed events.
You just need to subscribe to one of the `DistributedEventReceived` or `DistributedEventSent` events and take additional actions according to your cases.
**Example: Get informed when your application sends an event to the distributed event bus**
```csharp
public class DistributedEventSentHandler : ILocalEventHandler<DistributedEventSent>, ITransientDependency
{
public async Task HandleEventAsync(DistributedEventSent eventData)
{
// TODO: IMPLEMENT YOUR LOGIC...
}
}
```
> See the documentation to learn more: [https://docs.abp.io/en/abp/7.3/Distributed-Event-Bus](https://docs.abp.io/en/abp/7.3/Distributed-Event-Bus)
### Ordering of the Local Event Handlers
In this version, ABP Framework introduces the `LocalEventHandlerOrder` attribute, which can be used to set the execution order for the event handlers. This can be helpful if you want to handle your local event handlers in a specific order.
**Example:**
```csharp
[LocalEventHandlerOrder(-1)]
public class MyHandler
: ILocalEventHandler<StockCountChangedEvent>,
ITransientDependency
{
public async Task HandleEventAsync(StockCountChangedEvent eventData)
{
//TODO: your implementation
}
}
```
By default, all event handlers have an order value of 0. Thus, if you want to take certain event handlers to be executed before other event handlers, you can set the order value as a negative value.
> See the documentation to learn more: [https://docs.abp.io/en/abp/7.3/Local-Event-Bus](https://docs.abp.io/en/abp/7.3/Local-Event-Bus)
### Nonce attribute support for Content Security Policy (CSP)
ABP Framework supports adding unique value to nonce attribute for script tags which can be used by Content Security Policy to determine whether or not a given fetch will be allowed to proceed for a given element. In other words, it provides a mechanism to execute only correct script tags with the correct nonce value.
This feature is disabled by default. You can enable it by setting the *UseContentSecurityPolicyScriptNonce* property of the `AbpSecurityHeadersOptions` class to **true**:
```csharp
Configure<AbpSecurityHeadersOptions>(options =>
{
//adding script-src nonce
options.UseContentSecurityPolicyScriptNonce = true; //false by default
});
```
> See the [Security Headers](https://docs.abp.io/en/abp/7.3/UI/AspNetCore/Security-Headers) documentation for more information.
### Other News
* Upgraded the [Blazorise](https://blazorise.com/) library to v1.2.3 for Blazor UI. After the upgrade, ensure that all Blazorise-related packages are using v1.2.3 in your application.
* Module Entity Extension support has been added for the CMS Kit module. See [#16572](https://github.com/abpframework/abp/issues/16572) for more information.
If you want to see more details, you can check [the release on GitHub](https://github.com/abpframework/abp/releases/tag/5.3.0-rc.1), which contains a list of all the issues and pull requests were closed with this version.
## What's New with ABP Commercial 7.3?
We've also worked on [ABP Commercial](https://commercial.abp.io/) to align the features and changes made in the ABP Framework. The following sections introduce a few new features coming with ABP Commercial 7.3.
### Account Module - Using Authenticator App for Two-Factor Authentication
In this version, ABP Commercial provides a new **Two-Factor Authentication (2FA) provider** that allows you to log in to an application by scanning a QR Code with an Authenticator App, such as Microsoft Authenticator or Google Authenticator.
You need to apply the following actions to configure an Authenticator and then you are free to log in by using the Authenticator App:
**Step 1 - Enable Two Factor Authentication and Scan the QR Code:**
![](./two-factor-auth-1.png)
**Step 2 - Verify the QR Code with an authenticator app:**
![](./two-factor-auth-2.png)
**Step 3 - Save the recovery codes for later use in case of not being able to login by verifying the QR code:**
![](./two-factor-auth-3.png)
You can disable the two-factor authentication and reset the Authenticator App anytime you want, just by disabling the two-factor authentication or resetting the authenticator:
![](./reset-authenticator.png)
### Upgrade Blazorise to v1.2.3
Upgraded the [Blazorise](https://blazorise.com/) library to v1.2.3 for Blazor UI. If you are upgrading your project to v7.3.0, please ensure that all the Blazorise-related packages are using v1.2.3 in your application. Otherwise, you might get errors due to incompatible versions.
### CMS Kit: Module Entity Extensions
Module entity extension system is a high-level extension system that allows you to define new properties for existing entities of the dependent modules. ABP Framework and ABP Commercial use this system to allow developers to extend entities in different modules.
In this version, Module Entity Extension support has been added for the CMS Kit Pro module.
You can open the `YourProjectNameModuleExtensionConfigurator` class inside the `Domain.Shared` project of your solution and change the `ConfigureExtraProperties` method as shown below to add a new property to the `Poll` entity of the [CMS Kit Pro module](https://docs.abp.io/en/commercial/latest/modules/cms-kit/index):
```csharp
public static void ConfigureExtraProperties()
{
OneTimeRunner.Run(() =>
{
ObjectExtensionManager.Instance.Modules()
.ConfigureCmsKitPro(cmsKitPro =>
{
cmsKitPro.ConfigurePoll(poll =>
{
poll.AddOrUpdateProperty<string>(
"<property-name>",
property =>
{
//configuration for this property
}
)
});
});
});
}
```
> See the [Module Entity Extensions documentation](https://docs.abp.io/en/abp/latest/Module-Entity-Extensions) to learn more.
### LeptonX Account Layout
In this version, Account Layout has been re-designed for LeptonX Theme. You can see the new account layout in the following figure:
![](leptonx-account-layout.png)
> To use this new account layout, ensure that your LeptonX Theme package versions are v2.3+.
## Community News
### ABP Community Talks 2023.4: Angular 16 and ABP v7.3
![](./community-talks-2023-4.png)
In this episode, the core ABP team talked about what's new with ABP v7.3 and Angular 16. You can watch the event from [here](https://www.youtube.com/watch?v=lq6u4vQURcI).
### ABP .NET Conference 2023
![](./abp-conf.png)
We organized ABP .NET Conference 2023 on May 2023 and we are happy to share the success of the conference, which captivated overwhelmingly interested live viewers from all over the world. 13 great line up of speakers which includes .NET experts and Microsoft MVPs delivered captivating talks that resonated with the audiences. Each of the talks attracted a great amount of interest and a lot of questions, sparking curiosity in the attendees.
Thanks to all speakers and attendees for joining our event.
> We shared our takeaways in a blog post, which you can read at [https://blog.abp.io/abp/ABP-.NET-Conference-2023-Wrap-Up](https://blog.abp.io/abp/ABP-.NET-Conference-2023-Wrap-Up).
### Volosoft Attendeed & Sponsored Devnot .NET Conference 2023
![](devnot-conference.png)
We are thrilled to announce that the Volosoft Company proudly attended as one of the Gold Sponsors at the Devnot .NET Conference 2023! We are happy to join and be a sponsor of events and contribute to the software society, empowering developers and driving innovation with the .NET community.
![](devnot-talk.png)
Co-Founder of [Volosoft](https://volosoft.com/) and Lead Developer of the ABP Framework, [Halil Ibrahim Kalkan](https://twitter.com/hibrahimkalkan) gave a word about "Dealing with Concurrency and Multi Threading in .NET" at this event.
> You can check [this blog post](https://volosoft.com/blog/Reflecting-on-Devnot-Dotnet-Conference-2023) if you want to learn more about the Devnot .NET Conference 2023.
### New ABP Community Posts
There are exciting articles contributed by the ABP community as always. I will highlight some of them here:
* [Authority Delegation in ABP Commercial](https://community.abp.io/posts/authority-delegation-in-abp-commercial-3wtljpp0) by [Liang Shiwei](https://github.com/realLiangshiwei)
* [What's new in Angular 16? New Features and Updates](https://community.abp.io/posts/whats-new-in-angular-16-new-features-and-updates-s1izi9br) by [Masum Ulu](https://twitter.com/masumulu)
* [Kubernetes Integrated Microservice Development with ABP Studio](https://community.abp.io/videos/kubernetes-integrated-microservice-development-with-abp-studio-oix9zkp8) by [Halil Ibrahim Kalkan](https://twitter.com/hibrahimkalkan)
Thanks to the ABP Community for all the content they have published. You can also [post your ABP-related (text or video) content](https://community.abp.io/articles/submit) to the ABP Community.
### New ABP Blog Posts
There are also some exciting blog posts written by the ABP team. You can see the following list for some of those articles:
* [ABP .NET Conference 2023 Wrap Up](https://blog.abp.io/abp/ABP-.NET-Conference-2023-Wrap-Up) by [Bige Beşikçi](https://twitter.com/bigedediki)
* [Meet Volosoft at the Devnot .NET Conference 2023!](https://volosoft.com/blog/Meet-Volosoft-at-the-Devnot-.NET-Conference-2023) by [Roo Xu](https://github.com/Roo1227)
## Conclusion
This version comes with some new features and a lot of enhancements to the existing features. You can see the [Road Map](https://docs.abp.io/en/abp/7.3/Road-Map) documentation to learn about the release schedule and planned features for the next releases. Please try ABP v7.3 RC and provide feedback to help us release a more stable version.
Thanks for being a part of this community!

BIN
docs/en/Blog-Posts/2023-06-05 v7_3_Preview/abp-conf.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 KiB

BIN
docs/en/Blog-Posts/2023-06-05 v7_3_Preview/community-talks-2023-4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
docs/en/Blog-Posts/2023-06-05 v7_3_Preview/cover-image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

BIN
docs/en/Blog-Posts/2023-06-05 v7_3_Preview/devnot-conference.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

BIN
docs/en/Blog-Posts/2023-06-05 v7_3_Preview/devnot-talk.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
docs/en/Blog-Posts/2023-06-05 v7_3_Preview/leptonx-account-layout.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 KiB

BIN
docs/en/Blog-Posts/2023-06-05 v7_3_Preview/reset-authenticator.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
docs/en/Blog-Posts/2023-06-05 v7_3_Preview/two-factor-auth-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
docs/en/Blog-Posts/2023-06-05 v7_3_Preview/two-factor-auth-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
docs/en/Blog-Posts/2023-06-05 v7_3_Preview/two-factor-auth-3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

4
docs/en/Community-Articles/2023-06-05-Kubernetes-Integration-Abp-Studio/POST.md

@ -163,12 +163,10 @@ The solution runner is a great way of running multiple services locally. However
### How ABP Studio Kubernetes Tunnel works
I am sure that you want to see it in action, but before that, let me explain how the solution works. No problem if you can not understand it completely. It is enough to see the big picture:
I am sure that you want to see it in action, but before that, let me explain how the solution works.
![abp-studio-kubernetes-tunnel-how-it-works](06-abp-studio-kubernetes-tunnel-how-it-works.png)
Let's explain how it works:
* **Kubernetes cluster** is shown on the right side and your **local development machine** is shown on the left side.
* As you know, when a **user requests a web page** from your web application, the request is accepted by an **Ingress Controller** inside your Kubernetes cluster.
* The Ingress controller forwards the request to your **web application**, which then uses an **API gateway** to consume your microservices.

293
docs/en/Community-Articles/2023-07-03-Image-Compression-And-Resize/POST.md

@ -0,0 +1,293 @@
# Image Compression and Resize with ABP Framework
## Introduction
In this article, I will show how to compress and resize images easily with the ABP Framework's new [Image Manipulation System](https://docs.abp.io/en/abp/7.3/Image-Manipulation), which is introduced in v7.3.0.
ABP Framework provides services to compress and resize images and implements these services with popular [ImageSharp](https://sixlabors.com/products/imagesharp/) and [Magick.NET](https://github.com/dlemstra/Magick.NET) libraries. Currently, only these two providers are officially supported by the ABP Framework but thanks to the system being designed extensible, you can implement your own image resizer/compressor and use it in your application.
> Refer to the documentation for more info: [Image Manipulation](https://docs.abp.io/en/abp/7.3/Image-Manipulation)
### Source Code
You can find the source code of the application at [https://github.com/abpframework/abp-samples/tree/master/ImageManipulation](https://github.com/abpframework/abp-samples/tree/master/ImageManipulation). Don't hesitate to check the source code, if you are stuck on any point.
## Demo: Image Compression and Resize
The best way to see what ABP's Image Manipulation System is capable of is to see it in action. Thus, we can create a simple application that basically allows us to upload, search and display images.
### Creating a New ABP Solution
> I have created an ABP solution and you can find the [full source code of the demo application here](https://github.com/abpframework/abp-samples/tree/master/ImageManipulation). If you want to create the same solution from scratch, you can apply the following steps:
Install the ABP CLI, if you haven't installed it before:
```bash
dotnet tool install -g Volo.Abp.Cli
```
Create a new solution with the ABP Framework's Application Startup Template with MVC UI and EF Core database (default options):
```bash
abp new ImageManipulationDemo -t app --version 7.3.0-rc.2
```
> As I have mentioned above, ABP introduced the Image Manipulation System in v7.3.0. So, ensure your application is v7.3.0 or higher.
After creating the application, let's create the database and seed the initial data by running the `*.DbMigrator` project. Also, you can run the application to see if it's working as expected.
### Configuring the BLOB Storing System
Since we are creating an image upload application, we need to store our images somewhere and read these image contents when it's needed. [BLOB Storing System](https://docs.abp.io/en/abp/latest/Blob-Storing) is a great solution to achieve this. Let's install & configure the BLOB Storing System into our application.
First, run the following command under the directory of your `*.HttpApi` project:
```bash
abp add-package Volo.Abp.BlobStoring
```
Then, we need to select and configure a storage provider to tell the BLOB Storing System where to store the file contents. There are [multiple providers](https://docs.abp.io/en/abp/latest/Blob-Storing#blob-storage-providers) that we can choose. For the simplicity of the demo, let's continue with the **database provider** and run the following command under the directory of your solution (`*.sln`):
```bash
abp add-module Volo.Abp.BlobStoring.Database
```
* This command adds all the NuGet packages to the corresponding layers of your solution.
* Also, it makes the necessary configurations, adds a new database migration, and updates the database.
* Since we are not configuring the connection string, the BLOB Storing system will use the default connection string in our application.
That's it. We have installed and configured the BLOB Storing System in our application.
### Configuring the Image Manipulation System
After, configuring the BLOB Storing System, now we can install and configure the Image Manipulation System to be able to compress and resize images.
ABP Framework provides two image resizer/compressor implementations out of the box: [ImageSharp](https://docs.abp.io/en/abp/7.3/Image-Manipulation#imagesharp-provider) and [Magick.NET](https://docs.abp.io/en/abp/7.3/Image-Manipulation#magick-net-provider).
We can use the `Volo.Abp.Imaging.ImageSharp` as the provider for our application. To install the package, run the following command under the `*.HttpApi` project:
```bash
abp add-package Volo.Abp.Imaging.ImageSharp
```
* This package will provide the required services to compress and resize images.
* You can [configure the `ImageSharpCompressOptions`](https://docs.abp.io/en/abp/7.3/Image-Manipulation#configuration-1) to define *DefaultQuality* and encoders.
After installing the provider, now we can use the services to compress and resize our images, such as `IImageCompression` and `IImageResizer`. But there is an easier way. The `Volo.Abp.Imaging.AspNetCore` NuGet package defines some attributes for controller actions that can automatically compress and/or resize the uploaded files.
To be able to use these attributes, we need to install the `Volo.Abp.Imaging.AspNetCore` package. Type the following command under the `*.HttpApi` project:
```bash
abp add-package Volo.Abp.Imaging.AspNetCore
```
This package provides two attributes: `[CompressImage]` and `[ResizeImage]`. Whenever we use these attributes, the Image Manipulation System will automatically compress and/or resize uploaded files.
### Image Upload (with Compress & Resize)
After all the required package installations and configurations are done, now we can start implementing the API and UI for the Image Upload.
Let's start with creating the API. Create a controller in the `*.HttpApi` project named `ImageController` and perform the image upload and image display operations:
```csharp
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Volo.Abp.BlobStoring;
using Volo.Abp.Imaging;
namespace ImageManipulationDemo.Controllers
{
[Controller]
[Route("api/image")]
public class ImageController : ImageManipulationDemoController
{
private readonly IBlobContainer<ImageManipulationContainer> _blobContainer;
public ImageController(IBlobContainer<ImageManipulationContainer> blobContainer)
{
_blobContainer = blobContainer;
}
[HttpPost("upload")]
[CompressImage]
[ResizeImage(width: 200, height: 200)]
public async Task<IActionResult> UploadAsync(IFormFile file)
{
var fileBytes = await file.GetAllBytesAsync();
var blobName = file.FileName;
await _blobContainer.SaveAsync(blobName, fileBytes, overrideExisting: true);
return Ok();
}
[HttpGet("")]
public async Task<byte[]> GetImageAsync(string fileName)
{
return await _blobContainer.GetAllBytesAsync(fileName);
}
}
}
```
* Here, we have used both `CompressImage` and `ResizeImage` attributes to automatically compress & resize the uploaded file.
* As you can see, we used the `IBlobContainer<TContainer>` service to save our file content.
* Since we are using the *database provider* as BLOB storing provider, the file contents will be added to our database and then we will be able to fetch them whenever it's needed like we have done in the `GetImageAsync` method above.
* We simply used the required attributes (and they do the rest on behalf of us and call the related image resize and compress services) to resize & compress images and save the new resized/compressed image into the database.
Before implementing the UI side, as you may notice, we've injected the `IBlobContainer` as a typed service (`IBlobContainer<ImageManipulationContainer>`). A typed BLOB container system is a way of creating and managing multiple containers in an application. We haven't created the `ImageManipulationContainer` class yet.
Let's create this class as below:
```csharp
using Volo.Abp.BlobStoring;
namespace ImageManipulationDemo
{
[BlobContainerName("image-manipulation-demo")]
public class ImageManipulationContainer
{
}
}
```
* We have used the `BlobContainerName` attribute to define the name of the container.
* If we haven't used the `BlobContainerName` attribute, ABP Framework uses the full name of the class with its namespace.
We have implemented the endpoints and now can start implementing the UI side. You can see the following figure to see what we are going to design for the image upload page:
![](image-upload-ui.png)
Let's start designing this page. Open the `Index.cshtml` file (*/Pages/Index.cshtml*) under the `*.Web` project and replace it with the following content:
```html
@page
@using Microsoft.AspNetCore.Mvc.Localization
@using ImageManipulationDemo.Localization
@using Volo.Abp.Users
@model ImageManipulationDemo.Web.Pages.IndexModel
@inject IHtmlLocalizer<ImageManipulationDemoResource> L
@inject ICurrentUser CurrentUser
@section styles {
<abp-style src="/Pages/Index.css" />
}
@section scripts {
<abp-script src="/Pages/Index.js" />
}
<div class="container">
<div class="row">
<div class="col">
<div class="card">
<div class="card-body">
<form method="post" id="upload-image" enctype="multipart/form-data">
<div class="mb-3">
<label for="formFile" class="form-label">Upload an image</label>
<input class="form-control" type="file" id="formFile" required/>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary d-block w-100">Submit</button>
</div>
</form>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-title">
</div>
<div class="card-body">
<h5 class="card-title my-2">Search & Display Images</h5>
<form method="get" id="search-image">
<div class="input-group mb-3">
<input id="img-search-input" type="text" class="form-control" placeholder="Search with image name... E.g. image.png" aria-label="Search with image name" aria-describedby="button-search" required>
<button class="btn btn-outline-secondary" type="submit" id="button-search">Search</button>
</div>
</form>
<div class="d-none" id="image-result">
</div>
</div>
</div>
</div>
</div>
</div>
```
Then, open the `index.js` file and replace it with the following content:
```js
$(function () {
$("#upload-image").submit(function (e) {
e.preventDefault();
var file = document.getElementById("formFile").files[0];
var formData = new FormData();
formData.append("file", file);
$.ajax(
{
url: "/api/image/upload",
data: formData,
processData: false,
contentType: false,
type: "POST",
success: function (data) {
abp.message.success("Image saved successfully!");
},
error: function (err) {
abp.message.error("An error occured while saving the image.");
}
}
);
});
$("#search-image").submit(function (e) {
e.preventDefault();
var imgResult = $("#image-result");
imgResult.removeClass("d-none");
imgResult.html("<p>Loading...</p>");
var fileName = $("#img-search-input").val();
imageManipulationDemo.controllers.image.getImage(fileName)
.then(function (imageFile) {
var src = "data:image/png;base64," + imageFile;
var img = "<img src='" + src + "' />";
imgResult.html(img);
})
.catch(function (err) {
imgResult.html("<p>Could not find the image...</p>");
});
});
});
```
Now, we can run the application and see the Image Manipulation System in action:
![](image-manipulation.gif)
The results are impressive for the example above:
* The original image was 12 KB and now the compressed & resized image has been reduced to 8 KB.
* The original image was 225x225 and now resized as 200x200.
## Conclusion
In this article, I have shown you how to compress and/or resize images with ABP Framework's Image Manipulation System by just defining some attributes to the top of the controller actions.
Also, I have shown that you can use the BLOB Storing System to store file contents and compress/resize images before saving them into BLOB Storages thanks to the image resizers/compressors provided by ABP Framework.
## See Also
* [BLOB Storing](https://docs.abp.io/en/abp/latest/Blob-Storing)
* [Image Manipulation](https://docs.abp.io/en/abp/7.3/Image-Manipulation#iimageresizer)

BIN
docs/en/Community-Articles/2023-07-03-Image-Compression-And-Resize/image-manipulation.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 KiB

BIN
docs/en/Community-Articles/2023-07-03-Image-Compression-And-Resize/image-upload-ui.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

40
docs/en/Integration-Services.md

@ -34,11 +34,47 @@ public interface IProductAppService : IApplicationService
That's all. From now, ABP will handle your application service as integration service and implement the followings by convention:
* If you are using the [Auto API Controllers](API/Auto-API-Controllers.md) feature in your application, the URL prefix will be `/integration-api` instead of `/api` for your integration services. Thus, you can distinguish internal and external service communications and take additional actions, such as preventing REST API calls for integration services out of API Gateway.
* Audit logging is disabled by default for the integration services. See the next section if you want to enable it.
* That service is **not exposed** by default, unless you explicitly set `ExposeIntegrationServices` options (see the *Exposing Integration Services* section).
* If you are using the [Auto API Controllers](API/Auto-API-Controllers.md) feature in your application, the **URL prefix** will be `/integration-api` instead of `/api` for your integration services. Thus, you can distinguish internal and external service communications and take additional actions, such as preventing REST API calls for integration services out of API Gateway.
* **Audit logging** is disabled by default for the integration services. See the next section if you want to enable it.
## Marking an MVC Controller as Integration Service
In addition to application services, you can mark a regular MVC Controller as integration service, using the same `IntegrationService` attribute, or inheriting an interface that has the `IntegrationService` attribute.
**Example:**
````csharp
[IntegrationService] // Mark as integration service
[Route("integration-api/products")]
public class ProductController : AbpControllerBase
{
//...
}
````
When you use the `IntegrationService` attribute, ABP will handle your controller as integration service and implement the followings by convention:
* That controller is **not exposed** to clients by default, unless you explicitly set `ExposeIntegrationServices` options (see the *Exposing Integration Services* section).
* **Audit logging** is disabled by default for controller. See the next section if you want to enable it.
## Configuration
### Exposing Integration Services
Integration services and controllers are not exposed by default for security reasons. They typically don't require authorization, so you should **carefully and explicitly** allow them to be visible and usable to client applications.
To expose integration services and controllers, set `AbpAspNetCoreMvcOptions.ExposeIntegrationServices` to `true` in the `ConfigureServices` method of your [module class](Module-Development-Basics.md):
````csharp
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ExposeIntegrationServices = true;
});
````
> Hiding integration services is useful when you are building reusable application modules, where they may be used in a monolith application or in a microservice system. In a monolith application, integration services don't need to be exposed outside since the modules may in-process communicate with each other. On the other hand, if you build a microservice solution and use that module as a service, it will be proper to expose the integration services, so other microservices can consume them remotely inside your private network (or Kubernetes cluster). In that case, be careful to not accidently expose the integration services out of your private network. Configuring your API Gateway so that it blocks requests to `integration-api` prefixed URLs from outside of your network will be a good option.
### Enabling/Disabling the Audit Logging
Audit Logging is disabled by default for integration services but it can be enabled by configuring the `AbpAuditingOptions` [options class](Options.md) in the `ConfigureServices` method of your [module class](Module-Development-Basics.md):

8
docs/en/Migration-Guides/docs/en/Migration-Guides/Abp-7_4.md

@ -0,0 +1,8 @@
# ABP Version 7.4 Migration Guide
This document is a guide for upgrading ABP v7.3 solutions to ABP v7.4. There are a few changes in this version that may affect your applications, please read it carefully and apply the necessary changes to your application.
## TemplateDefinition
The `LocalizationResource(Type)` of `TemplateDefinition` class is changed to `LocalizationResourceName(string)`.

23
docs/en/Module-Development-Basics.md

@ -147,7 +147,7 @@ Lastly, you can override ``OnApplicationShutdown`` method if you want to execute
## Module Dependencies
In a modular application, it's not unusual for one module to depend upon another module(s). An Abp module must declare ``[DependsOn]`` attribute if it does have a dependency upon another module, as shown below:
In a modular application, it's not unusual for one module to depend upon another module(s). An ABP module must declare a ``[DependsOn]`` attribute if it does have a dependency upon another module, as shown below:
````C#
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
@ -162,6 +162,27 @@ You can use multiple ``DependsOn`` attribute or pass multiple module types to a
A depended module may depend on another module, but you only need to define your direct dependencies. ABP investigates the dependency graph for the application at startup and initializes/shutdowns modules in the correct order.
## Additional Module Assemblies
ABP automatically registers all the services of your module to the [dependency injection](Dependency-Injection.md) system. It finds the service types by scanning types in the assembly that defines your module class. That assembly is considered as the main assembly of your module.
Typically, every assembly contains a separate module class definition. Then modules depend on each other using the `DependsOn` attribute as explained in the previous section. However, in some rare cases, your module may consist of multiple assemblies, and only one of them defines a module class, and you want to make the other assemblies parts of your module. In that case, you can use the `AdditionalAssembly` attribute as shown below:
````csharp
[DependsOn(...)] // Your module dependencies as you normally do
[AdditionalAssembly(typeof(BlogService))] // A type in the target assembly
public class BlogModule
{
//...
}
````
In this example, we assume that the `BlogService` class is inside one assembly (`csproj`) and the `BlogModule` class is inside another assembly (`csproj`). With the `AdditionalAssembly` definition, ABP will load the assembly containing the `BlogService` class as a part of the blog module.
Notice that `BlogService` is only an arbitrary selected type in the target assembly. It is just used to indicate the related assembly. You could use any type in the assembly.
> WARNING: If you need to use the `AdditionalAssembly`, be sure that you don't design your system in a wrong way. With this example above, the `BlogService` class' assembly should normally have its own module class and the `BlogModule` should depend on it using the `DependsOn` attribute. Do not use the `AdditionalAssembly` attribute when you can already use the `DependsOn` attribute.
## Framework Modules vs Application Modules
There are **two types of modules.** They don't have any structural difference but categorized by functionality and purpose:

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

@ -255,6 +255,20 @@ property =>
Use `property.UI.OnCreateForm` and `property.UI.OnEditForm` to control forms too. If a property is required, but not added to the create form, you definitely get a validation exception, so use this option carefully. But a required property may not be in the edit form if that's your requirement.
### UI Order
When you define a property, it appears on the data table, create and edit forms on the related UI page. However, you can control its order. Example:
````csharp
property =>
{
property.UI.Order = 1;
//...other configurations
}
````
Use `property.UI.OnCreateForm` and `property.UI.OnEditForm` to control forms too. If a property is required, but not added to the create form, you definitely get a validation exception, so use this option carefully. But a required property may not be in the edit form if that's your requirement.
### HTTP API Availability
Even if you disable a property on UI, it can be still available through the HTTP API. By default, a property is available on all APIs.

2
framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo.Abp.ApiVersioning.Abstractions.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net7.0</TargetFrameworks>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<AssemblyName>Volo.Abp.ApiVersioning.Abstractions</AssemblyName>
<PackageId>Volo.Abp.ApiVersioning.Abstractions</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

2
framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/IRequestedApiVersion.cs

@ -2,5 +2,5 @@
public interface IRequestedApiVersion
{
string Current { get; }
string? Current { get; }
}

2
framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/NullRequestedApiVersion.cs

@ -4,7 +4,7 @@ public class NullRequestedApiVersion : IRequestedApiVersion
{
public static NullRequestedApiVersion Instance = new NullRequestedApiVersion();
public string Current => null;
public string? Current => null;
private NullRequestedApiVersion()
{

2
framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<AssemblyName>Volo.Abp.AspNetCore.Authentication.JwtBearer</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Authentication.JwtBearer</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

2
framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<AssemblyName>Volo.Abp.AspNetCore.Authentication.OAuth</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Authentication.OAuth</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

4
framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/MultipleClaimAction.cs

@ -29,7 +29,7 @@ public class MultipleClaimAction : ClaimAction
switch (prop.ValueKind)
{
case JsonValueKind.String:
claim = new Claim(ClaimType, prop.GetString(), ValueType, issuer);
claim = new Claim(ClaimType, prop.GetString()!, ValueType, issuer);
if (!identity.Claims.Any(c => c.Type == claim.Type && c.Value == claim.Value))
{
identity.AddClaim(claim);
@ -38,7 +38,7 @@ public class MultipleClaimAction : ClaimAction
case JsonValueKind.Array:
foreach (var arramItem in prop.EnumerateArray())
{
claim = new Claim(ClaimType, arramItem.GetString(), ValueType, issuer);
claim = new Claim(ClaimType, arramItem.GetString()!, ValueType, issuer);
if (!identity.Claims.Any(c => c.Type == claim.Type && c.Value == claim.Value))
{
identity.AddClaim(claim);

15
framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs

@ -28,8 +28,6 @@ public static class AbpOpenIdConnectExtensions
{
options.ClaimActions.MapAbpClaimTypes();
configureOptions?.Invoke(options);
options.Events ??= new OpenIdConnectEvents();
var authorizationCodeReceived = options.Events.OnAuthorizationCodeReceived ?? (_ => Task.CompletedTask);
@ -39,16 +37,7 @@ public static class AbpOpenIdConnectExtensions
return authorizationCodeReceived.Invoke(receivedContext);
};
options.Events.OnRemoteFailure = remoteFailureContext =>
{
if (remoteFailureContext.Failure is OpenIdConnectProtocolException &&
remoteFailureContext.Failure.Message.Contains("access_denied"))
{
remoteFailureContext.HandleResponse();
remoteFailureContext.Response.Redirect($"{remoteFailureContext.Request.PathBase}/");
}
return Task.CompletedTask;
};
options.AccessDeniedPath = "/";
options.Events.OnTokenValidated = async (context) =>
{
@ -63,6 +52,8 @@ public static class AbpOpenIdConnectExtensions
logger?.LogException(ex);
}
};
configureOptions?.Invoke(options);
});
}

2
framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<RootNamespace />
</PropertyGroup>

2
framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
</PropertyGroup>
<ItemGroup>

2
framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo.Abp.AspNetCore.Components.MauiBlazor.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<AssemblyName>Volo.Abp.AspNetCore.Components.MauiBlazor</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Components.MauiBlazor</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

2
framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/AbpAspNetCoreComponentsMauiBlazorModule.cs

@ -51,7 +51,7 @@ public class AbpAspNetCoreComponentsMauiBlazorModule : AbpModule
var cultureName = configuration.Localization?.CurrentCulture?.CultureName;
if (!cultureName.IsNullOrEmpty())
{
var culture = new CultureInfo(cultureName);
var culture = new CultureInfo(cultureName!);
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
}

2
framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/AbpMauiBlazorClientHttpMessageHandler.cs

@ -48,7 +48,7 @@ public class AbpMauiBlazorClientHttpMessageHandler : DelegatingHandler, ITransie
if (!selectedLanguage.IsNullOrWhiteSpace())
{
request.Headers.AcceptLanguage.Clear();
request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(selectedLanguage));
request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(selectedLanguage!));
}
}
}

6
framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/ApplicationConfigurationCache.cs

@ -7,11 +7,11 @@ namespace Volo.Abp.AspNetCore.Components.MauiBlazor;
public class ApplicationConfigurationCache : ISingletonDependency
{
protected ApplicationConfigurationDto Configuration { get; set; }
protected ApplicationConfigurationDto? Configuration { get; set; }
public event Action ApplicationConfigurationChanged;
public event Action? ApplicationConfigurationChanged;
public virtual ApplicationConfigurationDto Get()
public virtual ApplicationConfigurationDto? Get()
{
return Configuration;
}

2
framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/IMauiBlazorSelectedLanguageProvider.cs

@ -4,5 +4,5 @@ namespace Volo.Abp.AspNetCore.Components.MauiBlazor;
public interface IMauiBlazorSelectedLanguageProvider
{
Task<string> GetSelectedLanguageAsync();
Task<string?> GetSelectedLanguageAsync();
}

2
framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorCurrentTenantAccessor.cs

@ -6,5 +6,5 @@ namespace Volo.Abp.AspNetCore.Components.MauiBlazor;
[Dependency(ReplaceServices = true)]
public class MauiBlazorCurrentTenantAccessor : ICurrentTenantAccessor, ISingletonDependency
{
public BasicTenantInfo Current { get; set; }
public BasicTenantInfo? Current { get; set; }
}

18
framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs

@ -23,13 +23,13 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency
Cache = cache;
}
public async Task<TenantConfiguration> FindAsync(string name)
public async Task<TenantConfiguration?> FindAsync(string name)
{
var cacheKey = CreateCacheKey(name);
var tenantConfiguration = await Cache.GetOrAddAsync(
cacheKey,
async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name)),
async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name))!,
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow =
@ -40,13 +40,13 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency
return tenantConfiguration;
}
public async Task<TenantConfiguration> FindAsync(Guid id)
public async Task<TenantConfiguration?> FindAsync(Guid id)
{
var cacheKey = CreateCacheKey(id);
var tenantConfiguration = await Cache.GetOrAddAsync(
cacheKey,
async () => CreateTenantConfiguration(await TenantAppService.FindTenantByIdAsync(id)),
async () => CreateTenantConfiguration(await TenantAppService.FindTenantByIdAsync(id))!,
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow =
@ -57,13 +57,13 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency
return tenantConfiguration;
}
public TenantConfiguration Find(string name)
public TenantConfiguration? Find(string name)
{
var cacheKey = CreateCacheKey(name);
var tenantConfiguration = Cache.GetOrAdd(
cacheKey,
() => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name))),
() => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name)))!,
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow =
@ -74,13 +74,13 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency
return tenantConfiguration;
}
public TenantConfiguration Find(Guid id)
public TenantConfiguration? Find(Guid id)
{
var cacheKey = CreateCacheKey(id);
var tenantConfiguration = Cache.GetOrAdd(
cacheKey,
() => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByIdAsync(id))),
() => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByIdAsync(id)))!,
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow =
@ -91,7 +91,7 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency
return tenantConfiguration;
}
protected virtual TenantConfiguration CreateTenantConfiguration(FindTenantResultDto tenantResultDto)
protected virtual TenantConfiguration? CreateTenantConfiguration(FindTenantResultDto tenantResultDto)
{
if (!tenantResultDto.Success || tenantResultDto.TenantId == null)
{

2
framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorServerUrlProvider.cs

@ -17,7 +17,7 @@ public class MauiBlazorServerUrlProvider : IServerUrlProvider, ITransientDepende
RemoteServiceConfigurationProvider = remoteServiceConfigurationProvider;
}
public async Task<string> GetBaseUrlAsync(string remoteServiceName = null)
public async Task<string> GetBaseUrlAsync(string? remoteServiceName = null)
{
var remoteServiceConfiguration = await RemoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync(
remoteServiceName ?? RemoteServiceConfigurationDictionary.DefaultName

4
framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/NullMauiBlazorSelectedLanguageProvider.cs

@ -5,8 +5,8 @@ namespace Volo.Abp.AspNetCore.Components.MauiBlazor;
public class NullMauiBlazorSelectedLanguageProvider : IMauiBlazorSelectedLanguageProvider, ITransientDependency
{
public Task<string> GetSelectedLanguageAsync()
public Task<string?> GetSelectedLanguageAsync()
{
return Task.FromResult((string)null);
return Task.FromResult((string?)null);
}
}

2
framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Volo.Abp.AspNetCore.Components.Server.Theming.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<IsPackable>true</IsPackable>
<OutputType>Library</OutputType>
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>

2
framework/src/Volo.Abp.AspNetCore.Components.Server/Microsoft/AspNetCore/Authentication/Cookies/CookieAuthenticationOptionsExtensions.cs

@ -33,7 +33,7 @@ public static class CookieAuthenticationOptionsExtensions
var openIdConnectOptions = await GetOpenIdConnectOptions(principalContext, oidcAuthenticationScheme);
var response = await openIdConnectOptions.Backchannel.IntrospectTokenAsync(new TokenIntrospectionRequest
{
Address = openIdConnectOptions.Configuration?.IntrospectionEndpoint ?? openIdConnectOptions.Authority.EnsureEndsWith('/') + "connect/introspect",
Address = openIdConnectOptions.Configuration?.IntrospectionEndpoint ?? openIdConnectOptions.Authority!.EnsureEndsWith('/') + "connect/introspect",
ClientId = openIdConnectOptions.ClientId,
ClientSecret = openIdConnectOptions.ClientSecret,
Token = accessToken

2
framework/src/Volo.Abp.AspNetCore.Components.Server/Volo.Abp.AspNetCore.Components.Server.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<IsPackable>true</IsPackable>
<OutputType>Library</OutputType>
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>

2
framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/Extensibility/BlazorServerLookupApiRequestService.cs

@ -62,7 +62,7 @@ public class BlazorServerLookupApiRequestService : ILookupApiRequestService, ITr
{
baseUrl = NavigationManager.BaseUri;
client.BaseAddress = new Uri(baseUrl);
foreach (var header in HttpContextAccessor.HttpContext.Request.Headers)
foreach (var header in HttpContextAccessor.HttpContext!.Request.Headers)
{
requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
}

2
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/DynamicLayoutComponent.razor.cs

@ -6,5 +6,5 @@ namespace Volo.Abp.AspNetCore.Components.Web.Theming.Components;
public partial class DynamicLayoutComponent : ComponentBase
{
[Inject]
protected IOptions<AbpDynamicLayoutComponentOptions> AbpDynamicLayoutComponentOptions { get; set; }
protected IOptions<AbpDynamicLayoutComponentOptions> AbpDynamicLayoutComponentOptions { get; set; } = default!;
}

8
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs

@ -10,15 +10,15 @@ namespace Volo.Abp.AspNetCore.Components.Web.Theming.Components.LayoutHooks;
public partial class LayoutHook : ComponentBase
{
[Parameter]
public string Name { get; set; }
public string Name { get; set; } = default!;
[Parameter]
public string Layout { get; set; }
public string? Layout { get; set; }
[Inject]
protected IOptions<AbpLayoutHookOptions> LayoutHookOptions { get; set; }
protected IOptions<AbpLayoutHookOptions> LayoutHookOptions { get; set; } = default!;
protected LayoutHookViewModel LayoutHookViewModel { get; private set; }
protected LayoutHookViewModel LayoutHookViewModel { get; private set; } = default!;
protected override Task OnInitializedAsync()
{

10
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor.cs

@ -13,13 +13,13 @@ public partial class PageHeader : ComponentBase
{
protected List<RenderFragment> ToolbarItemRenders { get; set; }
public IPageToolbarManager PageToolbarManager { get; set; }
public IPageToolbarManager PageToolbarManager { get; set; } = default!;
[Inject]
public PageLayout PageLayout { get; private set; }
public PageLayout PageLayout { get; private set; } = default!;
[Parameter] // TODO: Consider removing this property in future and use only PageLayout.
public string Title { get => PageLayout.Title; set => PageLayout.Title = value; }
public string? Title { get => PageLayout.Title; set => PageLayout.Title = value; }
[Parameter]
public bool BreadcrumbShowHome { get; set; } = true;
@ -28,7 +28,7 @@ public partial class PageHeader : ComponentBase
public bool BreadcrumbShowCurrent { get; set; } = true;
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] // TODO: Consider removing this property in future and use only PageLayout.
public List<BreadcrumbItem> BreadcrumbItems {
@ -44,7 +44,7 @@ public partial class PageHeader : ComponentBase
}
[Parameter]
public PageToolbar Toolbar { get; set; }
public PageToolbar? Toolbar { get; set; }
public PageHeader()
{

12
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageLayout.cs

@ -9,10 +9,10 @@ namespace Volo.Abp.AspNetCore.Components.Web.Theming.Layout;
public class PageLayout : IScopedDependency, INotifyPropertyChanged
{
private string title;
private string? title;
// TODO: Consider using this property for setting Page Title too.
public virtual string Title {
public virtual string? Title {
get => title;
set {
title = value;
@ -20,9 +20,9 @@ public class PageLayout : IScopedDependency, INotifyPropertyChanged
}
}
private string menuItemName;
private string? menuItemName;
public string MenuItemName {
public string? MenuItemName {
get => menuItemName;
set
{
@ -35,9 +35,9 @@ public class PageLayout : IScopedDependency, INotifyPropertyChanged
public virtual ObservableCollection<PageToolbarItem> ToolbarItems { get; } = new();
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

16
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarExtensions.cs

@ -11,9 +11,9 @@ public static class PageToolbarExtensions
{
public static PageToolbar AddComponent<TComponent>(
this PageToolbar toolbar,
Dictionary<string, object> arguments = null,
Dictionary<string, object?>? arguments = null,
int order = 0,
string requiredPolicyName = null)
string? requiredPolicyName = null)
{
return toolbar.AddComponent(
typeof(TComponent),
@ -26,9 +26,9 @@ public static class PageToolbarExtensions
public static PageToolbar AddComponent(
this PageToolbar toolbar,
Type componentType,
Dictionary<string, object> arguments = null,
Dictionary<string, object?>? arguments = null,
int order = 0,
string requiredPolicyName = null)
string? requiredPolicyName = null)
{
toolbar.Contributors.Add(
new SimplePageToolbarContributor(
@ -46,14 +46,14 @@ public static class PageToolbarExtensions
this PageToolbar toolbar,
string text,
Func<Task> clicked,
object icon = null,
Color color = null,
object? icon = null,
Color? color = null,
bool disabled = false,
int order = 0,
string requiredPolicyName = null)
string? requiredPolicyName = null)
{
toolbar.AddComponent<ToolbarButton>(
new Dictionary<string, object>
new Dictionary<string, object?>
{
{ nameof(ToolbarButton.Color), color ?? Color.Primary},
{ nameof(ToolbarButton.Text), text},

5
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarItem.cs

@ -9,14 +9,13 @@ public class PageToolbarItem
[NotNull]
public Type ComponentType { get; }
[CanBeNull]
public Dictionary<string, object> Arguments { get; set; }
public Dictionary<string, object?>? Arguments { get; set; }
public int Order { get; set; }
public PageToolbarItem(
[NotNull] Type componentType,
[CanBeNull] Dictionary<string, object> arguments = null,
Dictionary<string, object?>? arguments = null,
int order = 0)
{
ComponentType = Check.NotNull(componentType, nameof(componentType));

8
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/SimplePageToolbarContributor.cs

@ -10,17 +10,17 @@ public class SimplePageToolbarContributor : IPageToolbarContributor
{
public Type ComponentType { get; }
public Dictionary<string, object> Arguments { get; set; }
public Dictionary<string, object?>? Arguments { get; set; }
public int Order { get; }
public string RequiredPolicyName { get; }
public string? RequiredPolicyName { get; }
public SimplePageToolbarContributor(
Type componentType,
Dictionary<string, object> arguments = null,
Dictionary<string, object?>? arguments = null,
int order = 0,
string requiredPolicyName = null)
string? requiredPolicyName = null)
{
ComponentType = componentType;
Arguments = arguments;

2
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Routing/AbpRouterOptions.cs

@ -4,7 +4,7 @@ namespace Volo.Abp.AspNetCore.Components.Web.Theming.Routing;
public class AbpRouterOptions
{
public Assembly AppAssembly { get; set; }
public Assembly AppAssembly { get; set; } = default!;
public RouterAssemblyList AdditionalAssemblies { get; }

2
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/AbpThemingOptions.cs

@ -4,7 +4,7 @@ public class AbpThemingOptions
{
public ThemeDictionary Themes { get; }
public string DefaultThemeName { get; set; }
public string? DefaultThemeName { get; set; }
public AbpThemingOptions()
{

2
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/DefaultThemeManager.cs

@ -9,7 +9,7 @@ public class DefaultThemeManager : IThemeManager, IScopedDependency, IServicePro
public IServiceProvider ServiceProvider { get; }
public ITheme CurrentTheme => GetCurrentTheme();
private ITheme _currentTheme;
private ITheme? _currentTheme;
protected IThemeSelector ThemeSelector { get; }

3
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/IToolbarConfigurationContext.cs

@ -17,8 +17,7 @@ public interface IToolbarConfigurationContext : IServiceProviderAccessor
Task<bool> IsGrantedAsync(string policyName);
[CanBeNull]
IStringLocalizer GetDefaultLocalizer();
IStringLocalizer? GetDefaultLocalizer();
[NotNull]
public IStringLocalizer GetLocalizer<T>();

3
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/ToolbarConfigurationContext.cs

@ -32,8 +32,7 @@ public class ToolbarConfigurationContext : IToolbarConfigurationContext
return AuthorizationService.IsGrantedAsync(policyName);
}
[CanBeNull]
public IStringLocalizer GetDefaultLocalizer()
public IStringLocalizer? GetDefaultLocalizer()
{
return StringLocalizerFactory.CreateDefaultOrNull();
}

2
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/ToolbarItem.cs

@ -9,7 +9,7 @@ public class ToolbarItem
get => _componentType;
set => _componentType = Check.NotNull(value, nameof(value));
}
private Type _componentType;
private Type _componentType = default!;
public int Order { get; set; }

2
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Volo.Abp.AspNetCore.Components.Web.Theming.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
</PropertyGroup>
<ItemGroup>

2
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo.Abp.AspNetCore.Components.Web.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<RootNamespace />
</PropertyGroup>

2
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpBlazorClientHttpMessageHandler.cs

@ -82,7 +82,7 @@ public class AbpBlazorClientHttpMessageHandler : DelegatingHandler, ITransientDe
var selfUri = new Uri(_navigationManager.Uri);
if (request.RequestUri.Host != selfUri.Host || request.RequestUri.Port != selfUri.Port)
if (request.RequestUri!.Host != selfUri.Host || request.RequestUri.Port != selfUri.Port)
{
return;
}

4
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpBlazorMessageLocalizerHelper.cs

@ -14,12 +14,12 @@ public class AbpBlazorMessageLocalizerHelper<T>
this.stringLocalizer = stringLocalizer;
}
public string Localize(string message, [CanBeNull] IEnumerable<string> arguments)
public string Localize(string message, IEnumerable<string>? arguments)
{
try
{
return arguments?.Count() > 0
? stringLocalizer[message, LocalizeMessageArguments(arguments)?.ToArray()]
? stringLocalizer[message, LocalizeMessageArguments(arguments)?.ToArray()!]
: stringLocalizer[message];
}
catch

2
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/CookieOptions.cs

@ -5,6 +5,6 @@ namespace Volo.Abp.AspNetCore.Components.Web;
public class CookieOptions
{
public DateTimeOffset? ExpireDate { get; set; }
public string Path { get; set; }
public string? Path { get; set; }
public bool Secure { get; set; }
}

4
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/CookieService.cs

@ -14,7 +14,7 @@ public class CookieService : ICookieService, ITransientDependency
JsRuntime = jsRuntime;
}
public async ValueTask SetAsync(string key, string value, CookieOptions options)
public async ValueTask SetAsync(string key, string value, CookieOptions? options)
{
await JsRuntime.InvokeVoidAsync("abp.utils.setCookieValue", key, value, options?.ExpireDate?.ToString("r"), options?.Path, options?.Secure);
}
@ -24,7 +24,7 @@ public class CookieService : ICookieService, ITransientDependency
return await JsRuntime.InvokeAsync<string>("abp.utils.getCookieValue", key);
}
public async ValueTask DeleteAsync(string key, string path = null)
public async ValueTask DeleteAsync(string key, string? path = null)
{
await JsRuntime.InvokeVoidAsync("abp.utils.deleteCookie", key);
}

2
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/DefaultServerUrlProvider.cs

@ -5,7 +5,7 @@ namespace Volo.Abp.AspNetCore.Components.Web;
public class DefaultServerUrlProvider : IServerUrlProvider, ISingletonDependency
{
public Task<string> GetBaseUrlAsync(string remoteServiceName = null)
public Task<string> GetBaseUrlAsync(string? remoteServiceName = null)
{
return Task.FromResult("/");
}

2
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/DependencyInjection/ComponentsClientScopeServiceProviderAccessor.cs

@ -7,5 +7,5 @@ public class ComponentsClientScopeServiceProviderAccessor :
IClientScopeServiceProviderAccessor,
ISingletonDependency
{
public IServiceProvider ServiceProvider { get; set; }
public IServiceProvider ServiceProvider { get; set; } = default!;
}

6
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/AbpExceptionHandlingLogger.cs

@ -8,7 +8,7 @@ namespace Volo.Abp.AspNetCore.Components.Web.ExceptionHandling;
public class AbpExceptionHandlingLogger : ILogger
{
private readonly IServiceCollection _serviceCollection;
private IUserExceptionInformer _userExceptionInformer;
private IUserExceptionInformer? _userExceptionInformer;
public AbpExceptionHandlingLogger(IServiceCollection serviceCollection)
{
@ -19,7 +19,7 @@ public class AbpExceptionHandlingLogger : ILogger
LogLevel logLevel,
EventId eventId,
TState state,
Exception exception,
Exception? exception,
Func<TState, Exception, string> formatter)
{
if (exception == null)
@ -58,7 +58,7 @@ public class AbpExceptionHandlingLogger : ILogger
return logLevel == LogLevel.Critical || logLevel == LogLevel.Error;
}
public virtual IDisposable BeginScope<TState>(TState state)
public virtual IDisposable? BeginScope<TState>(TState state) where TState : notnull
{
return NullDisposable.Instance;
}

2
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/AbpExceptionHandlingLoggerProvider.cs

@ -5,7 +5,7 @@ namespace Volo.Abp.AspNetCore.Components.Web.ExceptionHandling;
public class AbpExceptionHandlingLoggerProvider : ILoggerProvider
{
private AbpExceptionHandlingLogger _logger;
private AbpExceptionHandlingLogger? _logger;
private static readonly object SyncObj = new object();
private readonly IServiceCollection _serviceCollection;

8
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/UserExceptionInformer.cs

@ -39,11 +39,11 @@ public class UserExceptionInformer : IUserExceptionInformer, IScopedDependency
if (errorInfo.Details.IsNullOrEmpty())
{
MessageService.Error(errorInfo.Message);
MessageService.Error(errorInfo.Message!);
}
else
{
MessageService.Error(errorInfo.Details, errorInfo.Message);
MessageService.Error(errorInfo.Details!, errorInfo.Message);
}
}
@ -53,11 +53,11 @@ public class UserExceptionInformer : IUserExceptionInformer, IScopedDependency
if (errorInfo.Details.IsNullOrEmpty())
{
await MessageService.Error(errorInfo.Message);
await MessageService.Error(errorInfo.Message!);
}
else
{
await MessageService.Error(errorInfo.Details, errorInfo.Message);
await MessageService.Error(errorInfo.Details!, errorInfo.Message);
}
}

14
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/EntityActions/EntityAction.cs

@ -5,15 +5,15 @@ namespace Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions;
public class EntityAction : IEquatable<EntityAction>
{
public string Text { get; set; }
public Func<object, Task> Clicked { get; set; }
public Func<object, string> ConfirmationMessage { get; set; }
public string Text { get; set; } = default!;
public Func<object, Task> Clicked { get; set; } = default!;
public Func<object, string>? ConfirmationMessage { get; set; }
public bool Primary { get; set; }
public object Color { get; set; }
public string Icon { get; set; }
public Func<object, bool> Visible { get; set; }
public object? Color { get; set; }
public string? Icon { get; set; }
public Func<object, bool>? Visible { get; set; }
public bool Disabled { get; set; }
public bool Equals(EntityAction other)
public bool Equals(EntityAction? other)
{
return string.Equals(Text, other?.Text, StringComparison.OrdinalIgnoreCase);
}

2
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/EntityActions/EntityActionDictionary.cs

@ -6,6 +6,6 @@ public class EntityActionDictionary : Dictionary<string, List<EntityAction>>
{
public List<EntityAction> Get<T>()
{
return this.GetOrAdd(typeof(T).FullName, () => new List<EntityAction>());
return this.GetOrAdd(typeof(T).FullName!, () => new List<EntityAction>());
}
}

15
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/TableColumns/TableColumn.cs

@ -8,23 +8,20 @@ namespace Volo.Abp.AspNetCore.Components.Web.Extensibility.TableColumns;
public class TableColumn
{
public string Title { get; set; }
public string Data { get; set; }
public string Title { get; set; } = default!;
public string Data { get; set; } = default!;
public string PropertyName { get; set; }
public string PropertyName { get; set; } = default!;
[CanBeNull]
public string DisplayFormat { get; set; }
public string? DisplayFormat { get; set; }
public IFormatProvider DisplayFormatProvider { get; set; } = CultureInfo.CurrentCulture;
[CanBeNull]
public Type Component { get; set; }
public Type? Component { get; set; }
public List<EntityAction> Actions { get; set; }
[CanBeNull]
public Func<object, string> ValueConverter { get; set; }
public Func<object, string>? ValueConverter { get; set; }
public bool Sortable { get; set; }

2
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/TableColumns/TableColumnDictionary.cs

@ -6,6 +6,6 @@ public class TableColumnDictionary : Dictionary<string, List<TableColumn>>
{
public List<TableColumn> Get<T>()
{
return this.GetOrAdd(typeof(T).FullName, () => new List<TableColumn>());
return this.GetOrAdd(typeof(T).FullName!, () => new List<TableColumn>());
}
}

4
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ICookieService.cs

@ -4,7 +4,7 @@ namespace Volo.Abp.AspNetCore.Components.Web;
public interface ICookieService
{
public ValueTask SetAsync(string key, string value, CookieOptions options = null);
public ValueTask SetAsync(string key, string value, CookieOptions? options = null);
public ValueTask<string> GetAsync(string key);
public ValueTask DeleteAsync(string key, string path = null);
public ValueTask DeleteAsync(string key, string? path = null);
}

2
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/IServerUrlProvider.cs

@ -4,5 +4,5 @@ namespace Volo.Abp.AspNetCore.Components.Web;
public interface IServerUrlProvider
{
Task<string> GetBaseUrlAsync(string remoteServiceName = null);
Task<string> GetBaseUrlAsync(string? remoteServiceName = null);
}

10
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Messages/SimpleUiMessageService.cs

@ -15,27 +15,27 @@ public class SimpleUiMessageService : IUiMessageService, ITransientDependency
JsRuntime = jsRuntime;
}
public async Task Info(string message, string title = null, Action<UiMessageOptions> options = null)
public async Task Info(string message, string? title = null, Action<UiMessageOptions>? options = null)
{
await JsRuntime.InvokeVoidAsync("alert", message);
}
public async Task Success(string message, string title = null, Action<UiMessageOptions> options = null)
public async Task Success(string message, string? title = null, Action<UiMessageOptions>? options = null)
{
await JsRuntime.InvokeVoidAsync("alert", message);
}
public async Task Warn(string message, string title = null, Action<UiMessageOptions> options = null)
public async Task Warn(string message, string? title = null, Action<UiMessageOptions>? options = null)
{
await JsRuntime.InvokeVoidAsync("alert", message);
}
public async Task Error(string message, string title = null, Action<UiMessageOptions> options = null)
public async Task Error(string message, string? title = null, Action<UiMessageOptions>? options = null)
{
await JsRuntime.InvokeVoidAsync("alert", message);
}
public async Task<bool> Confirm(string message, string title = null, Action<UiMessageOptions> options = null)
public async Task<bool> Confirm(string message, string? title = null, Action<UiMessageOptions>? options = null)
{
return await JsRuntime.InvokeAsync<bool>("confirm", message);
}

5
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs

@ -9,10 +9,9 @@ namespace Volo.Abp.AspNetCore.Components.Web.Security;
public class AbpComponentsClaimsCache : IScopedDependency
{
public ClaimsPrincipal Principal { get; private set; }
public ClaimsPrincipal Principal { get; private set; } = default!;
[CanBeNull]
private readonly AuthenticationStateProvider _authenticationStateProvider;
private readonly AuthenticationStateProvider? _authenticationStateProvider;
public AbpComponentsClaimsCache(
IClientScopeServiceProviderAccessor serviceProviderAccessor)

2
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/ApplicationConfigurationChangedService.cs

@ -6,7 +6,7 @@ public delegate void ApplicationConfigurationChangedHandler();
public class ApplicationConfigurationChangedService : IScopedDependency
{
public event ApplicationConfigurationChangedHandler Changed;
public event ApplicationConfigurationChangedHandler Changed = default!;
public void NotifyChanged()
{

2
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
</PropertyGroup>
<ItemGroup>

4
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/EmptyWebAssemblyHostEnvironment.cs

@ -4,7 +4,7 @@ namespace Microsoft.Extensions.DependencyInjection;
public class EmptyWebAssemblyHostEnvironment : IWebAssemblyHostEnvironment
{
public string Environment { get; set; }
public string Environment { get; set; } = default!;
public string BaseAddress { get; set; }
public string BaseAddress { get; set; } = default!;
}

2
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo.Abp.AspNetCore.Components.WebAssembly.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<AssemblyName>Volo.Abp.AspNetCore.Components.WebAssembly</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Components.WebAssembly</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

2
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs

@ -67,7 +67,7 @@ public class AbpAspNetCoreComponentsWebAssemblyModule : AbpModule
var cultureName = configuration.Localization?.CurrentCulture?.CultureName;
if (!cultureName.IsNullOrEmpty())
{
var culture = new CultureInfo(cultureName);
var culture = new CultureInfo(cultureName!);
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
}

4
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ApplicationConfigurationCache.cs

@ -5,9 +5,9 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly;
public class ApplicationConfigurationCache : ISingletonDependency
{
protected ApplicationConfigurationDto Configuration { get; set; }
protected ApplicationConfigurationDto? Configuration { get; set; }
public virtual ApplicationConfigurationDto Get()
public virtual ApplicationConfigurationDto? Get()
{
return Configuration;
}

2
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCurrentTenantAccessor.cs

@ -6,5 +6,5 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly;
[Dependency(ReplaceServices = true)]
public class WebAssemblyCurrentTenantAccessor : ICurrentTenantAccessor, ISingletonDependency
{
public BasicTenantInfo Current { get; set; }
public BasicTenantInfo? Current { get; set; }
}

2
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyServerUrlProvider.cs

@ -17,7 +17,7 @@ public class WebAssemblyServerUrlProvider : IServerUrlProvider, ITransientDepend
RemoteServiceConfigurationProvider = remoteServiceConfigurationProvider;
}
public async Task<string> GetBaseUrlAsync(string remoteServiceName = null)
public async Task<string> GetBaseUrlAsync(string? remoteServiceName = null)
{
var remoteServiceConfiguration = await RemoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync(
remoteServiceName ?? RemoteServiceConfigurationDictionary.DefaultName

2
framework/src/Volo.Abp.AspNetCore.Components/Volo.Abp.AspNetCore.Components.csproj

@ -5,6 +5,8 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<AssemblyName>Volo.Abp.AspNetCore.Components</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Components</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

75
framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs

@ -20,8 +20,8 @@ namespace Volo.Abp.AspNetCore.Components;
public abstract class AbpComponentBase : OwningComponentBase
{
protected IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory);
private IStringLocalizerFactory _stringLocalizerFactory;
protected IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory)!;
private IStringLocalizerFactory? _stringLocalizerFactory;
protected IStringLocalizer L {
get {
@ -33,46 +33,46 @@ public abstract class AbpComponentBase : OwningComponentBase
return _localizer;
}
}
private IStringLocalizer _localizer;
private IStringLocalizer? _localizer;
protected Type LocalizationResource {
protected Type? LocalizationResource {
get => _localizationResource;
set {
_localizationResource = value;
_localizer = null;
}
}
private Type _localizationResource = typeof(DefaultResource);
private Type? _localizationResource = typeof(DefaultResource);
protected ILogger Logger => _lazyLogger.Value;
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true);
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName!) ?? NullLogger.Instance, true);
protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory);
private ILoggerFactory _loggerFactory;
protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory)!;
private ILoggerFactory? _loggerFactory;
protected IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService);
private IAuthorizationService _authorizationService;
protected IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService)!;
private IAuthorizationService? _authorizationService;
protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser);
private ICurrentUser _currentUser;
protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser)!;
private ICurrentUser? _currentUser;
protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant);
private ICurrentTenant _currentTenant;
protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant)!;
private ICurrentTenant? _currentTenant;
protected IUiMessageService Message => LazyGetNonScopedRequiredService(ref _message);
private IUiMessageService _message;
protected IUiMessageService Message => LazyGetNonScopedRequiredService(ref _message)!;
private IUiMessageService? _message;
protected IUiNotificationService Notify => LazyGetNonScopedRequiredService(ref _notify);
private IUiNotificationService _notify;
protected IUiNotificationService Notify => LazyGetNonScopedRequiredService(ref _notify)!;
private IUiNotificationService? _notify;
protected IUserExceptionInformer UserExceptionInformer => LazyGetNonScopedRequiredService(ref _userExceptionInformer);
private IUserExceptionInformer _userExceptionInformer;
protected IUserExceptionInformer UserExceptionInformer => LazyGetNonScopedRequiredService(ref _userExceptionInformer)!;
private IUserExceptionInformer? _userExceptionInformer;
protected IAlertManager AlertManager => LazyGetNonScopedRequiredService(ref _alertManager);
private IAlertManager _alertManager;
protected IAlertManager AlertManager => LazyGetNonScopedRequiredService(ref _alertManager)!;
private IAlertManager? _alertManager;
protected IClock Clock => LazyGetNonScopedRequiredService(ref _clock);
private IClock _clock;
protected IClock Clock => LazyGetNonScopedRequiredService(ref _clock)!;
private IClock? _clock;
protected AlertList Alerts => AlertManager.Alerts;
@ -85,19 +85,19 @@ public abstract class AbpComponentBase : OwningComponentBase
if (ObjectMapperContext == null)
{
return LazyGetRequiredService(ref _objectMapper);
return LazyGetRequiredService(ref _objectMapper)!;
}
return LazyGetRequiredService(
typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext),
ref _objectMapper
);
)!;
}
}
private IObjectMapper _objectMapper;
private IObjectMapper? _objectMapper;
protected Type ObjectMapperContext { get; set; }
protected Type? ObjectMapperContext { get; set; }
protected TService LazyGetRequiredService<TService>(ref TService reference) => LazyGetRequiredService(typeof(TService), ref reference);
@ -111,13 +111,13 @@ public abstract class AbpComponentBase : OwningComponentBase
return reference;
}
protected TService LazyGetService<TService>(ref TService reference) => LazyGetService(typeof(TService), ref reference);
protected TService? LazyGetService<TService>(ref TService? reference) => LazyGetService(typeof(TService), ref reference);
protected TRef LazyGetService<TRef>(Type serviceType, ref TRef reference)
protected TRef? LazyGetService<TRef>(Type serviceType, ref TRef? reference)
{
if (reference == null)
{
reference = (TRef)ScopedServices.GetService(serviceType);
reference = (TRef?)ScopedServices.GetService(serviceType);
}
return reference;
@ -135,20 +135,20 @@ public abstract class AbpComponentBase : OwningComponentBase
return reference;
}
protected TService LazyGetNonScopedService<TService>(ref TService reference) => LazyGetNonScopedService(typeof(TService), ref reference);
protected TService? LazyGetNonScopedService<TService>(ref TService? reference) => LazyGetNonScopedService(typeof(TService), ref reference);
protected TRef LazyGetNonScopedService<TRef>(Type serviceType, ref TRef reference)
protected TRef? LazyGetNonScopedService<TRef>(Type serviceType, ref TRef? reference)
{
if (reference == null)
{
reference = (TRef)NonScopedServices.GetService(serviceType);
reference = (TRef?)NonScopedServices.GetService(serviceType);
}
return reference;
}
[Inject]
protected IServiceProvider NonScopedServices { get; set; }
protected IServiceProvider NonScopedServices { get; set; } = default!;
protected virtual IStringLocalizer CreateLocalizer()
{
@ -168,6 +168,11 @@ public abstract class AbpComponentBase : OwningComponentBase
protected virtual async Task HandleErrorAsync(Exception exception)
{
if (IsDisposed)
{
return;
}
Logger.LogException(exception);
await InvokeAsync(async () =>
{

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

Loading…
Cancel
Save