Browse Source

Merge branch 'dev' of https://github.com/abpframework/abp into feat/angular-v12

pull/9340/head
mehmet-erim 5 years ago
parent
commit
cbeec9fa47
  1. 3
      .gitignore
  2. 15
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en-GB.json
  3. 15
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
  4. 15
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json
  5. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en-GB.json
  6. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
  7. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/hi.json
  8. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json
  9. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en-GB.json
  10. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
  11. 8
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
  12. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json
  13. 56
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json
  14. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json
  15. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
  16. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json
  17. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json
  18. 6
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en-GB.json
  19. 12
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
  20. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fr.json
  21. 16
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hi.json
  22. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/it.json
  23. 6
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
  24. 16
      docs/en/CLI.md
  25. 199
      docs/en/Community-Articles/2020-04-27-Use-Azure-Active-Directory-Authentication-for-MVC-Razor-Page-Applications/POST.md
  26. 25
      docs/en/Community-Articles/2020-09-16-How-to-Setup-Azure-Active-Directory-and-Integrate-Abp-Angular-Application/POST.md
  27. 1981
      docs/en/Domain-Driven-Design-Implementation-Guide.md
  28. 4
      docs/en/Domain-Driven-Design.md
  29. 72
      docs/en/Entity-Framework-Core.md
  30. 11
      docs/en/Index.md
  31. 190
      docs/en/Modules/Setting-Management.md
  32. 106
      docs/en/Modules/Tenant-Management.md
  33. 3
      docs/en/Road-Map.md
  34. 24
      docs/en/Tutorials/Todo/Index.md
  35. 2
      docs/en/UI/Angular/Account-Module.md
  36. 2
      docs/en/UI/Angular/Authorization.md
  37. 37
      docs/en/UI/Angular/Custom-Setting-Page.md
  38. 2
      docs/en/UI/Blazor/Overall.md
  39. 8
      docs/en/docs-nav.json
  40. 0
      docs/en/images/custom-settings.png
  41. BIN
      docs/en/images/implementing-domain-driven-design-book.png
  42. BIN
      docs/en/images/module-tenant-management-actions.png
  43. BIN
      docs/en/images/module-tenant-management-new-tenant.png
  44. BIN
      docs/en/images/module-tenant-management-page.png
  45. BIN
      docs/en/images/my-setting-group-blazor.png
  46. BIN
      docs/en/images/my-setting-group-component-contributor.png
  47. BIN
      docs/en/images/my-setting-group-component.png
  48. BIN
      docs/en/images/my-setting-group-page-contributor.png
  49. BIN
      docs/en/images/my-setting-group-ui.png
  50. BIN
      docs/en/images/my-setting-group-view-component.png
  51. 17
      docs/zh-Hans/CLI.md
  52. 192
      docs/zh-Hans/Modules/Setting-Management.md
  53. 41
      docs/zh-Hans/UI/Angular/Custom-Setting-Page.md
  54. 4
      docs/zh-Hans/docs-nav.json
  55. 0
      docs/zh-Hans/images/custom-settings.png
  56. BIN
      docs/zh-Hans/images/my-setting-group-blazor.png
  57. BIN
      docs/zh-Hans/images/my-setting-group-component-contributor.png
  58. BIN
      docs/zh-Hans/images/my-setting-group-component.png
  59. BIN
      docs/zh-Hans/images/my-setting-group-page-contributor.png
  60. BIN
      docs/zh-Hans/images/my-setting-group-ui.png
  61. BIN
      docs/zh-Hans/images/my-setting-group-view-component.png
  62. 49
      framework/Volo.Abp.sln
  63. 19
      framework/src/Volo.Abp.AspNetCore.Components.Server.BasicTheme/Volo.Abp.AspNetCore.Components.Server.BasicTheme.csproj
  64. 14
      framework/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Volo.Abp.AspNetCore.Components.Web.BasicTheme.csproj
  65. 17
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.csproj
  66. 3
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Table/AbpTableTagHelperService.cs
  67. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/fi.json
  68. 32
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj
  69. 8
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js
  70. 14
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs
  71. 46
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpMvcAttributeValidationResultProvider.cs
  72. 12
      framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpAspNetCoreSignalRModule.cs
  73. 2
      framework/src/Volo.Abp.Castle.Core/Volo.Abp.Castle.Core.csproj
  74. 1
      framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj
  75. 8
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs
  76. 78
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/InstallLibsCommand.cs
  77. 15
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/FileMatchResult.cs
  78. 9
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/IInstallLibsService.cs
  79. 230
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/InstallLibsService.cs
  80. 53
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/ResourceMapping.cs
  81. 23
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/ProjectNameValidator.cs
  82. 13
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/AbpCommonDbContextRegistrationOptions.cs
  83. 12
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs
  84. 11
      framework/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs
  85. 24
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs
  86. 5
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs
  87. 14
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpModelBuilderObjectExtensions.cs
  88. 70
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionInfoExtensions.cs
  89. 74
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionManagerExtensions.cs
  90. 39
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/ObjectExtensionInfoEfCoreMappingOptions.cs
  91. 2
      framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Domain/Entities/EntityNotFoundException.cs
  92. 19
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs
  93. 7
      framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ActionApiDescriptionModel.cs
  94. 12
      framework/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs
  95. 16
      framework/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs
  96. 2
      framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs
  97. 6
      framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManager.cs
  98. 5
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs
  99. 4
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs
  100. 13
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DefaultAttributeValidationResultProvider.cs

3
.gitignore

@ -271,6 +271,7 @@ modules/blogging/app/Volo.BloggingTestApp/wwwroot/files/*.*
modules/docs/app/VoloDocs.Web/Logs/*.* modules/docs/app/VoloDocs.Web/Logs/*.*
modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Logs/*.* modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Logs/*.*
templates/module/app/MyCompanyName.MyProjectName.DemoApp/Logs/*.* templates/module/app/MyCompanyName.MyProjectName.DemoApp/Logs/*.*
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Logs/logs.txt
templates/mvc/src/MyCompanyName.MyProjectName.Web/Logs/*.* templates/mvc/src/MyCompanyName.MyProjectName.Web/Logs/*.*
@ -313,4 +314,4 @@ abp-build-config.json
tempkey.jwk tempkey.jwk
# ABP Analyzing files # ABP Analyzing files
*.abppkg.analyze.json *.abppkg.analyze.json

15
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en-GB.json

@ -197,6 +197,19 @@
"RemoveCache": "Remove Cache", "RemoveCache": "Remove Cache",
"Language": "Language", "Language": "Language",
"Optional": "Optional", "Optional": "Optional",
"CreateArticleLanguageInfo": "The language in which the article is written" "CreateArticleLanguageInfo": "The language in which the article is written",
"Menu:Quotation": "Quotation",
"Menu:Invoice": "Invoice",
"Menu:PaymentRequests": "Payment Requests",
"Permission:PaymentRequests": "Payment Requests",
"PaymentRequests": "Payment Requests",
"Creator": "Creator",
"ExtraProperties": "Extra Properties",
"Organization": "Organization",
"Waiting": "Waiting",
"Completed": "Completed",
"Failed": "Failed",
"PaymentRequestDeletionWarningMessage": "This payment request will be deleted. Do you confirm that?",
"Payment": "Payment"
} }
} }

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

@ -277,6 +277,19 @@
"ThisExtensionIsNotAllowed": "This extension is not allowed.", "ThisExtensionIsNotAllowed": "This extension is not allowed.",
"TheFileIsTooLarge": "The file is too large!", "TheFileIsTooLarge": "The file is too large!",
"ArticleDeletionConfirmationMessage": "Are you sure you want to hard delete this article?", "ArticleDeletionConfirmationMessage": "Are you sure you want to hard delete this article?",
"ChooseCoverImage": "Choose a cover image..." "ChooseCoverImage": "Choose a cover image...",
"Menu:Quotation": "Quotation",
"Menu:Invoice": "Invoice",
"Menu:PaymentRequests": "Payment Requests",
"Permission:PaymentRequests": "Payment Requests",
"PaymentRequests": "Payment Requests",
"Creator": "Creator",
"ExtraProperties": "Extra Properties",
"Organization": "Organization",
"Waiting": "Waiting",
"Completed": "Completed",
"Failed": "Failed",
"PaymentRequestDeletionWarningMessage": "This payment request will be deleted. Do you confirm that?",
"Payment": "Payment"
} }
} }

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

@ -227,6 +227,19 @@
"TheFileIsTooLarge": "Dosya çok büyük.", "TheFileIsTooLarge": "Dosya çok büyük.",
"ArticleDeletionConfirmationMessage": "Bu makaleyi kalıcı olarak silmek istediğinizden emin misiniz?", "ArticleDeletionConfirmationMessage": "Bu makaleyi kalıcı olarak silmek istediğinizden emin misiniz?",
"ChooseCoverImage": "Bir kapak resmi seçin...", "ChooseCoverImage": "Bir kapak resmi seçin...",
"CoverImage": "Kapak Resmi" "CoverImage": "Kapak Resmi",
"Menu:Quotation": "Fiyatlandırma",
"Menu:Invoice": "Fatura",
"Menu:PaymentRequests": "Ödeme İstekleri",
"Permission:PaymentRequests": "Ödeme İstekleri",
"PaymentRequests": "Ödeme İstekleri",
"Creator": "Oluşturan",
"ExtraProperties": "Ekstra Özellikler",
"Organization": "Organizasyon",
"Waiting": "Bekliyor",
"Completed": "Tamamlandı",
"Failed": "Başarısız Oldu",
"PaymentRequestDeletionWarningMessage": "Bu ödeme isteği silinecek. Bunu onaylıyor musun?",
"Payment": "Ödeme"
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en-GB.json

@ -32,6 +32,7 @@
"SeeDocuments": "See Documents", "SeeDocuments": "See Documents",
"Samples": "Samples", "Samples": "Samples",
"FreeDDDBook": "Free DDD E-book", "FreeDDDBook": "Free DDD E-book",
"New": "New" "New": "New",
"Volo.AbpIo.Domain:020005": "License extend year can not be lower than {MinExtendLicenseYear} year and greater than {MaxExtendLicenseYear} years "
} }
} }

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

@ -34,6 +34,7 @@
"Framework": "Framework", "Framework": "Framework",
"Support": "Support", "Support": "Support",
"FreeDDDBook": "Free DDD E-book", "FreeDDDBook": "Free DDD E-book",
"New": "New" "New": "New",
"Volo.AbpIo.Domain:020005": "License extend year can not be lower than {MinExtendLicenseYear} year and greater than {MaxExtendLicenseYear} years "
} }
} }

4
abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/hi.json

@ -11,8 +11,8 @@
"Volo.AbpIo.Domain:010011": "व्यक्तिगत लाइसेंस में 1 से अधिक डेवलपर नहीं हो सकते हैं!", "Volo.AbpIo.Domain:010011": "व्यक्तिगत लाइसेंस में 1 से अधिक डेवलपर नहीं हो सकते हैं!",
"Volo.AbpIo.Domain:010012": "लाइसेंस की अवधि समाप्त होने के एक महीने बाद तक लाइसेंस नहीं बढ़ाया जा सकता है!", "Volo.AbpIo.Domain:010012": "लाइसेंस की अवधि समाप्त होने के एक महीने बाद तक लाइसेंस नहीं बढ़ाया जा सकता है!",
"Volo.AbpIo.Domain:020001": "इस NPM पैकेज को नहीं हटाया जा सका क्योंकि \"{NugetPackages}\" नुगेट पैकेज इस पैकेज पर निर्भर हैं।", "Volo.AbpIo.Domain:020001": "इस NPM पैकेज को नहीं हटाया जा सका क्योंकि \"{NugetPackages}\" नुगेट पैकेज इस पैकेज पर निर्भर हैं।",
"Volo.AbpIo.Domain:020002": "यह NPM पैकेज नहीं हटा सका क्योंकि \"{मॉड्यूल}\" मॉड्यूल इस पैकेज का उपयोग कर रहे हैं।", "Volo.AbpIo.Domain:020002": "यह NPM पैकेज नहीं हटा सका क्योंकि \"{Modules}\" मॉड्यूल इस पैकेज का उपयोग कर रहे हैं।",
"Volo.AbpIo.Domain:020003": "इस NPM पैकेज को नहीं हटाया जा सका क्योंकि \"{मॉड्यूल}\" मॉड्यूल इस पैकेज का उपयोग कर रहे हैं और \"{NugetPackages}\" नुगेट पैकेज इस पैकेज पर निर्भर हैं।", "Volo.AbpIo.Domain:020003": "इस NPM पैकेज को नहीं हटाया जा सका क्योंकि \"{Modules}\" मॉड्यूल इस पैकेज का उपयोग कर रहे हैं और \"{NugetPackages}\" नुगेट पैकेज इस पैकेज पर निर्भर हैं।",
"Volo.AbpIo.Domain:020004": "इस Nuget पैकेज को हटाया नहीं जा सका क्योंकि \"{Modules}\" मॉड्यूल इस पैकेज का उपयोग कर रहे हैं।", "Volo.AbpIo.Domain:020004": "इस Nuget पैकेज को हटाया नहीं जा सका क्योंकि \"{Modules}\" मॉड्यूल इस पैकेज का उपयोग कर रहे हैं।",
"WantToLearn?": "सीखना चाहते है?", "WantToLearn?": "सीखना चाहते है?",
"ReadyToGetStarted?": "आरंभ करने के लिए तैयार हैं?", "ReadyToGetStarted?": "आरंभ करने के लिए तैयार हैं?",

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

@ -28,6 +28,7 @@
"Commercial": "Ticari", "Commercial": "Ticari",
"SeeDocuments": "Dokümanlara Göz Atın", "SeeDocuments": "Dokümanlara Göz Atın",
"FreeDDDBook": "Ücretsiz DDD Kitabı", "FreeDDDBook": "Ücretsiz DDD Kitabı",
"New": "Yeni" "New": "Yeni",
"Volo.AbpIo.Domain:020005": "Lisans uzatma yılı {MinExtendLicenseYear} yıldan az {MaxExtendLicenseYear} yıldan fazla olamaz."
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en-GB.json

@ -100,6 +100,7 @@
"VolosoftSharingInformationMessage": "I would like Volosoft to share my information with select partners so I can receive relevant information about their products and services.", "VolosoftSharingInformationMessage": "I would like Volosoft to share my information with select partners so I can receive relevant information about their products and services.",
"WeWillSendYouADownloadLink": "We've sent the file to {0}.", "WeWillSendYouADownloadLink": "We've sent the file to {0}.",
"InvalidFormInputs": "Please, type the valid information specified on the form.", "InvalidFormInputs": "Please, type the valid information specified on the form.",
"DDDBookEmailBody": "Thank you. <br /> To download your book, <a href=\"{0}\">click here</a>." "DDDBookEmailBody": "Thank you. <br /> To download your book, <a href=\"{0}\">click here</a>.",
"FreeDDDEBook": "Free DDD E-Book"
} }
} }

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

@ -357,6 +357,7 @@
"VolosoftSharingInformationMessage": "I would like Volosoft to share my information with select partners so I can receive relevant information about their products and services.", "VolosoftSharingInformationMessage": "I would like Volosoft to share my information with select partners so I can receive relevant information about their products and services.",
"WeWillSendYouADownloadLink": "A link to download the e-book has been sent to {0}.<br/> Check your inbox / junk / spam boxes!", "WeWillSendYouADownloadLink": "A link to download the e-book has been sent to {0}.<br/> Check your inbox / junk / spam boxes!",
"InvalidFormInputs": "Please, type the valid information specified on the form.", "InvalidFormInputs": "Please, type the valid information specified on the form.",
"DDDBookEmailBody": "Thank you. <br /> To download your book, <a href=\"{0}\">click here</a>." "DDDBookEmailBody": "Thank you. <br /> To download your book, <a href=\"{0}\">click here</a>.",
"FreeDDDEBook": "Free DDD E-Book"
} }
} }

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

@ -151,7 +151,7 @@
"SeeAllModules": "Katso kaikki moduulit", "SeeAllModules": "Katso kaikki moduulit",
"ABPCLIExplanation": "ABP CLI (Command Line Interface) on komentorivityökalu joidenkin yleisten toimintojen suorittamiseen ABP-pohjaisiin ratkaisuihin.", "ABPCLIExplanation": "ABP CLI (Command Line Interface) on komentorivityökalu joidenkin yleisten toimintojen suorittamiseen ABP-pohjaisiin ratkaisuihin.",
"ABPSuiteEasilyCURD": "ABP Suite on työkalu, jonka avulla voit helposti luoda CRUD-sivuja", "ABPSuiteEasilyCURD": "ABP Suite on työkalu, jonka avulla voit helposti luoda CRUD-sivuja",
"WeAreHereToHelp": "<Span class = \"zero-text\"> Apua </span> olemme täällä", "WeAreHereToHelp": "<span class=\"zero-text\">Apua</span> olemme täällä",
"BrowseOrAskQuestion": "Voit selata ohjeaiheitamme tai etsiä usein kysyttyjä kysymyksiä tai voit esittää meille kysymyksiä <a href=\"{0}\" class=\"text-success\"> yhteydenottolomakkeella </a>.", "BrowseOrAskQuestion": "Voit selata ohjeaiheitamme tai etsiä usein kysyttyjä kysymyksiä tai voit esittää meille kysymyksiä <a href=\"{0}\" class=\"text-success\"> yhteydenottolomakkeella </a>.",
"SearchQuestionPlaceholder": "Hae usein kysyttyjä kysymyksiä", "SearchQuestionPlaceholder": "Hae usein kysyttyjä kysymyksiä",
"WhatIsTheABPCommercial": "Mikä on ABP-kauppa?", "WhatIsTheABPCommercial": "Mikä on ABP-kauppa?",
@ -177,7 +177,7 @@
"ChangingLicenseType": "Voinko muuttaa lisenssityyppiäni tulevaisuudessa?", "ChangingLicenseType": "Voinko muuttaa lisenssityyppiäni tulevaisuudessa?",
"ChangingLicenseTypeExplanation": "Voit aina lisätä uusia kehittäjiä samaan lisenssityyppiin. Katso myös \"Kuinka monta kehittäjää voi työskennellä ABP Commercialilla?\". Voit myös päivittää korkeampaan lisenssiin maksamalla lasketun hintaeron. Kun päivität korkeampaan lisenssisuunnitelmaan, saat uuden suunnitelman edut, mutta lisenssin päivitys ei muuta lisenssin voimassaolon päättymispäivää.", "ChangingLicenseTypeExplanation": "Voit aina lisätä uusia kehittäjiä samaan lisenssityyppiin. Katso myös \"Kuinka monta kehittäjää voi työskennellä ABP Commercialilla?\". Voit myös päivittää korkeampaan lisenssiin maksamalla lasketun hintaeron. Kun päivität korkeampaan lisenssisuunnitelmaan, saat uuden suunnitelman edut, mutta lisenssin päivitys ei muuta lisenssin voimassaolon päättymispäivää.",
"LicenseExtendUpgradeDiff": "Mitä eroa on lisenssin laajennuksella ja päivityksellä?", "LicenseExtendUpgradeDiff": "Mitä eroa on lisenssin laajennuksella ja päivityksellä?",
"LicenseExtendUpgradeDiffExplanation": "<strong> Laajentaminen: </strong> Laajentamalla / uusimalla käyttöoikeutta saat jatkossakin ensiluokkaista tukea ja saat tärkeitä päivityksiä moduuleille ja teemoille. Lisäksi voit jatkaa uusien projektien luomista. Ja voit silti käyttää ABP Suitea, joka vauhdittaa kehitystäsi. <Hr /> <strong> Päivittäminen: </strong> Päivittämällä lisenssisi edistyt korkeampaan lisenssisuunnitelmaan, jonka avulla voit saada lisäetuja . Katso lisenssisuunnitelmien väliset erot <a href=\"/pricing\"> lisenssien vertailutaulukosta </a>. <strong> Toisaalta, kun päivität, lisenssin vanhentumispäivä ei muutu! </ Strong > Lisenssin päättymispäivän jatkamiseksi sinun on jatkettava käyttöoikeutta.", "LicenseExtendUpgradeDiffExplanation": "<strong> Extension: </strong> en prolongeant/renouvelant votre licence, vous continuerez à bénéficier d'une assistance premium et à des mises à jour majeures pour les modules et les thèmes. De plus, vous pourrez continuer à créer de nouveaux projets. Et vous pourrez toujours utiliser ABP Suite, ce qui accélère votre développement. <hr/> <strong> Mise à niveau: </strong> En mettant à jour votre licence, vous passerez à un plan de licence supérieur qui vous permettra d’obtenir des avantages supplémentaires . Consultez le <a href=\"/pricing\"> tableau de comparaison des licences </a> pour vérifier les différences entre les plans de licence. <strong> En revanche, lors de la mise à niveau, la date d'expiration de votre licence ne changera pas! </strong> Pour prolonger la date de fin de votre licence, vous devez prolonger votre licence.",
"LicenseRenewalCost": "Mitkä ovat lisenssin uusimiskustannukset vuoden kuluttua?", "LicenseRenewalCost": "Mitkä ovat lisenssin uusimiskustannukset vuoden kuluttua?",
"LicenseRenewalCostExplanation": "Kaikkien ABP Commercial perpetual -lisenssien uusimis- (laajennus) hinta on {0} lisenssiluettelohinnasta. Tavallisen tiimilisenssin uusimishinta on $ {1}, tavallinen yrityslisenssi on $ {2} ja tavallinen yrityslisenssi on $ {3}. Jos olet jo asiakas, <a href='{4}' target='_blank'> kirjaudu tilillesi </a> ja tarkista käytettävissä oleva uusimishinta.", "LicenseRenewalCostExplanation": "Kaikkien ABP Commercial perpetual -lisenssien uusimis- (laajennus) hinta on {0} lisenssiluettelohinnasta. Tavallisen tiimilisenssin uusimishinta on $ {1}, tavallinen yrityslisenssi on $ {2} ja tavallinen yrityslisenssi on $ {3}. Jos olet jo asiakas, <a href='{4}' target='_blank'> kirjaudu tilillesi </a> ja tarkista käytettävissä oleva uusimishinta.",
"HowDoIRenewMyLicense": "Kuinka uusin lisenssin?", "HowDoIRenewMyLicense": "Kuinka uusin lisenssin?",
@ -230,7 +230,7 @@
"HowCanIRefundVatExplanation2": "Kirjaudu sisään <a href=\"https://secure.2checkout.com/cpanel/login.php\" target=\"_blank\"> 2Tarkista </a> -tiliisi.", "HowCanIRefundVatExplanation2": "Kirjaudu sisään <a href=\"https://secure.2checkout.com/cpanel/login.php\" target=\"_blank\"> 2Tarkista </a> -tiliisi.",
"HowCanIRefundVatExplanation3": "Etsi sopiva tilaus ja paina \"Hyvitä myöhässä oleva alv\" (kirjoita ALV-tunnuksesi)", "HowCanIRefundVatExplanation3": "Etsi sopiva tilaus ja paina \"Hyvitä myöhässä oleva alv\" (kirjoita ALV-tunnuksesi)",
"HowCanIGetMyInvoice": "Kuinka saan laskuni?", "HowCanIGetMyInvoice": "Kuinka saan laskuni?",
"HowCanIGetMyInvoiceExplanation": "Lisenssin ostamiseen on 2 maksuyhdyskäytävää: PayU ja 2Checkout. Jos ostat lisenssin 2Checkout gatewayn kautta, se lähettää PDF-laskun sähköpostiosoitteeseesi, katso <a href = \"https://knowledgecenter.2checkout.com/Documentation/03Billing-and-payments/Payment-operations/How-do -laskut-työ \"> 2Tarkista laskutus. </a> Jos ostat PayU-yhdyskäytävän kautta tai pankkisiirrolla, valmistelemme ja lähetämme laskusi. Voit pyytää laskua <a href=\"{0}\"> organisaation hallintasivulta </a>", "HowCanIGetMyInvoiceExplanation": "Lisenssin ostamiseen on 2 maksuyhdyskäytävää: PayU ja 2Checkout. Jos ostat lisenssin 2Checkout gatewayn kautta, se lähettää PDF-laskun sähköpostiosoitteeseesi, katso <a href=\"https://knowledgecenter.2checkout.com/Documentation/03Billing-and-payments/Payment-operations/How-do-invoices-work\"> 2Tarkista laskutus. </a> Jos ostat PayU-yhdyskäytävän kautta tai pankkisiirrolla, valmistelemme ja lähetämme laskusi. Voit pyytää laskua <a href=\"{0}\"> organisaation hallintasivulta </a>",
"Forum": "Foorumi", "Forum": "Foorumi",
"SupportExplanation": "ABP Commercial -lisenssit tarjoavat ensiluokkaisen foorumituen ABP-kehyksen asiantuntijoista koostuvalle tiimille.", "SupportExplanation": "ABP Commercial -lisenssit tarjoavat ensiluokkaisen foorumituen ABP-kehyksen asiantuntijoista koostuvalle tiimille.",
"PrivateTicket": "Yksityinen lippu", "PrivateTicket": "Yksityinen lippu",
@ -240,7 +240,7 @@
"FastEasy": "Nopea ja helppo", "FastEasy": "Nopea ja helppo",
"AbpSuiteExplanation3": "ABP Suiten avulla voit luoda helposti CRUD-sivuja. Sinun tarvitsee vain määritellä entiteetti ja sen ominaisuudet, antaa loput ABP Suiten puolestasi! ABP Suite luo kaikki tarvittavat koodit CRUD-sivullesi muutamassa sekunnissa. Se tukee Angular-, MVC- ja Blazor-käyttöliittymiä.", "AbpSuiteExplanation3": "ABP Suiten avulla voit luoda helposti CRUD-sivuja. Sinun tarvitsee vain määritellä entiteetti ja sen ominaisuudet, antaa loput ABP Suiten puolestasi! ABP Suite luo kaikki tarvittavat koodit CRUD-sivullesi muutamassa sekunnissa. Se tukee Angular-, MVC- ja Blazor-käyttöliittymiä.",
"RichOptions": "Monipuoliset vaihtoehdot", "RichOptions": "Monipuoliset vaihtoehdot",
"AbpSuiteExplanation4": "ABP Suite tukee useita käyttöliittymävaihtoehtoja, kuten <a href=\"https://docs.microsoft.com/en-us/aspnet/core/razor-pages\"> Razor Pages </a> ja <a href = \"https: / /angular.io\">Kulma </a> .Se tukee myös useita tietokantoja, kuten <a href=\"https://www.mongodb.com\"> MongoDB </a> ja kaikkia <strong> EntityFramework Core <: n tukemia tietokantoja. / strong> (MS SQL Server, Oracle, MySql, PostgreSQL ja <a href=\"https://docs.microsoft.com/en-us/ef/core/providers/?tabs=dotnet-core-cli\"> lisää </a>).", "AbpSuiteExplanation4": "ABP Suite supports multiple UI options like <a href=\"https://docs.microsoft.com/en-us/aspnet/core/razor-pages\">Razor Pages</a> and <a href=\"https://angular.io\">Angular</a>.It also supports multiple databases like <a href=\"https://www.mongodb.com\">MongoDB</a> and all databases supported by <strong>EntityFramework Core</strong> (MS SQL Server, Oracle, MySql, PostgreSQL and <a href=\"https://docs.microsoft.com/en-us/ef/core/providers/?tabs=dotnet-core-cli\">more</a>).",
"AbpSuiteExplanation5": "Hyvä asia on, että sinun ei tarvitse huolehtia näistä vaihtoehdoista. ABP Suite ymmärtää projektisi tyypin ja luo koodin projektillesi ja sijoittaa luodun koodin oikeaan paikkaan projektissasi.", "AbpSuiteExplanation5": "Hyvä asia on, että sinun ei tarvitse huolehtia näistä vaihtoehdoista. ABP Suite ymmärtää projektisi tyypin ja luo koodin projektillesi ja sijoittaa luodun koodin oikeaan paikkaan projektissasi.",
"SourceCode": "Lähdekoodi", "SourceCode": "Lähdekoodi",
"AbpSuiteExplanation6": "ABP Suite luo lähdekoodin sinulle! Se ei luo taikuustiedostoja verkkosivun luomiseksi. ABP Suite luo lähdekoodin <strong> Entity, Repository, Application Service, Code First Migration, JavaScript / TypeScript ja CSHTML / HTML </strong> sekä tarvittavat liitännät. ABP Suite tuottaa koodin myös ohjelmistokehityksen <strong> parhaiden käytäntöjen </strong> mukaisesti, joten sinun ei tarvitse huolehtia luodun koodin laadusta.", "AbpSuiteExplanation6": "ABP Suite luo lähdekoodin sinulle! Se ei luo taikuustiedostoja verkkosivun luomiseksi. ABP Suite luo lähdekoodin <strong> Entity, Repository, Application Service, Code First Migration, JavaScript / TypeScript ja CSHTML / HTML </strong> sekä tarvittavat liitännät. ABP Suite tuottaa koodin myös ohjelmistokehityksen <strong> parhaiden käytäntöjen </strong> mukaisesti, joten sinun ei tarvitse huolehtia luodun koodin laadusta.",

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

@ -177,7 +177,7 @@
"ChangingLicenseType": "Puis-je changer mon type de licence à l'avenir?", "ChangingLicenseType": "Puis-je changer mon type de licence à l'avenir?",
"ChangingLicenseTypeExplanation": "Vous pouvez toujours ajouter de nouveaux développeurs dans votre même type de licence. Voir aussi \"Combien de développeurs peuvent travailler sur l'ABP Commercial?\". Vous pouvez également passer à une licence supérieure en payant la différence de prix calculée. Lorsque vous passez à un plan de licence supérieur, vous bénéficiez des avantages du nouveau plan, mais la mise à niveau de la licence ne modifie pas la date d'expiration de la licence.", "ChangingLicenseTypeExplanation": "Vous pouvez toujours ajouter de nouveaux développeurs dans votre même type de licence. Voir aussi \"Combien de développeurs peuvent travailler sur l'ABP Commercial?\". Vous pouvez également passer à une licence supérieure en payant la différence de prix calculée. Lorsque vous passez à un plan de licence supérieur, vous bénéficiez des avantages du nouveau plan, mais la mise à niveau de la licence ne modifie pas la date d'expiration de la licence.",
"LicenseExtendUpgradeDiff": "Quelle est la différence entre l'extension de licence et la mise à niveau?", "LicenseExtendUpgradeDiff": "Quelle est la différence entre l'extension de licence et la mise à niveau?",
"LicenseExtendUpgradeDiffExplanation": "<strong> Extension: </strong> en prolongeant / renouvelant votre licence, vous continuerez à bénéficier d'une assistance premium et à des mises à jour majeures pour les modules et les thèmes. De plus, vous pourrez continuer à créer de nouveaux projets. Et vous pourrez toujours utiliser ABP Suite, ce qui accélère votre développement. <Hr /> <strong> Mise à niveau: </strong> En mettant à jour votre licence, vous passerez à un plan de licence supérieur qui vous permettra d’obtenir des avantages supplémentaires . Consultez le <a href=\"/pricing\"> tableau de comparaison des licences </a> pour vérifier les différences entre les plans de licence. <strong> En revanche, lors de la mise à niveau, la date d'expiration de votre licence ne changera pas! </ Strong > Pour prolonger la date de fin de votre licence, vous devez prolonger votre licence.", "LicenseExtendUpgradeDiffExplanation": "<strong> Extension: </strong> en prolongeant/renouvelant votre licence, vous continuerez à bénéficier d'une assistance premium et à des mises à jour majeures pour les modules et les thèmes. De plus, vous pourrez continuer à créer de nouveaux projets. Et vous pourrez toujours utiliser ABP Suite, ce qui accélère votre développement. <hr/> <strong> Mise à niveau: </strong> En mettant à jour votre licence, vous passerez à un plan de licence supérieur qui vous permettra d’obtenir des avantages supplémentaires . Consultez le <a href=\"/pricing\"> tableau de comparaison des licences </a> pour vérifier les différences entre les plans de licence. <strong> En revanche, lors de la mise à niveau, la date d'expiration de votre licence ne changera pas! </strong> Pour prolonger la date de fin de votre licence, vous devez prolonger votre licence.",
"LicenseRenewalCost": "Quel est le coût du renouvellement de la licence après 1 an?", "LicenseRenewalCost": "Quel est le coût du renouvellement de la licence après 1 an?",
"LicenseRenewalCostExplanation": "Le taux de renouvellement (extension) de toutes les licences perpétuelles ABP Commercial correspond à {0} du prix catalogue de la licence. Le prix de renouvellement de la licence d'équipe standard est de {1} $, la licence professionnelle standard de {2} $ et la licence d'entreprise standard de {3} $. Si vous êtes déjà client, <a href='{4}' target='_blank'> connectez-vous à votre compte </a> pour consulter les tarifs de renouvellement disponibles.", "LicenseRenewalCostExplanation": "Le taux de renouvellement (extension) de toutes les licences perpétuelles ABP Commercial correspond à {0} du prix catalogue de la licence. Le prix de renouvellement de la licence d'équipe standard est de {1} $, la licence professionnelle standard de {2} $ et la licence d'entreprise standard de {3} $. Si vous êtes déjà client, <a href='{4}' target='_blank'> connectez-vous à votre compte </a> pour consulter les tarifs de renouvellement disponibles.",
"HowDoIRenewMyLicense": "Comment renouveler ma licence?", "HowDoIRenewMyLicense": "Comment renouveler ma licence?",

56
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json

@ -42,7 +42,7 @@
"NotOrganizationMember": "आप किसी संगठन के सदस्य नहीं हैं।", "NotOrganizationMember": "आप किसी संगठन के सदस्य नहीं हैं।",
"UnsubscribeLicenseExpirationEmailSuccessTitle": "सफलतापूर्वक सदस्यता समाप्त कर दी गई", "UnsubscribeLicenseExpirationEmailSuccessTitle": "सफलतापूर्वक सदस्यता समाप्त कर दी गई",
"UnsubscribeLicenseExpirationEmailSuccessMessage": "अब आपको लाइसेंस समाप्ति तिथि अनुस्मारक ईमेल प्राप्त नहीं होंगे।", "UnsubscribeLicenseExpirationEmailSuccessMessage": "अब आपको लाइसेंस समाप्ति तिथि अनुस्मारक ईमेल प्राप्त नहीं होंगे।",
"IndexPageHeroSection": "<span class = \"first-line\"> एक पूर्ण </ span> <span class = \"दूसरी-पंक्ति\"> वेब विकास मंच </ span> <span class = \"third-line\"> अंतर्निहित <img src = \"{0}\" चौड़ाई = \"110\" वर्ग = \"एमएल -1\" /> ढांचा </ span>", "IndexPageHeroSection": "<span class=\"first-line\">एक पूर्ण</span><span class=\"second-line\"> वेब डेवलपमेंट प्लेटफॉर्म</span><span class=\"third-line\">बिल्ट-ऑन <img src=\"{0}\" width=\"110\" class=\"ml-1\" /> Framework</span>",
"AbpCommercialShortDescription": "एबीपी कमर्शियल प्री-बिल्ट एप्लिकेशन मॉड्यूल, रैपिड एप्लिकेशन डेवलपमेंट टूलिंग, पेशेवर यूआई थीम, प्रीमियम सपोर्ट आदि प्रदान करता है।", "AbpCommercialShortDescription": "एबीपी कमर्शियल प्री-बिल्ट एप्लिकेशन मॉड्यूल, रैपिड एप्लिकेशन डेवलपमेंट टूलिंग, पेशेवर यूआई थीम, प्रीमियम सपोर्ट आदि प्रदान करता है।",
"LiveDemo": "लाइव डेमो", "LiveDemo": "लाइव डेमो",
"GetLicence": "एक लाइसेंस प्राप्त करें", "GetLicence": "एक लाइसेंस प्राप्त करें",
@ -135,7 +135,7 @@
"GoHome": "घर जाओ", "GoHome": "घर जाओ",
"CreateLiveDemo": "लाइव डेमो बनाएँ", "CreateLiveDemo": "लाइव डेमो बनाएँ",
"RegisterToTheNewsletter": "ABP.IO के बारे में जानकारी प्राप्त करने के लिए न्यूज़लेटर के लिए रजिस्टर करें, जिसमें नई रिलीज़ आदि शामिल हैं।", "RegisterToTheNewsletter": "ABP.IO के बारे में जानकारी प्राप्त करने के लिए न्यूज़लेटर के लिए रजिस्टर करें, जिसमें नई रिलीज़ आदि शामिल हैं।",
"EnterYourEmailOrLogin": "अपने मौजूदा खाते का उपयोग करके अपना डेमो बनाने के लिए अपना ई-मेल पता दर्ज करें या अपना प्रदर्शन <a href=\"lights0 Ideal\"> लॉगिन </a> करें।", "EnterYourEmailOrLogin": "अपना डेमो बनाने के लिए अपना ई-मेल पता दर्ज करें या अपने मौजूदा खाते का उपयोग करके <a href=\"{0}\">लॉगिन करें</a>।",
"ApplicationTemplate": "एप्लिकेशन टेम्पलेट", "ApplicationTemplate": "एप्लिकेशन टेम्पलेट",
"ApplicationTemplateExplanation": "एप्लिकेशन स्टार्टअप टेम्पलेट का उपयोग एक नया वेब एप्लिकेशन बनाने के लिए किया जाता है।", "ApplicationTemplateExplanation": "एप्लिकेशन स्टार्टअप टेम्पलेट का उपयोग एक नया वेब एप्लिकेशन बनाने के लिए किया जाता है।",
"EfCoreProvider": "इकाई ढाँचा (SQL सर्वर, MySQL, PostgreSQL, Oracle <a href=\"https://docs.microsoft.com/en-us/ef/core/providers/\"> और अन्य </a> का समर्थन करता है)", "EfCoreProvider": "इकाई ढाँचा (SQL सर्वर, MySQL, PostgreSQL, Oracle <a href=\"https://docs.microsoft.com/en-us/ef/core/providers/\"> और अन्य </a> का समर्थन करता है)",
@ -152,50 +152,50 @@
"ABPCLIExplanation": "ABP CLI (कमांड लाइन इंटरफेस) ABP आधारित समाधानों के लिए कुछ सामान्य ऑपरेशन करने के लिए एक कमांड लाइन टूल है।", "ABPCLIExplanation": "ABP CLI (कमांड लाइन इंटरफेस) ABP आधारित समाधानों के लिए कुछ सामान्य ऑपरेशन करने के लिए एक कमांड लाइन टूल है।",
"ABPSuiteEasilyCURD": "एबीपी सूट एक उपकरण है जो आपको आसानी से CRUD पेज बनाने की अनुमति देता है", "ABPSuiteEasilyCURD": "एबीपी सूट एक उपकरण है जो आपको आसानी से CRUD पेज बनाने की अनुमति देता है",
"WeAreHereToHelp": "हम यहाँ हैं <span class = \"zero-text\"> मदद </ span>", "WeAreHereToHelp": "हम यहाँ हैं <span class = \"zero-text\"> मदद </ span>",
"BrowseOrAskQuestion": "आप हमारे सहायता विषयों को ब्राउज़ कर सकते हैं या अक्सर पूछे जाने वाले प्रश्नों में खोज कर सकते हैं, या आप <a href=\" जटिलताओं0arios\" class=\"text-success\"> संपर्क फ़ॉर्म </a> का उपयोग करके हमसे एक प्रश्न पूछ सकते हैं।", "BrowseOrAskQuestion": "आप हमारे सहायता विषयों को ब्राउज़ कर सकते हैं या अक्सर पूछे जाने वाले प्रश्नों में खोज कर सकते हैं, या आप <a href=\"{0}\" class=\"text-success\">संपर्क फ़ॉर्म</a> का उपयोग करके हमसे एक प्रश्न पूछ सकते हैं।",
"SearchQuestionPlaceholder": "अक्सर पूछे जाने वाले प्रश्नों में खोजें", "SearchQuestionPlaceholder": "अक्सर पूछे जाने वाले प्रश्नों में खोजें",
"WhatIsTheABPCommercial": "ABP कमर्शियल क्या है?", "WhatIsTheABPCommercial": "ABP कमर्शियल क्या है?",
"WhatAreDifferencesThanAbpFramework": "ओपन सोर्स ABP फ्रेमवर्क और ABP कमर्शियल के बीच क्या अंतर हैं?", "WhatAreDifferencesThanAbpFramework": "ओपन सोर्स ABP फ्रेमवर्क और ABP कमर्शियल के बीच क्या अंतर हैं?",
"ABPCommercialExplanation": "एबीपी कमर्शियल, खुले स्रोत के शीर्ष पर बनाए गए प्रीमियम मॉड्यूल, टूल, थीम और सेवाओं का एक सेट है जो <a target=\"_blank\" href=\"ministr0arios\"> ABP फ्रेमवर्क </a> है। एबीपी कमर्शियल को एबीपी फ्रेमवर्क के पीछे उसी टीम द्वारा विकसित और समर्थित किया जा रहा है।", "ABPCommercialExplanation": "एबीपी कमर्शियल ओपन सोर्स <a target=\"_blank\" href=\"{0}\">ABP फ्रेमवर्क</a> के शीर्ष पर निर्मित प्रीमियम मॉड्यूल, टूल, थीम और सेवाओं का एक सेट है। एबीपी कमर्शियल को एबीपी ढांचे के पीछे उसी टीम द्वारा विकसित और समर्थित किया जा रहा है।",
"WhatAreDifferencesThanABPFrameworkExplanation": "<p> <a target=\"_blank\" href=\"lights0 Ideal\"> ABP फ्रेमवर्क </a> ASP.NET Core के लिए एक मॉड्यूलर, थीमेबल, माइक्रो-सर्विस संगत एप्लिकेशन डेवलपमेंट फ्रेमवर्क है। यह आपको हर नई परियोजना के लिए खुद को दोहराने के बजाय अपने खुद के व्यवसाय कोड पर ध्यान केंद्रित करने के लिए एक पूर्ण वास्तुकला और एक मजबूत बुनियादी ढांचा प्रदान करता है। यह सॉफ्टवेयर विकास सर्वोत्तम प्रथाओं और लोकप्रिय उपकरणों पर आधारित है जिन्हें आप पहले से जानते हैं। </ p> <p> एबीपी फ्रेमवर्क पूरी तरह से मुक्त, खुला स्रोत और समुदाय-संचालित है। यह एक मुफ्त थीम और कुछ पूर्व-निर्मित मॉड्यूल (जैसे पहचान प्रबंधन और किरायेदार प्रबंधन) प्रदान करता है। </ p>", "WhatAreDifferencesThanABPFrameworkExplanation": "<p> <a target=\"_blank\" href=\"{0}\">ABP फ्रेमवर्क</a> ASP.NET कोर के लिए एक मॉड्यूलर, थीम योग्य, माइक्रो-सर्विस संगत एप्लिकेशन डेवलपमेंट फ्रेमवर्क है। यह आपको हर नई परियोजना के लिए खुद को दोहराने के बजाय अपने स्वयं के व्यवसाय कोड पर ध्यान केंद्रित करने के लिए एक पूर्ण वास्तुकला और एक मजबूत बुनियादी ढांचा प्रदान करता है। यह सॉफ्टवेयर विकास सर्वोत्तम प्रथाओं और लोकप्रिय टूल पर आधारित है जिन्हें आप पहले से जानते हैं। </p> <p> एबीपी ढांचा पूरी तरह से मुक्त, खुला स्रोत और समुदाय संचालित है। यह एक मुफ्त थीम और कुछ पूर्व-निर्मित मॉड्यूल (जैसे पहचान प्रबंधन और किरायेदार प्रबंधन) भी प्रदान करता है।</p>",
"VisitTheFrameworkVSCommercialDocument": "अधिक जानकारी के लिए, निम्न लिंक पर जाएं <a href=\"ministr0arios\" target=\"_blank\"> {1} </a>", "VisitTheFrameworkVSCommercialDocument": "अधिक जानकारी के लिए, निम्न लिंक पर जाएँ <a href=\"{0}\" target=\"_blank\"> {1} </a>",
"ABPCommercialFollowingBenefits": "एबीपी वाणिज्यिक एबीपी ढांचे के शीर्ष पर निम्नलिखित लाभ जोड़ता है;", "ABPCommercialFollowingBenefits": "एबीपी वाणिज्यिक एबीपी ढांचे के शीर्ष पर निम्नलिखित लाभ जोड़ता है;",
"Professional": "पेशेवर", "Professional": "पेशेवर",
"UIThemes": "यूआई थीम", "UIThemes": "यूआई थीम",
"EnterpriseModules": "एंटरप्राइज रेडी, फीचर से भरपूर, पहले से निर्मित <a href=\"lights0 Ideal\"> एप्लिकेशन मॉड्यूल </a> (जैसे पहचान सर्वर प्रबंधन, सास प्रबंधन, भाषा प्रबंधन)", "EnterpriseModules": "एंटरप्राइज़ तैयार, सुविधा संपन्न, पूर्व-निर्मित <a href=\"{0}\">एप्लिकेशन मॉड्यूल</a> (उदा. पहचान सर्वर प्रबंधन, SaaS प्रबंधन, भाषा प्रबंधन)",
"ToolingToSupport": "अपनी विकास उत्पादकता का समर्थन करने का टूल", "ToolingToSupport": "आपकी विकास उत्पादकता का समर्थन करने के लिए टूलिंग (उदा. <a href=\"{0}\">ABP Suite</a>)",
"PremiumSupportLink": "प्रीमियम <a href=\"ministr0arios\" target=\"_blank\"> समर्थन </a>", "PremiumSupportLink": "प्रीमियम <a href=\"{0}\" target=\"_blank\">समर्थन</a>",
"WhatDoIDownloadABPCommercial": "जब मैं एबीपी कमर्शियल खरीदता हूं तो क्या डाउनलोड करता हूं?", "WhatDoIDownloadABPCommercial": "जब मैं एबीपी कमर्शियल खरीदता हूं तो क्या डाउनलोड करता हूं?",
"CreateUnlimitedSolutions": "एक बार जब आप एक एबीपी कमर्शियल लाइसेंस खरीदते हैं, तो आप असीमित समाधान बना पाएंगे, जैसे कि <a href=\"find0 Ideal\"> Get Started </a> दस्तावेज़ में वर्णित है।", "CreateUnlimitedSolutions": "एक बार जब आप एबीपी वाणिज्यिक लाइसेंस खरीद लेते हैं, तो आप असीमित समाधान बनाने में सक्षम होंगे जैसा कि <a href=\"{0}\">आरंभ करना</a> दस्तावेज़ में वर्णित है।",
"ABPCommercialSolutionExplanation": "जब आप एक नया एप्लिकेशन बनाते हैं, तो आपको अपनी प्राथमिकताओं के आधार पर एक विज़ुअल स्टूडियो समाधान (एक स्टार्टअप टेम्प्लेट) मिलता है। डाउनलोड किए गए समाधान में आपके लिए पहले से इंस्टॉल और कॉन्फ़िगर किए गए वाणिज्यिक मॉड्यूल और थीम हैं। यदि आप चाहें तो आप पहले से स्थापित मॉड्यूल को हटा सकते हैं या किसी अन्य मॉड्यूल को जोड़ सकते हैं। सभी मॉड्यूल और थीम डिफ़ॉल्ट रूप से एक NuGet / NPM पैकेज का उपयोग किया जाता है।", "ABPCommercialSolutionExplanation": "जब आप एक नया एप्लिकेशन बनाते हैं, तो आपको अपनी प्राथमिकताओं के आधार पर एक विज़ुअल स्टूडियो समाधान (एक स्टार्टअप टेम्प्लेट) मिलता है। डाउनलोड किए गए समाधान में आपके लिए पहले से इंस्टॉल और कॉन्फ़िगर किए गए वाणिज्यिक मॉड्यूल और थीम हैं। यदि आप चाहें तो आप पहले से स्थापित मॉड्यूल को हटा सकते हैं या किसी अन्य मॉड्यूल को जोड़ सकते हैं। सभी मॉड्यूल और थीम डिफ़ॉल्ट रूप से एक NuGet / NPM पैकेज का उपयोग किया जाता है।",
"StartDevelopWithTutorials": "डाउनलोड किया गया समाधान अच्छी तरह से वास्तुकला और दस्तावेज है। आप अपने स्वयं के व्यवसाय कोड को इस आधार पर विकसित करना शुरू कर सकते हैं कि वह <a href=\"directory0 Ideal\"> ट्यूटोरियल्स </a> का अनुसरण कर सकता है", "StartDevelopWithTutorials": "डाउनलोड किया गया समाधान अच्छी तरह से संरचित और प्रलेखित है। आप <a href=\"{0}\">ट्यूटोरियल</a> . का अनुसरण करके इसके आधार पर अपना खुद का व्यवसाय कोड विकसित करना शुरू कर सकते हैं",
"TryTheCommercialDemo": "ABP कमर्शियल स्टार्टअप टेम्प्लेट का उपयोग करके बनाए गए एक नमूना अनुप्रयोग को देखने के लिए आप <a href=\" जटिलताओं0 Ideal\"> डेमो </a> का प्रयास कर सकते हैं।", "TryTheCommercialDemo": "ABP कमर्शियल स्टार्टअप टेम्प्लेट का उपयोग करके बनाए गए एक नमूना एप्लिकेशन को देखने के लिए आप <a href=\"{0}\">डेमो</a> आज़मा सकते हैं।",
"HowManyProducts": "ABP वाणिज्यिक का उपयोग करके मैं कितने विभिन्न उत्पाद / समाधान बना सकता हूं?", "HowManyProducts": "ABP वाणिज्यिक का उपयोग करके मैं कितने विभिन्न उत्पाद / समाधान बना सकता हूं?",
"HowManyProductsExplanation": "ABP प्रोजेक्ट बनाने की कोई सीमा नहीं है। आप जितने चाहें उतने प्रोजेक्ट बना सकते हैं, उन्हें विकसित कर सकते हैं और उन्हें विभिन्न सर्वरों पर अपलोड कर सकते हैं।", "HowManyProductsExplanation": "ABP प्रोजेक्ट बनाने की कोई सीमा नहीं है। आप जितने चाहें उतने प्रोजेक्ट बना सकते हैं, उन्हें विकसित कर सकते हैं और उन्हें विभिन्न सर्वरों पर अपलोड कर सकते हैं।",
"HowManyDevelopers": "एबीपी कमर्शियल पर कितने डेवलपर काम कर सकते हैं?", "HowManyDevelopers": "एबीपी कमर्शियल पर कितने डेवलपर काम कर सकते हैं?",
"HowManyDevelopersExplanation": "एबीपी वाणिज्यिक लाइसेंस प्रति डेवलपर हैं। विभिन्न लाइसेंस प्रकारों में अलग-अलग डेवलपर सीमाएँ होती हैं। हालाँकि, जब भी आपको आवश्यकता हो, आप किसी भी प्रकार के लाइसेंस में अधिक डेवलपर्स जोड़ सकते हैं। लाइसेंस प्रकार, डेवलपर सीमा और अतिरिक्त डेवलपर लागतों के लिए <a href=\" जटिलताओं0 Ideal\"> कीमतें </a> पृष्ठ देखें।", "HowManyDevelopersExplanation": "एबीपी वाणिज्यिक लाइसेंस प्रति डेवलपर हैं। विभिन्न लाइसेंस प्रकारों की अलग-अलग डेवलपर सीमाएँ होती हैं। हालांकि, जब भी आपको आवश्यकता हो, आप किसी भी प्रकार के लाइसेंस में अधिक डेवलपर जोड़ सकते हैं। लाइसेंस प्रकारों, डेवलपर सीमाओं और अतिरिक्त डेवलपर लागतों के लिए <a href=\"{0}\">कीमतें</a> पृष्ठ देखें।",
"ChangingLicenseType": "क्या मैं भविष्य में अपना लाइसेंस प्रकार बदल सकता हूं?", "ChangingLicenseType": "क्या मैं भविष्य में अपना लाइसेंस प्रकार बदल सकता हूं?",
"ChangingLicenseTypeExplanation": "आप अपने समान लाइसेंस प्रकार में हमेशा नए डेवलपर्स को जोड़ सकते हैं। यह भी देखें \"एबीपी कमर्शियल पर कितने डेवलपर काम कर सकते हैं?\"। आप गणना मूल्य अंतर का भुगतान करके एक उच्च लाइसेंस के लिए भी अपग्रेड कर सकते हैं। जब आप उच्च लाइसेंस योजना में अपग्रेड करते हैं, तो आपको नई योजना का लाभ मिलता है, लेकिन लाइसेंस अपग्रेड लाइसेंस की समाप्ति की तारीख को नहीं बदलता है।", "ChangingLicenseTypeExplanation": "आप अपने समान लाइसेंस प्रकार में हमेशा नए डेवलपर्स को जोड़ सकते हैं। यह भी देखें \"एबीपी कमर्शियल पर कितने डेवलपर काम कर सकते हैं?\"। आप गणना मूल्य अंतर का भुगतान करके एक उच्च लाइसेंस के लिए भी अपग्रेड कर सकते हैं। जब आप उच्च लाइसेंस योजना में अपग्रेड करते हैं, तो आपको नई योजना का लाभ मिलता है, लेकिन लाइसेंस अपग्रेड लाइसेंस की समाप्ति की तारीख को नहीं बदलता है।",
"LicenseExtendUpgradeDiff": "लाइसेंस विस्तार और उन्नयन के बीच क्या अंतर है?", "LicenseExtendUpgradeDiff": "लाइसेंस विस्तार और उन्नयन के बीच क्या अंतर है?",
"LicenseExtendUpgradeDiffExplanation": "<strong> विस्तार: </ strong> अपने लाइसेंस का विस्तार / नवीनीकरण करके, आप प्रीमियम समर्थन प्राप्त करना और मॉड्यूल और थीम के लिए प्रमुख अपडेट प्राप्त करना जारी रखेंगे। इसके अलावा, आप नई परियोजनाओं को जारी रखने में सक्षम होंगे। और आप अभी भी एबीपी सूट का उपयोग कर पाएंगे जो आपके विकास को गति देता है। <hr /> <strong> उन्नयन: </ strong> अपने लाइसेंस को अपग्रेड करके, आप एक उच्च लाइसेंस योजना को बढ़ावा देंगे जिससे आप अतिरिक्त लाभ प्राप्त कर सकेंगे। । लाइसेंस योजनाओं के बीच अंतर की जांच करने के लिए <a href=\"/pricing\"> लाइसेंस तुलना तालिका </a> देखें। <strong> दूसरी ओर, जब आप अपग्रेड करते हैं, तो आपकी लाइसेंस की समाप्ति तिथि नहीं बदलेगी! </ Strong> > अपनी लाइसेंस की अंतिम तिथि बढ़ाने के लिए, आपको अपने लाइसेंस का विस्तार करना होगा।", "LicenseExtendUpgradeDiffExplanation": "<strong> विस्तार: </ strong> अपने लाइसेंस का विस्तार / नवीनीकरण करके, आप प्रीमियम समर्थन प्राप्त करना और मॉड्यूल और थीम के लिए प्रमुख अपडेट प्राप्त करना जारी रखेंगे। इसके अलावा, आप नई परियोजनाओं को जारी रखने में सक्षम होंगे। और आप अभी भी एबीपी सूट का उपयोग कर पाएंगे जो आपके विकास को गति देता है। <hr /> <strong> उन्नयन: </ strong> अपने लाइसेंस को अपग्रेड करके, आप एक उच्च लाइसेंस योजना को बढ़ावा देंगे जिससे आप अतिरिक्त लाभ प्राप्त कर सकेंगे। । लाइसेंस योजनाओं के बीच अंतर की जांच करने के लिए <a href=\"/pricing\"> लाइसेंस तुलना तालिका </a> देखें। <strong> दूसरी ओर, जब आप अपग्रेड करते हैं, तो आपकी लाइसेंस की समाप्ति तिथि नहीं बदलेगी! </ Strong> > अपनी लाइसेंस की अंतिम तिथि बढ़ाने के लिए, आपको अपने लाइसेंस का विस्तार करना होगा।",
"LicenseRenewalCost": "1 वर्ष के बाद लाइसेंस नवीनीकरण लागत क्या है?", "LicenseRenewalCost": "1 वर्ष के बाद लाइसेंस नवीनीकरण लागत क्या है?",
"LicenseRenewalCostExplanation": "सभी एबीपी वाणिज्यिक स्थायी लाइसेंसों का नवीकरण (विस्तार) दर लाइसेंस सूची मूल्य का {0} है। मानक टीम लाइसेंस का नवीनीकरण मूल्य $ {1} है, मानक व्यवसाय लाइसेंस $ {2} है और मानक एंटरप्राइज़ लाइसेंस $ {3} है। यदि आप पहले से ही ग्राहक हैं, तो उपलब्ध नवीनीकरण मूल्य निर्धारण की समीक्षा करने के लिए <a href='ministr4 Ideal' target='_blank'> अपने खाते में लॉग इन करें </a>।", "LicenseRenewalCostExplanation": "सभी एबीपी वाणिज्यिक स्थायी लाइसेंसों की नवीनीकरण (विस्तार) दर लाइसेंस सूची मूल्य का {0} है। मानक टीम लाइसेंस का नवीनीकरण मूल्य ${1} है, मानक व्यवसाय लाइसेंस ${2} है और मानक एंटरप्राइज़ लाइसेंस ${3} है। यदि आप पहले से ही ग्राहक हैं, तो उपलब्ध नवीनीकरण मूल्य-निर्धारण की समीक्षा के लिए <a href='{4}' target='_blank'>अपने खाते में लॉग इन करें</a>।",
"HowDoIRenewMyLicense": "मैं अपने लाइसेंस का नवीनीकरण कैसे करूँ?", "HowDoIRenewMyLicense": "मैं अपने लाइसेंस का नवीनीकरण कैसे करूँ?",
"HowDoIRenewMyLicenseExplanation": "आप अपने लाइसेंस को <a href='elling0 Ideal' target='_blank'> संगठन प्रबंधन पृष्ठ </a> पर नेविगेट करके नवीनीकृत कर सकते हैं। हमारी रियायती अर्ली रिन्यूअल दरों का लाभ उठाने के लिए, सुनिश्चित करें कि आप अपने लाइसेंस की समय सीमा समाप्त होने से पहले नवीनीकरण करें। हालाँकि, जब आपका प्रारंभिक नवीनीकरण अवसर बंद हो जाता है, तो यह जानने की चिंता न करें। आपकी सदस्यता समाप्त होने से पहले आपको 2 अनुस्मारक ई-मेल प्राप्त होंगे। हम उन्हें 30 दिन, समाप्ति से 7 दिन पहले भेज देंगे।", "HowDoIRenewMyLicenseExplanation": "आप <a href='{0}' target='_blank'>संगठन प्रबंधन पृष्ठ</a> पर नेविगेट करके अपने लाइसेंस का नवीनीकरण कर सकते हैं। हमारी रियायती प्रारंभिक नवीनीकरण दरों का लाभ उठाने के लिए, अपने लाइसेंस की समय सीमा समाप्त होने से पहले नवीनीकरण करना सुनिश्चित करें। हालाँकि, यह जानने की चिंता न करें कि आपका प्रारंभिक नवीनीकरण अवसर कब बंद होगा। आपकी सदस्यता समाप्त होने से पहले आपको 2 अनुस्मारक ई-मेल प्राप्त होंगे। हम उन्हें समाप्ति से ७ दिन पहले, ३० दिनों में भेजेंगे।",
"IsSourceCodeIncluded": "क्या मेरे लाइसेंस में वाणिज्यिक मॉड्यूल और थीम का स्रोत कोड शामिल है?", "IsSourceCodeIncluded": "क्या मेरे लाइसेंस में वाणिज्यिक मॉड्यूल और थीम का स्रोत कोड शामिल है?",
"IsSourceCodeIncludedExplanation1": "आपके द्वारा खरीदे गए लाइसेंस प्रकार पर निर्भर करता है:", "IsSourceCodeIncludedExplanation1": "आपके द्वारा खरीदे गए लाइसेंस प्रकार पर निर्भर करता है:",
"IsSourceCodeIncludedExplanation2": "<strong> टीम </ strong>: आपका समाधान मॉड्यूल और थीम को NuGet और NPM पैकेज के रूप में उपयोग करता है। इसमें उनका स्रोत कोड शामिल नहीं है। इस तरह, जब भी कोई नया संस्करण उपलब्ध हो, आप इन मॉड्यूल और थीम को आसानी से अपग्रेड कर सकते हैं। हालाँकि, आप मॉड्यूल और थीम के स्रोत कोड प्राप्त नहीं कर सकते।", "IsSourceCodeIncludedExplanation2": "<strong> टीम </ strong>: आपका समाधान मॉड्यूल और थीम को NuGet और NPM पैकेज के रूप में उपयोग करता है। इसमें उनका स्रोत कोड शामिल नहीं है। इस तरह, जब भी कोई नया संस्करण उपलब्ध हो, आप इन मॉड्यूल और थीम को आसानी से अपग्रेड कर सकते हैं। हालाँकि, आप मॉड्यूल और थीम के स्रोत कोड प्राप्त नहीं कर सकते।",
"IsSourceCodeIncludedExplanation3": "<strong> व्यवसाय / उद्यम </ strong>: टीम लाइसेंस के अतिरिक्त, आप किसी भी मॉड्यूल या थीम की आवश्यकता के स्रोत कोड को डाउनलोड करने में सक्षम हैं। तुम भी एक विशेष मॉड्यूल के लिए NuGet / NPM पैकेज संदर्भ निकाल सकते हैं और इसे पूरी तरह से बदलने के लिए अपने समाधान के लिए अपने स्रोत कोड को सीधे जोड़ सकते हैं।", "IsSourceCodeIncludedExplanation3": "<strong> व्यवसाय / उद्यम </ strong>: टीम लाइसेंस के अतिरिक्त, आप किसी भी मॉड्यूल या थीम की आवश्यकता के स्रोत कोड को डाउनलोड करने में सक्षम हैं। तुम भी एक विशेष मॉड्यूल के लिए NuGet / NPM पैकेज संदर्भ निकाल सकते हैं और इसे पूरी तरह से बदलने के लिए अपने समाधान के लिए अपने स्रोत कोड को सीधे जोड़ सकते हैं।",
"IsSourceCodeIncludedExplanation4": "<p> एक मॉड्यूल के स्रोत कोड को आपके समाधान में शामिल करना आपको उस मॉड्यूल को अनुकूलित करने की अधिकतम स्वतंत्रता देता है। हालाँकि, तब नया संस्करण जारी होने पर मॉड्यूल को स्वचालित रूप से अपग्रेड करना संभव नहीं होगा। </ p> <p> किसी भी लाइसेंस में ABP सुइट स्रोत कोड शामिल नहीं है, जो एक बाहरी उपकरण है जो आपके लिए कोड बनाता है और सहायता करता है आपके विकास के लिए। </ p> <p> लाइसेंस प्रकारों के अन्य अंतरों के लिए <a href=\"lights0 Ideal\"> मूल्य निर्धारण </a> पृष्ठ देखें। </ p>", "IsSourceCodeIncludedExplanation4": "<p>अपने समाधान में मॉड्यूल के स्रोत कोड को शामिल करने से आपको उस मॉड्यूल को अनुकूलित करने की अधिकतम स्वतंत्रता मिलती है। हालांकि, नया संस्करण जारी होने पर मॉड्यूल को स्वचालित रूप से अपग्रेड करना संभव नहीं होगा।</p><p>किसी भी लाइसेंस में एबीपी सूट स्रोत कोड शामिल नहीं है, जो एक बाहरी उपकरण है जो आपके लिए कोड उत्पन्न करता है और सहायता करता है। आपके विकास के लिए।</p><p>लाइसेंस प्रकारों के बीच अन्य अंतरों के लिए <a href=\"{0}\">मूल्य निर्धारण</a> पृष्ठ देखें।</p>",
"ChangingDevelopers": "क्या मैं भविष्य में अपने संगठन के पंजीकृत डेवलपर्स को बदल सकता हूं?", "ChangingDevelopers": "क्या मैं भविष्य में अपने संगठन के पंजीकृत डेवलपर्स को बदल सकता हूं?",
"ChangingDevelopersExplanation": "अपने लाइसेंस में नए डेवलपर्स को जोड़ने के अलावा, आप मौजूदा डेवलपर्स को भी बदल सकते हैं (आप एक डेवलपर को हटा सकते हैं और एक ही सीट पर एक नया जोड़ सकते हैं) बिना किसी अतिरिक्त लागत के।", "ChangingDevelopersExplanation": "अपने लाइसेंस में नए डेवलपर्स को जोड़ने के अलावा, आप मौजूदा डेवलपर्स को भी बदल सकते हैं (आप एक डेवलपर को हटा सकते हैं और एक ही सीट पर एक नया जोड़ सकते हैं) बिना किसी अतिरिक्त लागत के।",
"WhatHappensWhenLicenseEnds": "मेरे लाइसेंस की अवधि समाप्त होने पर क्या होता है?", "WhatHappensWhenLicenseEnds": "मेरे लाइसेंस की अवधि समाप्त होने पर क्या होता है?",
"WhatHappensWhenLicenseEndsExplanation1": "ABP कमर्शियल लाइसेंस का प्रकार <a href=\" जटिलताओं0arios\" target=\"_blank\"> स्थायी लाइसेंस </a> है। आपके लाइसेंस की समय सीमा समाप्त होने के बाद, आप अपना प्रोजेक्ट विकसित करना जारी रख सकते हैं। और आप अपने लाइसेंस को नवीनीकृत करने के लिए बाध्य नहीं हैं। आपका लाइसेंस एक वर्ष के अपडेट और समर्थन योजना के साथ आता है। नई सुविधाओं को प्राप्त करने के लिए, प्रदर्शन में वृद्धि, बग फिक्स, समर्थन और एबीपी सूट का उपयोग करना जारी रखें, प्रत्येक वर्ष अपनी योजना को नवीनीकृत करना सुनिश्चित करें। जब आपका लाइसेंस समाप्त हो जाता है, तो आप निम्नलिखित लाभ प्राप्त नहीं कर पाएंगे;", "WhatHappensWhenLicenseEndsExplanation1": "ABP वाणिज्यिक लाइसेंस प्रकार <a href=\"{0}\" target=\"_blank\">स्थायी लाइसेंस</a> है। आपके लाइसेंस की समय सीमा समाप्त होने के बाद, आप अपने प्रोजेक्ट को विकसित करना जारी रख सकते हैं। और आप अपने लाइसेंस को नवीनीकृत करने के लिए बाध्य नहीं हैं। आपका लाइसेंस बॉक्स से बाहर एक साल के अपडेट और समर्थन योजना के साथ आता है। नई सुविधाओं, प्रदर्शन में सुधार, बग फिक्स, समर्थन प्राप्त करना जारी रखने और एबीपी सूट का उपयोग जारी रखने के लिए, हर साल अपनी योजना को नवीनीकृत करना सुनिश्चित करें। जब आपका लाइसेंस समाप्त हो जाता है, तो आप निम्नलिखित में से अधिक लाभ प्राप्त नहीं कर पाएंगे;",
"WhatHappensWhenLicenseEndsExplanation2": "आप एबीपी कमर्शियल का उपयोग करके नए समाधान नहीं बना सकते हैं, लेकिन आप अपने मौजूदा अनुप्रयोगों को हमेशा के लिए विकसित कर सकते हैं।", "WhatHappensWhenLicenseEndsExplanation2": "आप एबीपी कमर्शियल का उपयोग करके नए समाधान नहीं बना सकते हैं, लेकिन आप अपने मौजूदा अनुप्रयोगों को हमेशा के लिए विकसित कर सकते हैं।",
"WhatHappensWhenLicenseEndsExplanation3": "आप अपने मुख्य संस्करण के भीतर मॉड्यूल और विषयों के लिए अद्यतन प्राप्त करने में सक्षम होंगे। उदाहरण के लिए; यदि आप किसी मॉड्यूल के v3.2.0 का उपयोग कर रहे हैं, तो आप उस मॉड्यूल के v3.x.x (v3.3.0, v3.5.2 ... आदि) के लिए अपडेट प्राप्त कर सकते हैं। लेकिन आपको अगले प्रमुख संस्करण के लिए अपडेट नहीं मिल सकता है (जैसे v4.x, v5.x)", "WhatHappensWhenLicenseEndsExplanation3": "आप अपने मुख्य संस्करण के भीतर मॉड्यूल और विषयों के लिए अद्यतन प्राप्त करने में सक्षम होंगे। उदाहरण के लिए; यदि आप किसी मॉड्यूल के v3.2.0 का उपयोग कर रहे हैं, तो आप उस मॉड्यूल के v3.x.x (v3.3.0, v3.5.2 ... आदि) के लिए अपडेट प्राप्त कर सकते हैं। लेकिन आपको अगले प्रमुख संस्करण के लिए अपडेट नहीं मिल सकता है (जैसे v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation4": "आप अपने लाइसेंस समाप्त होने के बाद एबीपी वाणिज्यिक मंच में जोड़े गए नए मॉड्यूल और थीम स्थापित नहीं कर सकते।", "WhatHappensWhenLicenseEndsExplanation4": "आप अपने लाइसेंस समाप्त होने के बाद एबीपी वाणिज्यिक मंच में जोड़े गए नए मॉड्यूल और थीम स्थापित नहीं कर सकते।",
"WhatHappensWhenLicenseEndsExplanation5": "आप एबीपी सूट का उपयोग नहीं कर सकते।", "WhatHappensWhenLicenseEndsExplanation5": "आप एबीपी सूट का उपयोग नहीं कर सकते।",
"WhatHappensWhenLicenseEndsExplanation6": "आपको अब और <a href=\" जटिलताओं0 Ideal\"> प्रीमियम सहायता </a> नहीं मिल सकती है।", "WhatHappensWhenLicenseEndsExplanation6": "अब आपको <a href=\"{0}\">प्रीमियम सहायता</a> नहीं मिल सकती है।",
"WhatHappensWhenLicenseEndsExplanation7": "यदि आप इन लाभों को प्राप्त करना जारी रखना चाहते हैं तो आप अपनी सदस्यता को नवीनीकृत कर सकते हैं। जब आप अपनी सदस्यता को नवीनीकृत करते हैं तो 20% छूट मिलती है।", "WhatHappensWhenLicenseEndsExplanation7": "यदि आप इन लाभों को प्राप्त करना जारी रखना चाहते हैं तो आप अपनी सदस्यता को नवीनीकृत कर सकते हैं। जब आप अपनी सदस्यता को नवीनीकृत करते हैं तो 20% छूट मिलती है।",
"WhenShouldIRenewMyLicense": "मुझे अपना लाइसेंस कब नवीनीकृत करना चाहिए?", "WhenShouldIRenewMyLicense": "मुझे अपना लाइसेंस कब नवीनीकृत करना चाहिए?",
"WhenShouldIRenewMyLicenseExplanation1": "यदि आप अपना लाइसेंस समाप्त होने के बाद अपने लाइसेंस का नवीनीकरण <strong> 1 महीने </ strong> के भीतर करते हैं, तो कुल लाइसेंस मूल्य पर% 20 छूट लागू होगी।", "WhenShouldIRenewMyLicenseExplanation1": "यदि आप अपना लाइसेंस समाप्त होने के बाद अपने लाइसेंस का नवीनीकरण <strong> 1 महीने </ strong> के भीतर करते हैं, तो कुल लाइसेंस मूल्य पर% 20 छूट लागू होगी।",
@ -206,21 +206,21 @@
"DoYouAcceptBankWireTransferExplanation": "हां, हम बैंक वायर ट्रांसफर स्वीकार करते हैं। <br /> बैंक वायर ट्रांसफर के माध्यम से लाइसेंस राशि भेजने के बाद, हमें अपनी रसीद और अनुरोधित लाइसेंस प्रकार ई-मेल के माध्यम से भेजें। <br /> हमारे अंतरराष्ट्रीय बैंक खाते की जानकारी:", "DoYouAcceptBankWireTransferExplanation": "हां, हम बैंक वायर ट्रांसफर स्वीकार करते हैं। <br /> बैंक वायर ट्रांसफर के माध्यम से लाइसेंस राशि भेजने के बाद, हमें अपनी रसीद और अनुरोधित लाइसेंस प्रकार ई-मेल के माध्यम से भेजें। <br /> हमारे अंतरराष्ट्रीय बैंक खाते की जानकारी:",
"HowToUpgrade": "नया संस्करण उपलब्ध होने पर मौजूदा एप्लिकेशन को कैसे अपग्रेड किया जाए?", "HowToUpgrade": "नया संस्करण उपलब्ध होने पर मौजूदा एप्लिकेशन को कैसे अपग्रेड किया जाए?",
"HowToUpgradeExplanation1": "जब आप ABP कमर्शियल का उपयोग करके एक नया एप्लिकेशन बनाते हैं, तो सभी मॉड्यूल और थीम को NuGet और NPM पैकेज के रूप में उपयोग किया जाता है। इसलिए, नया संस्करण उपलब्ध होने पर आप आसानी से संकुल को अपग्रेड कर सकते हैं।", "HowToUpgradeExplanation1": "जब आप ABP कमर्शियल का उपयोग करके एक नया एप्लिकेशन बनाते हैं, तो सभी मॉड्यूल और थीम को NuGet और NPM पैकेज के रूप में उपयोग किया जाता है। इसलिए, नया संस्करण उपलब्ध होने पर आप आसानी से संकुल को अपग्रेड कर सकते हैं।",
"HowToUpgradeExplanation2": "मानक NuGet / NPM अपग्रेड के अलावा, <a href=\"lights0arios\"> ABP CLI </a> एक अपडेट कमांड प्रदान करता है जो आपके समाधान में सभी एबीपी से संबंधित पैकेजों को स्वचालित रूप से ढूंढता है और उन्हें अपग्रेड करता है।", "HowToUpgradeExplanation2": "मानक NuGet/NPM अपग्रेड के अलावा, <a href=\"{0}\">ABP CLI</a> एक अपडेट कमांड प्रदान करता है जो आपके समाधान में सभी ABP संबंधित पैकेजों को स्वचालित रूप से ढूंढता और अपग्रेड करता है।",
"DatabaseSupport": "कौन से डेटाबेस सिस्टम समर्थित हैं?", "DatabaseSupport": "कौन से डेटाबेस सिस्टम समर्थित हैं?",
"DatabaseSupportExplanation": "ABP फ्रेमवर्क स्वयं ही डेटाबेस अज्ञेयवादी है और अपनी प्रकृति के अनुसार किसी भी डेटाबेस प्रदाता के साथ काम कर सकता है। वर्तमान में कार्यान्वित प्रदाताओं की सूची के लिए <a href=\" जटिलताओं0arios\" target=\"_blank\"> डेटा एक्सेस दस्तावेज़ </a> देखें।", "DatabaseSupportExplanation": "एबीपी फ्रेमवर्क अपने आप में डेटाबेस अज्ञेयवादी है और अपनी प्रकृति से किसी भी डेटाबेस प्रदाता के साथ काम कर सकता है। वर्तमान में कार्यान्वित प्रदाताओं की सूची के लिए <a href=\"{0}\" target=\"_blank\">डेटा एक्सेस दस्तावेज़</a> देखें।",
"UISupport": "कौन से UI फ्रेमवर्क समर्थित हैं?", "UISupport": "कौन से UI फ्रेमवर्क समर्थित हैं?",
"Supported": "समर्थित", "Supported": "समर्थित",
"UISupportExplanation": "ABP फ्रेमवर्क स्वयं UI फ्रेमवर्क अज्ञेयवादी है और किसी भी UI फ्रेमवर्क के साथ काम कर सकता है। हालाँकि, सभी UI फ्रेमवर्क के लिए स्टार्टअप टेम्प्लेट, मॉड्यूल UI और थीम लागू नहीं किए गए थे। UI विकल्पों की अप-टू-डेट सूची के लिए <a href=\" जटिलताओं0arios\"> आरंभ किया गया दस्तावेज़ </a> देखें।", "UISupportExplanation": "एबीपी फ्रेमवर्क अपने आप में यूआई फ्रेमवर्क अज्ञेयवादी है और किसी भी यूआई फ्रेमवर्क के साथ काम कर सकता है। हालांकि, स्टार्टअप टेम्प्लेट, मॉड्यूल UI और थीम सभी UI फ्रेमवर्क के लिए लागू नहीं किए गए थे। UI विकल्पों की अप-टू-डेट सूची के लिए <a href=\"{0}\">आरंभ करने वाला दस्तावेज़</a> देखें।",
"MicroserviceSupport": "क्या यह सूक्ष्म सेवा वास्तुकला का समर्थन करता है?", "MicroserviceSupport": "क्या यह सूक्ष्म सेवा वास्तुकला का समर्थन करता है?",
"MicroserviceSupportExplanation1": "एबीपी ढांचे का एक प्रमुख लक्ष्य सूक्ष्म सेवा समाधान बनाने के लिए एक सुविधाजनक बुनियादी ढांचा प्रदान करना है। यह समझने के लिए कि यह माइक्रो-सर्विस सिस्टम बनाने में कैसे मदद करता है, यह समझने के लिए <a href=\" जटिलताओं0 Ideal\"> माइक्रो-सर्विस आर्किटेक्चर </a> दस्तावेज़ देखें।", "MicroserviceSupportExplanation1": "एबीपी ढांचे के प्रमुख लक्ष्यों में से एक सूक्ष्म सेवा समाधान बनाने के लिए एक सुविधाजनक बुनियादी ढांचा प्रदान करना है। यह समझने के लिए कि यह माइक्रो-सर्विस सिस्टम बनाने में कैसे मदद करता है, <a href=\"{0}\">माइक्रो-सर्विस आर्किटेक्चर</a> दस्तावेज़ देखें।",
"MicroserviceSupportExplanation2": "सभी एबीपी कमर्शियल मॉड्यूल्स को <a href=\" जटिलताओं0arios\"> मॉड्यूल डेवलपमेंट बेस्ट प्रैक्टिस </a> दस्तावेज़ का पालन करके माइक्रो-सर्विस परिनियोजन परिदृश्य (अपने एपीआई और डेटाबेस के साथ) का समर्थन करने के लिए डिज़ाइन किया गया है।", "MicroserviceSupportExplanation2": "सभी एबीपी वाणिज्यिक मॉड्यूल <a href=\"{0}\">मॉड्यूल विकास सर्वोत्तम प्रथाओं</a> दस्तावेज़ का पालन करके माइक्रो-सेवा परिनियोजन परिदृश्यों (अपने स्वयं के एपीआई और डेटाबेस के साथ) का समर्थन करने के लिए डिज़ाइन किए गए हैं।",
"MicroserviceSupportExplanation3": "हम आपको अपना स्वयं का समाधान बनाने में मदद करने के लिए एक माइक्रो-सेवा वास्तुकला कार्यान्वयन को प्रदर्शित करने वाला एक नमूना <a href=\"ministr0 Ideal\"> माइक्रो-सर्विस डेमो समाधान </a> प्रदान करते हैं।", "MicroserviceSupportExplanation3": "हम एक नमूना <a href=\"{0}\">माइक्रो-सर्विस डेमो सॉल्यूशन</a> प्रदान करते हैं जो आपको अपना समाधान बनाने में मदद करने के लिए एक माइक्रो-सर्विस आर्किटेक्चर कार्यान्वयन दर्शाता है।",
"MicroserviceSupportExplanation4": "तो, संक्षिप्त उत्तर \"<strong> हां है, यह सूक्ष्म सेवा वास्तुकला का समर्थन करता है </ strong>\"।", "MicroserviceSupportExplanation4": "तो, संक्षिप्त उत्तर \"<strong> हां है, यह सूक्ष्म सेवा वास्तुकला का समर्थन करता है </ strong>\"।",
"MicroserviceSupportExplanation5": "हालाँकि, एक माइक्रो-सर्विस सिस्टम एक समाधान है और हर समाधान में अलग-अलग आवश्यकताएं, नेटवर्क टोपोलॉजी, संचार परिदृश्य, प्रमाणीकरण संभावनाएं, डेटाबेस पृथक्करण / साझा करने के निर्णय, रनटाइम कॉन्फ़िगरेशन, 3 पार्टी सिस्टम एकीकरण और कई और अधिक होंगे।", "MicroserviceSupportExplanation5": "हालाँकि, एक माइक्रो-सर्विस सिस्टम एक समाधान है और हर समाधान में अलग-अलग आवश्यकताएं, नेटवर्क टोपोलॉजी, संचार परिदृश्य, प्रमाणीकरण संभावनाएं, डेटाबेस पृथक्करण / साझा करने के निर्णय, रनटाइम कॉन्फ़िगरेशन, 3 पार्टी सिस्टम एकीकरण और कई और अधिक होंगे।",
"MicroserviceSupportExplanation6": "ABP फ्रेमवर्क और ABP कमर्शियल आपको अपने स्वयं के समाधान का निर्माण करने में मदद करने के लिए सूक्ष्म सेवा परिदृश्य, सूक्ष्म सेवा संगत मॉड्यूल, नमूने और प्रलेखन के लिए बुनियादी ढाँचा प्रदान करता है। लेकिन अपने सपनों के समाधान को सीधे आपके लिए पहले से डाउनलोड करने की उम्मीद न करें। आपको इसे समझने और अपनी आवश्यकताओं के आधार पर कुछ हिस्सों को एक साथ लाने की आवश्यकता होगी।", "MicroserviceSupportExplanation6": "ABP फ्रेमवर्क और ABP कमर्शियल आपको अपने स्वयं के समाधान का निर्माण करने में मदद करने के लिए सूक्ष्म सेवा परिदृश्य, सूक्ष्म सेवा संगत मॉड्यूल, नमूने और प्रलेखन के लिए बुनियादी ढाँचा प्रदान करता है। लेकिन अपने सपनों के समाधान को सीधे आपके लिए पहले से डाउनलोड करने की उम्मीद न करें। आपको इसे समझने और अपनी आवश्यकताओं के आधार पर कुछ हिस्सों को एक साथ लाने की आवश्यकता होगी।",
"WhereCanIDownloadSourceCode": "मैं स्रोत-कोड कहां से डाउनलोड कर सकता हूं?", "WhereCanIDownloadSourceCode": "मैं स्रोत-कोड कहां से डाउनलोड कर सकता हूं?",
"WhereCanIDownloadSourceCodeExplanation": "आप एबीपी सूट या एबीपी सीएलआई के माध्यम से सभी एबीपी मॉड्यूल, कोणीय पैकेज और थीम के स्रोत कोड डाउनलोड कर सकते हैं। <a href=\"find0 Ideal\"> स्रोत-कोड डाउनलोड कैसे करें? </a> देखें", "WhereCanIDownloadSourceCodeExplanation": "आप एबीपी सूट या एबीपी सीएलआई के माध्यम से सभी एबीपी मॉड्यूल, एंगुलर पैकेज और थीम का सोर्स कोड डाउनलोड कर सकते हैं। देखें <a href=\"{0}\">स्रोत-कोड कैसे डाउनलोड करें?</a>",
"ComputerLimitation": "एबीपी विकसित करते समय एक डेवलपर कितने कंप्यूटरों पर लॉगिन कर सकता है?", "ComputerLimitation": "एबीपी विकसित करते समय एक डेवलपर कितने कंप्यूटरों पर लॉगिन कर सकता है?",
"ComputerLimitationExplanation": "हम विशेष रूप से प्रति व्यक्ति / लाइसेंस प्राप्त डेवलपर के लिए <strong> {0} कंप्यूटर </ strong> की अनुमति देते हैं। जब भी किसी तीसरे मशीन पर एबीपी कमर्शियल उत्पादों को विकसित करने के लिए डेवलपर की आवश्यकता होती है, तो स्थिति को समझाते हुए लाइसेंस@abp.io को एक ई-मेल भेजा जाना चाहिए और फिर हम अपने सिस्टम में उचित आवंटन करेंगे।", "ComputerLimitationExplanation": "हम विशेष रूप से प्रति व्यक्ति / लाइसेंस प्राप्त डेवलपर के लिए <strong> {0} कंप्यूटर </ strong> की अनुमति देते हैं। जब भी किसी तीसरे मशीन पर एबीपी कमर्शियल उत्पादों को विकसित करने के लिए डेवलपर की आवश्यकता होती है, तो स्थिति को समझाते हुए लाइसेंस@abp.io को एक ई-मेल भेजा जाना चाहिए और फिर हम अपने सिस्टम में उचित आवंटन करेंगे।",
"RefundPolicy": "क्या आपके पास धनवापसी नीति है?", "RefundPolicy": "क्या आपके पास धनवापसी नीति है?",
@ -230,17 +230,17 @@
"HowCanIRefundVatExplanation2": "अपने <a href=\"https://secure.2checkout.com/cpanel/login.php\" target=\"_blank\"> 2 चेकआउट </a> खाते में लॉग इन करें", "HowCanIRefundVatExplanation2": "अपने <a href=\"https://secure.2checkout.com/cpanel/login.php\" target=\"_blank\"> 2 चेकआउट </a> खाते में लॉग इन करें",
"HowCanIRefundVatExplanation3": "उपयुक्त आदेश खोजें और \"रिफंड बेल्ड वैट\" दबाएं (अपनी वैट आईडी दर्ज करें)", "HowCanIRefundVatExplanation3": "उपयुक्त आदेश खोजें और \"रिफंड बेल्ड वैट\" दबाएं (अपनी वैट आईडी दर्ज करें)",
"HowCanIGetMyInvoice": "मैं अपना चालान कैसे प्राप्त कर सकता हूं?", "HowCanIGetMyInvoice": "मैं अपना चालान कैसे प्राप्त कर सकता हूं?",
"HowCanIGetMyInvoiceExplanation": "लाइसेंस खरीदने के लिए 2 भुगतान गेटवे हैं: PayU और 2 चेकआउट। यदि आप 2Checkout गेटवे के माध्यम से अपना लाइसेंस खरीदते हैं, तो यह आपके ईमेल पते पर पीडीएफ चालान भेजता है, देखें <a href = \"https://knowledgecenter.2checkout.com/Documentation/03Billing-and-payments/Payment-operations/How-do -invoices- काम \"> 2 चेकआउट चालान। </a> यदि आप पेयू गेटवे या बैंक वायर ट्रांसफर के माध्यम से खरीदते हैं, तो हम आपका चालान तैयार करेंगे और भेजेंगे। आप अपने चालान का अनुरोध <a href=\" जटिलताओं0 Ideal\"> संगठन प्रबंधन पृष्ठ </a> से कर सकते हैं", "HowCanIGetMyInvoiceExplanation": "लाइसेंस खरीदने के लिए 2 भुगतान गेटवे हैं: PayU और 2 चेकआउट। यदि आप 2Checkout गेटवे के माध्यम से अपना लाइसेंस खरीदते हैं, तो यह आपके ईमेल पते पर पीडीएफ चालान भेजता है, देखें <a href=\"https://knowledgecenter.2checkout.com/Documentation/03Billing-and-payments/Payment-operations/How-do-invoices-work\"> 2 चेकआउट चालान। </a> यदि आप पेयू गेटवे या बैंक वायर ट्रांसफर के माध्यम से खरीदते हैं, तो हम आपका चालान तैयार करेंगे और भेजेंगे। आप अपने चालान का अनुरोध <a href=\"{0}\"> संगठन प्रबंधन पृष्ठ </a> से कर सकते हैं",
"Forum": "मंच", "Forum": "मंच",
"SupportExplanation": "ABP कमर्शियल लाइसेंस एक टीम द्वारा प्रीमियम फ़ोरम सपोर्ट प्रदान करता है जिसमें ABP फ्रेमवर्क विशेषज्ञ होते हैं।", "SupportExplanation": "ABP कमर्शियल लाइसेंस एक टीम द्वारा प्रीमियम फ़ोरम सपोर्ट प्रदान करता है जिसमें ABP फ्रेमवर्क विशेषज्ञ होते हैं।",
"PrivateTicket": "निजी टिकट", "PrivateTicket": "निजी टिकट",
"PrivateTicketExplanation": "एंटरप्राइज लाइसेंस में ई-मेल और टिकट प्रणाली के साथ एक निजी सहायता भी शामिल है।", "PrivateTicketExplanation": "एंटरप्राइज लाइसेंस में ई-मेल और टिकट प्रणाली के साथ एक निजी सहायता भी शामिल है।",
"AbpSuiteExplanation1": "ABP सुइट आपको कुछ ही मिनटों में वेब पेज बनाने की अनुमति देता है। यह .NET कोर ग्लोबल टूल है जिसे कमांड लाइन से इंस्टॉल किया जा सकता है।", "AbpSuiteExplanation1": "ABP सुइट आपको कुछ ही मिनटों में वेब पेज बनाने की अनुमति देता है। यह .NET कोर ग्लोबल टूल है जिसे कमांड लाइन से इंस्टॉल किया जा सकता है।",
"AbpSuiteExplanation2": "यह एक नया ABP समाधान बना सकता है, डेटाबेस से फ्रंट-एंड तक CRUD पेज बना सकता है। तकनीकी ओवरव्यू के लिए <a href=\" जटिलताओं0 Ideal\"> दस्तावेज़ </a> देखें", "AbpSuiteExplanation2": "यह एक नया ABP समाधान बना सकता है, डेटाबेस से फ्रंट-एंड तक CRUD पेज बना सकता है। तकनीकी ओवरव्यू के लिए <a href=\"{0}\"> दस्तावेज़ </a> देखें",
"FastEasy": "तेज और आसान", "FastEasy": "तेज और आसान",
"AbpSuiteExplanation3": "ABP सुइट आपको आसानी से CRUD पेज बनाने की अनुमति देता है। आपको बस अपनी इकाई और उसके गुणों को परिभाषित करने की आवश्यकता है, बाकी को आप के लिए एबीपी सूट करने दें! एबीपी सूट कुछ ही सेकंड में आपके सीआरयूडी पृष्ठ के लिए सभी आवश्यक कोड उत्पन्न करता है। यह Angular, MVC और Blazor यूजर इंटरफेस को सपोर्ट करता है।", "AbpSuiteExplanation3": "ABP सुइट आपको आसानी से CRUD पेज बनाने की अनुमति देता है। आपको बस अपनी इकाई और उसके गुणों को परिभाषित करने की आवश्यकता है, बाकी को आप के लिए एबीपी सूट करने दें! एबीपी सूट कुछ ही सेकंड में आपके सीआरयूडी पृष्ठ के लिए सभी आवश्यक कोड उत्पन्न करता है। यह Angular, MVC और Blazor यूजर इंटरफेस को सपोर्ट करता है।",
"RichOptions": "अमीर विकल्प", "RichOptions": "अमीर विकल्प",
"AbpSuiteExplanation4": "ABP सुइट <a href=\"https://docs.microsoft.com/en-us/aspnet/core/razor-pages\"> रेजर पेज </a> और <a href = \"https: / जैसे कई UI विकल्पों का समर्थन करता है /angular.io\">Angular </a>। यह <a href=\"https://www.mongodb.com\"> MongoDB </a> जैसे कई डेटाबेस का समर्थन करता है और सभी डेटाबेस <strong> EntityFramework Core <द्वारा समर्थित है / strong> (MS SQL सर्वर, Oracle, MySql, PostgreSQL और <a href=\"https://docs.microsoft.com/en-us/ef/core/providers/?tabs=dotnet-core-cii] और </a>)।", "AbpSuiteExplanation4": "ABP Suite supports multiple UI options like <a href=\"https://docs.microsoft.com/en-us/aspnet/core/razor-pages\">Razor Pages</a> and <a href=\"https://angular.io\">Angular</a>.It also supports multiple databases like <a href=\"https://www.mongodb.com\">MongoDB</a> and all databases supported by <strong>EntityFramework Core</strong> (MS SQL Server, Oracle, MySql, PostgreSQL and <a href=\"https://docs.microsoft.com/en-us/ef/core/providers/?tabs=dotnet-core-cli\">more</a>).",
"AbpSuiteExplanation5": "अच्छी बात यह है कि, आपको उन विकल्पों के बारे में चिंता करने की ज़रूरत नहीं है। एबीपी सूट आपके प्रोजेक्ट के प्रकार को समझता है और आपकी परियोजना के लिए कोड बनाता है और उत्पन्न कोड को आपके प्रोजेक्ट में सही जगह पर रखता है।", "AbpSuiteExplanation5": "अच्छी बात यह है कि, आपको उन विकल्पों के बारे में चिंता करने की ज़रूरत नहीं है। एबीपी सूट आपके प्रोजेक्ट के प्रकार को समझता है और आपकी परियोजना के लिए कोड बनाता है और उत्पन्न कोड को आपके प्रोजेक्ट में सही जगह पर रखता है।",
"SourceCode": "सोर्स कोड", "SourceCode": "सोर्स कोड",
"AbpSuiteExplanation6": "ABP स्वीट आपके लिए सोर्स कोड जेनरेट करता है! यह वेब पेज जनरेट करने के लिए मैजिक फाइल्स जेनरेट नहीं करता है। एबीपी सूट <strong> इकाई, रिपोजिटरी, एप्लीकेशन सर्विस, कोड फर्स्ट माइग्रेशन, जावास्क्रिप्ट / टाइपस्क्रिप्ट और सीएसएचटीएमएल / एचटीएमएल </ strong> और आवश्यक इंटरफेस के लिए भी स्रोत कोड उत्पन्न करता है। ABP Suite सॉफ्टवेयर डेवलपमेंट के <strong> बेस्ट प्रैक्टिसेस </ strong> के अनुसार कोड भी तैयार करता है, इसलिए आपको जनरेट किए गए कोड की गुणवत्ता के बारे में चिंता करने की आवश्यकता नहीं है।", "AbpSuiteExplanation6": "ABP स्वीट आपके लिए सोर्स कोड जेनरेट करता है! यह वेब पेज जनरेट करने के लिए मैजिक फाइल्स जेनरेट नहीं करता है। एबीपी सूट <strong> इकाई, रिपोजिटरी, एप्लीकेशन सर्विस, कोड फर्स्ट माइग्रेशन, जावास्क्रिप्ट / टाइपस्क्रिप्ट और सीएसएचटीएमएल / एचटीएमएल </ strong> और आवश्यक इंटरफेस के लिए भी स्रोत कोड उत्पन्न करता है। ABP Suite सॉफ्टवेयर डेवलपमेंट के <strong> बेस्ट प्रैक्टिसेस </ strong> के अनुसार कोड भी तैयार करता है, इसलिए आपको जनरेट किए गए कोड की गुणवत्ता के बारे में चिंता करने की आवश्यकता नहीं है।",

4
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json

@ -151,7 +151,7 @@
"SeeAllModules": "Vedi tutti i moduli", "SeeAllModules": "Vedi tutti i moduli",
"ABPCLIExplanation": "ABP CLI (Command Line Interface) è uno strumento a riga di comando per eseguire alcune operazioni comuni per soluzioni basate su ABP.", "ABPCLIExplanation": "ABP CLI (Command Line Interface) è uno strumento a riga di comando per eseguire alcune operazioni comuni per soluzioni basate su ABP.",
"ABPSuiteEasilyCURD": "ABP Suite è uno strumento che ti permette di creare facilmente pagine CRUD", "ABPSuiteEasilyCURD": "ABP Suite è uno strumento che ti permette di creare facilmente pagine CRUD",
"WeAreHereToHelp": "Siamo qui per <span class = \"zero-text\"> Aiuto </span>", "WeAreHereToHelp": "Siamo qui per <span class=\"zero-text\"> Aiuto </span>",
"BrowseOrAskQuestion": "Puoi sfogliare i nostri argomenti della guida o cercare nelle domande frequenti oppure puoi farci una domanda utilizzando il <a href=\"{0}\" class=\"text-success\"> modulo di contatto </a>.", "BrowseOrAskQuestion": "Puoi sfogliare i nostri argomenti della guida o cercare nelle domande frequenti oppure puoi farci una domanda utilizzando il <a href=\"{0}\" class=\"text-success\"> modulo di contatto </a>.",
"SearchQuestionPlaceholder": "Cerca nelle domande frequenti", "SearchQuestionPlaceholder": "Cerca nelle domande frequenti",
"WhatIsTheABPCommercial": "Cos'è l'ABP Commercial?", "WhatIsTheABPCommercial": "Cos'è l'ABP Commercial?",
@ -177,7 +177,7 @@
"ChangingLicenseType": "Posso cambiare il mio tipo di licenza in futuro?", "ChangingLicenseType": "Posso cambiare il mio tipo di licenza in futuro?",
"ChangingLicenseTypeExplanation": "Puoi sempre aggiungere nuovi sviluppatori con lo stesso tipo di licenza. Vedi anche \"Quanti sviluppatori possono lavorare su ABP Commercial?\". Puoi anche passare a una licenza superiore pagando la differenza di prezzo calcolata. Quando esegui l'aggiornamento a un piano di licenza superiore, ottieni i vantaggi del nuovo piano, ma l'aggiornamento della licenza non modifica la data di scadenza della licenza.", "ChangingLicenseTypeExplanation": "Puoi sempre aggiungere nuovi sviluppatori con lo stesso tipo di licenza. Vedi anche \"Quanti sviluppatori possono lavorare su ABP Commercial?\". Puoi anche passare a una licenza superiore pagando la differenza di prezzo calcolata. Quando esegui l'aggiornamento a un piano di licenza superiore, ottieni i vantaggi del nuovo piano, ma l'aggiornamento della licenza non modifica la data di scadenza della licenza.",
"LicenseExtendUpgradeDiff": "Qual è la differenza tra estensione della licenza e aggiornamento?", "LicenseExtendUpgradeDiff": "Qual è la differenza tra estensione della licenza e aggiornamento?",
"LicenseExtendUpgradeDiffExplanation": "<strong> Estensione: </strong> estendendo / rinnovando la tua licenza, continuerai a ricevere supporto premium e a ricevere aggiornamenti importanti per moduli e temi. Inoltre, potrai continuare a creare nuovi progetti. E sarai ancora in grado di utilizzare ABP Suite che accelera il tuo sviluppo. <Hr /> <strong> Upgrade: </strong> aggiornando la tua licenza, promuoverai un piano di licenza superiore che ti consentirà di ottenere ulteriori vantaggi . Consulta la <a href=\"/pricing\"> tabella di confronto delle licenze </a> per verificare le differenze tra i piani di licenza. <strong> D'altra parte, quando esegui l'upgrade, la data di scadenza della licenza non cambierà! </ Strong > Per estendere la data di fine della licenza, è necessario estendere la licenza.", "LicenseExtendUpgradeDiffExplanation": "<strong> Estensione: </strong> estendendo/rinnovando la tua licenza, continuerai a ricevere supporto premium e a ricevere aggiornamenti importanti per moduli e temi. Inoltre, potrai continuare a creare nuovi progetti. E sarai ancora in grado di utilizzare ABP Suite che accelera il tuo sviluppo. <hr/> <strong> Upgrade: </strong> aggiornando la tua licenza, promuoverai un piano di licenza superiore che ti consentirà di ottenere ulteriori vantaggi . Consulta la <a href=\"/pricing\"> tabella di confronto delle licenze </a> per verificare le differenze tra i piani di licenza. <strong> D'altra parte, quando esegui l'upgrade, la data di scadenza della licenza non cambierà! </strong> Per estendere la data di fine della licenza, è necessario estendere la licenza.",
"LicenseRenewalCost": "Qual è il costo del rinnovo della licenza dopo 1 anno?", "LicenseRenewalCost": "Qual è il costo del rinnovo della licenza dopo 1 anno?",
"LicenseRenewalCostExplanation": "La tariffa di rinnovo (estensione) di tutte le licenze perpetue ABP Commercial è {0} del prezzo di listino della licenza. Il prezzo di rinnovo della licenza Team standard è $ {1}, la licenza Business standard è $ {2} e la licenza Enterprise standard è $ {3}. Se sei già un cliente, <a href='{4}' target='_blank'> accedi al tuo account </a> per esaminare i prezzi di rinnovo disponibili.", "LicenseRenewalCostExplanation": "La tariffa di rinnovo (estensione) di tutte le licenze perpetue ABP Commercial è {0} del prezzo di listino della licenza. Il prezzo di rinnovo della licenza Team standard è $ {1}, la licenza Business standard è $ {2} e la licenza Enterprise standard è $ {3}. Se sei già un cliente, <a href='{4}' target='_blank'> accedi al tuo account </a> per esaminare i prezzi di rinnovo disponibili.",
"HowDoIRenewMyLicense": "Come rinnovo la mia licenza?", "HowDoIRenewMyLicense": "Come rinnovo la mia licenza?",

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

@ -97,6 +97,7 @@
"VolosoftSharingInformationMessage": "Volosoft'un ürünlerimi seçkin ortaklarla paylaşmasını kabul ediyorum, böylece ilgili ortakların ürünleri ve hizmetleri hakkında ilgili bilgileri alabilirim.", "VolosoftSharingInformationMessage": "Volosoft'un ürünlerimi seçkin ortaklarla paylaşmasını kabul ediyorum, böylece ilgili ortakların ürünleri ve hizmetleri hakkında ilgili bilgileri alabilirim.",
"WeWillSendYouADownloadLink": "{0} adresine email gönderilmiştir.", "WeWillSendYouADownloadLink": "{0} adresine email gönderilmiştir.",
"InvalidFormInputs": "Lütfen formda belirtilen geçerli bilgileri yazınız.", "InvalidFormInputs": "Lütfen formda belirtilen geçerli bilgileri yazınız.",
"DDDBookEmailBody": "Teşekkürler. <br /> Kitabı indirmek için, <a href=\"{0}\">buraya tıklayınız</a>." "DDDBookEmailBody": "Teşekkürler. <br /> Kitabı indirmek için, <a href=\"{0}\">buraya tıklayınız</a>.",
"FreeDDDEBook": "Ücretsiz DDD E-Kitap"
} }
} }

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

@ -118,7 +118,7 @@
"CreatePostCoverInfo": "Lisää kansikuva, jotta voit luoda tehokkaan viestin. Lataa 16: 9-kuvasuhteen kuvat parhaan näkymän saamiseksi. Tiedoston enimmäiskoko: 1 Mt.", "CreatePostCoverInfo": "Lisää kansikuva, jotta voit luoda tehokkaan viestin. Lataa 16: 9-kuvasuhteen kuvat parhaan näkymän saamiseksi. Tiedoston enimmäiskoko: 1 Mt.",
"ThankYouForContribution": "Kiitos osallistumisesta ABP-yhteisöön.", "ThankYouForContribution": "Kiitos osallistumisesta ABP-yhteisöön.",
"GithubArticle": "Github-artikkeli", "GithubArticle": "Github-artikkeli",
"GithubArticleSubmitStepOne": "<span class = \"font-weight-bold\"> 1. </span> Kirjoita artikkeli mistä tahansa julkisesta GitHub-arkistosta Markdown-muodossa. <a target=\"_blank\" href=\"https://github.com/abpframework/abp/blob/dev/docs/fi/Community-Articles/2020-12-04-Event-Organizer/Post.md\"> esimerkki </a>", "GithubArticleSubmitStepOne": "<span class=\"font-weight-bold\">1.</span> Kirjoita artikkeli mistä tahansa julkisesta GitHub-arkistosta Markdown-muodossa. <a target=\"_blank\" href=\"https://github.com/abpframework/abp/blob/dev/docs/en/Community-Articles/2020-12-04-Event-Organizer/Post.md\"> esimerkki </a>",
"GithubArticleSubmitStepTwo": "<span class = \"font-weight-bold\"> 2. </span> Lähetä artikkelin URL-osoite lomaketta käyttämällä.", "GithubArticleSubmitStepTwo": "<span class = \"font-weight-bold\"> 2. </span> Lähetä artikkelin URL-osoite lomaketta käyttämällä.",
"GithubArticleSubmitStepThree": "<span class = \"font-weight-bold\"> 3. </span> Artikkelisi renderöidään tällä verkkosivustolla.", "GithubArticleSubmitStepThree": "<span class = \"font-weight-bold\"> 3. </span> Artikkelisi renderöidään tällä verkkosivustolla.",
"YoutubeVideo": "Youtube-video", "YoutubeVideo": "Youtube-video",

4
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json

@ -96,7 +96,7 @@
"JoinOurArticleNewsletter": "हमारे लेख समाचार पत्र में शामिल हों", "JoinOurArticleNewsletter": "हमारे लेख समाचार पत्र में शामिल हों",
"Community": "समुदाय", "Community": "समुदाय",
"Marketing": "विपणन", "Marketing": "विपणन",
"CommunityPrivacyPolicyConfirmation": "मैं नियम और शर्तों और <a href=\"https://com Commercial.abp.io/Privacy\"> गोपनीयता नीति </a> से सहमत हूं।", "CommunityPrivacyPolicyConfirmation": "मैं नियम और शर्तों और <a href=\"https://commercial.abp.io/Privacy\">गोपनीयता नीति</a> से सहमत हूं।",
"ArticleRequestMessageTitle": "GitHub पर एक लेख / ट्यूटोरियल जिसे आप इस वेब साइट पर देखना चाहते हैं, का अनुरोध करने के लिए <a href=\"https://github.com/abpframework/abp/issues/new\"> एक समस्या खोलें </a>।", "ArticleRequestMessageTitle": "GitHub पर एक लेख / ट्यूटोरियल जिसे आप इस वेब साइट पर देखना चाहते हैं, का अनुरोध करने के लिए <a href=\"https://github.com/abpframework/abp/issues/new\"> एक समस्या खोलें </a>।",
"ArticleRequestMessageBody": "यहाँ, समुदाय द्वारा अनुरोधित लेखों की सूची। क्या आप एक अनुरोधित लेख लिखना चाहते हैं? कृपया अनुरोध पर क्लिक करें और चर्चा में शामिल हों।", "ArticleRequestMessageBody": "यहाँ, समुदाय द्वारा अनुरोधित लेखों की सूची। क्या आप एक अनुरोधित लेख लिखना चाहते हैं? कृपया अनुरोध पर क्लिक करें और चर्चा में शामिल हों।",
"Language": "भाषा: हिन्दी", "Language": "भाषा: हिन्दी",
@ -118,7 +118,7 @@
"CreatePostCoverInfo": "एक प्रभावी पोस्ट बनाने के लिए, एक कवर फ़ोटो जोड़ें। सर्वश्रेष्ठ दृश्य के लिए 16: 9 पहलू अनुपात चित्र अपलोड करें। अधिकतम फ़ाइल आकार: 1 एमबी।", "CreatePostCoverInfo": "एक प्रभावी पोस्ट बनाने के लिए, एक कवर फ़ोटो जोड़ें। सर्वश्रेष्ठ दृश्य के लिए 16: 9 पहलू अनुपात चित्र अपलोड करें। अधिकतम फ़ाइल आकार: 1 एमबी।",
"ThankYouForContribution": "ABP समुदाय में योगदान के लिए धन्यवाद।", "ThankYouForContribution": "ABP समुदाय में योगदान के लिए धन्यवाद।",
"GithubArticle": "गीथब लेख", "GithubArticle": "गीथब लेख",
"GithubArticleSubmitStepOne": "<span class = \"font-weight-bold\"> 1। </ span> मार्कडाउन प्रारूप के साथ किसी भी सार्वजनिक GitHub रिपॉजिटरी पर एक लेख लिखें। <a target=\"_blank\" href=\"https://github.com/abpframework/abp/blob/dev/docs/en/Community-Articles/2020-12-04-Event-Offganizer/Post.md\"> उदाहरण </a>", "GithubArticleSubmitStepOne": "<span class=\"font-weight-bold\">1.</span> मार्कडाउन प्रारूप के साथ किसी भी सार्वजनिक GitHub रिपॉजिटरी पर एक लेख लिखें। <a target=\"_blank\" href=\"https://github.com/abpframework/abp/blob/dev/docs/en/Community-Articles/2020-12-04-Event-Organizer/Post.md\">उदाहरण </a>",
"GithubArticleSubmitStepTwo": "<span class = \"font-weight-bold\"> 2। </ span> फ़ॉर्म का उपयोग करके अपना लेख URL सबमिट करें।", "GithubArticleSubmitStepTwo": "<span class = \"font-weight-bold\"> 2। </ span> फ़ॉर्म का उपयोग करके अपना लेख URL सबमिट करें।",
"GithubArticleSubmitStepThree": "<span class = \"font-weight-bold\"> 3। </ span> इस वेब साइट में आपका लेख प्रस्तुत किया जाएगा।", "GithubArticleSubmitStepThree": "<span class = \"font-weight-bold\"> 3। </ span> इस वेब साइट में आपका लेख प्रस्तुत किया जाएगा।",
"YoutubeVideo": "यूट्यूब वीडियो", "YoutubeVideo": "यूट्यूब वीडियो",

6
abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en-GB.json

@ -255,8 +255,6 @@
"Surname": "Surname", "Surname": "Surname",
"CompanyName": "Company Name", "CompanyName": "Company Name",
"DoYouAgreePrivacyPolicy": "I agree to the Terms & Conditions and <a href=\"https://commercial.abp.io/Privacy\">Privacy Policy</a>.", "DoYouAgreePrivacyPolicy": "I agree to the Terms & Conditions and <a href=\"https://commercial.abp.io/Privacy\">Privacy Policy</a>.",
"VolosoftMarketingInformationMessage": "I would like information, tips, and offers about Solutions for Businesses and Organizations and other Volosoft products and services.",
"VolosoftSharingInformationMessage": "I would like Volosoft to share my information with select partners so I can receive relevant information about their products and services.",
"Free": "Free", "Free": "Free",
"DDDEBook": "DDD E-book", "DDDEBook": "DDD E-book",
"PracticalGuideForImplementingDDD": "This book is a practical guide for implementing the Domain Driven Design with the ABP Framework.", "PracticalGuideForImplementingDDD": "This book is a practical guide for implementing the Domain Driven Design with the ABP Framework.",
@ -270,6 +268,8 @@
"WeWillSendYouADownloadLink": "We've sent the file to {0}.", "WeWillSendYouADownloadLink": "We've sent the file to {0}.",
"GoHome": "Go Home", "GoHome": "Go Home",
"InvalidFormInputs": "Please, type the valid information specified on the form.", "InvalidFormInputs": "Please, type the valid information specified on the form.",
"DDDBookEmailBody": "Thank you. <br /> To download your book, <a href=\"{0}\">click here</a>." "DDDBookEmailBody": "Thank you. <br /> To download your book, <a href=\"{0}\">click here</a>.",
"SubscribeToNewsletter": "Subscribe to the newsletter to get information about happenings in the ABP.IO Platform, like new releases, articles, offers, and more.",
"FirstEdition": "First Edition"
} }
} }

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

@ -244,7 +244,7 @@
"ExampleUseCase": "Example Use Case", "ExampleUseCase": "Example Use Case",
"DomainAndApplicationLogic": "Domain Logic & Application Logic", "DomainAndApplicationLogic": "Domain Logic & Application Logic",
"Author": "Author", "Author": "Author",
"Page": "Page", "Pages": "Pages",
"PublishedOn": "Published on", "PublishedOn": "Published on",
"FreeEBook": "Free E-Book", "FreeEBook": "Free E-Book",
"Download": "Download", "Download": "Download",
@ -256,8 +256,6 @@
"Surname": "Surname", "Surname": "Surname",
"CompanyName": "Company Name", "CompanyName": "Company Name",
"DoYouAgreePrivacyPolicy": "I agree to the <a href=\"https://account.abp.io/Account/TermsConditions\">Terms & Conditions</a> and <a href=\"https://account.abp.io/Account/Privacy\">Privacy Policy</a>.", "DoYouAgreePrivacyPolicy": "I agree to the <a href=\"https://account.abp.io/Account/TermsConditions\">Terms & Conditions</a> and <a href=\"https://account.abp.io/Account/Privacy\">Privacy Policy</a>.",
"VolosoftMarketingInformationMessage": "I would like information, tips, and offers about Solutions for Businesses and Organizations and other Volosoft products and services.",
"VolosoftSharingInformationMessage": "I would like Volosoft to share my information with select partners so I can receive relevant information about their products and services.",
"Free": "Free", "Free": "Free",
"DDDEBook": "DDD E-book", "DDDEBook": "DDD E-book",
"PracticalGuideForImplementingDDD": "This book is a practical guide for implementing the Domain Driven Design with the ABP Framework.", "PracticalGuideForImplementingDDD": "This book is a practical guide for implementing the Domain Driven Design with the ABP Framework.",
@ -268,9 +266,13 @@
"DomainVsApplicationLogic": "Domain Logic vs Application Logic", "DomainVsApplicationLogic": "Domain Logic vs Application Logic",
"SamplesAndDiscussions": "Samples & Discussions", "SamplesAndDiscussions": "Samples & Discussions",
"EmailNotValid": "Please enter a valid email address.", "EmailNotValid": "Please enter a valid email address.",
"WeWillSendYouADownloadLink": "A link to download the e-book has been sent to {0}.<br/> Check your inbox / junk / spam boxes!", "WeWillSendYouADownloadLink": "A link to download the e-book has been sent to {0}. Check your inbox, junk or spam boxes!",
"GoHome": "Go Home", "GoHome": "Go Home",
"InvalidFormInputs": "Please, type the valid information specified on the form.", "InvalidFormInputs": "Please, type the valid information specified on the form.",
"DDDBookEmailBody": "Thank you. <br /> To download your book, <a href=\"{0}\">click here</a>." "DDDBookEmailBody": "Thank you. <br /> To download your book, <a href=\"{0}\">click here</a>.",
"SubscribeToNewsletter": "Subscribe to the newsletter to get information about happenings in the ABP.IO Platform, like new releases, articles, offers, and more.",
"FirstEdition": "First Edition",
"ThankYou": "Thank you!",
"CheckboxMandatory": "You need to check this to proceed!"
} }
} }

2
abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fr.json

@ -155,7 +155,7 @@
"Code": "Code", "Code": "Code",
"Result": "Résultat", "Result": "Résultat",
"SeeTheDocumentForMoreInformation": "Consultez le <a href=\"{1}\"> {0} document </a> pour plus d'informations", "SeeTheDocumentForMoreInformation": "Consultez le <a href=\"{1}\"> {0} document </a> pour plus d'informations",
"IndexPageHeroSection": "<span class = \"first-line shine\"> <strong> open source </strong> </span> <span class = \"second-line text-uppercase\"> Application Web <br /> Framework </span> <span class = \"troisième ligne shine2\"> <strong> pour asp.net core </strong> </span>", "IndexPageHeroSection": "<span class=\"first-line shine\"><strong>open source</strong></span><span class=\"second-line text-uppercase\">Web Application<br />Framework </span><span class=\"third-line shine2\"><strong>for asp.net core</strong></span>",
"UiFramework": "Framework de l'interface utilisateur", "UiFramework": "Framework de l'interface utilisateur",
"EmailAddress": "Adresse e-mail", "EmailAddress": "Adresse e-mail",
"Mobile": "Mobile", "Mobile": "Mobile",

16
abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hi.json

@ -94,7 +94,7 @@
"DynamicForms": "गतिशील रूप", "DynamicForms": "गतिशील रूप",
"BundlingMinification": "बंडलिंग और न्यूनतमकरण", "BundlingMinification": "बंडलिंग और न्यूनतमकरण",
"BackgroundJobs": "बैकग्राउंड जॉब्स", "BackgroundJobs": "बैकग्राउंड जॉब्स",
"BackgroundJobsExplanation": "सरल कक्षाओं को परिभाषित करें ताकि पृष्ठभूमि में नौकरियों को निष्पादित किया जा सके। अंतर्निहित नौकरी प्रबंधक का उपयोग करें या अपने स्वयं के एकीकृत करें। <a href=\" जटिलताओं0 Ideal\"> Hangfire </a> और <a href=\" जटिलताओं1 Ideal\"> RabbitMQ </a> एकीकरण पहले से ही उपलब्ध हैं।", "BackgroundJobsExplanation": "कतारबद्ध के रूप में पृष्ठभूमि में कार्य निष्पादित करने के लिए सरल वर्गों को परिभाषित करें। बिल्ट-इन जॉब मैनेजर का उपयोग करें या अपना खुद का एकीकृत करें। <a href=\"{0}\">Hangfire</a> और <a href=\"{1}\">RabbitMQ</a> एकीकरण पहले से ही उपलब्ध हैं।",
"DDDInfrastructure": "डीडीडी इन्फ्रास्ट्रक्चर", "DDDInfrastructure": "डीडीडी इन्फ्रास्ट्रक्चर",
"DomainDrivenDesignInfrastructure": "डोमेन संचालित डिज़ाइन इन्फ्रास्ट्रक्चर", "DomainDrivenDesignInfrastructure": "डोमेन संचालित डिज़ाइन इन्फ्रास्ट्रक्चर",
"AutoRESTAPIs": "ऑटो रीस्ट एपीआई", "AutoRESTAPIs": "ऑटो रीस्ट एपीआई",
@ -104,7 +104,7 @@
"TestInfrastructure": "टेस्ट इन्फ्रास्ट्रक्चर", "TestInfrastructure": "टेस्ट इन्फ्रास्ट्रक्चर",
"AuditLoggingEntityHistories": "ऑडिट लॉगिंग और इकाई इतिहास", "AuditLoggingEntityHistories": "ऑडिट लॉगिंग और इकाई इतिहास",
"ObjectToObjectMapping": "ऑब्जेक्ट टू ऑब्जेक्ट मैपिंग", "ObjectToObjectMapping": "ऑब्जेक्ट टू ऑब्जेक्ट मैपिंग",
"ObjectToObjectMappingExplanation": "AutoMapper एकीकरण के साथ अमूर्तता के लिए <a href=\" जटिलताओं0directory\"> ऑब्जेक्ट मैपिंग पर ऑब्जेक्ट </a>।", "ObjectToObjectMappingExplanation": "ऑटोमैपर एकीकरण के साथ <a href=\"{0}\">ऑब्जेक्ट टू ऑब्जेक्ट मैपिंग</a> एब्स्ट्रैक्शन।",
"EmailSMSAbstractions": "ईमेल और एसएमएस अंश", "EmailSMSAbstractions": "ईमेल और एसएमएस अंश",
"EmailSMSAbstractionsWithTemplatingSupport": "ईमेल और एसएमएस अंशांकन समर्थन के साथ", "EmailSMSAbstractionsWithTemplatingSupport": "ईमेल और एसएमएस अंशांकन समर्थन के साथ",
"Localization": "स्थानीयकरण", "Localization": "स्थानीयकरण",
@ -154,8 +154,8 @@
"AndMore": "और अधिक...", "AndMore": "और अधिक...",
"Code": "कोड", "Code": "कोड",
"Result": "परिणाम", "Result": "परिणाम",
"SeeTheDocumentForMoreInformation": "अधिक जानकारी के लिए <a href=\"find1 Ideal\"> {0} दस्तावेज़ </a> देखें", "SeeTheDocumentForMoreInformation": "अधिक जानकारी के लिए <a href=\"{1}\">{0} दस्तावेज़</a> देखें",
"IndexPageHeroSection": "<स्पैन क्लास = \"फर्स्ट-लाइन शाइन\"> <strong> ओपन सोर्स </ strong> </ span> <स्पैन क्लास = \"सेकंड-लाइन टेक्स्ट-अपरकेस\"> वेब एप्लिकेशन <br /> फ्रेमवर्क </ span> <span class = \"third-line shine2\"> <strong> asp.net core के लिए </ strong> </ span>", "IndexPageHeroSection": "<span class=\"first-line shine\"><strong>open source</strong></span><span class=\"second-line text-uppercase\">Web Application<br />Framework </span><span class=\"third-line shine2\"><strong>for asp.net core</strong></span>",
"UiFramework": "यूआई फ्रेमवर्क", "UiFramework": "यूआई फ्रेमवर्क",
"EmailAddress": "ईमेल पता", "EmailAddress": "ईमेल पता",
"Mobile": "मोबाइल", "Mobile": "मोबाइल",
@ -169,13 +169,13 @@
"JoinTheABPCommunityInfo": "एक जीवंत समुदाय के साथ शामिल हों और ABP फ्रेमवर्क में योगदानकर्ता बनें!", "JoinTheABPCommunityInfo": "एक जीवंत समुदाय के साथ शामिल हों और ABP फ्रेमवर्क में योगदानकर्ता बनें!",
"AllArticles": "सभी चीज़ें", "AllArticles": "सभी चीज़ें",
"SubmitYourArticle": "अपना लेख प्रस्तुत करें", "SubmitYourArticle": "अपना लेख प्रस्तुत करें",
"DynamicClientProxyDocument": "<a href=\" जटिलताओं0 Ideal\"> JavaScript </a> और <a href=\" जटिलताओं1 Ideal\"> C # </a> के लिए डायनेमिक क्लाइंट प्रॉक्सी दस्तावेज़ देखें।", "DynamicClientProxyDocument": "<a href=\"{0}\">JavaScript</a> और <a href=\"{1}\">C#</a> के लिए गतिशील क्लाइंट प्रॉक्सी दस्तावेज़ देखें।",
"EmailSMSAbstractionsDocument": "अधिक जानकारी के लिए <a href=\"lights0 Ideal\"> ईमेल करना </a> और <a href=\" जटिलताओं1 Ideal\"> एसएमएस भेजने </a> के दस्तावेज़ देखें।", "EmailSMSAbstractionsDocument": "अधिक जानकारी के लिए <a href=\"{0}\">ईमेलिंग</a> और <a href=\"{1}\">एसएमएस भेजना</a> दस्तावेज़ देखें।",
"CreateProjectWizard": "यह विज़ार्ड स्टार्टअप टेम्प्लेट से एक नई परियोजना बनाता है जो आपकी परियोजना को शुरू करने के लिए ठीक से कॉन्फ़िगर किया गया है।", "CreateProjectWizard": "यह विज़ार्ड स्टार्टअप टेम्प्लेट से एक नई परियोजना बनाता है जो आपकी परियोजना को शुरू करने के लिए ठीक से कॉन्फ़िगर किया गया है।",
"TieredOption": "एक ऐसा समाधान तैयार करता है जहाँ वेब और Http API परतें शारीरिक रूप से अलग हो जाती हैं। यदि जांच नहीं की जाती है, तो एक स्तरित समाधान बनाता है जो कम जटिल है और अधिकांश परिदृश्यों के लिए उपयुक्त है।", "TieredOption": "एक ऐसा समाधान तैयार करता है जहाँ वेब और Http API परतें शारीरिक रूप से अलग हो जाती हैं। यदि जांच नहीं की जाती है, तो एक स्तरित समाधान बनाता है जो कम जटिल है और अधिकांश परिदृश्यों के लिए उपयुक्त है।",
"SeparateIdentityServerOption": "सर्वर एप्लिकेशन को दो अनुप्रयोगों में अलग करता है: पहला पहचान सर्वर के लिए है और दूसरा आपके सर्वर साइड HTTP एपीआई के लिए है।", "SeparateIdentityServerOption": "सर्वर एप्लिकेशन को दो अनुप्रयोगों में अलग करता है: पहला पहचान सर्वर के लिए है और दूसरा आपके सर्वर साइड HTTP एपीआई के लिए है।",
"UseslatestPreVersion": "नवीनतम पूर्व-रिलीज़ संस्करण का उपयोग करता है", "UseslatestPreVersion": "नवीनतम पूर्व-रिलीज़ संस्करण का उपयोग करता है",
"ReadTheDocumentation": "<स्पैन क्लास = \"टेक्स्ट-प्राइमरी\"> पढ़ें </ span> <स्पैन क्लास = \"टेक्स्ट-सक्सेस\"> डॉक्यूमेंटेशन </ span>", "ReadTheDocumentation": "<span class=\"text-primary\">पढ़ें</span><span class=\"text-success\">दस्तावेज़ीकरण</span>",
"Documentation": "प्रलेखन", "Documentation": "प्रलेखन",
"GettingStartedTutorial": "स्टार्टिंग ट्यूटोरियल", "GettingStartedTutorial": "स्टार्टिंग ट्यूटोरियल",
"ApplicationDevelopmentTutorial": "अनुप्रयोग विकास ट्यूटोरियल", "ApplicationDevelopmentTutorial": "अनुप्रयोग विकास ट्यूटोरियल",
@ -183,7 +183,7 @@
"InstallABPCLIInfo": "एबीपी सीएलआई एबीपी ढांचे के साथ एक नया समाधान शुरू करने का सबसे तेज़ तरीका है। कमांड लाइन विंडो का उपयोग करके ABP CLI स्थापित करें:", "InstallABPCLIInfo": "एबीपी सीएलआई एबीपी ढांचे के साथ एक नया समाधान शुरू करने का सबसे तेज़ तरीका है। कमांड लाइन विंडो का उपयोग करके ABP CLI स्थापित करें:",
"DifferentLevelOfNamespaces": "आप विभिन्न स्तरों के नामस्थानों का उपयोग कर सकते हैं; जैसे BookStore, Acme.BookStore या Acme.Retail.BookStore।", "DifferentLevelOfNamespaces": "आप विभिन्न स्तरों के नामस्थानों का उपयोग कर सकते हैं; जैसे BookStore, Acme.BookStore या Acme.Retail.BookStore।",
"ABPCLIExamplesInfo": "<strong> नया </ strong> कमांड डेटाबेस प्रदाता के रूप में <strong> एंटिटी फ्रेमवर्क कोर </ strong> के साथ <strong> स्तरित MVC एप्लिकेशन </ strong> बनाता है। हालांकि, इसके पास अतिरिक्त विकल्प हैं। उदाहरण:", "ABPCLIExamplesInfo": "<strong> नया </ strong> कमांड डेटाबेस प्रदाता के रूप में <strong> एंटिटी फ्रेमवर्क कोर </ strong> के साथ <strong> स्तरित MVC एप्लिकेशन </ strong> बनाता है। हालांकि, इसके पास अतिरिक्त विकल्प हैं। उदाहरण:",
"SeeCliDocumentForMoreInformation": "अधिक विकल्पों के लिए <a href=\"lights0 Ideal\"> ABP CLI दस्तावेज़ </a> देखें या ऊपर \"डायरेक्ट डाउनलोड\" टैब चुनें।", "SeeCliDocumentForMoreInformation": "अधिक विकल्पों के लिए <a href=\"{0}\">ABP CLI दस्तावेज़</a> देखें या ऊपर \"डायरेक्ट डाउनलोड\" टैब चुनें।",
"Optional": "ऐच्छिक", "Optional": "ऐच्छिक",
"LocalFrameworkRef": "फ्रेमवर्क पैकेज के लिए स्थानीय प्रोजेक्ट संदर्भ रखें।", "LocalFrameworkRef": "फ्रेमवर्क पैकेज के लिए स्थानीय प्रोजेक्ट संदर्भ रखें।",
"BlobStoring": "ब्लॉब भंडारण", "BlobStoring": "ब्लॉब भंडारण",

4
abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/it.json

@ -155,7 +155,7 @@
"Code": "Codice", "Code": "Codice",
"Result": "Risultato", "Result": "Risultato",
"SeeTheDocumentForMoreInformation": "Consulta il <a href=\"{1}\"> {0} documento </a> per ulteriori informazioni", "SeeTheDocumentForMoreInformation": "Consulta il <a href=\"{1}\"> {0} documento </a> per ulteriori informazioni",
"IndexPageHeroSection": "<span class = \"first-line shine\"> <strong> open source </strong> </span> <span class = \"second-line text-uppercase\"> Framework <br /> applicazione web </span> <span class = \"third-line shine2\"> <strong> per asp.net core </strong> </span>", "IndexPageHeroSection": "<span class=\"first-line shine\"> <strong> open source </strong> </span> <span class=\"second-line text-uppercase\"> Framework <br /> applicazione web </span> <span class=\"third-line shine2\"> <strong> per asp.net core </strong> </span>",
"UiFramework": "Framework dell'interfaccia utente", "UiFramework": "Framework dell'interfaccia utente",
"EmailAddress": "Indirizzo e-mail", "EmailAddress": "Indirizzo e-mail",
"Mobile": "Mobile", "Mobile": "Mobile",
@ -175,7 +175,7 @@
"TieredOption": "Crea una soluzione a più livelli in cui i livelli API Web e Http sono fisicamente separati. Se non selezionata, crea una soluzione a più livelli meno complessa e adatta alla maggior parte degli scenari.", "TieredOption": "Crea una soluzione a più livelli in cui i livelli API Web e Http sono fisicamente separati. Se non selezionata, crea una soluzione a più livelli meno complessa e adatta alla maggior parte degli scenari.",
"SeparateIdentityServerOption": "Separa il lato server in due applicazioni: la prima è per il server di identità e la seconda è per l'API HTTP lato server.", "SeparateIdentityServerOption": "Separa il lato server in due applicazioni: la prima è per il server di identità e la seconda è per l'API HTTP lato server.",
"UseslatestPreVersion": "Utilizza l'ultima versione pre-rilascio", "UseslatestPreVersion": "Utilizza l'ultima versione pre-rilascio",
"ReadTheDocumentation": "<span class = \"text-primary\"> Leggi </span> <span class = \"text-success\"> La documentazione </span>", "ReadTheDocumentation": "<span class=\"text-primary\"> Leggi </span> <span class=\"text-success\"> La documentazione </span>",
"Documentation": "Documentazione", "Documentation": "Documentazione",
"GettingStartedTutorial": "Tutorial introduttivo", "GettingStartedTutorial": "Tutorial introduttivo",
"ApplicationDevelopmentTutorial": "Tutorial sullo sviluppo di applicazioni", "ApplicationDevelopmentTutorial": "Tutorial sullo sviluppo di applicazioni",

6
abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json

@ -218,8 +218,6 @@
"Surname": "Soyad", "Surname": "Soyad",
"CompanyName": "Şirket adı", "CompanyName": "Şirket adı",
"DoYouAgreePrivacyPolicy": "Şartlar & Koşulları ve <a href=\"https://commercial.abp.io/Privacy\">Gizlilik Politikasını</a> kabul ediyorum.", "DoYouAgreePrivacyPolicy": "Şartlar & Koşulları ve <a href=\"https://commercial.abp.io/Privacy\">Gizlilik Politikasını</a> kabul ediyorum.",
"VolosoftMarketingInformationMessage": "İşletmeler ve Organizasyonlar için çözümler ve diğer Volosoft ürün ve hizmetleri hakkında bilgi, ipucu ve teklifler almak istiyorum.",
"VolosoftSharingInformationMessage": "Volosoft'un ürünlerimi seçkin ortaklarla paylaşmasını kabul ediyorum, böylece ilgili ortakların ürünleri ve hizmetleri hakkında ilgili bilgileri alabilirim.",
"Free": "Ücretsiz", "Free": "Ücretsiz",
"DDDEBook": "DDD E-kitap", "DDDEBook": "DDD E-kitap",
"PracticalGuideForImplementingDDD": "Bu kitap ABP Framework ile birlikte Domain Driven Design'ın uygulanması için pratik bir kılavuz görevi görür.", "PracticalGuideForImplementingDDD": "Bu kitap ABP Framework ile birlikte Domain Driven Design'ın uygulanması için pratik bir kılavuz görevi görür.",
@ -233,6 +231,8 @@
"WeWillSendYouADownloadLink": "{0} adresine email gönderilmiştir.", "WeWillSendYouADownloadLink": "{0} adresine email gönderilmiştir.",
"GoHome": "Anasayfaya Dön", "GoHome": "Anasayfaya Dön",
"InvalidFormInputs": "Lütfen formda belirtilen geçerli bilgileri yazınız.", "InvalidFormInputs": "Lütfen formda belirtilen geçerli bilgileri yazınız.",
"DDDBookEmailBody": "Teşekkürler. <br /> Kitabı indirmek için, <a href=\"{0}\">buraya tıklayınız</a>." "DDDBookEmailBody": "Teşekkürler. <br /> Kitabı indirmek için, <a href=\"{0}\">buraya tıklayınız</a>.",
"SubscribeToNewsletter": "ABP.IO Platform'u ile ilgili yeni haberler, makaleler, teklifler ve daha fazlası gibi gelişmeler hakkında bilgi almak için bültene abone olun.",
"FirstEdition": "İlk Baskı"
} }
} }

16
docs/en/CLI.md

@ -42,6 +42,7 @@ Here, the list of all available commands before explaining their details:
* **`login`**: Authenticates on your computer with your [abp.io](https://abp.io/) username and password. * **`login`**: Authenticates on your computer with your [abp.io](https://abp.io/) username and password.
* **`logout`**: Logouts from your computer if you've authenticated before. * **`logout`**: Logouts from your computer if you've authenticated before.
* **`bundle`**: Generates script and style references for an ABP Blazor project. * **`bundle`**: Generates script and style references for an ABP Blazor project.
* **`install-libs`**: Install NPM Packages for MVC / Razor Pages and Blazor Server UI types.
### help ### help
@ -433,3 +434,18 @@ abp bundle [options]
`bundle` command reads the `appsettings.json` file inside the Blazor project for bundling options. For more details about managing style and script references in Blazor apps, see [Managing Global Scripts & Styles](UI/Blazor/Global-Scripts-Styles.md) `bundle` command reads the `appsettings.json` file inside the Blazor project for bundling options. For more details about managing style and script references in Blazor apps, see [Managing Global Scripts & Styles](UI/Blazor/Global-Scripts-Styles.md)
### install-libs
This command install NPM Packages for MVC / Razor Pages and Blazor Server UI types. Its **executing directory** or passed ```--working-directory``` parameter's directory must contain a project file(*.csproj).
`install-libs` command reads the `abp.resourcemapping.js` file to manage package. For more details see [Client Side Package Management](UI/AspNetCore/Client-Side-Package-Management.md).
Usage:
````bash
abp install-libs [options]
````
#### Options
* ```--working-directory``` or ```-wd```: Specifies the working directory. This option is useful when executing directory doesn't contain a project file.

199
docs/en/Community-Articles/2020-04-27-Use-Azure-Active-Directory-Authentication-for-MVC-Razor-Page-Applications/POST.md

@ -6,23 +6,21 @@ Adding Azure Active Directory is pretty straightforward in ABP framework. Couple
Two different **alternative approaches** for AzureAD integration will be demonstrated for better coverage. Two different **alternative approaches** for AzureAD integration will be demonstrated for better coverage.
1. ~~**AddAzureAD**: This approach uses Microsoft [AzureAD UI nuget package](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.AzureAD.UI/) which is very popular when users search the web about how to integrate AzureAD to their web application.~~ Now marked **Obsolete** (see https://github.com/aspnet/Announcements/issues/439). 1. **AddOpenIdConnect**: This approach uses default [OpenIdConnect](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.OpenIdConnect/) which can be used for not only AzureAD but for all OpenId connections.
2. **AddOpenIdConnect**: This approach uses default [OpenIdConnect](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.OpenIdConnect/) which can be used for not only AzureAD but for all OpenId connections.
3. **AddMicrosoftIdentityWebAppAuthentication:** This approach uses newly introduced [Microsoft.Identity.Web nuget package](https://www.nuget.org/packages/Microsoft.Identity.Web/) to replace AddAzureAD. 3. **AddMicrosoftIdentityWebAppAuthentication:** This approach uses newly introduced [Microsoft.Identity.Web nuget package](https://www.nuget.org/packages/Microsoft.Identity.Web/) to replace AddAzureAD.
3. ~~**AddAzureAD**: This approach uses Microsoft [AzureAD UI nuget package](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.AzureAD.UI/) which is very popular when users search the web about how to integrate AzureAD to their web application.~~ Now marked **Obsolete** (see https://github.com/aspnet/Announcements/issues/439).
> There is **no difference** in functionality between these approaches. AddAzureAD is an abstracted way of OpenIdConnection ([source](https://github.com/dotnet/aspnetcore/blob/c56aa320c32ee5429d60647782c91d53ac765865/src/Azure/AzureAD/Authentication.AzureAD.UI/src/AzureADAuthenticationBuilderExtensions.cs#L122)) with predefined cookie settings. > There is **no difference** in functionality between these approaches. AddAzureAD is an abstracted way of OpenIdConnection ([source](https://github.com/dotnet/aspnetcore/blob/c56aa320c32ee5429d60647782c91d53ac765865/src/Azure/AzureAD/Authentication.AzureAD.UI/src/AzureADAuthenticationBuilderExtensions.cs#L122)) with predefined cookie settings.
> >
> However there are key differences in integration to ABP applications because of default configurated signin schemes which will be explained below. > However there are key differences in integration to ABP applications because of default configurated signin schemes which will be explained below.
## 1. AddAzureAD ## 1. AddOpenIdConnect
This approach uses the most common way to integrate AzureAD by using the [Microsoft AzureAD UI nuget package](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.AzureAD.UI/). If you don't want to use an extra nuget package in your application, you can use the straight default [OpenIdConnect](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.OpenIdConnect/) which can be used for all OpenId connections including AzureAD external authentication.
If you choose this approach, you will need to install `Microsoft.AspNetCore.Authentication.AzureAD.UI` package to your **.Web** project. Also, since AddAzureAD extension uses [configuration binding](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1#default-configuration), you need to update your appsettings.json file located in your **.Web** project.
#### **Updating `appsettings.json`** You don't have to use `appsettings.json` configuration but it is a good practice to set AzureAD information in the `appsettings.json`.
You need to add a new section to your `appsettings.json` which will be binded to configuration when configuring the `OpenIdConnectOptions`: To get the AzureAD information from `appsettings.json`, which will be used in `OpenIdConnectOptions` configuration, simply add a new section to `appsettings.json` located in your **.Web** project:
````json ````json
"AzureAd": { "AzureAd": {
@ -34,63 +32,90 @@ You need to add a new section to your `appsettings.json` which will be binded to
} }
```` ````
> Important configuration here is the CallbackPath. This value must be the same with one of your Azure AD-> app registrations-> Authentication -> RedirectUri. Then, In your **.Web** project; you can modify the `ConfigureAuthentication` method located in your **ApplicationWebModule** with the following:
Then, you need to configure the `OpenIdConnectOptions` to complete the integration.
#### Configuring OpenIdConnectOptions
In your **.Web** project, locate your **ApplicationWebModule** and modify `ConfigureAuthentication` method with the following:
````csharp ````csharp
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration) private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{ {
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);
context.Services.AddAuthentication() context.Services.AddAuthentication()
.AddIdentityServerAuthentication(options => ... //Omitted other third party configurations
{ .AddOpenIdConnect("AzureOpenId", "Azure Active Directory OpenId", options =>
options.Authority = configuration["AuthServer:Authority"]; {
options.Authority = "https://login.microsoftonline.com/" + configuration["AzureAd:TenantId"] + "/v2.0/";
options.ClientId = configuration["AzureAd:ClientId"];
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.CallbackPath = configuration["AzureAd:CallbackPath"];
options.ClientSecret = configuration["AzureAd:ClientSecret"];
options.RequireHttpsMetadata = false; options.RequireHttpsMetadata = false;
options.ApiName = "Acme.BookStore"; options.SaveTokens = true;
}) options.GetClaimsFromUserInfoEndpoint = true;
.AddAzureAD(options => configuration.Bind("AzureAd", options)); options.Scope.Add("email");
context.Services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options => options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");
});
}
````
> **Don't forget to:**
>
> * Add `options.Scope.Add("email");` since [default signin scheme is `AzureADOpenID`](https://github.com/dotnet/aspnetcore/blob/c56aa320c32ee5429d60647782c91d53ac765865/src/Azure/AzureAD/Authentication.AzureAD.UI/src/AzureADOpenIdConnectOptionsConfiguration.cs#L35).
> * Add `options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");`. Mapping this to [ClaimTypes.NameIdentifier](https://github.com/dotnet/runtime/blob/6d395de48ac718a913e567ae80961050f2a9a4fa/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimTypes.cs#L59) is important since default SignIn Manager behavior uses this claim type for external login information.
And that's it, integration is completed. Keep on mind that you can connect any other external authentication providers.
## 2. Alternative Approach: AddMicrosoftIdentityWebApp
With .Net 5.0, AzureAd is marked [obsolete](https://github.com/dotnet/aspnetcore/issues/25807) and will not be supported in the near future. However its expanded functionality is available in [microsoft-identity-web](https://github.com/AzureAD/microsoft-identity-web/wiki) packages.
Add (or replace with) the new nuget package Microsoft.Identity.Web nuget package](https://www.nuget.org/packages/Microsoft.Identity.Web/).
In your **.Web** project; you update the `ConfigureAuthentication` method located in your **ApplicationWebModule** with the following while having the AzureAd appsettings section as defined before:
````csharp
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddAuthentication()
... //Omitted other third party configurations
.AddMicrosoftIdentityWebApp(configuration.GetSection("AzureAd"));
context.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{ {
options.Authority = options.Authority + "/v2.0/"; options.Authority = "https://login.microsoftonline.com/" + configuration["AzureAd:TenantId"] + "/v2.0/";
options.ClientId = configuration["AzureAd:ClientId"]; options.ClientId = configuration["AzureAd:ClientId"];
options.CallbackPath = configuration["AzureAd:CallbackPath"];
options.ResponseType = OpenIdConnectResponseType.CodeIdToken; options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.CallbackPath = configuration["AzureAd:CallbackPath"];
options.ClientSecret = configuration["AzureAd:ClientSecret"];
options.RequireHttpsMetadata = false; options.RequireHttpsMetadata = false;
options.SaveTokens = false;
options.TokenValidationParameters.ValidateIssuer = false;
options.GetClaimsFromUserInfoEndpoint = true; options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.SignInScheme = IdentityConstants.ExternalScheme;
options.Scope.Add("email"); options.SignInScheme = IdentityConstants.ExternalScheme;
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");
}); });
} }
```` ````
And that's all to add new Microsoft-Identity-Web.
> **Don't forget to:** > **Don't forget to:**
> >
> * Add `.AddAzureAD(options => configuration.Bind("AzureAd", options))` after `.AddAuthentication()`. This binds your AzureAD appsettings and easy to miss out.
> * Add `JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear()`. This will disable the default Microsoft claim type mapping.
> * Add `JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier)`. Mapping this to [ClaimTypes.NameIdentifier](https://github.com/dotnet/runtime/blob/6d395de48ac718a913e567ae80961050f2a9a4fa/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimTypes.cs#L59) is important since default SignIn Manager behavior uses this claim type for external login information.
> * Add `options.SignInScheme = IdentityConstants.ExternalScheme` since [default signin scheme is `AzureADOpenID`](https://github.com/dotnet/aspnetcore/blob/c56aa320c32ee5429d60647782c91d53ac765865/src/Azure/AzureAD/Authentication.AzureAD.UI/src/AzureADOpenIdConnectOptionsConfiguration.cs#L35). > * Add `options.SignInScheme = IdentityConstants.ExternalScheme` since [default signin scheme is `AzureADOpenID`](https://github.com/dotnet/aspnetcore/blob/c56aa320c32ee5429d60647782c91d53ac765865/src/Azure/AzureAD/Authentication.AzureAD.UI/src/AzureADOpenIdConnectOptionsConfiguration.cs#L35).
> * Add `options.Scope.Add("email")` if you are using **v2.0** endpoint of AzureAD since v2.0 endpoint doesn't return the `email` claim as default. The [Account Module](https://docs.abp.io/en/abp/latest/Modules/Account) uses `email` claim to [register external users](https://github.com/abpframework/abp/blob/be32a55449e270d2d456df3dabdc91f3ffdd4fa9/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs#L215). > * Add `options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");`. Mapping this to [ClaimTypes.NameIdentifier](https://github.com/dotnet/runtime/blob/6d395de48ac718a913e567ae80961050f2a9a4fa/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimTypes.cs#L59) is important since default SignIn Manager behavior uses this claim type for external login information.
You are done and integration is completed. Keep in mind that [Microsoft-Identity-Web](https://github.com/AzureAD/microsoft-identity-web) is relatively new and keeps getting new enhancements, features and documentation.
## 2. Alternative Approach: AddOpenIdConnect ## 3. Obsolete Alternative Approach: AddAzureAD
If you don't want to use an extra nuget package in your application, you can use the straight default [OpenIdConnect](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.OpenIdConnect/) which can be used for all OpenId connections including AzureAD external authentication. This approach uses the most common way to integrate AzureAD by using the [Microsoft AzureAD UI nuget package](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.AzureAD.UI/).
You don't have to use `appsettings.json` configuration but it is a good practice to set AzureAD information in the `appsettings.json`. If you choose this approach, you will need to install `Microsoft.AspNetCore.Authentication.AzureAD.UI` package to your **.Web** project. Also, since AddAzureAD extension uses [configuration binding](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1#default-configuration), you need to update your appsettings.json file located in your **.Web** project.
To get the AzureAD information from `appsettings.json`, which will be used in `OpenIdConnectOptions` configuration, simply add a new section to `appsettings.json` located in your **.Web** project: #### **Updating `appsettings.json`**
You need to add a new section to your `appsettings.json` which will be binded to configuration when configuring the `OpenIdConnectOptions`:
````json ````json
"AzureAd": { "AzureAd": {
@ -102,74 +127,49 @@ To get the AzureAD information from `appsettings.json`, which will be used in `O
} }
```` ````
Then, In your **.Web** project; you can modify the `ConfigureAuthentication` method located in your **ApplicationWebModule** with the following: > Important configuration here is the CallbackPath. This value must be the same with one of your Azure AD-> app registrations-> Authentication -> RedirectUri.
````csharp
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);
context.Services.AddAuthentication()
.AddIdentityServerAuthentication(options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = false;
options.ApiName = "BookStore";
})
.AddOpenIdConnect("AzureOpenId", "Azure Active Directory OpenId", options =>
{
options.Authority = "https://login.microsoftonline.com/" + configuration["AzureAd:TenantId"] + "/v2.0/";
options.ClientId = configuration["AzureAd:ClientId"];
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.CallbackPath = configuration["AzureAd:CallbackPath"];
options.RequireHttpsMetadata = false;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("email");
});
}
````
And that's it, integration is completed. Keep on mind that you can connect any other external authentication providers.
## 3. AddMicrosoftIdentityWebAppAuthentication
With .Net 5.0, AzureAd is marked [obsolete](https://github.com/dotnet/aspnetcore/issues/25807) and will not be supported in the near future. However its expanded functionality is available in [microsoft-identity-web](https://github.com/AzureAD/microsoft-identity-web/wiki) packages. Then, you need to configure the `OpenIdConnectOptions` to complete the integration.
Add (or replace with) the new nuget package Microsoft.Identity.Web nuget package](https://www.nuget.org/packages/Microsoft.Identity.Web/). #### Configuring OpenIdConnectOptions
In your **.Web** project; you update the `ConfigureAuthentication` method located in your **ApplicationWebModule** with the following while having the AzureAd appsettings section as defined before: In your **.Web** project, locate your **ApplicationWebModule** and modify `ConfigureAuthentication` method with the following:
````csharp ````csharp
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration) private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{ {
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);
context.Services.AddAuthentication() context.Services.AddAuthentication()
.AddIdentityServerAuthentication(options => ... //Omitted other third party configurations
{ .AddAzureAD(options => configuration.Bind("AzureAd", options));
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = false; context.Services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
options.ApiName = "Acme.BookStore"; {
}); options.Authority = options.Authority + "/v2.0/";
options.ClientId = configuration["AzureAd:ClientId"];
context.Services.AddMicrosoftIdentityWebAppAuthentication( options.CallbackPath = configuration["AzureAd:CallbackPath"];
configuration: configuration, options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
configSectionName: "AzureAd", options.RequireHttpsMetadata = false;
openIdConnectScheme:"AzureAD",
cookieScheme:null); options.TokenValidationParameters.ValidateIssuer = false;
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.SignInScheme = IdentityConstants.ExternalScheme;
options.Scope.Add("email");
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");
});
} }
```` ````
And that's all to add new Microsoft-Identity-Web.
> **Don't forget to:** > **Don't forget to:**
> >
> * Pass **cookieScheme** parameter as **null** or your [*GetExternalLoginInfoAsync* method will always return null](https://github.com/AzureAD/microsoft-identity-web/issues/133#). > * Add `.AddAzureAD(options => configuration.Bind("AzureAd", options))` after `.AddAuthentication()`. This binds your AzureAD appsettings and easy to miss out.
> * Add `options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");`. Mapping this to [ClaimTypes.NameIdentifier](https://github.com/dotnet/runtime/blob/6d395de48ac718a913e567ae80961050f2a9a4fa/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimTypes.cs#L59) is important since default SignIn Manager behavior uses this claim type for external login information.
> * Add `options.SignInScheme = IdentityConstants.ExternalScheme` since [default signin scheme is `AzureADOpenID`](https://github.com/dotnet/aspnetcore/blob/c56aa320c32ee5429d60647782c91d53ac765865/src/Azure/AzureAD/Authentication.AzureAD.UI/src/AzureADOpenIdConnectOptionsConfiguration.cs#L35).
> * Add `options.Scope.Add("email")` if you are using **v2.0** endpoint of AzureAD since v2.0 endpoint doesn't return the `email` claim as default. The [Account Module](https://docs.abp.io/en/abp/latest/Modules/Account) uses `email` claim to [register external users](https://github.com/abpframework/abp/blob/be32a55449e270d2d456df3dabdc91f3ffdd4fa9/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs#L215).
Keep in mind that [Microsoft-Identity-Web](https://github.com/AzureAD/microsoft-identity-web) is relatively new and keeps getting new enhancements, features and documentation. You are done and integration is completed.
## The Source Code ## The Source Code
@ -247,3 +247,14 @@ You can find the source code of the completed example [here](https://github.com/
await Task.CompletedTask; await Task.CompletedTask;
}); });
```` ````
* I get page not found error on redirection to **https://login.live.com/oauth20_authorize.srf?**!
* Probably you are trying to login with Microsoft account to Azure portal instead of the Azure AD account. Try azure AD user account for login instead of microsoft account. You can also check the answers for [this question](https://answers.microsoft.com/en-us/msoffice/forum/msoffice_o365admin-mso_dirservices-mso_o365b/cant-login-in-loginlivecom-with-a-ms-account-valid/6da991e6-9528-461a-9638-9c5680e95888) and [this question](https://docs.microsoft.com/en-us/answers/questions/34806/azure-ad-404-error-when-login-with-microsoft-accou.html) for more details.
# May 2021 Update
- **AddOpenIdConnect**: Removed `JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();` and added `sub` claim mapping in ClaimActions rather than global mapping.
- Updated `AddMicrosoftIdentityWebAppAuthentication ` to `AddMicrosoftIdentityWebApp`.
- Updated OpenIdConnect and AddMicrosoftIdentityWebApp configurations.
- Obsolete approach moved to third place in the list.

25
docs/en/Community-Articles/2020-09-16-How-to-Setup-Azure-Active-Directory-and-Integrate-Abp-Angular-Application/POST.md

@ -23,20 +23,9 @@ This means your application will be using AzureAD user store for authentication.
Lets start with adding OpenId connection. Open the **HttpApiHostModule.cs** and update the **ConfigureAuthentication** method as below: Lets start with adding OpenId connection. Open the **HttpApiHostModule.cs** and update the **ConfigureAuthentication** method as below:
```csharp ```csharp
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);
context.Services.AddAuthentication() context.Services.AddAuthentication()
.AddIdentityServerAuthentication(options => ... //Omitted other third party configurations
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = false;
options.ApiName = "NonTieredAngular";
options.JwtBackChannelHandler = new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};
})
.AddOpenIdConnect("AzureOpenId", "Azure AD OpenId", options => .AddOpenIdConnect("AzureOpenId", "Azure AD OpenId", options =>
{ {
options.Authority = "https://login.microsoftonline.com/" + configuration["AzureAd:TenantId"] + "/v2.0/"; options.Authority = "https://login.microsoftonline.com/" + configuration["AzureAd:TenantId"] + "/v2.0/";
@ -48,6 +37,8 @@ context.Services.AddAuthentication()
options.SaveTokens = true; options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true; options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("email"); options.Scope.Add("email");
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");
}); });
``` ```
@ -58,10 +49,7 @@ public override void ConfigureServices(ServiceConfigurationContext context)
{ {
var hostingEnvironment = context.Services.GetHostingEnvironment(); var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration(); var configuration = context.Services.GetConfiguration();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);
context.Services.AddAuthentication() context.Services.AddAuthentication()
.AddOpenIdConnect("AzureOpenId", "Azure AD OpenId", options => .AddOpenIdConnect("AzureOpenId", "Azure AD OpenId", options =>
{ {
@ -120,3 +108,8 @@ Next time you hit login, you should be seeing login screen enabled Azure AD like
* But I don't want my users to see default login screen. I want my users to login **only** from AzureAD. * But I don't want my users to see default login screen. I want my users to login **only** from AzureAD.
* You can **mimic** this behaviour by customizing the login page and instantly trigger Azure AD provider click. For more info, you can check [this article](https://community.abp.io/articles/how-to-customize-the-login-page-for-mvc-razor-page-applications-9a40f3cd). * You can **mimic** this behaviour by customizing the login page and instantly trigger Azure AD provider click. For more info, you can check [this article](https://community.abp.io/articles/how-to-customize-the-login-page-for-mvc-razor-page-applications-9a40f3cd).
# May 2021 Update
- **AddOpenIdConnect**: Removed `JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();` and added `sub` claim mapping in ClaimActions rather than global mapping.
- Updated OpenIdConnect configurations.

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

File diff suppressed because it is too large

4
docs/en/Domain-Driven-Design.md

@ -32,6 +32,6 @@ DDD mostly interest in the **Domain** and the **Application** layers, rather tha
* [Data Transfer Objects (DTOs)](Data-Transfer-Objects.md) * [Data Transfer Objects (DTOs)](Data-Transfer-Objects.md)
* [Unit of Work](Unit-Of-Work.md) * [Unit of Work](Unit-Of-Work.md)
## The Ultimate DDD Implementation Guide ## Free E-Book: Implementing DDD
See the [Implementing Domain Driven Design](Domain-Driven-Design-Implementation-Guide.md) guide as a **complete reference**. The Guide explains the Domain Driven Design and introduces explicit **rules and examples** to give a deep understanding of the **implementation details**. See the [Implementing Domain Driven Design book](https://abp.io/books/implementing-domain-driven-design) as a **complete reference**. This book explains the Domain Driven Design and introduces explicit **rules and examples** to give a deep understanding of the **implementation details**.

72
docs/en/Entity-Framework-Core.md

@ -604,23 +604,77 @@ ObjectExtensionManager.Instance
); );
```` ````
If the related module has implemented this feature (by using the `ConfigureEfCoreEntity` explained below), then the new property is added to the model. Then you need to run the standard `Add-Migration` and `Update-Database` commands to update your database to add the new field. ### MapEfCoreEntity
>`MapEfCoreProperty` method must be called before using the related `DbContext`. It is a static method. The best way is to use it in your application as earlier as possible. The application startup template has a `YourProjectNameEfCoreEntityExtensionMappings` class that is safe to use this method inside. `MapEfCoreEntity` is a shortcut extension method to configure the `Entity`.
### ConfigureEfCoreEntity **Example**: Set the max length of `Name` to the `IdentityRole` entity:
If you are building a reusable module and want to allow application developers to add properties to your entities, you can use the `ConfigureEfCoreEntity` extension method in your entity mapping. However, there is a shortcut extension method `ConfigureObjectExtensions` that can be used while configuring the entity mapping: ````csharp
ObjectExtensionManager.Instance
.MapEfCoreEntity<IdentityRole>(builder =>
{
builder.As<EntityTypeBuilder<IdentityRole>>().Property(x => x.Name).HasMaxLength(200);
});
````
### MapEfCoreDbContext
`MapEfCoreDbContext` is a shortcut extension method to configure the `DbContext`.
**Example**: Set the max length of `Name` to the `IdentityRole` entity of `IdentityDbContext`:
````csharp ````csharp
builder.Entity<YourEntity>(b => ObjectExtensionManager.Instance.MapEfCoreDbContext<IdentityDbContext>(b =>
{ {
b.ConfigureObjectExtensions(); b.Entity<IdentityRole>().Property(x => x.Name).HasMaxLength(200);
//...
}); });
```` ````
> If you call `ConfigureByConvention()` extension method (like `b.ConfigureByConvention()` for this example), ABP Framework internally calls the `ConfigureObjectExtensions` method. It is a **best practice** to use the `ConfigureByConvention()` method since it also configures database mapping for base properties by convention. If the related module has implemented this feature(explained below), then the new property is added to the model or the DbContext/Entity configure changed. Then you need to run the standard `Add-Migration` and `Update-Database` commands to update your database to add the new field.
> The `MapEfCoreProperty`, `MapEfCoreEntity` and `MapEfCoreDbContext` methods must be called before using the related `DbContext`. It is a static method. The best way is to use it in your application as earlier as possible. The application startup template has a `YourProjectNameEfCoreEntityExtensionMappings` class that is safe to use this method inside.
### ConfigureEfCoreEntity, ApplyObjectExtensionMappings and TryConfigureObjectExtensions
If you are building a reusable module and want to allow application developers to add properties to your entities, you can use the `ConfigureEfCoreEntity`, `ApplyObjectExtensionMappings` and `TryConfigureObjectExtensions` extension methods in your entity mapping.
**Example**:
````csharp
public static class QADbContextModelCreatingExtensions
{
public static void ConfigureQA(
this ModelBuilder builder,
Action<QAModelBuilderConfigurationOptions> optionsAction = null)
{
Check.NotNull(builder, nameof(builder));
var options = new QAModelBuilderConfigurationOptions(
QADatabaseDbProperties.DbTablePrefix,
QADatabaseDbProperties.DbSchema
);
optionsAction?.Invoke(options);
builder.Entity<QA_Question>(b =>
{
b.ToTable(options.TablePrefix + "Questions", options.Schema);
b.ConfigureByConvention();
//...
//Call this in the end of buildAction.
b.ApplyObjectExtensionMappings();
});
//...
//Call this in the end of ConfigureQA.
builder.TryConfigureObjectExtensions<QADbContext>();
}
}
````
> If you call `ConfigureByConvention()` extension method (like `b.ConfigureByConvention()` for this example), ABP Framework internally calls the `ConfigureObjectExtensions` and `ConfigureEfCoreEntity` methods. It is a **best practice** to use the `ConfigureByConvention()` method since it also configures database mapping for base properties by convention.
See the "*ConfigureByConvention Method*" section above for more information. See the "*ConfigureByConvention Method*" section above for more information.
@ -812,4 +866,4 @@ public class MyCustomEfCoreBulkOperationProvider
## See Also ## See Also
* [Entities](Entities.md) * [Entities](Entities.md)
* [Repositories](Repositories.md) * [Repositories](Repositories.md)

11
docs/en/Index.md

@ -29,8 +29,9 @@ ABP has a **comprehensive documentation** that not only explains the ABP Framewo
ABP offers a complete, modular and layered software architecture based on [Domain Driven Design](Domain-Driven-Design.md) principles and patterns. It also provides the necessary infrastructure to implement this architecture. ABP offers a complete, modular and layered software architecture based on [Domain Driven Design](Domain-Driven-Design.md) principles and patterns. It also provides the necessary infrastructure to implement this architecture.
* See the [Modularity](Module-Development-Basics.md) document to understand the module system. * See the [Modularity](Module-Development-Basics.md) document to understand the module system.
* [Implementing Domain Driven Design](Domain-Driven-Design-Implementation-Guide.md) document is an ultimate guide for who want to understand and implement the DDD. * [Implementing Domain Driven Design book](https://abp.io/books/implementing-domain-driven-design?ref=doc) is an ultimate guide for who want to understand and implement the DDD with the ABP Framework.
* [Microservice Architecture](Microservice-Architecture.md) document explains how ABP helps to create a microservice solution. * [Microservice Architecture](Microservice-Architecture.md) document explains how ABP helps to create a microservice solution.
* [Multi-Tenancy](Multi-Tenancy.md) document introduces multi-tenancy and explores the ABP multi-tenancy infrastructure.
### Infrastructure ### Infrastructure
@ -55,6 +56,14 @@ See the [Application Modules](Modules/Index.md) document for all pre-built modul
The [Startup templates](Startup-Templates/Index.md) are pre-built Visual Studio solution templates. You can create your own solution based on these templates to **immediately start your development**. The [Startup templates](Startup-Templates/Index.md) are pre-built Visual Studio solution templates. You can create your own solution based on these templates to **immediately start your development**.
## Free E-Book: Implementing Domain Driven Design
![Implementing Domain Driven Design](images/implementing-domain-driven-design-book.png)
A **practical guide** for implementing Domain Driven Design (DDD). While the implementation details are **based on the ABP Framework** infrastructure, the basic concepts, principles and models can be applied to any solution, even if it is not a .NET solution.
[Click here to get your free copy](https://abp.io/books/implementing-domain-driven-design?ref=doc).
## ABP Community ## ABP Community
### The Source Code ### The Source Code

190
docs/en/Modules/Setting-Management.md

@ -83,4 +83,192 @@ Setting Management module is extensible, just like the [setting system](../Setti
* `TenantSettingManagementProvider`: Gets or sets the setting value for a tenant. * `TenantSettingManagementProvider`: Gets or sets the setting value for a tenant.
* `UserSettingManagementProvider`: Gets the setting value for a user. * `UserSettingManagementProvider`: Gets the setting value for a user.
`ISettingManager` uses the setting management providers on get/set methods. Typically, every setting management provider defines extension methods on the `ISettingManagement` service (like `SetForUserAsync` defined by the user setting management provider). `ISettingManager` uses the setting management providers on get/set methods. Typically, every setting management provider defines extension methods on the `ISettingManagement` service (like `SetForUserAsync` defined by the user setting management provider).
## Setting Management UI
Setting Mangement module provided the email setting UI by default, and it is extensible; You can add your tabs to this page for your application settings.
### MVC UI
#### Create a setting View Component
Create `MySettingGroup` folder under the `Components` folder. Add a new view component. Name it as `MySettingGroupViewComponent`:
![MySettingGroupViewComponent](../images/my-setting-group-view-component.png)
Open the `MySettingGroupViewComponent.cs` and change the whole content as shown below:
```csharp
public class MySettingGroupViewComponent : AbpViewComponent
{
public virtual IViewComponentResult Invoke()
{
return View("~/Components/MySettingGroup/Default.cshtml");
}
}
```
> You can also use the `InvokeAsync` method, In this example, we use the `Invoke` method.
#### Default.cshtml
Create a `Default.cshtml` file under the `MySettingGroup` folder.
Open the `Default.cshtml` and change the whole content as shown below:
```html
<div>
<p>My setting group page</p>
</div>
```
#### BookStoreSettingPageContributor
Create a `BookStoreSettingPageContributor.cs` file under the `Settings` folder:
![BookStoreSettingPageContributor](../images/my-setting-group-page-contributor.png)
The content of the file is shown below:
```csharp
public class BookStoreSettingPageContributor : ISettingPageContributor
{
public Task ConfigureAsync(SettingPageCreationContext context)
{
context.Groups.Add(
new SettingPageGroup(
"Volo.Abp.MySettingGroup",
"MySettingGroup",
typeof(MySettingGroupViewComponent)
)
);
return Task.CompletedTask;
}
public Task<bool> CheckPermissionsAsync(SettingPageCreationContext context)
{
// You can check the permissions here
return Task.FromResult(true);
}
}
```
Open the `BookStoreWebModule.cs` file and add the following code:
```csharp
Configure<SettingManagementPageOptions>(options =>
{
options.Contributors.Add(new BookStoreSettingPageContributor());
});
```
#### Run the Application
Navigate to `/SettingManagement` route to see the changes:
![Custom Settings Tab](../images/my-setting-group-ui.png)
### Blazor UI
#### Create a Razor Component
Create `MySettingGroup` folder under the `Pages` folder. Add a new razor component. Name it as `MySettingGroupComponent`:
![MySettingGroupComponent](../images/my-setting-group-component.png)
Open the `MySettingGroupComponent.razor` and change the whole content as shown below:
```csharp
<Row>
<p>my setting group</p>
</Row>
```
#### BookStoreSettingComponentContributor
Create a `BookStoreSettingComponentContributor.cs` file under the `Settings` folder:
![BookStoreSettingComponentContributor](../images/my-setting-group-component-contributor.png)
The content of the file is shown below:
```csharp
public class BookStoreSettingComponentContributor : ISettingComponentContributor
{
public Task ConfigureAsync(SettingComponentCreationContext context)
{
context.Groups.Add(
new SettingComponentGroup(
"Volo.Abp.MySettingGroup",
"MySettingGroup",
typeof(MySettingGroupComponent)
)
);
return Task.CompletedTask;
}
public Task<bool> CheckPermissionsAsync(SettingComponentCreationContext context)
{
// You can check the permissions here
return Task.FromResult(true);
}
}
```
Open the `BookStoreBlazorModule.cs` file and add the following code:
```csharp
Configure<SettingManagementComponentOptions>(options =>
{
options.Contributors.Add(new BookStoreSettingComponentContributor());
});
```
#### Run the Application
Navigate to `/setting-management` route to see the changes:
![Custom Settings Tab](../images/my-setting-group-blazor.png)
### Angular UI
#### Create a Component
Create a component with the following command:
```bash
yarn ng generate component my-settings
```
Open the `app.component.ts` and modify the file as shown below:
```js
import { Component } from '@angular/core';
import { SettingTabsService } from '@abp/ng.core'; // imported SettingTabsService
import { MySettingsComponent } from './my-settings/my-settings.component'; // imported MySettingsComponent
@Component(/* component metadata */)
export class AppComponent {
constructor(private settingTabs: SettingTabsService) // injected MySettingsComponent
{
// added below
settingTabs.add([
{
name: 'MySettings',
order: 1,
requiredPolicy: 'policy key here',
component: MySettingsComponent,
},
]);
}
}
```
#### Run the Application
Navigate to `/setting-management` route to see the changes:
![Custom Settings Tab](../images/custom-settings.png)

106
docs/en/Modules/Tenant-Management.md

@ -1,3 +1,107 @@
# Tenant Management Module # Tenant Management Module
TODO [Multi-Tenancy](../Multi-Tenancy.md) is one of the core features of ABP Framework. It provides the fundamental infrastructure to build your own SaaS (Software-as-a-Service) solution. ABP's multi-tenancy system abstracts where your tenants are stored, by providing the `ITenantStore` interface. All you need to do is to implement that interface.
**The Tenant Management module is an implementation of the the `ITenantStore` interface. It stores tenants in a database. It also provides UI to manage your tenants and their [features](../Features.md).**
> Please **refer to the [Multi-Tenancy](../Multi-Tenancy.md) documentation** to understand the multi-tenancy system of the ABP Framework. This document focuses on the Tenant Management module.
### About the ABP Commercial SaaS Module
The [SaaS Module](https://commercial.abp.io/modules/Volo.Saas) is an alternative implementation of this module with more features and possibilities. It is distributed as a part of the [ABP Commercial](https://commercial.abp.io/) subscription.
## How to Install
This module comes as pre-installed (as [NuGet/NPM packages](NuGet/NPM packages)) when you [create a new solution](https://abp.io/get-started) with the ABP Framework. You can continue to use it as package and get updates easily, or you can include its source code into your solution (see `get-source` [CLI](../CLI.md) command) to develop your custom module.
### The Source Code
The source code of this module can be accessed [here](https://github.com/abpframework/abp/tree/dev/modules/tenant-management). The source code is licensed with [MIT](https://choosealicense.com/licenses/mit/), so you can freely use and customize it.
## User Interface
This module adds "*Administration -> Tenant Management -> Tenants*" menu item to the main menu of the application, which opens the page shown below:
![module-tenant-management-page](../images/module-tenant-management-page.png)
In this page, you see the all the tenants. You can create a new tenant as shown below:
![module-tenant-management-new-tenant](../images/module-tenant-management-new-tenant.png)
In this modal;
* **Name**: The unique name of the tenant. If you use subdomains for your tenants (like https://some-tenant.your-domain.com), this will be the subdomain name.
* **Admin Email Address**: Email address of the admin user for this tenant.
* **Admin Password**: The password of the admin user for this tenant.
When you click to *Actions* button near to a tenant, you will see the actions you can take:
![module-tenant-management-actions](../images/module-tenant-management-actions.png)
### Managing the Tenant Features
The Features action opens a modal to enable/disable/set [features](../Features.md) for the related tenant. Here, an example modal:
![features-modal](../images/features-modal.png)
### Managing the Host Features
*Manage Host features* button is used to set features for the host side, if you use the features of your application also in the host side.
## Internals
This section can be used as a reference if you want to [customize](../Customizing-Application-Modules-Guide.md) this module without changing [its source code](https://github.com/abpframework/abp/tree/dev/modules/tenant-management).
### Domain Layer
#### Aggregates
* `Tenant`
#### Repositories
* `ITenantRepository`
#### Domain Services
* `TenantManager`
### Application Layer
#### Application Services
* `TenantAppService`
#### Permissions
- `AbpTenantManagement.Tenants`: Tenant management.
- `AbpTenantManagement.Tenants.Create`: Creating a new tenant.
- `AbpTenantManagement.Tenants.Update`: Editing an existing tenant.
- `AbpTenantManagement.Tenants.Delete`: Deleting an existing tenant.
- `AbpTenantManagement.Tenants.ManageFeatures`: Manage features of the tenants.
### Entity Framework Core Integration
* `TenantManagementDbContext` (implements `ITenantManagementDbContext`)
**Database Tables:**
* `AbpTenants`
* `AbpTenantConnectionStrings`
### MongoDB Integration
* `TenantManagementMongoDbContext` (implements `ITenantManagementMongoDbContext`)
**Database Collections:**
* `AbpTenants` (also includes the connection string)
## Notices
ABP Framework allows to use *database per tenant* approach that allows a tenant can have a dedicated database. This module has the fundamental infrastructure to make that implementation possible (see its source code), however it doesn't implement the application layer and UI functionalities to provide it as an out of the box implementation. You can implement these features yourself, or consider to use the [ABP Commercial Saas Module](https://docs.abp.io/en/commercial/latest/modules/saas) that fully implements it and provides much more business features.
## See Also
* [Multi-Tenancy](../Multi-Tenancy.md)
* [ABP Commercial SaaS Module](https://docs.abp.io/en/commercial/latest/modules/saas)

3
docs/en/Road-Map.md

@ -8,11 +8,9 @@ This document provides a road map, release schedule and planned features for the
This version will focus on **documentation** and **improvements** of current features. In addition, the following features are planned: This version will focus on **documentation** and **improvements** of current features. In addition, the following features are planned:
* Publishing distributed events as transactional ([#6126](https://github.com/abpframework/abp/issues/6126))
* Revisit the microservice demo solution ([#8385](https://github.com/abpframework/abp/issues/8385)) * Revisit the microservice demo solution ([#8385](https://github.com/abpframework/abp/issues/8385))
* A new UI Theme alternative to the Basic Theme ([#6132](https://github.com/abpframework/abp/issues/6132)) * A new UI Theme alternative to the Basic Theme ([#6132](https://github.com/abpframework/abp/issues/6132))
* Improvements and new features to the [CMS Kit](Modules/Cms-Kit.md) module ([#8380](https://github.com/abpframework/abp/issues/8380) [#8381](https://github.com/abpframework/abp/issues/8381)) * Improvements and new features to the [CMS Kit](Modules/Cms-Kit.md) module ([#8380](https://github.com/abpframework/abp/issues/8380) [#8381](https://github.com/abpframework/abp/issues/8381))
* Pre-configured test project for the [Blazor UI](UI/Blazor/Overall.md) ([#5516](https://github.com/abpframework/abp/issues/5516))
* Razor engine support for text templating ([#8373](https://github.com/abpframework/abp/issues/8373)) * Razor engine support for text templating ([#8373](https://github.com/abpframework/abp/issues/8373))
**Planned release date**: End of Quarter 2, 2021. See the [4.4 milestone](https://github.com/abpframework/abp/milestone/52) to track the progress. **Planned release date**: End of Quarter 2, 2021. See the [4.4 milestone](https://github.com/abpframework/abp/milestone/52) to track the progress.
@ -25,6 +23,7 @@ We planned to focus on the ABP Framework v5.0 after the 4.4 release. This versio
* Upgrading to Bootstrap 5.x ([#8922](https://github.com/abpframework/abp/issues/8922)) * Upgrading to Bootstrap 5.x ([#8922](https://github.com/abpframework/abp/issues/8922))
* Alternative to IdentityServer4 ([#7221](https://github.com/abpframework/abp/issues/7221)) * Alternative to IdentityServer4 ([#7221](https://github.com/abpframework/abp/issues/7221))
* Dapr integration ([#2183](https://github.com/abpframework/abp/issues/2183)) * Dapr integration ([#2183](https://github.com/abpframework/abp/issues/2183))
* Publishing distributed events as transactional ([#6126](https://github.com/abpframework/abp/issues/6126))
* Resource based authorization system ([#236](https://github.com/abpframework/abp/issues/236)) * Resource based authorization system ([#236](https://github.com/abpframework/abp/issues/236))
* API Versioning system: finalize & document ([#497](https://github.com/abpframework/abp/issues/497)) * API Versioning system: finalize & document ([#497](https://github.com/abpframework/abp/issues/497))
* Performance optimizations; Enabling .NET Trimming, using source generators and reducing reflection, etc. * Performance optimizations; Enabling .NET Trimming, using source generators and reducing reflection, etc.

24
docs/en/Tutorials/Todo/Index.md

@ -135,7 +135,7 @@ namespace TodoApp
} }
```` ````
`BasicAggregateRoot` is one the simplest base class to create root entities, and `Guid` is the primary key (`Id`) of the entity here. `BasicAggregateRoot` is the simplest base class to create root entities, and `Guid` is the primary key (`Id`) of the entity here.
## Database Integration ## Database Integration
@ -214,7 +214,7 @@ Now, we can use ABP repositories to save and retrieve todo items, as we'll do in
## Application Layer ## Application Layer
An [Application Service](../../Application-Services.md) is used to perform use cases of the application. We need to perform the following use cases; An [Application Service](../../Application-Services.md) is used to perform use cases of the application. We need to perform the following use cases:
* Get the list of todo items * Get the list of todo items
* Create a new todo item * Create a new todo item
@ -243,7 +243,7 @@ namespace TodoApp
### Data Transfer Object ### Data Transfer Object
`GetListAsync` and `CreateAsync` methods return `TodoItemDto`. Applications Services typically gets and returns DTOs ([Data Transfer Objects](../../Data-Transfer-Objects.md)) instead of entities. So, we should define the DTO class here. Create a new `TodoItemDto` class inside the *TodoApp.Application.Contracts* project: `GetListAsync` and `CreateAsync` methods return `TodoItemDto`. `ApplicationService` typically gets and returns DTOs ([Data Transfer Objects](../../Data-Transfer-Objects.md)) instead of entities. So, we should define the DTO class here. Create a new `TodoItemDto` class inside the *TodoApp.Application.Contracts* project:
````csharp ````csharp
using System; using System;
@ -465,9 +465,9 @@ $(function () {
}); });
```` ````
In the first part, we are registering to click events of the trash icons near to the todo items, deleting the related item on the server and showing a notification on the UI. Also, we are removing the deleted item from DOM, so we don't need to refresh the page. In the first part, we are subscribing to click events of the trash icons near to the todo items, deleting the related item on the server and showing a notification on the UI. Also, we are removing the deleted item from DOM, so we don't need to refresh the page.
In the second part, we are creating a new todo item on the server. If it succeed, we are then manipulating DOM to insert a new `<li>` element to the todo list. In this way, no need to refresh the whole page after creating a new todo item. In the second part, we are creating a new todo item on the server. If it succeeds, we are then manipulating DOM to insert a new `<li>` element to the todo list. This way we don't need to refresh the whole page after creating a new todo item.
The interesting part here is how we communicate with the server. See the *Dynamic JavaScript Proxies & Auto API Controllers* section to understand how it works. But now, let's continue and complete the application. The interesting part here is how we communicate with the server. See the *Dynamic JavaScript Proxies & Auto API Controllers* section to understand how it works. But now, let's continue and complete the application.
@ -504,13 +504,13 @@ As the final touch, open the `Index.css` file in the `Pages` folder of the *Todo
This is a simple styling for the todo page. We believe that you can do much better :) This is a simple styling for the todo page. We believe that you can do much better :)
Now, you can run the application again to see the result. Now, you can run the application again and see the result.
### Dynamic JavaScript Proxies & Auto API Controllers ### Dynamic JavaScript Proxies & Auto API Controllers
In the `Index.js` file, we've used `todoApp.todo.delete(...)` and `todoApp.todo.create(...)` functions to communicate with the server. These functions are dynamically created by the ABP Framework, thanks to the [Dynamic JavaScript Client Proxy](../../UI/AspNetCore/Dynamic-JavaScript-Proxies.md) system. They perform HTTP API calls to the server and return a promise, so you can register a callback to the `then` function as we've done above. In the `Index.js` file, we've used `todoApp.todo.delete(...)` and `todoApp.todo.create(...)` functions to communicate with the server. These functions are dynamically created by the ABP Framework, thanks to the [Dynamic JavaScript Client Proxy](../../UI/AspNetCore/Dynamic-JavaScript-Proxies.md) system. They perform HTTP API calls to the server and return a promise, so you can register a callback to the `then` function as we've done above.
However, you may ask that we haven't created any API Controller, so how server handles these requests? This question brings us the [Auto API Controller](../../API/Auto-API-Controllers.md) feature of the ABP Framework. It automatically converts the application services to API Controllers by conventions. However, you may notice that we haven't created any API Controller, so how server handles these requests? This question brings us the [Auto API Controller](../../API/Auto-API-Controllers.md) feature of the ABP Framework. It automatically converts the application services to API Controllers by convention.
If you open the [Swagger UI](https://swagger.io/tools/swagger-ui/) by entering the `/swagger` URL in your application, you can see the Todo API: If you open the [Swagger UI](https://swagger.io/tools/swagger-ui/) by entering the `/swagger` URL in your application, you can see the Todo API:
@ -559,7 +559,7 @@ namespace TodoApp.Blazor.Pages
} }
```` ````
This class uses the `ITodoAppService` to perform operations for the todo items. It manipulates the `TodoItems` list after create and delete operations. In this way, we don't need to refresh the whole todo list from the server. This class uses the `ITodoAppService` to perform operations for the todo items. It manipulates the `TodoItems` list after create and delete operations. This way, we don't need to refresh the whole todo list from the server.
{{if UI=="Blazor"}} {{if UI=="Blazor"}}
@ -653,7 +653,7 @@ In the `Index.razor.cs` file, we've injected (with the `[Inject]` attribute) and
The magic is done by the ABP Framework's [Dynamic C# Client Proxy](../../API/Dynamic-CSharp-API-Clients.md) system. It uses the standard `HttpClient` and performs HTTP API requests to the remote server. It also handles all the standard tasks for us, including authorization, JSON serialization and exception handling. The magic is done by the ABP Framework's [Dynamic C# Client Proxy](../../API/Dynamic-CSharp-API-Clients.md) system. It uses the standard `HttpClient` and performs HTTP API requests to the remote server. It also handles all the standard tasks for us, including authorization, JSON serialization and exception handling.
However, you may ask that we haven't created any API Controller, so how server handles these requests? This question brings us the [Auto API Controller](../../API/Auto-API-Controllers.md) feature of the ABP Framework. It automatically converts the application services to API Controllers by conventions. However, you may ask that we haven't created any API Controller, so how server handles these requests? This question brings us the [Auto API Controller](../../API/Auto-API-Controllers.md) feature of the ABP Framework. It automatically converts the application services to API Controllers by convention.
If you run the `TodoApp.HttpApi.Host` application, you can see the Todo API: If you run the `TodoApp.HttpApi.Host` application, you can see the Todo API:
@ -669,7 +669,7 @@ ABP provides a handy feature to automatically create client-side services to eas
You first need to run the `TodoApp.HttpApi.Host` project since the proxy generator reads API definitions from the server application. You first need to run the `TodoApp.HttpApi.Host` project since the proxy generator reads API definitions from the server application.
> **Warning**: There is a problem with IIS Express; it doesn't allow to connect to the application from another process. If you are using Visual Studio, select the `TodoApp.HttpApi.Host` instead of IIS Express in the run button drop-down list, as shown in the figure below: > **Warning**: There is an issue with IIS Express: it doesn't allow to connect to the application from another process. If you are using Visual Studio, select the `TodoApp.HttpApi.Host` instead of IIS Express in the run button drop-down list, as shown in the figure below:
![run-without-iisexpress](run-without-iisexpress.png) ![run-without-iisexpress](run-without-iisexpress.png)
@ -813,7 +813,7 @@ Now, you can run the application again to see the result.
## Conclusion ## Conclusion
In this tutorial, we've build a very simple application to warm up to the ABP Framework. If you are looking to build a serious application, please check the [web application development tutorial](../Part-1.md) which covers all the aspects of a real-life web application development. In this tutorial, we've built a very simple application to warm up to the ABP Framework. If you are looking to build a serious application, please check the [web application development tutorial](../Part-1.md) which covers all the aspects of a real-life web application development.
## Source Code ## Source Code
@ -821,4 +821,4 @@ You can find source code of the completed application [here](https://github.com/
## See Also ## See Also
* [Web Application Development Tutorial](../Part-1.md) * [Web Application Development Tutorial](../Part-1.md)

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

@ -120,6 +120,4 @@ export const environment = {
} as Config.Environment; } as Config.Environment;
``` ```
> Note: The resource owner password flow does not support the two-factor authentication for some technical reasons.
See the [Authorization in Angular UI](./Authorization.md) document for more details. See the [Authorization in Angular UI](./Authorization.md) document for more details.

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

@ -52,5 +52,3 @@ export const environment = {
``` ```
According to this flow, the user is redirected to the login page in the account module. According to this flow, the user is redirected to the login page in the account module.
> Note: The resource owner password flow does not support the two-factor authentication for some technical reasons.

37
docs/en/UI/Angular/Custom-Setting-Page.md

@ -1,37 +0,0 @@
# Custom Setting Page
There are several settings tabs from different modules. You can add a custom setting page to your project.
1. Create a component with the following command:
```bash
yarn ng generate component my-settings
```
2. Open the `app.component.ts` and modify the file as shown below:
```js
import { Component } from '@angular/core';
import { SettingTabsService } from '@abp/ng.core'; // imported SettingTabsService
import { MySettingsComponent } from './my-settings/my-settings.component'; // imported MySettingsComponent
@Component(/* component metadata */)
export class AppComponent {
constructor(private settingTabs: SettingTabsService) // injected MySettingsComponent
{
// added below
settingTabs.add([
{
name: 'MySettings',
order: 1,
requiredPolicy: 'policy key here',
component: MySettingsComponent,
},
]);
}
}
```
Navigate to `/setting-management` route to see the changes:
![Custom Settings Tab](./images/custom-settings.png)

2
docs/en/UI/Blazor/Overall.md

@ -93,6 +93,8 @@ These libraries are selected as the base libraries and available to the applicat
> Bootstrap's JavaScript part is not used since the Blazorise library already provides the necessary functionalities to the Bootstrap components in a native way. > Bootstrap's JavaScript part is not used since the Blazorise library already provides the necessary functionalities to the Bootstrap components in a native way.
> Beginning from June, 2021, the Blazorise library has dual licenses; open source & commercial. Based on your yearly revenue, you may need to buy a commercial license. See [this post](https://blazorise.com/news/blazorise-commercial-going-live/) for the announcement.
### The Layout ### The Layout
The themes provide the layout. So, you have a responsive layout with the standard features already implemented. The screenshot below has taken from the layout of the [Basic Theme](Basic-Theme.md): The themes provide the layout. So, you have a responsive layout with the standard features already implemented. The screenshot below has taken from the layout of the [Basic Theme](Basic-Theme.md):

8
docs/en/docs-nav.json

@ -543,8 +543,8 @@
] ]
}, },
{ {
"text": "Guide: Implementing DDD", "text": "E-Book: Implementing DDD",
"path": "Domain-Driven-Design-Implementation-Guide.md" "path": "https://abp.io/books/implementing-domain-driven-design"
} }
] ]
}, },
@ -1027,10 +1027,6 @@
"text": "Component Replacement", "text": "Component Replacement",
"path": "UI/Angular/Component-Replacement.md" "path": "UI/Angular/Component-Replacement.md"
}, },
{
"text": "Custom Setting Page",
"path": "UI/Angular/Custom-Setting-Page.md"
},
{ {
"text": "Extensions", "text": "Extensions",
"items": [ "items": [

0
docs/en/UI/Angular/images/custom-settings.png → docs/en/images/custom-settings.png

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

BIN
docs/en/images/implementing-domain-driven-design-book.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
docs/en/images/module-tenant-management-actions.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

BIN
docs/en/images/module-tenant-management-new-tenant.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/en/images/module-tenant-management-page.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
docs/en/images/my-setting-group-blazor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
docs/en/images/my-setting-group-component-contributor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/en/images/my-setting-group-component.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
docs/en/images/my-setting-group-page-contributor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
docs/en/images/my-setting-group-ui.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
docs/en/images/my-setting-group-view-component.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

17
docs/zh-Hans/CLI.md

@ -39,6 +39,7 @@ dotnet tool update -g Volo.Abp.Cli
* **`translate`**: 当源代码控制存储库中有多个JSON[本地化](Localization.md文件时,可简化翻译本地化文件的过程. * **`translate`**: 当源代码控制存储库中有多个JSON[本地化](Localization.md文件时,可简化翻译本地化文件的过程.
* **`login`**: 使用你在[abp.io](https://abp.io/)的用户名和密码在你的计算机上认证. * **`login`**: 使用你在[abp.io](https://abp.io/)的用户名和密码在你的计算机上认证.
* **`logout`**: 在你的计算机注销认证. * **`logout`**: 在你的计算机注销认证.
* **`install-libs`**: 为 MVC / Razor Pages 和 Blazor Server UI 类型安装NPM包.
### help ### help
@ -339,3 +340,19 @@ abp login <username> -p <password> -o <organization> # You can enter both your
``` ```
abp logout abp logout
``` ```
### install-libs
为 MVC / Razor Pages 和 Blazor Server UI 类型安装NPM包, 它的 **执行目录** 或者传递的 ```--working-directory``` 目录必须包含一个项目文件(*.csproj).
`install-libs` 命令读取 `abp.resourcemapping.js` 来管理包. 参阅[客户端包管理](UI/AspNetCore/Client-Side-Package-Management.md)了解更多细节.
用法:
````bash
abp install-libs [options]
````
#### Options
* ```--working-directory``` 或 ```-wd```: 指定工作目录, 当执行目录不包含项目文件时会很有用.

192
docs/zh-Hans/Modules/Setting-Management.md

@ -83,4 +83,194 @@ namespace Demo
* `TenantSettingManagementProvider`: 获取或设定租户的设置值. * `TenantSettingManagementProvider`: 获取或设定租户的设置值.
* `UserSettingManagementProvider`: 获取或设定用户的设置值. * `UserSettingManagementProvider`: 获取或设定用户的设置值.
`ISettingManager` 在 `get/set` 方法中使用设置管理提供程序. 通常每个设置程序提供程序都在 `ISettingManagement` 服务上定义了模块方法 (比如用户设置管理程序提供定义了 `SetForUserAsync` 方法). `ISettingManager` 在 `get/set` 方法中使用设置管理提供程序. 通常每个设置程序提供程序都在 `ISettingManagement` 服务上定义了模块方法 (比如用户设置管理程序提供定义了 `SetForUserAsync` 方法).
## Setting Management UI.
设置管理模块默认提供了邮件设置页面并且它是可扩展的; 你可以为你的应用程序设置添加设置标签到设置页面.
### MVC UI
#### 创建视图组件
在 `Components` 目录下创建 `MySettingGroup` 文件夹, 添加一个名为 `MySettingGroupViewComponent` 的视图组件:
![MySettingGroupViewComponent](../images/my-setting-group-view-component.png)
打开 `MySettingGroupViewComponent.cs` 替换为以下内容:
```csharp
public class MySettingGroupViewComponent : AbpViewComponent
{
public virtual IViewComponentResult Invoke()
{
return View("~/Components/MySettingGroup/Default.cshtml");
}
}
```
> 你还可以使用 `InvokeAsync` 方法,在这个示例中我们使用 `Invoke` 方法.
#### Default.cshtml
在 `MySettingGroup` 目录下创建 `Default.cshtml` 文件.
打开 `Default.cshtml` 替换为以下内容:
```html
<div>
<p>My setting group page</p>
</div>
```
#### BookStoreSettingPageContributor
在 `Settings` 目录下创建 `BookStoreSettingPageContributor.cs` 文件.
![BookStoreSettingPageContributor](../images/my-setting-group-page-contributor.png)
文件内容如下:
```csharp
public class BookStoreSettingPageContributor : ISettingPageContributor
{
public Task ConfigureAsync(SettingPageCreationContext context)
{
context.Groups.Add(
new SettingPageGroup(
"Volo.Abp.MySettingGroup",
"MySettingGroup",
typeof(MySettingGroupViewComponent)
)
);
return Task.CompletedTask;
}
public Task<bool> CheckPermissionsAsync(SettingPageCreationContext context)
{
// You can check the permissions here
return Task.FromResult(true);
}
}
```
打开 `BookStoreWebModule.cs` 文件添加以下代码:
```csharp
Configure<SettingManagementPageOptions>(options =>
{
options.Contributors.Add(new BookStoreSettingPageContributor());
});
```
#### 运行应用程序
导航到 `/SettingManagement` 路由查看更改:
![Custom Settings Tab](../images/my-setting-group-ui.png)
### Blazor UI
#### 创建 Razor 组件
在 `Pages` 目录下创建 `MySettingGroup` 文件夹, 添加一个名为 `MySettingGroupComponent` 的Razor组件:
![MySettingGroupComponent](../images/my-setting-group-component.png)
打开 `MySettingGroupComponent.razor` 替换为以下内容:
```csharp
<Row>
<p>my setting group</p>
</Row>
```
#### BookStoreSettingComponentContributor
在 `Settings` 目录下创建 `BookStoreSettingComponentContributor.cs` 文件.
![BookStoreSettingComponentContributor](../images/my-setting-group-component-contributor.png)
文件内容如下:
```csharp
public class BookStoreSettingComponentContributor : ISettingComponentContributor
{
public Task ConfigureAsync(SettingComponentCreationContext context)
{
context.Groups.Add(
new SettingComponentGroup(
"Volo.Abp.MySettingGroup",
"MySettingGroup",
typeof(MySettingGroupComponent)
)
);
return Task.CompletedTask;
}
public Task<bool> CheckPermissionsAsync(SettingComponentCreationContext context)
{
// You can check the permissions here
return Task.FromResult(true);
}
}
```
打开 `BookStoreBlazorModule.cs` 文件添加以下代码:
```csharp
Configure<SettingManagementComponentOptions>(options =>
{
options.Contributors.Add(new BookStoreSettingComponentContributor());
});
```
#### 运行应用程序
导航到 `/setting-management` 路由查看更改:
![Custom Settings Tab](../images/my-setting-group-blazor.png)
### Angular UI
不同的模块提供它们的设置选项卡. 你可以通过3个步骤在项目中自定义设置页面.
#### 创建组件
使用以下命令创建一个组件
```bash
yarn ng generate component my-settings
```
打开 `app.component.ts` 做以下修改:
```js
import { Component } from '@angular/core';
import { SettingTabsService } from '@abp/ng.core'; // imported SettingTabsService
import { MySettingsComponent } from './my-settings/my-settings.component'; // imported MySettingsComponent
@Component(/* component metadata */)
export class AppComponent {
constructor(private settingTabs: SettingTabsService) // injected MySettingsComponent
{
// added below
settingTabs.add([
{
name: 'MySettings',
order: 1,
requiredPolicy: 'policy key here',
component: MySettingsComponent,
},
]);
}
}
```
#### 运行应用程序
导航到 `/setting-management` 路由你会看到以下变化:
![Custom Settings Tab](../images/custom-settings.png)

41
docs/zh-Hans/UI/Angular/Custom-Setting-Page.md

@ -1,41 +0,0 @@
# 自定义设置页面
不同的模块提供它们的设置选项卡. 你可以通过3个步骤在项目中自定义设置页面.
1. 使用以下命令创建一个组件
```bash
yarn ng generate component my-settings
```
2. 打开 `app.component.ts` 做以下修改:
```js
import { Component } from '@angular/core';
import { SettingTabsService } from '@abp/ng.core'; // imported SettingTabsService
import { MySettingsComponent } from './my-settings/my-settings.component'; // imported MySettingsComponent
@Component(/* component metadata */)
export class AppComponent {
constructor(private settingTabs: SettingTabsService) // injected MySettingsComponent
{
// added below
settingTabs.add([
{
name: 'MySettings',
order: 1,
requiredPolicy: 'policy key here',
component: MySettingsComponent,
},
]);
}
}
```
导航到 `/setting-management` 路由你会看到以下变化:
![Custom Settings Tab](./images/custom-settings.png)
## 下一步是什么?
- [懒加载 Scripts 与 Styles](./Lazy-Load-Service.md)

4
docs/zh-Hans/docs-nav.json

@ -518,10 +518,6 @@
"text": "替换组件", "text": "替换组件",
"path": "UI/Angular/Component-Replacement.md" "path": "UI/Angular/Component-Replacement.md"
}, },
{
"text": "自定义设置页",
"path": "UI/Angular/Custom-Setting-Page.md"
},
{ {
"text": "懒加载Scripts与Styles", "text": "懒加载Scripts与Styles",
"path": "UI/Angular/Lazy-Load-Service.md" "path": "UI/Angular/Lazy-Load-Service.md"

0
docs/zh-Hans/UI/Angular/images/custom-settings.png → docs/zh-Hans/images/custom-settings.png

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

BIN
docs/zh-Hans/images/my-setting-group-blazor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
docs/zh-Hans/images/my-setting-group-component-contributor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/zh-Hans/images/my-setting-group-component.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
docs/zh-Hans/images/my-setting-group-page-contributor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
docs/zh-Hans/images/my-setting-group-ui.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
docs/zh-Hans/images/my-setting-group-view-component.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

49
framework/Volo.Abp.sln

@ -155,16 +155,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.EntityFrameworkCor
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.EventBus.RabbitMQ", "src\Volo.Abp.EventBus.RabbitMQ\Volo.Abp.EventBus.RabbitMQ.csproj", "{468C3DCB-8C00-40E7-AE51-0738EAAB312A}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.EventBus.RabbitMQ", "src\Volo.Abp.EventBus.RabbitMQ\Volo.Abp.EventBus.RabbitMQ.csproj", "{468C3DCB-8C00-40E7-AE51-0738EAAB312A}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic", "src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj", "{2F5EE6D9-511B-4998-BD62-0B9F03E02432}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared", "src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.csproj", "{86A3BB43-8FA2-4CC2-BAD0-A86C6C9D9585}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared", "src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.csproj", "{86A3BB43-8FA2-4CC2-BAD0-A86C6C9D9585}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Tests", "test\Volo.Abp.AspNetCore.Mvc.UI.Tests\Volo.Abp.AspNetCore.Mvc.UI.Tests.csproj", "{7E0517E0-AE09-4E10-8469-308F065F2F43}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Tests", "test\Volo.Abp.AspNetCore.Mvc.UI.Tests\Volo.Abp.AspNetCore.Mvc.UI.Tests.csproj", "{7E0517E0-AE09-4E10-8469-308F065F2F43}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo", "test\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.csproj", "{57E29185-6DAF-4A41-8CE0-3F07EE3E289A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests", "test\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests.csproj", "{869F7453-7DDC-4915-B92C-7861466AB68B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Emailing", "src\Volo.Abp.Emailing\Volo.Abp.Emailing.csproj", "{8B1CB44B-BA40-4C78-9447-A7864126D7C3}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Emailing", "src\Volo.Abp.Emailing\Volo.Abp.Emailing.csproj", "{8B1CB44B-BA40-4C78-9447-A7864126D7C3}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Sms", "src\Volo.Abp.Sms\Volo.Abp.Sms.csproj", "{8BB10746-8BAD-4317-8EE5-A36805DB93F6}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Sms", "src\Volo.Abp.Sms\Volo.Abp.Sms.csproj", "{8BB10746-8BAD-4317-8EE5-A36805DB93F6}"
@ -271,8 +265,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.BackgroundWorkers.
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo", "src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.csproj", "{29E42ADB-85F8-44AE-A9B0-078F84C1B866}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo", "src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.csproj", "{29E42ADB-85F8-44AE-A9B0-078F84C1B866}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo", "test\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.csproj", "{0C498CF2-D052-4BF7-AD35-509A90F69707}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Http.Client.IdentityModel.Web.Tests", "test\Volo.Abp.Http.Client.IdentityModel.Web.Tests\Volo.Abp.Http.Client.IdentityModel.Web.Tests.csproj", "{E1963439-2BE5-4DB5-8438-2A9A792A1ADA}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Http.Client.IdentityModel.Web.Tests", "test\Volo.Abp.Http.Client.IdentityModel.Web.Tests\Volo.Abp.Http.Client.IdentityModel.Web.Tests.csproj", "{E1963439-2BE5-4DB5-8438-2A9A792A1ADA}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.ObjectExtending", "src\Volo.Abp.ObjectExtending\Volo.Abp.ObjectExtending.csproj", "{D1815C77-16D6-4F99-8814-69065CD89FB3}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.ObjectExtending", "src\Volo.Abp.ObjectExtending\Volo.Abp.ObjectExtending.csproj", "{D1815C77-16D6-4F99-8814-69065CD89FB3}"
@ -343,8 +335,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Compone
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.BlazoriseUI", "src\Volo.Abp.BlazoriseUI\Volo.Abp.BlazoriseUI.csproj", "{4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.BlazoriseUI", "src\Volo.Abp.BlazoriseUI\Volo.Abp.BlazoriseUI.csproj", "{4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme", "src\Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme\Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.csproj", "{ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Components.WebAssembly.Theming", "src\Volo.Abp.AspNetCore.Components.WebAssembly.Theming\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj", "{29CA7471-4E3E-4E75-8B33-001DDF682F01}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Components.WebAssembly.Theming", "src\Volo.Abp.AspNetCore.Components.WebAssembly.Theming\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj", "{29CA7471-4E3E-4E75-8B33-001DDF682F01}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Autofac.WebAssembly", "src\Volo.Abp.Autofac.WebAssembly\Volo.Abp.Autofac.WebAssembly.csproj", "{37F89B0B-1C6B-426F-A5EE-676D1956D9E9}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Autofac.WebAssembly", "src\Volo.Abp.Autofac.WebAssembly\Volo.Abp.Autofac.WebAssembly.csproj", "{37F89B0B-1C6B-426F-A5EE-676D1956D9E9}"
@ -365,14 +355,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Http.Tests", "test
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Components.Web", "src\Volo.Abp.AspNetCore.Components.Web\Volo.Abp.AspNetCore.Components.Web.csproj", "{F03A1CEA-FA44-4F30-BFC2-00BC2EAAB4E2}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Components.Web", "src\Volo.Abp.AspNetCore.Components.Web\Volo.Abp.AspNetCore.Components.Web.csproj", "{F03A1CEA-FA44-4F30-BFC2-00BC2EAAB4E2}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Components.Web.BasicTheme", "src\Volo.Abp.AspNetCore.Components.Web.BasicTheme\Volo.Abp.AspNetCore.Components.Web.BasicTheme.csproj", "{5AD34048-5DAA-4067-9C7D-09295617A057}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Components.Web.Theming", "src\Volo.Abp.AspNetCore.Components.Web.Theming\Volo.Abp.AspNetCore.Components.Web.Theming.csproj", "{B9133C38-AC24-4E2F-B581-D124CF410CDF}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Components.Web.Theming", "src\Volo.Abp.AspNetCore.Components.Web.Theming\Volo.Abp.AspNetCore.Components.Web.Theming.csproj", "{B9133C38-AC24-4E2F-B581-D124CF410CDF}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.EventBus.Abstractions", "src\Volo.Abp.EventBus.Abstractions\Volo.Abp.EventBus.Abstractions.csproj", "{8FDB3BF7-AD89-43F6-8DEB-C3E29B8801FE}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.EventBus.Abstractions", "src\Volo.Abp.EventBus.Abstractions\Volo.Abp.EventBus.Abstractions.csproj", "{8FDB3BF7-AD89-43F6-8DEB-C3E29B8801FE}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Components.Server.BasicTheme", "src\Volo.Abp.AspNetCore.Components.Server.BasicTheme\Volo.Abp.AspNetCore.Components.Server.BasicTheme.csproj", "{F35E5CFC-569F-4D7D-A30F-DD8AE97FEC5A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Sms.Aliyun", "src\Volo.Abp.Sms.Aliyun\Volo.Abp.Sms.Aliyun.csproj", "{ACFBA3FB-18CE-4655-9D14-1F1F5C3DFC30}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Sms.Aliyun", "src\Volo.Abp.Sms.Aliyun\Volo.Abp.Sms.Aliyun.csproj", "{ACFBA3FB-18CE-4655-9D14-1F1F5C3DFC30}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Sms.Aliyun.Tests", "test\Volo.Abp.Sms.Aliyun.Tests\Volo.Abp.Sms.Aliyun.Tests.csproj", "{DADEA538-3CA1-4ADE-A7E6-EF77A0CE4401}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Sms.Aliyun.Tests", "test\Volo.Abp.Sms.Aliyun.Tests\Volo.Abp.Sms.Aliyun.Tests.csproj", "{DADEA538-3CA1-4ADE-A7E6-EF77A0CE4401}"
@ -699,10 +685,6 @@ Global
{468C3DCB-8C00-40E7-AE51-0738EAAB312A}.Debug|Any CPU.Build.0 = Debug|Any CPU {468C3DCB-8C00-40E7-AE51-0738EAAB312A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{468C3DCB-8C00-40E7-AE51-0738EAAB312A}.Release|Any CPU.ActiveCfg = Release|Any CPU {468C3DCB-8C00-40E7-AE51-0738EAAB312A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{468C3DCB-8C00-40E7-AE51-0738EAAB312A}.Release|Any CPU.Build.0 = Release|Any CPU {468C3DCB-8C00-40E7-AE51-0738EAAB312A}.Release|Any CPU.Build.0 = Release|Any CPU
{2F5EE6D9-511B-4998-BD62-0B9F03E02432}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F5EE6D9-511B-4998-BD62-0B9F03E02432}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F5EE6D9-511B-4998-BD62-0B9F03E02432}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F5EE6D9-511B-4998-BD62-0B9F03E02432}.Release|Any CPU.Build.0 = Release|Any CPU
{86A3BB43-8FA2-4CC2-BAD0-A86C6C9D9585}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {86A3BB43-8FA2-4CC2-BAD0-A86C6C9D9585}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86A3BB43-8FA2-4CC2-BAD0-A86C6C9D9585}.Debug|Any CPU.Build.0 = Debug|Any CPU {86A3BB43-8FA2-4CC2-BAD0-A86C6C9D9585}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86A3BB43-8FA2-4CC2-BAD0-A86C6C9D9585}.Release|Any CPU.ActiveCfg = Release|Any CPU {86A3BB43-8FA2-4CC2-BAD0-A86C6C9D9585}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -711,14 +693,6 @@ Global
{7E0517E0-AE09-4E10-8469-308F065F2F43}.Debug|Any CPU.Build.0 = Debug|Any CPU {7E0517E0-AE09-4E10-8469-308F065F2F43}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E0517E0-AE09-4E10-8469-308F065F2F43}.Release|Any CPU.ActiveCfg = Release|Any CPU {7E0517E0-AE09-4E10-8469-308F065F2F43}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7E0517E0-AE09-4E10-8469-308F065F2F43}.Release|Any CPU.Build.0 = Release|Any CPU {7E0517E0-AE09-4E10-8469-308F065F2F43}.Release|Any CPU.Build.0 = Release|Any CPU
{57E29185-6DAF-4A41-8CE0-3F07EE3E289A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{57E29185-6DAF-4A41-8CE0-3F07EE3E289A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{57E29185-6DAF-4A41-8CE0-3F07EE3E289A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{57E29185-6DAF-4A41-8CE0-3F07EE3E289A}.Release|Any CPU.Build.0 = Release|Any CPU
{869F7453-7DDC-4915-B92C-7861466AB68B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{869F7453-7DDC-4915-B92C-7861466AB68B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{869F7453-7DDC-4915-B92C-7861466AB68B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{869F7453-7DDC-4915-B92C-7861466AB68B}.Release|Any CPU.Build.0 = Release|Any CPU
{8B1CB44B-BA40-4C78-9447-A7864126D7C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8B1CB44B-BA40-4C78-9447-A7864126D7C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8B1CB44B-BA40-4C78-9447-A7864126D7C3}.Debug|Any CPU.Build.0 = Debug|Any CPU {8B1CB44B-BA40-4C78-9447-A7864126D7C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B1CB44B-BA40-4C78-9447-A7864126D7C3}.Release|Any CPU.ActiveCfg = Release|Any CPU {8B1CB44B-BA40-4C78-9447-A7864126D7C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -931,10 +905,6 @@ Global
{29E42ADB-85F8-44AE-A9B0-078F84C1B866}.Debug|Any CPU.Build.0 = Debug|Any CPU {29E42ADB-85F8-44AE-A9B0-078F84C1B866}.Debug|Any CPU.Build.0 = Debug|Any CPU
{29E42ADB-85F8-44AE-A9B0-078F84C1B866}.Release|Any CPU.ActiveCfg = Release|Any CPU {29E42ADB-85F8-44AE-A9B0-078F84C1B866}.Release|Any CPU.ActiveCfg = Release|Any CPU
{29E42ADB-85F8-44AE-A9B0-078F84C1B866}.Release|Any CPU.Build.0 = Release|Any CPU {29E42ADB-85F8-44AE-A9B0-078F84C1B866}.Release|Any CPU.Build.0 = Release|Any CPU
{0C498CF2-D052-4BF7-AD35-509A90F69707}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0C498CF2-D052-4BF7-AD35-509A90F69707}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C498CF2-D052-4BF7-AD35-509A90F69707}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C498CF2-D052-4BF7-AD35-509A90F69707}.Release|Any CPU.Build.0 = Release|Any CPU
{E1963439-2BE5-4DB5-8438-2A9A792A1ADA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E1963439-2BE5-4DB5-8438-2A9A792A1ADA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E1963439-2BE5-4DB5-8438-2A9A792A1ADA}.Debug|Any CPU.Build.0 = Debug|Any CPU {E1963439-2BE5-4DB5-8438-2A9A792A1ADA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1963439-2BE5-4DB5-8438-2A9A792A1ADA}.Release|Any CPU.ActiveCfg = Release|Any CPU {E1963439-2BE5-4DB5-8438-2A9A792A1ADA}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -1075,10 +1045,6 @@ Global
{4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}.Debug|Any CPU.Build.0 = Debug|Any CPU {4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}.Release|Any CPU.ActiveCfg = Release|Any CPU {4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}.Release|Any CPU.Build.0 = Release|Any CPU {4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}.Release|Any CPU.Build.0 = Release|Any CPU
{ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}.Release|Any CPU.Build.0 = Release|Any CPU
{29CA7471-4E3E-4E75-8B33-001DDF682F01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {29CA7471-4E3E-4E75-8B33-001DDF682F01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{29CA7471-4E3E-4E75-8B33-001DDF682F01}.Debug|Any CPU.Build.0 = Debug|Any CPU {29CA7471-4E3E-4E75-8B33-001DDF682F01}.Debug|Any CPU.Build.0 = Debug|Any CPU
{29CA7471-4E3E-4E75-8B33-001DDF682F01}.Release|Any CPU.ActiveCfg = Release|Any CPU {29CA7471-4E3E-4E75-8B33-001DDF682F01}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -1119,10 +1085,6 @@ Global
{F03A1CEA-FA44-4F30-BFC2-00BC2EAAB4E2}.Debug|Any CPU.Build.0 = Debug|Any CPU {F03A1CEA-FA44-4F30-BFC2-00BC2EAAB4E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F03A1CEA-FA44-4F30-BFC2-00BC2EAAB4E2}.Release|Any CPU.ActiveCfg = Release|Any CPU {F03A1CEA-FA44-4F30-BFC2-00BC2EAAB4E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F03A1CEA-FA44-4F30-BFC2-00BC2EAAB4E2}.Release|Any CPU.Build.0 = Release|Any CPU {F03A1CEA-FA44-4F30-BFC2-00BC2EAAB4E2}.Release|Any CPU.Build.0 = Release|Any CPU
{5AD34048-5DAA-4067-9C7D-09295617A057}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5AD34048-5DAA-4067-9C7D-09295617A057}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5AD34048-5DAA-4067-9C7D-09295617A057}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5AD34048-5DAA-4067-9C7D-09295617A057}.Release|Any CPU.Build.0 = Release|Any CPU
{B9133C38-AC24-4E2F-B581-D124CF410CDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B9133C38-AC24-4E2F-B581-D124CF410CDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B9133C38-AC24-4E2F-B581-D124CF410CDF}.Debug|Any CPU.Build.0 = Debug|Any CPU {B9133C38-AC24-4E2F-B581-D124CF410CDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B9133C38-AC24-4E2F-B581-D124CF410CDF}.Release|Any CPU.ActiveCfg = Release|Any CPU {B9133C38-AC24-4E2F-B581-D124CF410CDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -1131,10 +1093,6 @@ Global
{8FDB3BF7-AD89-43F6-8DEB-C3E29B8801FE}.Debug|Any CPU.Build.0 = Debug|Any CPU {8FDB3BF7-AD89-43F6-8DEB-C3E29B8801FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8FDB3BF7-AD89-43F6-8DEB-C3E29B8801FE}.Release|Any CPU.ActiveCfg = Release|Any CPU {8FDB3BF7-AD89-43F6-8DEB-C3E29B8801FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8FDB3BF7-AD89-43F6-8DEB-C3E29B8801FE}.Release|Any CPU.Build.0 = Release|Any CPU {8FDB3BF7-AD89-43F6-8DEB-C3E29B8801FE}.Release|Any CPU.Build.0 = Release|Any CPU
{F35E5CFC-569F-4D7D-A30F-DD8AE97FEC5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F35E5CFC-569F-4D7D-A30F-DD8AE97FEC5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F35E5CFC-569F-4D7D-A30F-DD8AE97FEC5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F35E5CFC-569F-4D7D-A30F-DD8AE97FEC5A}.Release|Any CPU.Build.0 = Release|Any CPU
{ACFBA3FB-18CE-4655-9D14-1F1F5C3DFC30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {ACFBA3FB-18CE-4655-9D14-1F1F5C3DFC30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACFBA3FB-18CE-4655-9D14-1F1F5C3DFC30}.Debug|Any CPU.Build.0 = Debug|Any CPU {ACFBA3FB-18CE-4655-9D14-1F1F5C3DFC30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACFBA3FB-18CE-4655-9D14-1F1F5C3DFC30}.Release|Any CPU.ActiveCfg = Release|Any CPU {ACFBA3FB-18CE-4655-9D14-1F1F5C3DFC30}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -1262,11 +1220,8 @@ Global
{82ED4DD2-DEF8-40D5-9BF9-663AFD35B06D} = {447C8A77-E5F0-4538-8687-7383196D04EA} {82ED4DD2-DEF8-40D5-9BF9-663AFD35B06D} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{6EABA98D-0B71-4ED7-A939-AFDA106D1151} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {6EABA98D-0B71-4ED7-A939-AFDA106D1151} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{468C3DCB-8C00-40E7-AE51-0738EAAB312A} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {468C3DCB-8C00-40E7-AE51-0738EAAB312A} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{2F5EE6D9-511B-4998-BD62-0B9F03E02432} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{86A3BB43-8FA2-4CC2-BAD0-A86C6C9D9585} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {86A3BB43-8FA2-4CC2-BAD0-A86C6C9D9585} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{7E0517E0-AE09-4E10-8469-308F065F2F43} = {447C8A77-E5F0-4538-8687-7383196D04EA} {7E0517E0-AE09-4E10-8469-308F065F2F43} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{57E29185-6DAF-4A41-8CE0-3F07EE3E289A} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{869F7453-7DDC-4915-B92C-7861466AB68B} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{8B1CB44B-BA40-4C78-9447-A7864126D7C3} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {8B1CB44B-BA40-4C78-9447-A7864126D7C3} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{8BB10746-8BAD-4317-8EE5-A36805DB93F6} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {8BB10746-8BAD-4317-8EE5-A36805DB93F6} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{EC71FBDD-A6BD-4B5D-92FE-E108FE12CE8B} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {EC71FBDD-A6BD-4B5D-92FE-E108FE12CE8B} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
@ -1320,7 +1275,6 @@ Global
{9467418B-4A9B-4093-9B31-01A9DEF5B372} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {9467418B-4A9B-4093-9B31-01A9DEF5B372} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{CD5770BB-2E0C-4B3C-80E0-21B8CC43DBA9} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {CD5770BB-2E0C-4B3C-80E0-21B8CC43DBA9} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{29E42ADB-85F8-44AE-A9B0-078F84C1B866} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {29E42ADB-85F8-44AE-A9B0-078F84C1B866} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{0C498CF2-D052-4BF7-AD35-509A90F69707} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{E1963439-2BE5-4DB5-8438-2A9A792A1ADA} = {447C8A77-E5F0-4538-8687-7383196D04EA} {E1963439-2BE5-4DB5-8438-2A9A792A1ADA} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{D1815C77-16D6-4F99-8814-69065CD89FB3} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {D1815C77-16D6-4F99-8814-69065CD89FB3} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{17F8CA89-D9A2-4863-A5BD-B8E4D2901FD5} = {447C8A77-E5F0-4538-8687-7383196D04EA} {17F8CA89-D9A2-4863-A5BD-B8E4D2901FD5} = {447C8A77-E5F0-4538-8687-7383196D04EA}
@ -1356,7 +1310,6 @@ Global
{8A22D962-016E-474A-8BB7-F831F0ABF3AC} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {8A22D962-016E-474A-8BB7-F831F0ABF3AC} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{E1A62D10-F2FB-4040-BD60-11A3934058DF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {E1A62D10-F2FB-4040-BD60-11A3934058DF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{ABC27C10-C0FF-44CB-B4FF-A09C0B79F695} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{29CA7471-4E3E-4E75-8B33-001DDF682F01} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {29CA7471-4E3E-4E75-8B33-001DDF682F01} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{37F89B0B-1C6B-426F-A5EE-676D1956D9E9} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {37F89B0B-1C6B-426F-A5EE-676D1956D9E9} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{DEFE3DB2-EA4F-4F90-87FC-B25D64427BC5} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {DEFE3DB2-EA4F-4F90-87FC-B25D64427BC5} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
@ -1367,10 +1320,8 @@ Global
{00D07595-993C-40FC-BD90-0DD6331414D3} = {447C8A77-E5F0-4538-8687-7383196D04EA} {00D07595-993C-40FC-BD90-0DD6331414D3} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{A37BFEB5-7C57-4CDC-93B8-B5CE4BB9ACE1} = {447C8A77-E5F0-4538-8687-7383196D04EA} {A37BFEB5-7C57-4CDC-93B8-B5CE4BB9ACE1} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{F03A1CEA-FA44-4F30-BFC2-00BC2EAAB4E2} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {F03A1CEA-FA44-4F30-BFC2-00BC2EAAB4E2} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{5AD34048-5DAA-4067-9C7D-09295617A057} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{B9133C38-AC24-4E2F-B581-D124CF410CDF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {B9133C38-AC24-4E2F-B581-D124CF410CDF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{8FDB3BF7-AD89-43F6-8DEB-C3E29B8801FE} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {8FDB3BF7-AD89-43F6-8DEB-C3E29B8801FE} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{F35E5CFC-569F-4D7D-A30F-DD8AE97FEC5A} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{ACFBA3FB-18CE-4655-9D14-1F1F5C3DFC30} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {ACFBA3FB-18CE-4655-9D14-1F1F5C3DFC30} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{DADEA538-3CA1-4ADE-A7E6-EF77A0CE4401} = {447C8A77-E5F0-4538-8687-7383196D04EA} {DADEA538-3CA1-4ADE-A7E6-EF77A0CE4401} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{863C18F9-2407-49F9-9ADC-F6229AF3B385} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {863C18F9-2407-49F9-9ADC-F6229AF3B385} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}

19
framework/src/Volo.Abp.AspNetCore.Components.Server.BasicTheme/Volo.Abp.AspNetCore.Components.Server.BasicTheme.csproj

@ -1,19 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.Server.Theming\Volo.Abp.AspNetCore.Components.Server.Theming.csproj" />
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.Web.BasicTheme\Volo.Abp.AspNetCore.Components.Web.BasicTheme.csproj" />
</ItemGroup>
</Project>

14
framework/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Volo.Abp.AspNetCore.Components.Web.BasicTheme.csproj

@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.Web.Theming\Volo.Abp.AspNetCore.Components.Web.Theming.csproj" />
</ItemGroup>
</Project>

17
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.csproj

@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<PackageId>Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme</PackageId>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.Web.BasicTheme\Volo.Abp.AspNetCore.Components.Web.BasicTheme.csproj" />
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.WebAssembly.Theming\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj" />
<ProjectReference Include="..\Volo.Abp.Http.Client.IdentityModel.WebAssembly\Volo.Abp.Http.Client.IdentityModel.WebAssembly.csproj" />
</ItemGroup>
</Project>

3
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Table/AbpTableTagHelperService.cs

@ -9,6 +9,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Table
{ {
output.TagName = "table"; output.TagName = "table";
output.Attributes.AddClass("table"); output.Attributes.AddClass("table");
output.TagMode = TagMode.StartTagAndEndTag;
SetResponsiveness(context, output); SetResponsiveness(context, output);
SetTheme(context, output); SetTheme(context, output);
@ -95,4 +96,4 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Table
} }
} }
} }
} }

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/fi.json

@ -10,4 +10,4 @@
"SwitchTenant": "Vaihda vuokralainen", "SwitchTenant": "Vaihda vuokralainen",
"NotSelected": "Ei valittu" "NotSelected": "Ei valittu"
} }
} }

32
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj

@ -1,32 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<AssemblyName>Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<IsPackable>true</IsPackable>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="wwwroot\**\*.*" />
</ItemGroup>
<ItemGroup>
<Content Remove="wwwroot\**\*.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy\Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.csproj" />
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.csproj" />
</ItemGroup>
</Project>

8
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js

@ -236,9 +236,11 @@ var abp = abp || {};
var $actionContainer = _createRowAction(aData, column.rowAction, tableInstance); var $actionContainer = _createRowAction(aData, column.rowAction, tableInstance);
hideEmptyColumn($actionContainer, tableInstance, colIndex); hideEmptyColumn($actionContainer, tableInstance, colIndex);
var $actionButton = $(cells[colIndex]).find(".abp-action-button"); if ($actionContainer) {
if ($actionButton.length === 0) { var $actionButton = $(cells[colIndex]).find(".abp-action-button");
$(cells[colIndex]).empty().append($actionContainer); if ($actionButton.length === 0) {
$(cells[colIndex]).empty().append($actionContainer);
}
} }
} }
} }

14
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs

@ -4,6 +4,7 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.AspNetCore.Mvc.ApiExplorer;
@ -102,6 +103,16 @@ namespace Volo.Abp.AspNetCore.Mvc
Logger.LogDebug($"ActionApiDescriptionModel.Create: {controllerModel.ControllerName}.{uniqueMethodName}"); Logger.LogDebug($"ActionApiDescriptionModel.Create: {controllerModel.ControllerName}.{uniqueMethodName}");
bool? allowAnonymous = null;
if (apiDescription.ActionDescriptor.EndpointMetadata.Any(x => x is IAllowAnonymous))
{
allowAnonymous = true;
}
else if (apiDescription.ActionDescriptor.EndpointMetadata.Any(x => x is IAuthorizeData))
{
allowAnonymous = false;
}
var actionModel = controllerModel.AddAction( var actionModel = controllerModel.AddAction(
uniqueMethodName, uniqueMethodName,
ActionApiDescriptionModel.Create( ActionApiDescriptionModel.Create(
@ -109,7 +120,8 @@ namespace Volo.Abp.AspNetCore.Mvc
method, method,
apiDescription.RelativePath, apiDescription.RelativePath,
apiDescription.HttpMethod, apiDescription.HttpMethod,
GetSupportedVersions(controllerType, method, setting) GetSupportedVersions(controllerType, method, setting),
allowAnonymous
) )
); );

46
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpMvcAttributeValidationResultProvider.cs

@ -0,0 +1,46 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc.Validation;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Validation;
namespace Volo.Abp.AspNetCore.Mvc.Localization
{
[Dependency(ReplaceServices = true)]
public class AbpMvcAttributeValidationResultProvider : DefaultAttributeValidationResultProvider
{
private readonly AbpMvcDataAnnotationsLocalizationOptions _abpMvcDataAnnotationsLocalizationOptions;
private readonly IStringLocalizerFactory _stringLocalizerFactory;
public AbpMvcAttributeValidationResultProvider(
IOptions<AbpMvcDataAnnotationsLocalizationOptions> abpMvcDataAnnotationsLocalizationOptions,
IStringLocalizerFactory stringLocalizerFactory)
{
_abpMvcDataAnnotationsLocalizationOptions = abpMvcDataAnnotationsLocalizationOptions.Value;
_stringLocalizerFactory = stringLocalizerFactory;
}
public override ValidationResult GetOrDefault(ValidationAttribute validationAttribute, object validatingObject, ValidationContext validationContext)
{
var resourceSource = _abpMvcDataAnnotationsLocalizationOptions.AssemblyResources.GetOrDefault(validationContext.ObjectType.Assembly);
if (resourceSource == null)
{
return base.GetOrDefault(validationAttribute, validatingObject, validationContext);
}
if (validationAttribute.ErrorMessage == null)
{
ValidationAttributeHelper.SetDefaultErrorMessage(validationAttribute);
}
if (validationAttribute.ErrorMessage != null)
{
validationAttribute.ErrorMessage = _stringLocalizerFactory.Create(resourceSource)[validationAttribute.ErrorMessage];
}
return base.GetOrDefault(validationAttribute, validatingObject, validationContext);
}
}
}

12
framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpAspNetCoreSignalRModule.cs

@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Auditing;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
@ -30,6 +31,7 @@ namespace Volo.Abp.AspNetCore.SignalR
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
var routePatterns = new List<string> {"/signalr-hubs"};
var signalRServerBuilder = context.Services.AddSignalR(); var signalRServerBuilder = context.Services.AddSignalR();
context.Services.ExecutePreConfiguredActions(signalRServerBuilder); context.Services.ExecutePreConfiguredActions(signalRServerBuilder);
@ -45,6 +47,8 @@ namespace Volo.Abp.AspNetCore.SignalR
foreach (var hubConfig in signalROptions.Hubs) foreach (var hubConfig in signalROptions.Hubs)
{ {
routePatterns.AddIfNotContains(hubConfig.RoutePattern);
MapHubType( MapHubType(
hubConfig.HubType, hubConfig.HubType,
endpointContext.Endpoints, endpointContext.Endpoints,
@ -60,6 +64,14 @@ namespace Volo.Abp.AspNetCore.SignalR
} }
}); });
}); });
Configure<AbpAspNetCoreAuditingOptions>(options =>
{
foreach (var routePattern in routePatterns)
{
options.IgnoredUrls.AddIfNotContains(x => routePattern.StartsWith(x), () => routePattern);
}
});
} }
private void AutoAddHubTypes(IServiceCollection services) private void AutoAddHubTypes(IServiceCollection services)

2
framework/src/Volo.Abp.Castle.Core/Volo.Abp.Castle.Core.csproj

@ -16,7 +16,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Castle.Core" Version="4.4.1" /> <PackageReference Include="Castle.Core" Version="4.4.1" />
<PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.0.21-alpha" /> <PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

1
framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj

@ -13,6 +13,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileSystemGlobbing" Version="$(MicrosoftPackageVersion)" />
<PackageReference Include="SharpZipLib" Version="1.3.1" /> <PackageReference Include="SharpZipLib" Version="1.3.1" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
<PackageReference Include="NuGet.Versioning" Version="5.9.0" /> <PackageReference Include="NuGet.Versioning" Version="5.9.0" />

8
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs

@ -2,9 +2,11 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Cli.Commands; using Volo.Abp.Cli.Commands;
using Volo.Abp.Cli.Http; using Volo.Abp.Cli.Http;
using Volo.Abp.Cli.LIbs;
using Volo.Abp.Domain; using Volo.Abp.Domain;
using Volo.Abp.IdentityModel; using Volo.Abp.IdentityModel;
using Volo.Abp.Json; using Volo.Abp.Json;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Minify; using Volo.Abp.Minify;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
@ -25,6 +27,11 @@ namespace Volo.Abp.Cli
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
options.UnsupportedTypes.Add(typeof(ResourceMapping));
});
Configure<AbpCliOptions>(options => Configure<AbpCliOptions>(options =>
{ {
//TODO: Define constants like done for GenerateProxyCommand.Name. //TODO: Define constants like done for GenerateProxyCommand.Name.
@ -49,6 +56,7 @@ namespace Volo.Abp.Cli
options.Commands["build"] = typeof(BuildCommand); options.Commands["build"] = typeof(BuildCommand);
options.Commands["bundle"] = typeof(BundleCommand); options.Commands["bundle"] = typeof(BundleCommand);
options.Commands["create-migration-and-run-migrator"] = typeof(CreateMigrationAndRunMigratorCommand); options.Commands["create-migration-and-run-migrator"] = typeof(CreateMigrationAndRunMigratorCommand);
options.Commands["install-libs"] = typeof(InstallLibsCommand);
}); });
} }
} }

78
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/InstallLibsCommand.cs

@ -0,0 +1,78 @@
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.LIbs;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Commands
{
public class InstallLibsCommand : IConsoleCommand, ITransientDependency
{
public ILogger<InstallLibsCommand> Logger { get; set; }
protected IInstallLibsService InstallLibsService { get; }
public InstallLibsCommand(IInstallLibsService installLibsService)
{
InstallLibsService = installLibsService;
Logger = NullLogger<InstallLibsCommand>.Instance;
}
public async Task ExecuteAsync(CommandLineArgs commandLineArgs)
{
var workingDirectoryArg = commandLineArgs.Options.GetOrNull(
Options.WorkingDirectory.Short,
Options.WorkingDirectory.Long
);
var workingDirectory = workingDirectoryArg ?? Directory.GetCurrentDirectory();
if (!Directory.Exists(workingDirectory))
{
throw new CliUsageException(
"Specified directory does not exist." +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
}
await InstallLibsService.InstallLibsAsync(workingDirectory);
}
public string GetUsageInfo()
{
var sb = new StringBuilder();
sb.AppendLine("");
sb.AppendLine("Usage:");
sb.AppendLine("");
sb.AppendLine(" abp install-libs");
sb.AppendLine("");
sb.AppendLine("Options:");
sb.AppendLine("");
sb.AppendLine("-wd|--working-directory <directory-path> (default: empty)");
sb.AppendLine("");
sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI");
return sb.ToString();
}
public string GetShortDescription()
{
return "Install NPM Packages for MVC / Razor Pages and Blazor Server UI types.";
}
public static class Options
{
public static class WorkingDirectory
{
public const string Short = "wd";
public const string Long = "working-directory";
}
}
}
}

15
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/FileMatchResult.cs

@ -0,0 +1,15 @@
namespace Volo.Abp.Cli.LIbs
{
public class FileMatchResult
{
public string Path { get; }
public string Stem { get; }
public FileMatchResult(string path, string stem)
{
Path = path;
Stem = stem;
}
}
}

9
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/IInstallLibsService.cs

@ -0,0 +1,9 @@
using System.Threading.Tasks;
namespace Volo.Abp.Cli.LIbs
{
public interface IInstallLibsService
{
Task InstallLibsAsync(string directory);
}
}

230
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/InstallLibsService.cs

@ -0,0 +1,230 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.FileSystemGlobbing;
using Microsoft.Extensions.FileSystemGlobbing.Abstractions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using NuGet.Versioning;
using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Json;
namespace Volo.Abp.Cli.LIbs
{
public class InstallLibsService : IInstallLibsService, ITransientDependency
{
public const string LibsDirectory = "./wwwroot/libs";
public ILogger<InstallLibsService> Logger { get; set; }
private readonly IJsonSerializer _jsonSerializer;
public InstallLibsService(IJsonSerializer jsonSerializer)
{
_jsonSerializer = jsonSerializer;
Logger = NullLogger<InstallLibsService>.Instance;
}
public async Task InstallLibsAsync(string directory)
{
var projectFiles = Directory.GetFiles(directory, "*.csproj");
if (!projectFiles.Any())
{
Logger.LogError("No project file found in the directory.");
return;
}
if (!await CanInstallLibs(directory))
{
Logger.LogWarning(
"abp install-libs command is available for MVC, Razor Page, and Blazor-Server UI types");
return;
}
if (!IsNpmInstalled())
{
Logger.LogWarning("NPM is not installed, visit https://nodejs.org/en/download/ and install NPM");
return;
}
if (IsYarnAvailable())
{
RunYarn(directory);
}
else
{
RunNpmInstall(directory);
}
await CleanAndCopyResources(directory);
}
private async Task CleanAndCopyResources(string fileDirectory)
{
var mappingFiles = Directory.GetFiles(fileDirectory, "abp.resourcemapping.js", SearchOption.AllDirectories);
var resourceMapping = new ResourceMapping
{
Clean = new List<string> {LibsDirectory}
};
foreach (var mappingFile in mappingFiles)
{
using (var reader = File.OpenText(mappingFile))
{
var mappingFileContent = await reader.ReadToEndAsync();
var mapping = _jsonSerializer.Deserialize<ResourceMapping>(mappingFileContent
.Replace("module.exports", string.Empty)
.Replace("=", string.Empty).Trim().TrimEnd(';'));
mapping.ReplaceAliases();
mapping.Clean.ForEach(c => resourceMapping.Clean.AddIfNotContains(c));
mapping.Aliases.ToList().ForEach(x =>
{
resourceMapping.Aliases.AddIfNotContains(new KeyValuePair<string, string>(x.Key, x.Value));
});
mapping.Mappings.ToList().ForEach(x =>
{
resourceMapping.Mappings.AddIfNotContains(new KeyValuePair<string, string>(x.Key, x.Value));
});
}
}
EnsureLibsFolderExists(fileDirectory, LibsDirectory);
CleanDirsAndFiles(fileDirectory, resourceMapping);
CopyResourcesToLibs(fileDirectory, resourceMapping);
}
private void EnsureLibsFolderExists(string fileDirectory, string libsDirectory)
{
Directory.CreateDirectory(Path.Combine(fileDirectory, libsDirectory));
}
private void CopyResourcesToLibs(string fileDirectory, ResourceMapping resourceMapping)
{
foreach (var mapping in resourceMapping.Mappings)
{
var destPath = Path.Combine(fileDirectory, mapping.Value);
var files = FindFiles(fileDirectory, mapping.Key);
foreach (var file in files)
{
var destFilePath = Path.Combine(destPath, file.Stem);
if (File.Exists(destFilePath))
{
continue;
}
Directory.CreateDirectory(Path.GetDirectoryName(destFilePath));
File.Copy(file.Path, destFilePath);
}
}
}
private async Task<bool> CanInstallLibs(string fileDirectory)
{
var projectFiles = Directory.GetFiles(fileDirectory, "*.csproj");
using (var reader = File.OpenText(projectFiles[0]))
{
var projectFileContent = await reader.ReadToEndAsync();
return projectFileContent.Contains("Microsoft.NET.Sdk.Web");
}
}
private void CleanDirsAndFiles(string directory, ResourceMapping resourceMapping)
{
var files = FindFiles(directory, resourceMapping.Clean.ToArray());
foreach (var file in files)
{
if (File.Exists(file.Path))
{
File.Delete(file.Path);
}
}
foreach (var directoryInfo in Directory.GetDirectories(Path.Combine(directory, resourceMapping.Clean.First()),"*", SearchOption.AllDirectories).Reverse())
{
if (!Directory.EnumerateFileSystemEntries(directoryInfo).Any())
{
Directory.Delete(directoryInfo);
}
}
}
private List<FileMatchResult> FindFiles(string directory, params string[] patterns)
{
var matcher = new Matcher();
foreach (var pattern in patterns)
{
if (pattern.StartsWith("!"))
{
matcher.AddExclude(NormalizeGlob(pattern).TrimStart('!'));
}
else
{
matcher.AddInclude(NormalizeGlob(pattern));
}
}
var result = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(directory)));
return result.Files.Select(x => new FileMatchResult(Path.Combine(directory, x.Path), x.Stem)).ToList();
}
private string NormalizeGlob(string pattern)
{
pattern = pattern.Replace("//", "/");
if (!Path.HasExtension(pattern) && !pattern.EndsWith("*"))
{
return pattern.EnsureEndsWith('/') + "**";
}
return pattern;
}
private void RunNpmInstall(string directory)
{
Logger.LogInformation($"Running npm install on {directory}");
CmdHelper.RunCmd($"cd {directory} && npm install");
}
private void RunYarn(string directory)
{
Logger.LogInformation($"Running Yarn on {directory}");
CmdHelper.RunCmd($"cd {directory} && yarn");
}
private bool IsNpmInstalled()
{
var output = CmdHelper.RunCmdAndGetOutput("npm -v").Trim();
return SemanticVersion.TryParse(output, out _);
}
private bool IsYarnAvailable()
{
var output = CmdHelper.RunCmdAndGetOutput("npm list yarn -g").Trim();
if (output.Contains("empty"))
{
return false;
}
if (!SemanticVersion.TryParse(output.Substring(output.IndexOf('@') + 1), out var version))
{
return false;
}
return version > SemanticVersion.Parse("1.20.0");
}
}
}

53
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/ResourceMapping.cs

@ -0,0 +1,53 @@
using System.Collections.Generic;
using System.Linq;
namespace Volo.Abp.Cli.LIbs
{
public class ResourceMapping
{
public Dictionary<string, string> Aliases { get; set; }
public List<string> Clean { get; set; }
public Dictionary<string, string> Mappings { get; set; }
public ResourceMapping()
{
Aliases = new Dictionary<string, string>
{
{"@node_modules", "./node_modules"},
{"@libs", "./wwwroot/libs"},
};
Clean = new List<string>();
Mappings = new Dictionary<string, string>();
}
public void ReplaceAliases()
{
for (var i = 0; i < Mappings.Count; i++)
{
var mapping = Mappings.ElementAt(i);
Mappings.Remove(mapping.Key);
var key = mapping.Key;
var value = mapping.Value;
foreach (var alias in Aliases)
{
key = key.Replace(alias.Key, alias.Value);
value = value.Replace(alias.Key, alias.Value);
}
Mappings[key] = value;
}
for (var i = 0; i < Clean.Count; i++)
{
foreach (var alias in Aliases)
{
Clean[i] = Clean[i].Replace(alias.Key, alias.Value);
}
}
}
}
}

23
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/ProjectNameValidator.cs

@ -17,6 +17,11 @@ namespace Volo.Abp.Cli.Utils
"LPT2" "LPT2"
}; };
private static readonly string[] IllegalKeywords = new[]
{
"Blazor"
};
private static bool HasParentDirectoryString(string projectName) private static bool HasParentDirectoryString(string projectName)
{ {
return projectName.Contains(".."); return projectName.Contains("..");
@ -40,6 +45,19 @@ namespace Volo.Abp.Cli.Utils
return false; return false;
} }
private static bool HasIllegalKeywords(string projectName)
{
foreach (var illegalKeyword in IllegalKeywords)
{
if (projectName.Contains(illegalKeyword))
{
return true;
}
}
return false;
}
public static bool IsValid(string projectName) public static bool IsValid(string projectName)
{ {
if (projectName == null) if (projectName == null)
@ -62,6 +80,11 @@ namespace Volo.Abp.Cli.Utils
return false; return false;
} }
if (HasIllegalKeywords(projectName))
{
return false;
}
return true; return true;
} }
} }

13
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/AbpCommonDbContextRegistrationOptions.cs

@ -15,7 +15,7 @@ namespace Volo.Abp.DependencyInjection
public IServiceCollection Services { get; } public IServiceCollection Services { get; }
public List<Type> ReplacedDbContextTypes { get; } public Dictionary<Type, Type> ReplacedDbContextTypes { get; }
public Type DefaultRepositoryDbContextType { get; protected set; } public Type DefaultRepositoryDbContextType { get; protected set; }
@ -39,7 +39,7 @@ namespace Volo.Abp.DependencyInjection
Services = services; Services = services;
DefaultRepositoryDbContextType = originalDbContextType; DefaultRepositoryDbContextType = originalDbContextType;
CustomRepositories = new Dictionary<Type, Type>(); CustomRepositories = new Dictionary<Type, Type>();
ReplacedDbContextTypes = new List<Type>(); ReplacedDbContextTypes = new Dictionary<Type, Type>();
SpecifiedDefaultRepositories = new List<Type>(); SpecifiedDefaultRepositories = new List<Type>();
} }
@ -47,15 +47,20 @@ namespace Volo.Abp.DependencyInjection
{ {
return ReplaceDbContext(typeof(TOtherDbContext)); return ReplaceDbContext(typeof(TOtherDbContext));
} }
public IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext<TOtherDbContext, TTargetDbContext>()
{
return ReplaceDbContext(typeof(TOtherDbContext), typeof(TTargetDbContext));
}
public IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext(Type otherDbContextType) public IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext(Type otherDbContextType, Type targetDbContextType = null)
{ {
if (!otherDbContextType.IsAssignableFrom(OriginalDbContextType)) if (!otherDbContextType.IsAssignableFrom(OriginalDbContextType))
{ {
throw new AbpException($"{OriginalDbContextType.AssemblyQualifiedName} should inherit/implement {otherDbContextType.AssemblyQualifiedName}!"); throw new AbpException($"{OriginalDbContextType.AssemblyQualifiedName} should inherit/implement {otherDbContextType.AssemblyQualifiedName}!");
} }
ReplacedDbContextTypes.AddIfNotContains(otherDbContextType); ReplacedDbContextTypes[otherDbContextType] = targetDbContextType;
return this; return this;
} }

12
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs

@ -75,9 +75,17 @@ namespace Volo.Abp.DependencyInjection
IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext<TOtherDbContext>(); IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext<TOtherDbContext>();
/// <summary> /// <summary>
/// Replaces given DbContext type with this DbContext type. /// Replaces given DbContext type with the target DbContext type.
/// </summary>
/// <typeparam name="TOtherDbContext">The DbContext type to be replaced</typeparam>
/// <typeparam name="TTargetDbContext">The target DbContext type</typeparam>
IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext<TOtherDbContext, TTargetDbContext>();
/// <summary>
/// Replaces given DbContext type with the given or this DbContext type.
/// </summary> /// </summary>
/// <param name="otherDbContextType">The DbContext type to be replaced</param> /// <param name="otherDbContextType">The DbContext type to be replaced</param>
IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext(Type otherDbContextType); /// <param name="targetDbContextType">The target DbContext type (optional, used this DbContext type if not provided)</param>
IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext(Type otherDbContextType, Type targetDbContextType = null);
} }
} }

11
framework/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs

@ -31,18 +31,21 @@ namespace Microsoft.Extensions.DependencyInjection
services.TryAddTransient(DbContextOptionsFactory.Create<TDbContext>); services.TryAddTransient(DbContextOptionsFactory.Create<TDbContext>);
foreach (var dbContextType in options.ReplacedDbContextTypes) foreach (var entry in options.ReplacedDbContextTypes)
{ {
var originalDbContextType = entry.Key;
var targetDbContextType = entry.Value ?? typeof(TDbContext);
services.Replace( services.Replace(
ServiceDescriptor.Transient( ServiceDescriptor.Transient(
dbContextType, originalDbContextType,
sp => sp.GetRequiredService(typeof(TDbContext)) sp => sp.GetRequiredService(targetDbContextType)
) )
); );
services.Configure<AbpDbContextOptions>(opts => services.Configure<AbpDbContextOptions>(opts =>
{ {
opts.DbContextReplacements[dbContextType] = typeof(TDbContext); opts.DbContextReplacements[originalDbContextType] = targetDbContextType;
}); });
} }

24
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs

@ -86,7 +86,6 @@ namespace Volo.Abp.EntityFrameworkCore
protected AbpDbContext(DbContextOptions<TDbContext> options) protected AbpDbContext(DbContextOptions<TDbContext> options)
: base(options) : base(options)
{ {
} }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
@ -372,17 +371,20 @@ namespace Volo.Abp.EntityFrameworkCore
protected virtual void ApplyAbpConceptsForModifiedEntity(EntityEntry entry, EntityChangeReport changeReport) protected virtual void ApplyAbpConceptsForModifiedEntity(EntityEntry entry, EntityChangeReport changeReport)
{ {
UpdateConcurrencyStamp(entry); if (entry.State == EntityState.Modified && entry.Properties.Any(x => x.IsModified && x.Metadata.ValueGenerated == ValueGenerated.Never))
SetModificationAuditProperties(entry);
if (entry.Entity is ISoftDelete && entry.Entity.As<ISoftDelete>().IsDeleted)
{
SetDeletionAuditProperties(entry);
changeReport.ChangedEntities.Add(new EntityChangeEntry(entry.Entity, EntityChangeType.Deleted));
}
else
{ {
changeReport.ChangedEntities.Add(new EntityChangeEntry(entry.Entity, EntityChangeType.Updated)); UpdateConcurrencyStamp(entry);
SetModificationAuditProperties(entry);
if (entry.Entity is ISoftDelete && entry.Entity.As<ISoftDelete>().IsDeleted)
{
SetDeletionAuditProperties(entry);
changeReport.ChangedEntities.Add(new EntityChangeEntry(entry.Entity, EntityChangeType.Deleted));
}
else
{
changeReport.ChangedEntities.Add(new EntityChangeEntry(entry.Entity, EntityChangeType.Updated));
}
} }
} }

5
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs

@ -82,6 +82,11 @@ namespace Volo.Abp.EntityFrameworkCore.Modeling
} }
} }
public static void ApplyObjectExtensionMappings(this EntityTypeBuilder b)
{
ObjectExtensionManager.Instance.ConfigureEfCoreEntity(b);
}
public static void ConfigureSoftDelete<T>(this EntityTypeBuilder<T> b) public static void ConfigureSoftDelete<T>(this EntityTypeBuilder<T> b)
where T : class, ISoftDelete where T : class, ISoftDelete
{ {

14
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpModelBuilderObjectExtensions.cs

@ -0,0 +1,14 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.EntityFrameworkCore.Modeling
{
public static class AbpModelBuilderObjectExtensions
{
public static void TryConfigureObjectExtensions<TDbContext>(this ModelBuilder modelBuilder)
where TDbContext : DbContext
{
ObjectExtensionManager.Instance.ConfigureEfCoreDbContext<TDbContext>(modelBuilder);
}
}
}

70
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionInfoExtensions.cs

@ -1,11 +1,17 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Volo.Abp.ObjectExtending namespace Volo.Abp.ObjectExtending
{ {
public static class EfCoreObjectExtensionInfoExtensions public static class EfCoreObjectExtensionInfoExtensions
{ {
public const string EfCoreDbContextConfigurationName = "EfCoreDbContextMapping";
public const string EfCoreEntityConfigurationName = "EfCoreEntityMapping";
[Obsolete("Use MapEfCoreProperty with EntityTypeAndPropertyBuildAction parameters.")] [Obsolete("Use MapEfCoreProperty with EntityTypeAndPropertyBuildAction parameters.")]
public static ObjectExtensionInfo MapEfCoreProperty<TProperty>( public static ObjectExtensionInfo MapEfCoreProperty<TProperty>(
[NotNull] this ObjectExtensionInfo objectExtensionInfo, [NotNull] this ObjectExtensionInfo objectExtensionInfo,
@ -71,5 +77,69 @@ namespace Volo.Abp.ObjectExtending
} }
); );
} }
public static ObjectExtensionInfo MapEfCoreEntity(
[NotNull] this ObjectExtensionInfo objectExtensionInfo,
[NotNull] Action<EntityTypeBuilder> entityTypeBuildAction)
{
Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));
var mappingOptionList = new List<ObjectExtensionInfoEfCoreMappingOptions>
{
new ObjectExtensionInfoEfCoreMappingOptions(
objectExtensionInfo,
entityTypeBuildAction)
};
objectExtensionInfo.Configuration.AddOrUpdate(EfCoreEntityConfigurationName, mappingOptionList,
(k, v) =>
{
v.As<List<ObjectExtensionInfoEfCoreMappingOptions>>().Add(mappingOptionList.First());
return v;
});
return objectExtensionInfo;
}
public static ObjectExtensionInfo MapEfCoreDbContext(
[NotNull] this ObjectExtensionInfo objectExtensionInfo,
[NotNull] Action<ModelBuilder> modelBuildAction)
{
Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));
var mappingOptionList = new List<ObjectExtensionInfoEfCoreMappingOptions>
{
new ObjectExtensionInfoEfCoreMappingOptions(
objectExtensionInfo,
modelBuildAction)
};
objectExtensionInfo.Configuration.AddOrUpdate(EfCoreDbContextConfigurationName, mappingOptionList,
(k, v) =>
{
v.As<List<ObjectExtensionInfoEfCoreMappingOptions>>().Add(mappingOptionList.First());
return v;
});
return objectExtensionInfo;
}
public static List<ObjectExtensionInfoEfCoreMappingOptions> GetEfCoreEntityMappings(
[NotNull] this ObjectExtensionInfo objectExtensionInfo)
{
Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));
return !objectExtensionInfo.Configuration.TryGetValue(EfCoreEntityConfigurationName, out var options) ?
new List<ObjectExtensionInfoEfCoreMappingOptions>() : options.As<List<ObjectExtensionInfoEfCoreMappingOptions>>();
}
public static List<ObjectExtensionInfoEfCoreMappingOptions> GetEfCoreDbContextMappings(
[NotNull] this ObjectExtensionInfo objectExtensionInfo)
{
Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));
return !objectExtensionInfo.Configuration.TryGetValue(EfCoreDbContextConfigurationName, out var options) ?
new List<ObjectExtensionInfoEfCoreMappingOptions>() : options.As<List<ObjectExtensionInfoEfCoreMappingOptions>>();
}
} }
} }

74
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionManagerExtensions.cs

@ -1,5 +1,6 @@
using System; using System;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
@ -8,6 +9,45 @@ namespace Volo.Abp.ObjectExtending
{ {
public static class EfCoreObjectExtensionManagerExtensions public static class EfCoreObjectExtensionManagerExtensions
{ {
public static ObjectExtensionManager MapEfCoreDbContext<TDbContext>(
[NotNull] this ObjectExtensionManager objectExtensionManager,
[NotNull] Action<ModelBuilder> modelBuilderAction)
where TDbContext : DbContext
{
return objectExtensionManager.AddOrUpdate(
typeof(TDbContext),
options =>
{
options.MapEfCoreDbContext(modelBuilderAction);
});
}
public static ObjectExtensionManager MapEfCoreEntity<TEntity>(
[NotNull] this ObjectExtensionManager objectExtensionManager,
[NotNull] Action<EntityTypeBuilder> entityTypeBuildAction)
where TEntity : IEntity
{
return MapEfCoreEntity(
objectExtensionManager,
typeof(TEntity),
entityTypeBuildAction);
}
public static ObjectExtensionManager MapEfCoreEntity(
[NotNull] this ObjectExtensionManager objectExtensionManager,
[NotNull] Type entityType,
[NotNull] Action<EntityTypeBuilder> entityTypeBuildAction)
{
Check.NotNull(objectExtensionManager, nameof(objectExtensionManager));
return objectExtensionManager.AddOrUpdate(
entityType,
options =>
{
options.MapEfCoreEntity(entityTypeBuildAction);
});
}
public static ObjectExtensionManager MapEfCoreProperty<TEntity, TProperty>( public static ObjectExtensionManager MapEfCoreProperty<TEntity, TProperty>(
[NotNull] this ObjectExtensionManager objectExtensionManager, [NotNull] this ObjectExtensionManager objectExtensionManager,
[NotNull] string propertyName) [NotNull] string propertyName)
@ -32,10 +72,7 @@ namespace Volo.Abp.ObjectExtending
entityType, entityType,
propertyType, propertyType,
propertyName, propertyName,
options => options => { options.MapEfCore(); }
{
options.MapEfCore();
}
); );
} }
@ -126,6 +163,13 @@ namespace Volo.Abp.ObjectExtending
return; return;
} }
var efCoreEntityMappings = objectExtension.GetEfCoreEntityMappings();
foreach (var efCoreEntityMapping in efCoreEntityMappings)
{
efCoreEntityMapping.EntityTypeBuildAction?.Invoke(typeBuilder);
}
foreach (var property in objectExtension.GetProperties()) foreach (var property in objectExtension.GetProperties())
{ {
var efCoreMapping = property.GetEfCoreMappingOrNull(); var efCoreMapping = property.GetEfCoreMappingOrNull();
@ -148,5 +192,27 @@ namespace Volo.Abp.ObjectExtending
#pragma warning restore 618 #pragma warning restore 618
} }
} }
public static void ConfigureEfCoreDbContext<TDbContext>(
[NotNull] this ObjectExtensionManager objectExtensionManager,
[NotNull] ModelBuilder modelBuilder)
where TDbContext : DbContext
{
Check.NotNull(objectExtensionManager, nameof(objectExtensionManager));
Check.NotNull(modelBuilder, nameof(modelBuilder));
var objectExtension = objectExtensionManager.GetOrNull(typeof(TDbContext));
if (objectExtension == null)
{
return;
}
var efCoreDbContextMappings = objectExtension.GetEfCoreDbContextMappings();
foreach (var efCoreDbContextMapping in efCoreDbContextMappings)
{
efCoreDbContextMapping.ModelBuildAction?.Invoke(modelBuilder);
}
}
} }
} }

39
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/ObjectExtensionInfoEfCoreMappingOptions.cs

@ -0,0 +1,39 @@
using System;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Volo.Abp.ObjectExtending
{
public class ObjectExtensionInfoEfCoreMappingOptions
{
[NotNull]
public ObjectExtensionInfo ObjectExtension { get; }
[CanBeNull]
public Action<EntityTypeBuilder> EntityTypeBuildAction { get; set; }
[CanBeNull]
public Action<ModelBuilder> ModelBuildAction { get; set; }
public ObjectExtensionInfoEfCoreMappingOptions(
[NotNull] ObjectExtensionInfo objectExtension,
[NotNull] Action<EntityTypeBuilder> entityTypeBuildAction)
{
ObjectExtension = Check.NotNull(objectExtension, nameof(objectExtension));
EntityTypeBuildAction = Check.NotNull(entityTypeBuildAction, nameof(entityTypeBuildAction));
EntityTypeBuildAction = entityTypeBuildAction;
}
public ObjectExtensionInfoEfCoreMappingOptions(
[NotNull] ObjectExtensionInfo objectExtension,
[NotNull] Action<ModelBuilder> modelBuildAction)
{
ObjectExtension = Check.NotNull(objectExtension, nameof(objectExtension));
ModelBuildAction = Check.NotNull(modelBuildAction, nameof(modelBuildAction));
ModelBuildAction = modelBuildAction;
}
}
}

2
framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Domain/Entities/EntityNotFoundException.cs

@ -49,7 +49,7 @@ namespace Volo.Abp.Domain.Entities
public EntityNotFoundException(Type entityType, object id, Exception innerException) public EntityNotFoundException(Type entityType, object id, Exception innerException)
: base( : base(
id == null id == null
? $"There is no such an entity given given id. Entity type: {entityType.FullName}" ? $"There is no such an entity given id. Entity type: {entityType.FullName}"
: $"There is no such an entity. Entity type: {entityType.FullName}, id: {id}", : $"There is no such an entity. Entity type: {entityType.FullName}, id: {id}",
innerException) innerException)
{ {

19
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs

@ -156,14 +156,17 @@ namespace Volo.Abp.Http.Client.DynamicProxying
AddHeaders(invocation, action, requestMessage, apiVersion); AddHeaders(invocation, action, requestMessage, apiVersion);
await ClientAuthenticator.Authenticate( if (action.AllowAnonymous != true)
new RemoteServiceHttpClientAuthenticateContext( {
client, await ClientAuthenticator.Authenticate(
requestMessage, new RemoteServiceHttpClientAuthenticateContext(
remoteServiceConfig, client,
clientConfig.RemoteServiceName requestMessage,
) remoteServiceConfig,
); clientConfig.RemoteServiceName
)
);
}
var response = await client.SendAsync( var response = await client.SendAsync(
requestMessage, requestMessage,

7
framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ActionApiDescriptionModel.cs

@ -26,12 +26,14 @@ namespace Volo.Abp.Http.Modeling
public ReturnValueApiDescriptionModel ReturnValue { get; set; } public ReturnValueApiDescriptionModel ReturnValue { get; set; }
public bool? AllowAnonymous { get; set; }
public ActionApiDescriptionModel() public ActionApiDescriptionModel()
{ {
} }
public static ActionApiDescriptionModel Create([NotNull] string uniqueName, [NotNull] MethodInfo method, [NotNull] string url, [CanBeNull] string httpMethod, [NotNull] IList<string> supportedVersions) public static ActionApiDescriptionModel Create([NotNull] string uniqueName, [NotNull] MethodInfo method, [NotNull] string url, [CanBeNull] string httpMethod, [NotNull] IList<string> supportedVersions, bool? allowAnonymous = null)
{ {
Check.NotNull(uniqueName, nameof(uniqueName)); Check.NotNull(uniqueName, nameof(uniqueName));
Check.NotNull(method, nameof(method)); Check.NotNull(method, nameof(method));
@ -50,7 +52,8 @@ namespace Volo.Abp.Http.Modeling
.GetParameters() .GetParameters()
.Select(MethodParameterApiDescriptionModel.Create) .Select(MethodParameterApiDescriptionModel.Create)
.ToList(), .ToList(),
SupportedVersions = supportedVersions SupportedVersions = supportedVersions,
AllowAnonymous = allowAnonymous
}; };
} }

12
framework/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs

@ -18,9 +18,17 @@ namespace Microsoft.Extensions.DependencyInjection
services.TryAddSingleton(options.DefaultRepositoryDbContextType, sp => sp.GetRequiredService<TMemoryDbContext>()); services.TryAddSingleton(options.DefaultRepositoryDbContextType, sp => sp.GetRequiredService<TMemoryDbContext>());
} }
foreach (var dbContextType in options.ReplacedDbContextTypes) foreach (var entry in options.ReplacedDbContextTypes)
{ {
services.Replace(ServiceDescriptor.Singleton(dbContextType, sp => sp.GetRequiredService<TMemoryDbContext>())); var originalDbContextType = entry.Key;
var targetDbContextType = entry.Value ?? typeof(TMemoryDbContext);
services.Replace(
ServiceDescriptor.Singleton(
originalDbContextType,
sp => sp.GetRequiredService(targetDbContextType)
)
);
} }
new MemoryDbRepositoryRegistrar(options).AddRepositories(); new MemoryDbRepositoryRegistrar(options).AddRepositories();

16
framework/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs

@ -25,23 +25,21 @@ namespace Microsoft.Extensions.DependencyInjection
optionsBuilder?.Invoke(options); optionsBuilder?.Invoke(options);
foreach (var dbContextType in options.ReplacedDbContextTypes) foreach (var entry in options.ReplacedDbContextTypes)
{
services.Replace(ServiceDescriptor.Transient(dbContextType, typeof(TMongoDbContext)));
}
foreach (var dbContextType in options.ReplacedDbContextTypes)
{ {
var originalDbContextType = entry.Key;
var targetDbContextType = entry.Value ?? typeof(TMongoDbContext);
services.Replace( services.Replace(
ServiceDescriptor.Transient( ServiceDescriptor.Transient(
dbContextType, originalDbContextType,
sp => sp.GetRequiredService(typeof(TMongoDbContext)) sp => sp.GetRequiredService(targetDbContextType)
) )
); );
services.Configure<AbpMongoDbContextOptions>(opts => services.Configure<AbpMongoDbContextOptions>(opts =>
{ {
opts.DbContextReplacements[dbContextType] = typeof(TMongoDbContext); opts.DbContextReplacements[originalDbContextType] = targetDbContextType;
}); });
} }

2
framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs

@ -24,7 +24,7 @@ namespace Volo.Abp.ObjectExtending
public ObjectExtensionInfo([NotNull] Type type) public ObjectExtensionInfo([NotNull] Type type)
{ {
Type = Check.AssignableTo<IHasExtraProperties>(type, nameof(type)); Type = Check.NotNull(type, nameof(type));
Properties = new ConcurrentDictionary<string, ObjectExtensionPropertyInfo>(); Properties = new ConcurrentDictionary<string, ObjectExtensionPropertyInfo>();
Configuration = new ConcurrentDictionary<object, object>(); Configuration = new ConcurrentDictionary<object, object>();
Validators = new List<Action<ObjectExtensionValidationContext>>(); Validators = new List<Action<ObjectExtensionValidationContext>>();

6
framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManager.cs

@ -25,7 +25,6 @@ namespace Volo.Abp.ObjectExtending
[NotNull] [NotNull]
public virtual ObjectExtensionManager AddOrUpdate<TObject>( public virtual ObjectExtensionManager AddOrUpdate<TObject>(
[CanBeNull] Action<ObjectExtensionInfo> configureAction = null) [CanBeNull] Action<ObjectExtensionInfo> configureAction = null)
where TObject : IHasExtraProperties
{ {
return AddOrUpdate(typeof(TObject), configureAction); return AddOrUpdate(typeof(TObject), configureAction);
} }
@ -50,8 +49,6 @@ namespace Volo.Abp.ObjectExtending
[NotNull] Type type, [NotNull] Type type,
[CanBeNull] Action<ObjectExtensionInfo> configureAction = null) [CanBeNull] Action<ObjectExtensionInfo> configureAction = null)
{ {
Check.AssignableTo<IHasExtraProperties>(type, nameof(type));
var extensionInfo = ObjectsExtensions.GetOrAdd( var extensionInfo = ObjectsExtensions.GetOrAdd(
type, type,
_ => new ObjectExtensionInfo(type) _ => new ObjectExtensionInfo(type)
@ -64,7 +61,6 @@ namespace Volo.Abp.ObjectExtending
[CanBeNull] [CanBeNull]
public virtual ObjectExtensionInfo GetOrNull<TObject>() public virtual ObjectExtensionInfo GetOrNull<TObject>()
where TObject : IHasExtraProperties
{ {
return GetOrNull(typeof(TObject)); return GetOrNull(typeof(TObject));
} }
@ -72,8 +68,6 @@ namespace Volo.Abp.ObjectExtending
[CanBeNull] [CanBeNull]
public virtual ObjectExtensionInfo GetOrNull([NotNull] Type type) public virtual ObjectExtensionInfo GetOrNull([NotNull] Type type)
{ {
Check.AssignableTo<IHasExtraProperties>(type, nameof(type));
return ObjectsExtensions.GetOrDefault(type); return ObjectsExtensions.GetOrDefault(type);
} }

5
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs

@ -89,6 +89,11 @@ namespace Volo.Abp.Uow
public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default) public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default)
{ {
if (_isRolledback)
{
return;
}
foreach (var databaseApi in GetAllActiveDatabaseApis()) foreach (var databaseApi in GetAllActiveDatabaseApis())
{ {
if (databaseApi is ISupportsSavingChanges) if (databaseApi is ISupportsSavingChanges)

4
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Reflection; using Volo.Abp.Reflection;
@ -120,9 +121,10 @@ namespace Volo.Abp.Validation
MemberName = property.Name MemberName = property.Name
}; };
var attributeValidationResultProvider = ServiceProvider.GetRequiredService<IAttributeValidationResultProvider>();
foreach (var attribute in validationAttributes) foreach (var attribute in validationAttributes)
{ {
var result = attribute.GetValidationResult(property.GetValue(validatingObject), validationContext); var result = attributeValidationResultProvider.GetOrDefault(attribute, property.GetValue(validatingObject), validationContext);
if (result != null) if (result != null)
{ {
errors.Add(result); errors.Add(result);

13
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DefaultAttributeValidationResultProvider.cs

@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Validation
{
public class DefaultAttributeValidationResultProvider : IAttributeValidationResultProvider, ITransientDependency
{
public virtual ValidationResult GetOrDefault(ValidationAttribute validationAttribute, object validatingObject, ValidationContext validationContext)
{
return validationAttribute.GetValidationResult(validatingObject, validationContext);
}
}
}

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

Loading…
Cancel
Save