Browse Source

Merge branch 'docs-unification-1' into upgrade-command-doc

pull/19973/head
Yunus Emre Kalkan 2 years ago
parent
commit
e8273f45d6
  1. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json
  2. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json
  3. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json
  4. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json
  5. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json
  6. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json
  7. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json
  8. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json
  9. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json
  10. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json
  11. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json
  12. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json
  13. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json
  14. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json
  15. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json
  16. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json
  17. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json
  18. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json
  19. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json
  20. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
  21. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json
  22. BIN
      docs/en/Community-Articles/2024-04-19-using-blob-storage-with-abp/images/blob-storage.png
  23. 114
      docs/en/Community-Articles/2024-04-19-using-blob-storage-with-abp/post.md
  24. BIN
      docs/en/Community-Articles/2024-05-07-using-fluent-validation-with-abp/images/adding-incorrect-data.png
  25. BIN
      docs/en/Community-Articles/2024-05-07-using-fluent-validation-with-abp/images/error.png
  26. BIN
      docs/en/Community-Articles/2024-05-07-using-fluent-validation-with-abp/images/validation.png
  27. 336
      docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/POST.md
  28. BIN
      docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/cover-image.png
  29. BIN
      docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/demo.gif
  30. BIN
      docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/sentiment-analysis-steps.png
  31. BIN
      docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/sentiment-analysis.png
  32. 411
      docs/en/cli/index.md
  33. 67
      docs/en/cli/new-command-samples.md
  34. 4
      docs/en/modules/audit-logging-pro.md
  35. 4
      docs/en/modules/chat.md
  36. 4
      docs/en/modules/cms-kit-pro/index.md
  37. 2
      docs/en/modules/cms-kit-pro/newsletter.md
  38. 2
      docs/en/modules/cms-kit-pro/page-feedback.md
  39. 2
      docs/en/modules/cms-kit-pro/poll.md
  40. 2
      docs/en/modules/cms-kit-pro/url-forwarding.md
  41. 2
      docs/en/modules/cms-kit/comments.md
  42. 2
      docs/en/modules/cms-kit/dynamic-widget.md
  43. 2
      docs/en/modules/cms-kit/ratings.md
  44. 2
      docs/en/modules/cms-kit/reactions.md
  45. 2
      docs/en/modules/cms-kit/tags.md
  46. 4
      docs/en/modules/file-management.md
  47. 4
      docs/en/modules/forms.md
  48. 4
      docs/en/modules/gdpr.md
  49. 4
      docs/en/modules/identity-pro.md
  50. 4
      docs/en/modules/identity-server-pro.md
  51. 2
      docs/en/modules/identity/idap.md
  52. 4
      docs/en/modules/language-management.md
  53. 4
      docs/en/modules/openiddict-pro.md
  54. 2
      docs/en/modules/payment-custom-gateway.md
  55. 4
      docs/en/modules/payment.md
  56. 4
      docs/en/modules/saas.md
  57. 4
      docs/en/modules/text-template-management.md
  58. 4
      docs/en/modules/twilio-sms.md
  59. 30
      docs/en/solution-templates/microservice/authentication.md
  60. 18
      docs/en/solution-templates/microservice/database-configurations.md
  61. BIN
      docs/en/solution-templates/microservice/images/account-external-provider.png
  62. BIN
      docs/en/solution-templates/microservice/images/grafana-dashboard.png
  63. BIN
      docs/en/solution-templates/microservice/images/new-solution-openiddict-module.png
  64. BIN
      docs/en/solution-templates/microservice/images/openiddict-ui.png
  65. 2
      docs/en/solution-templates/microservice/index.md
  66. 6
      docs/en/solution-templates/microservice/logging.md
  67. 6
      docs/en/solution-templates/microservice/microservices.md
  68. 62
      docs/en/solution-templates/microservice/monitoring.md
  69. 26
      docs/en/solution-templates/microservice/overview.md
  70. 2
      docs/en/solution-templates/microservice/solution-structure.md
  71. 376
      docs/en/studio/cli.md
  72. BIN
      docs/en/studio/images/preference-theme-change.png
  73. 3
      docs/en/studio/index.md
  74. 17
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs
  75. 1
      framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
  76. 8
      framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs
  77. 4
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs
  78. 35
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsTransformation.cs
  79. 8
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs
  80. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeThemeStep.cs
  81. 7
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs
  82. 4
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs
  83. 68
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationScheme.cs
  84. 2
      modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/wwwroot/themes/basic/layout.js
  85. 2
      npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html
  86. 20
      npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts
  87. 1
      templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/Components/Routes.razor
  88. 1
      templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Components/Routes.razor
  89. 1
      templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Client/Routes.razor
  90. 1
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Client/Routes.razor
  91. 1
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Components/Routes.razor
  92. 1
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Components/Routes.razor
  93. 1
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Client/Routes.razor
  94. 1
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client/Routes.razor
  95. 1
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host.Client/Routes.razor
  96. 1
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Components/Routes.razor

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> أيد.",
"Preview": "معاينة",
"VisitVideoCourseDescription": "إذا كنت ترغب في تعلم أساسيات إطار عمل برنامج ABP، فاطلع على دورات الفيديو الخاصة ببرنامج ABP Essentials.",
"VisitPage": "زر الصفحة"
"VisitPage": "زر الصفحة",
"ConfirmEmailForPost": "لتتمكن من النشر، تحتاج إلى تأكيد بريدك الإلكتروني. انتقل إلى account.abp.io/Account/Manage وتحقق من بريدك الإلكتروني في علامة التبويب \"المعلومات الشخصية\".",
"DailyPostCreateLimitation": "لقد وصلت إلى الحد الأقصى اليومي لإنشاء المنشورات. يمكنك إنشاء مشاركة جديدة في {0}."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> podporováno.",
"Preview": "Náhled",
"VisitPage": "Navštivte stránku",
"VisitVideoCourseDescription": "Pokud se chcete naučit základy rámce ABP, podívejte se na videokurzy ABP Essentials."
"VisitVideoCourseDescription": "Pokud se chcete naučit základy rámce ABP, podívejte se na videokurzy ABP Essentials.",
"ConfirmEmailForPost": "Abyste mohli přidávat příspěvky, musíte potvrdit svůj e-mail. Přejděte na stránku account.abp.io/Account/Manage a ověřte svůj e-mail na kartě Osobní údaje.",
"DailyPostCreateLimitation": "Dosáhli jste denního limitu pro vytváření příspěvků. Nový příspěvek můžete vytvořit v {0}."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> unterstützt.",
"Preview": "Vorschau",
"VisitPage": "Seite besuchen",
"VisitVideoCourseDescription": "Wenn Sie die Grundlagen des ABP Framework erlernen möchten, schauen Sie sich die ABP Essentials-Videokurse an."
"VisitVideoCourseDescription": "Wenn Sie die Grundlagen des ABP Framework erlernen möchten, schauen Sie sich die ABP Essentials-Videokurse an.",
"ConfirmEmailForPost": "Um Beiträge verfassen zu können, müssen Sie Ihre E-Mail-Adresse bestätigen. Gehen Sie zu account.abp.io/Account/Manage und bestätigen Sie Ihre E-Mail-Adresse auf der Registerkarte „Persönliche Daten“.",
"DailyPostCreateLimitation": "Sie haben das tägliche Limit für die Erstellung von Beiträgen erreicht. Sie können in {0} einen neuen Beitrag erstellen."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> soportado.",
"Preview": "Avance",
"VisitPage": "Visita la página",
"VisitVideoCourseDescription": "Si desea aprender los conceptos básicos del marco ABP, consulte los cursos en vídeo de ABP Essentials."
"VisitVideoCourseDescription": "Si desea aprender los conceptos básicos del marco ABP, consulte los cursos en vídeo de ABP Essentials.",
"ConfirmEmailForPost": "Para poder publicar, debe confirmar su correo electrónico. Vaya a account.abp.io/Account/Manage y verifique su correo electrónico en la pestaña Información personal.",
"DailyPostCreateLimitation": "Has alcanzado el límite diario de creación de publicaciones. Puedes crear una nueva publicación en {0}."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> tuettu.",
"Preview": "Esikatselu",
"VisitPage": "Vieraile sivulla",
"VisitVideoCourseDescription": "Jos haluat oppia ABP Frameworkin perusteet, katso ABP Essentials Video -kurssit."
"VisitVideoCourseDescription": "Jos haluat oppia ABP Frameworkin perusteet, katso ABP Essentials Video -kurssit.",
"ConfirmEmailForPost": "Jotta voit lähettää viestejä, sinun on vahvistettava sähköpostiosoitteesi. Siirry osoitteeseen account.abp.io/Account/Manage ja vahvista sähköpostiosoitteesi Henkilökohtaiset tiedot -välilehdessä.",
"DailyPostCreateLimitation": "Olet saavuttanut päivittäisen viestien luomisrajan. Voit luoda uuden viestin kohteessa {0}."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> prise en charge.",
"Preview": "Aperçu",
"VisitPage": "Page de visite",
"VisitVideoCourseDescription": "Si vous souhaitez apprendre les bases du framework ABP, consultez les cours vidéo ABP Essentials."
"VisitVideoCourseDescription": "Si vous souhaitez apprendre les bases du framework ABP, consultez les cours vidéo ABP Essentials.",
"ConfirmEmailForPost": "Pour pouvoir publier, vous devez confirmer votre e-mail. Accédez à account.abp.io/Account/Manage et vérifiez votre e-mail dans l'onglet Informations personnelles.",
"DailyPostCreateLimitation": "Vous avez atteint la limite quotidienne de création de publications. Vous pouvez créer une nouvelle publication dans {0}."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> का समर्थन किया।",
"Preview": "पूर्व दर्शन",
"VisitPage": "यात्रा पेज",
"VisitVideoCourseDescription": "यदि आप एबीपी फ्रेमवर्क की मूल बातें सीखना चाहते हैं, तो एबीपी एसेंशियल वीडियो पाठ्यक्रम देखें।"
"VisitVideoCourseDescription": "यदि आप एबीपी फ्रेमवर्क की मूल बातें सीखना चाहते हैं, तो एबीपी एसेंशियल वीडियो पाठ्यक्रम देखें।",
"ConfirmEmailForPost": "पोस्ट करने में सक्षम होने के लिए, आपको अपने ईमेल की पुष्टि करनी होगी। account.abp.io/Account/Manage पर जाएं और व्यक्तिगत जानकारी टैब में अपना ईमेल सत्यापित करें।",
"DailyPostCreateLimitation": "आप दैनिक पोस्ट निर्माण सीमा तक पहुंच गए हैं। आप {0} में एक नई पोस्ट बना सकते हैं।"
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> podržan.",
"Preview": "Pregled",
"VisitPage": "Posjetite stranicu",
"VisitVideoCourseDescription": "Ako želite naučiti osnove ABP okvira, pogledajte video tečajeve ABP Essentials."
"VisitVideoCourseDescription": "Ako želite naučiti osnove ABP okvira, pogledajte video tečajeve ABP Essentials.",
"ConfirmEmailForPost": "Da biste mogli objavljivati, morate potvrditi svoju e-poštu. Idite na account.abp.io/Account/Manage i potvrdite svoju e-poštu na kartici Osobni podaci.",
"DailyPostCreateLimitation": "Dosegli ste dnevno ograničenje za izradu postova. Možete stvoriti novi post u {0}."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> támogatott.",
"Preview": "Előnézet",
"VisitPage": "Látogassa meg az oldalt",
"VisitVideoCourseDescription": "Ha meg szeretné tanulni az ABP Framework alapjait, nézze meg az ABP Essentials Video tanfolyamokat."
"VisitVideoCourseDescription": "Ha meg szeretné tanulni az ABP Framework alapjait, nézze meg az ABP Essentials Video tanfolyamokat.",
"ConfirmEmailForPost": "A bejegyzések közzétételéhez meg kell erősítenie e-mail-címét. Nyissa meg az account.abp.io/Account/Manage oldalt, és ellenőrizze e-mail-címét a Személyes adatok lapon.",
"DailyPostCreateLimitation": "Elérte a napi bejegyzéslétrehozási korlátot. Új bejegyzést itt hozhat létre: {0}."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> stutt.",
"Preview": "Forskoðun",
"VisitPage": "Heimsæktu síðu",
"VisitVideoCourseDescription": "Ef þú vilt læra grunnatriði ABP Framework skaltu skoða ABP Essentials Video námskeiðin."
"VisitVideoCourseDescription": "Ef þú vilt læra grunnatriði ABP Framework skaltu skoða ABP Essentials Video námskeiðin.",
"ConfirmEmailForPost": "Til að geta sent færslur þarftu að staðfesta netfangið þitt. Farðu á account.abp.io/Account/Manage og staðfestu tölvupóstinn þinn á Persónulegum upplýsingum flipanum.",
"DailyPostCreateLimitation": "Þú hefur náð daglegu takmörkunum fyrir færslu færslu. Þú getur búið til nýja færslu í {0}."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> supportato.",
"Preview": "Anteprima",
"VisitPage": "Visita la pagina",
"VisitVideoCourseDescription": "Se vuoi apprendere le nozioni di base del Framework ABP, dai un'occhiata ai corsi video ABP Essentials."
"VisitVideoCourseDescription": "Se vuoi apprendere le nozioni di base del Framework ABP, dai un'occhiata ai corsi video ABP Essentials.",
"ConfirmEmailForPost": "Per poter pubblicare, devi confermare la tua email. Vai su account.abp.io/Account/Manage e verifica la tua email nella scheda Informazioni personali.",
"DailyPostCreateLimitation": "Hai raggiunto il limite giornaliero di creazione di post. Puoi creare un nuovo post in {0}."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> ondersteund.",
"Preview": "Voorbeeld",
"VisitPage": "Bezoek pagina",
"VisitVideoCourseDescription": "Als je de basis van het ABP Framework wilt leren, bekijk dan de ABP Essentials Videocursussen."
"VisitVideoCourseDescription": "Als je de basis van het ABP Framework wilt leren, bekijk dan de ABP Essentials Videocursussen.",
"ConfirmEmailForPost": "Om te kunnen posten, moet u uw e-mailadres bevestigen. Ga naar account.abp.io/Account/Manage en verifieer uw e-mailadres op het tabblad Persoonlijke informatie.",
"DailyPostCreateLimitation": "Je hebt de dagelijkse limiet voor het maken van berichten bereikt. Je kunt een nieuw bericht maken in {0}."
}
}

4
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> utrzymany.",
"Preview": "Zapowiedź",
"VisitPage": "Odwiedź stronę",
"VisitVideoCourseDescription": "Jeśli chcesz poznać podstawy ABP Framework, sprawdź kursy wideo ABP Essentials."
"VisitVideoCourseDescription": "Jeśli chcesz poznać podstawy ABP Framework, sprawdź kursy wideo ABP Essentials.",
"ConfirmEmailForPost": "Aby móc publikować, musisz potwierdzić swój adres e-mail. Przejdź do account.abp.io/Account/Manage i zweryfikuj swój adres e-mail w zakładce Dane osobowe.",
"DailyPostCreateLimitation": "Osiągnąłeś dzienny limit tworzenia postów. Możesz utworzyć nowy post w {0}."
}
}

4
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> suportado.",
"Preview": "Visualização",
"VisitPage": "Visite a página",
"VisitVideoCourseDescription": "Se você quiser aprender o básico do ABP Framework, confira os cursos em vídeo ABP Essentials."
"VisitVideoCourseDescription": "Se você quiser aprender o básico do ABP Framework, confira os cursos em vídeo ABP Essentials.",
"ConfirmEmailForPost": "Para poder postar, você precisa confirmar seu e-mail. Acesse account.abp.io/Account/Manage e verifique seu e-mail na guia Informações pessoais.",
"DailyPostCreateLimitation": "Você atingiu o limite diário de criação de postagens. Você pode criar uma nova postagem em {0}."
}
}

4
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> sprijinit.",
"Preview": "previzualizare",
"VisitPage": "Vizitați pagina",
"VisitVideoCourseDescription": "Dacă doriți să aflați elementele de bază ale cadrului ABP, consultați cursurile video ABP Essentials."
"VisitVideoCourseDescription": "Dacă doriți să aflați elementele de bază ale cadrului ABP, consultați cursurile video ABP Essentials.",
"ConfirmEmailForPost": "Pentru a putea posta, trebuie să vă confirmați adresa de e-mail. Accesați account.abp.io/Account/Manage și verificați e-mailul în fila Informații personale.",
"DailyPostCreateLimitation": "Ați atins limita zilnică de creare a postărilor. Puteți crea o postare nouă în {0}."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> podporované.",
"Preview": "Náhľad",
"VisitPage": "Navštívte stránku",
"VisitVideoCourseDescription": "Ak sa chcete naučiť základy rámca ABP, pozrite si video kurzy ABP Essentials."
"VisitVideoCourseDescription": "Ak sa chcete naučiť základy rámca ABP, pozrite si video kurzy ABP Essentials.",
"ConfirmEmailForPost": "Aby ste mohli uverejňovať príspevky, musíte potvrdiť svoj e-mail. Prejdite na stránku account.abp.io/Account/Manage a overte svoj e-mail na karte Osobné informácie.",
"DailyPostCreateLimitation": "Dosiahli ste denný limit na vytváranie príspevkov. Nový príspevok môžete vytvoriť v {0}."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> podprt.",
"Preview": "Predogled",
"VisitPage": "Obiščite stran",
"VisitVideoCourseDescription": "Če se želite naučiti osnov ogrodja ABP, si oglejte video tečaje ABP Essentials."
"VisitVideoCourseDescription": "Če se želite naučiti osnov ogrodja ABP, si oglejte video tečaje ABP Essentials.",
"ConfirmEmailForPost": "Če želite objavljati, morate potrditi svoj e-poštni naslov. Pojdite na account.abp.io/Account/Manage in potrdite svoj e-poštni naslov na zavihku Osebni podatki.",
"DailyPostCreateLimitation": "Dosegli ste dnevno omejitev za ustvarjanje objav. Novo objavo lahko ustvarite v {0}."
}
}

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

@ -244,6 +244,8 @@
"BuyTicket": "Bilet al",
"SeeEvent": "Etkinliği Gör",
"Cancel": "Vazgeç",
"Continue": "Devam"
"Continue": "Devam",
"ConfirmEmailForPost": "Gönderi paylaşabilmek için e-posta adresinizi onaylamanız gerekir. account.abp.io/Account/Manage adresine gidin ve Kişisel Bilgiler sekmesinden e-posta adresinizi doğrulayın.",
"DailyPostCreateLimitation": "Günlük gönderi paylaşma sınırına ulaştınız. {0}'da yeni bir gönderi paylaşabilirsiniz."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> được hỗ trợ.",
"Preview": "Xem trước",
"VisitPage": "Ghé thăm trang",
"VisitVideoCourseDescription": "Nếu bạn muốn tìm hiểu những kiến ​​thức cơ bản về Khung ABP, hãy xem các khóa học Video Cơ bản về ABP."
"VisitVideoCourseDescription": "Nếu bạn muốn tìm hiểu những kiến ​​thức cơ bản về Khung ABP, hãy xem các khóa học Video Cơ bản về ABP.",
"ConfirmEmailForPost": "Để có thể đăng bài, bạn cần xác nhận email của mình. Hãy truy cập account.abp.io/Account/Quản lý và xác minh email của bạn trong tab Thông tin cá nhân.",
"DailyPostCreateLimitation": "Bạn đã đạt đến giới hạn tạo bài đăng hàng ngày. Bạn có thể tạo bài đăng mới trong {0}."
}
}

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

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> 支持的。",
"Preview": "预览",
"VisitPage": "访问页面",
"VisitVideoCourseDescription": "如果您想学习 ABP 框架的基础知识,请查看 ABP Essentials 视频课程。"
"VisitVideoCourseDescription": "如果您想学习 ABP 框架的基础知识,请查看 ABP Essentials 视频课程。",
"ConfirmEmailForPost": "为了能够发帖,您需要确认您的电子邮件。转到 account.abp.io/Account/Manage 并在“个人信息”选项卡中验证您的电子邮件。",
"DailyPostCreateLimitation": "您已达到每日帖子创建限制。您可以在 {0} 中创建新帖子。"
}
}

4
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json

@ -259,6 +259,8 @@
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a> 支持的。",
"Preview": "预览",
"VisitPage": "访问页面",
"VisitVideoCourseDescription": "如果您想学习 ABP 框架的基础知识,请查看 ABP Essentials 视频课程。"
"VisitVideoCourseDescription": "如果您想学习 ABP 框架的基础知识,请查看 ABP Essentials 视频课程。",
"ConfirmEmailForPost": "为了能够发帖,您需要确认您的电子邮件。转到 account.abp.io/Account/Manage 并在“个人信息”选项卡中验证您的电子邮件。",
"DailyPostCreateLimitation": "您已达到每日帖子创建限制。您可以在 {0} 中创建新帖子。"
}
}

BIN
docs/en/Community-Articles/2024-04-19-using-blob-storage-with-abp/images/blob-storage.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

114
docs/en/Community-Articles/2024-04-19-using-blob-storage-with-abp/post.md

@ -0,0 +1,114 @@
# Using Blob Storage with ABP
ABP Framework provides a comprehensive solution to meet the needs of modern application development, while addressing the important requirement of BLOB Storing. ABP Framework [provides an easy integration for Blob Storing](https://docs.abp.io/en/abp/latest/Blob-Storing) and offers many storage services that you can easily integrate. In addition to efficiently storing large files, these services offer significant advantages such as scalability, security and backup.
## What is Blob Storage ?
Blob Storage is a service for storing unstructured data. It is becoming increasingly important to efficiently store and manage large data types (e.g. images, videos, documents). Blob Storage was developed to meet these needs and offers a secure solution with the advantages of scalability, durability and low cost.
![Blob Stroge](./images/blob-storage.png)
## How to use Blob Storage ?
I would like to explain this to you with an example.For example, storing large files such as user profile pictures in the database negatively affects the performance and database.You can store this data using Blob storage. One of the advantages of storing user profile pictures in blob storage is that it improves database performance. Blob storage is a more efficient option than storing large size files in the database and allows database queries to run faster. Furthermore, blob storage provides scalability, so that the number of profile pictures can grow with the number of users, but without storage issues. This approach also maintains database normalization and makes the database design cleaner.
How do we store user profile pictures with Blob Storage using ABP Framework?
- #### Step 1: Configure the Blob Container
Define a Blob Container named `profile-pictures` using the `[BlobContainerName("profile-pictures")]` attribute.
````csharp
[BlobContainerName("profile-pictures")]
public class ProfilePictureContainer
{
}
````
- #### Step 2: Create the ProfileAppService (Saving & Reading BLOBs)
Create the `ProfileAppService` class and derive it from the `ApplicationService` class. This class will perform the necessary operations to store and retrieve profile pictures.
````csharp
using Volo.Abp.Application.Services;
public class ProfileAppService : ApplicationService
{
// Code snippets will come here
}
````
- #### Step 3: Inject the `IBlobContainer` Service
Inject the `IBlobContainer` service, in the constructor of the `ProfileAppService` class. The `IBlobContainer` is the main interface to store and read BLOB and is used to interact with the container.
````csharp
private readonly IBlobContainer<ProfilePictureContainer> _blobContainer;
public ProfileAppService(IBlobContainer<ProfilePictureContainer> blobContainer)
{
_blobContainer = blobContainer;
}
````
- #### Step 4: Save Profile Picture
The SaveProfilePictureAsync method is used to store the user's profile picture. A unique name is generated based on the user's credentials and the profile picture byte array with this name is saved in the Blob Container.
````csharp
public async Task SaveProfilePictureAsync(byte[] bytes)
{
var blobName = CurrentUser.GetId().ToString();
await _blobContainer.SaveAsync(blobName, bytes);
}
````
- #### Step 5: Getting Profile Picture
The GetProfilePictureAsync method is used to get the user's profile picture. A profile picture byte array is retrieved from the Blob Container with a specified name based on the user's credential.
````csharp
public async Task<byte[]> GetProfilePictureAsync()
{
var blobName = CurrentUser.GetId().ToString();
return await _blobContainer.GetAllBytesOrNullAsync(blobName);
}
````
Finally, add controls in the user interface that will allow users to upload and view their profile pictures. These controls will perform the operations by calling the corresponding methods in the ProfileAppService class.
These steps cover the basic steps to store user profile pictures with Blob Storage using the ABP Framework. [Check out the documentation for more information.](https://docs.abp.io/en/abp/latest/Blob-Storing)
## What are the Advantages/Disadvantages of Keeping the BLOBs in a Database?
#### Advantages:
- Data Integrity and Relational Model: To ensure data integrity and preserve the relational model, it is important to store blob data in the database. This approach preserves the relationships between data and maintains the structural integrity of the database.
- A Single Storage Location: Storing blob data in the database allows you to collect all data in a single storage location. This simplifies the management of data and increases data integrity.
- Advanced Security Controls: Database systems often offer advanced security controls. Storing blob data in a database allows you to take advantage of these security features and ensures that data is accessed by authorized users.
#### Disadvantages:
- Performance Issues: Storing blob data in a database can negatively impact database performance. Oversized blob data can slow down query processing and reduce database performance.
- Storage Space Issue: Storing blob data in the database can increase the size of the database and require more storage space. This can increase storage costs and complicate infrastructure requirements.
- Backup and Recovery Challenges: Storing blob data in a database can make backup and recovery difficult. The large size of blob data can make backup and recovery time-consuming and data recovery difficult.
## Other Blob Storage Providers
ABP Framework provides developers with a variety of options and flexibility by offering integration infrastructure for multiple cloud providers. This makes it easy for users to choose between different cloud platforms and select the most suitable solution for their business needs.
- Azure Blob Storage: A cloud storage service offered on the Microsoft Azure platform. It is used to store and access large amounts of data. It supports various data types such as files, images, videos and provides high scalability. ABP Framework provides integration with [Azure Blob Storage](https://docs.abp.io/en/abp/latest/Blob-Storing-Azure).
- Aliyun Object Storage Service (OSS): OSS, Alibaba Cloud's cloud storage service, is an ideal solution for use cases such as big data storage, backup and media storage. It offers flexible storage options and provides a high level of security. ABP Framework interfaces with [Aliyun Blob Storage](https://docs.abp.io/en/abp/latest/Blob-Storing-Aliyun), making it easier for developers to manage data storage and access.
- MinIO: MinIO is known as an open source object storage system and offers an Amazon S3 compatible cloud storage solution. It is a high-performance, scalable and fast storage service. ABP Framework integrates with [MinIO Blob Storage](https://docs.abp.io/en/abp/latest/Blob-Storing-Minio) to provide developers with cloud-based file and object storage.
- Amazon Simple Storage Service (S3): Amazon S3 is a cloud storage service offered on the Amazon Web Services (AWS) platform. It can be used to store virtually unlimited amounts of data. It provides high durability, scalability and low cost.ABP Framework integrates with [Amazon S3 Blob Storage](https://docs.abp.io/en/abp/latest/Blob-Storing-Aws) to provide developers with cloud-based file and object storage.

BIN
docs/en/Community-Articles/2024-05-07-using-fluent-validation-with-abp/images/adding-incorrect-data.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 61 KiB

BIN
docs/en/Community-Articles/2024-05-07-using-fluent-validation-with-abp/images/error.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 17 KiB

BIN
docs/en/Community-Articles/2024-05-07-using-fluent-validation-with-abp/images/validation.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 48 KiB

336
docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/POST.md

@ -0,0 +1,336 @@
# Sentiment Analysis Within ABP-Based Application
In this article, first I will briefly explain what sentiment analysis is and then show you how you can apply sentiment analysis in an ABP-Based application (or any kind of .NET application).
We will use ML.NET Framework, which is an open-source machine learning framework created by the dotnet team and also we will create a layered ABP Solution by using the application template and finally we will use CMS Kit's Comment Feature and extend its behavior by adding spam detection while creating or updating a comment, at that point we will make sentiment analysis.
## Sentiment Analysis
[Sentiment Analysis (or opinion mining)](https://en.wikipedia.org/wiki/Sentiment_analysis) refers to determining the emotion from the given input. The primary goal of sentiment analysis is to identify, extract, and categorize (positive, negative, or neutral) the sentiments expressed in textual data.
To understand it better, let's check the following figure and examine the comments:
![](sentiment-analysis.png)
* If you look at these comments, you will notice that comments have ratings and it's easy to understand the emotion or thoughts of the users who commented about the related product.
* But even if there was not any rating specified for the given comments we still can get the emotion of the users. Because, as you can see, the comments specified some obvious words that express emotions, for example, in the first comment, the user says **he/she liked the product**, **it's easy to use** and **its battery is good**, and therefore this is obviously a positive comment.
* On the other hand, if we look at the second comment, we will notice some negative statements such as **useless phone**, **cannot maintain any data connection** and the user suggests **do not buy this phone**. Actually, this is what sentiment analysis is all about, abstracting the emotion from a given input, it's comment in that case but it can be any kind of input or input-group.
## Demo: Spam Detection (Applying Sentiment Analysis)
> You can get the source code of the demo from [https://github.com/EngincanV/SentimentAnalysisDemo](https://github.com/EngincanV/SentimentAnalysisDemo).
In this demo application, we will create an [ABP-based application](https://docs.abp.io/en/abp/8.1/Startup-Templates/Application) and integrate the [ABP's CMS Kit Module's Comment Feature](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Comments), which provides a comment system to add a comment to any kind of resource, such as blog posts or products.
By default, CMS Kit's Comment Feature does not provide spam detection and therefore in this sample application, we will add [spam detection](https://github.com/EngincanV/SentimentAnalysisDemo/blob/master/src/SentimentAnalysisDemo.Application/ML/SpamDetector.cs) while creating or updating a comment. Thus, whenever a comment is being added or updated, the spam detection service will validate the comment and reject it if it contains spam content otherwise it will make the other validations and save the comment:
![](sentiment-analysis-steps.png)
To get started, we will first create an application, and add the CMS Kit Module to the solution and then we will enable the Comment Feature of the CMS Kit Module, and finally, we will add the Comment Component to the homepage and add spam detection by extending the behavior. Let's start with creating the application!
### Creating an ABP-Based Application
You can use the following command to create a layered ABP solution (with MongoDB as the database option):
```bash
abp new SentimentAnalysisDemo -t app -d mongodb --version 8.1.1
```
### Installing the CMS Kit Module
After creating the project, we can add the CMS Kit module to our project. [ABP CLI](https://docs.abp.io/en/abp/latest/CLI) provides the `add-module` command to install a specific module to a solution.
You can use the following command to install the CMS Kit module into your application (run this command in the solution directory):
```bash
abp add-module Volo.CmsKit --skip-db-migrations
```
After this command is executed, all related CMS Kit packages will be added to the correct layers and then you can enable any CMS Kit feature you want.
### Enabling the Comment Feature
By default, CMS Kit features are disabled. Therefore, you need to enable the features you want, before starting to use it. You can either enable all of them or enable them one by one. In our demo application, we only need the **Comment Feature**, therefore we can only enable it.
To enable the Comment Feature, you can open the `SentimentAnalysisDemoGlobalFeatureConfigurator` class (under the `*.Domain.Shared` project) and update it as follows:
```csharp
using Volo.Abp.GlobalFeatures;
using Volo.Abp.Threading;
namespace SentimentAnalysisDemo;
public static class SentimentAnalysisDemoGlobalFeatureConfigurator
{
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
public static void Configure()
{
OneTimeRunner.Run(() =>
{
GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit =>
{
cmsKit.Comments.Enable();
});
});
}
}
```
After enabling the feature, now we can make the final configurations and directly use it in our application.
### Configurations for Comment Feature
Open the `SentimentAnalysisDemoDomainModule` class and add the following code-block into the `ConfigureServices` method:
```csharp
Configure<CmsKitCommentOptions>(options =>
{
options.EntityTypes.Add(new CommentEntityTypeDefinition("Comment"));
options.IsRecaptchaEnabled = true;
});
```
Here, we simply defining what should be the entity-type name of our comment and also enable the reCaptcha for the comment system. After this configuration, now we can open the `Index.cshtml` file in the `*.Web` project and invoke the `CommentingViewComponent` as below:
```html
@page
@using Microsoft.AspNetCore.Mvc.Localization
@using SentimentAnalysisDemo.Localization
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting
@model SentimentAnalysisDemo.Web.Pages.IndexModel
<div class="container">
<h5 class="display-5">Comments:</h5>
@await Component.InvokeAsync(typeof(CommentingViewComponent), new
{
entityType = "Comment",
entityId = "SentimentAnalysisDemo",
isReadOnly = false
})
</div>
```
After adding the related component, now you can run the web project and see the comment component if you want.
### Applying Sentiment Analysis (Creating the Spam Detection Service)
By default, CMS Kit's Comment Feature does not provide a spam detection system. In this demo application, we will override the `CommentPublicAppService`'s `CreateAsync` and `UpdateAsync` methods and then will add the spam detection control whenever a new comment has been submitted or an existing one is being updated.
To override the `CommentPublicAppService` and extend its use-case implementations, create a `MyCommentAppService` class and update its content as below:
```csharp
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using SentimentAnalysisDemo.ML;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.CmsKit.Comments;
using Volo.CmsKit.Public.Comments;
using Volo.CmsKit.Users;
namespace SentimentAnalysisDemo.Volo.CmsKit.Public.Comments;
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(ICommentPublicAppService), typeof(CommentPublicAppService), typeof(MyCommentAppService))]
public class MyCommentAppService : CommentPublicAppService
{
protected ISpamDetector SpamDetector { get; }
public MyCommentAppService(
ICommentRepository commentRepository,
ICmsUserLookupService cmsUserLookupService,
IDistributedEventBus distributedEventBus,
CommentManager commentManager,
IOptionsSnapshot<CmsKitCommentOptions> cmsCommentOptions,
ISpamDetector spamDetector
)
: base(commentRepository, cmsUserLookupService, distributedEventBus, commentManager, cmsCommentOptions)
{
SpamDetector = spamDetector;
}
public override async Task<CommentDto> CreateAsync(string entityType, string entityId, CreateCommentInput input)
{
//Check message: spam or ham.
await SpamDetector.CheckAsync(input.Text);
return await base.CreateAsync(entityType, entityId, input);
}
public override async Task<CommentDto> UpdateAsync(Guid id, UpdateCommentInput input)
{
//Check message: spam or ham.
await SpamDetector.CheckAsync(input.Text);
return await base.UpdateAsync(id, input);
}
}
```
Here, we simply just inject the `ISpamDetector` service, which we will create in a minute, and use its `CheckAsync` method to make a spam check before the comment is created or updated.
Now, we can create the `ISpamDetector` service in the `*.Application.Contracts` project as follows:
```csharp
using System.Threading.Tasks;
namespace SentimentAnalysisDemo.ML;
public interface ISpamDetector
{
Task CheckAsync(string text);
}
```
Then, we can create the `SpamDetector` and implement the `ISpamDetector` interface (in the `*.Application` project):
```csharp
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.ML;
using SentimentAnalysisDemo.ML.Model;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
namespace SentimentAnalysisDemo.ML;
public class SpamDetector : ISpamDetector, ITransientDependency
{
public async Task CheckAsync(string text)
{
//check if the text contains a spam content or not...
}
}
```
The `CheckAsync` method is where we need to make the sentiment analysis and detect if the comment contains spam content or not. If it's spam, then we should throw a [UserFriendlyException](https://docs.abp.io/en/abp/latest/Exception-Handling#user-friendly-exception) and notify the user that the comment should be updated and should not contain any spam content.
#### Spam Detection
Before, making the spam check, we should have a dataset to train a machine-learning model and add `Microsoft.ML` package into our project. For that purpose, I searched in [Kaggle](https://www.kaggle.com/) for spam datasets, found the **Spam-Mail-Detection-Dataset** from Kaggle, and downloaded the csv file to use in my application. Therefore, [you should also download the dataset from the link and put it under the **/ML/Data/spam_data.csv** directory of the `*.Web` project](https://github.com/EngincanV/SentimentAnalysisDemo/blob/master/src/SentimentAnalysisDemo.Web/ML/Data/spam_data.csv).
Here is what our dataset looks like (**0 -> not spam / 1 -> spam**):
| Category | Message |
|----------|---------|
| 0 | Is that seriously how you spell his name? |
| 1 | Free entry in 2 a wkly comp to win FA Cup final tkts 21st May 2005. Text FA to 87121 to receive entry question(std txt rate)T&C's apply 08452810075over18's |
| . | . |
| . | . |
| . | . |
> **Note:** This dataset is not ready-to use in a real-world solution. It's for mail spam detection but for the simplicity of the sample, it's not important and can be used for development purposes.
After, downloading the dataset and putting it in the directory of **/ML/Data**, now we can add the `Microsoft.ML` package into our `*.Application` project:
```bash
dotnet add package Microsoft.ML
```
Finally, we can implement the `CheckAsync` method and use sentiment analysis to make spam checks as follows:
```csharp
public async Task CheckAsync(string text)
{
var dataPath = Path.Combine(Environment.CurrentDirectory, "ML", "Data", "spam_data.csv");
var mlContext = new MLContext();
//Step 1: Load Data 👇
IDataView dataView = mlContext.Data.LoadFromTextFile<SentimentAnalyzeInput>(dataPath, hasHeader: true, separatorChar: ',');
//Step 2: Split data to train-test data 👇
DataOperationsCatalog.TrainTestData trainTestSplit = mlContext.Data.TrainTestSplit(dataView, testFraction: 0.2);
IDataView trainingData = trainTestSplit.TrainSet; //80% of the data.
IDataView testData = trainTestSplit.TestSet; //20% of the data.
//Step 3: Common data process configuration with pipeline data transformations + choose and set the training algorithm 👇
var estimator = mlContext.Transforms.Text.FeaturizeText(outputColumnName: "Features", inputColumnName: nameof(SentimentAnalyzeInput.Message))
.Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(labelColumnName: "Label", featureColumnName: "Features"));
//Step 4: Train the model 👇
ITransformer model = estimator.Fit(trainingData);
//Step 5: Predict 👇
var sentimentAnalyzeInput = new SentimentAnalyzeInput
{
Message = text
};
var predictionEngine = mlContext.Model.CreatePredictionEngine<SentimentAnalyzeInput, SentimentAnalyzeResult>(model);
var result = predictionEngine.Predict(sentimentAnalyzeInput);
if (IsSpam(result))
{
throw new UserFriendlyException("Spam detected! Please update the message!");
}
}
private static bool IsSpam(SentimentAnalyzeResult result)
{
//1 -> spam / 0 -> ham (for 'Prediction' column)
return result is { Prediction: true, Probability: >= 0.5f };
}
```
Here, we have done the following things:
1. **First, we loaded the data**: For that reason, we created a `MLContext` object, which is a main class for all ML.NET operations. Then, we used its `LoadFromTextFile` method and specified the dataset path in our application. Also, we mapped the dataset columns to the `SentimentAnalyzeInput` class, which we will create later on.
2. **For the second step, we split the data as training and testing data**: To be able to train a machine learning model and then evaluate its accuracy, we should not use all the data for training purposes, instead, we should split the data as training and testing data and after training the model, compare the training data accuracy with the testing data.
3. **For the third step, we should make data transformation, convert the text-based data into numeric vectors and then choose a training algorithm**: After splitting the data for training and testing purposes, now we can apply some data transformations for the *Message* column in our dataset. Because, as you would see, messages are text-based inputs and machine-learning algorithms work best with the numeric vectors. So, we are making data transformations and representing the data as numeric values. Then, we can apply `BinaryClassification` with the **SdcaLogicticRegression** algorithm to our training data.
4. **Train the model**: Since we make the data transformations and chose the correct algorithm for our model, now we can train the model.
5. **Predict the sample data**: Finally, we can pass a comment to this method and make spam check and either approve our reject the comment according to the predicted result. (To make predictions, we need to create a **PredictionEngine** and get the final results in the output class that we specified, `SentimentAnalyzeResult` in our example)
Let's create the `SentimentAnalyzeInput` and `SentimentAnalyzeResult` classes as follows.
**SentimentAnalyzeInput.cs:**
```csharp
using Microsoft.ML.Data;
namespace SentimentAnalysisDemo.ML.Model;
public class SentimentAnalyzeInput
{
[LoadColumn(0), ColumnName("Label")]
public bool Category { get; set; }
[LoadColumn(1), ColumnName("Message")]
public string Message { get; set; }
}
```
**SentimentAnalyzeResult.cs:**
```csharp
using Microsoft.ML.Data;
namespace SentimentAnalysisDemo.ML.Model;
public class SentimentAnalyzeResult
{
[ColumnName("PredictedLabel")]
public bool Prediction { get; set; }
public float Probability { get; set; }
public float Score { get; set; }
}
```
Then, finally we can run the application to see the final results:
![](demo.gif)
## Conclusion
In this article, I briefly explain what sentiment analysis is, created a sample ABP-based application, integrated the CMS Kit Module and finally, applied sentiment analysis to make spam checks whenever a new comment has been submitted or updated. You can get the source code of the demo from [https://github.com/EngincanV/SentimentAnalysisDemo](https://github.com/EngincanV/SentimentAnalysisDemo)
Thanks for reading :)

BIN
docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/cover-image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

BIN
docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/demo.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 KiB

BIN
docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/sentiment-analysis-steps.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
docs/en/Community-Articles/2024-05-10-Sentiment-Analysis-within-ABP-Based-Application/sentiment-analysis.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

411
docs/en/cli/index.md

@ -1,19 +1,19 @@
# ABP CLI
ABP CLI (Command Line Interface) is a command line tool to perform some common operations for ABP based solutions.
ABP CLI (Command Line Interface) is a command line tool to perform some common operations for ABP based solutions or ABP Studio features.
## Installation
ABP CLI is a [dotnet global tool](https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools). Install it using a command line window:
````bash
dotnet tool install -g Volo.Abp.Cli
dotnet tool install -g Volo.Abp.Studio.Cli
````
To update an existing installation:
````bash
dotnet tool update -g Volo.Abp.Cli
dotnet tool update -g Volo.Abp.Studio.Cli
````
## Global Options
@ -29,13 +29,24 @@ Here, is the list of all available commands before explaining their details:
* **`help`**: Shows help on the usage of the ABP CLI.
* **`cli`**: Update or remove ABP CLI.
* **`new`**: Generates a new solution based on the ABP [startup templates](../solution-templates).
* **`new-module`**: Generates a new module based on the given template.
* **`new-package`**: Generates a new package based on the given template.
* **`update`**: Automatically updates all ABP related NuGet and NPM packages in a solution.
* **`clean`**: Deletes all `BIN` and `OBJ` folders in the current folder.
* **`add-package`**: Adds an ABP package to a project.
* **`add-module`**: Adds a [multi-package application module](../modules) to a solution.
* **`add-package-ref`**: Adds package to given project.
* **`install-module`**: Adds a [multi-package application module](../modules) to a given module.
* **`install-local-module`**: Installs a local module to given module.
* **`list-modules`**: Lists names of open-source application modules.
* **`list-templates`**: Lists the names of available templates to create a solution.
* **`get-source`**: Downloads the source code of a module.
* **`add-source-code`**: Downloads the source code and replaces package references with project references.
* **`init-solution`**: Creates ABP Studio configuration files for a given solution.
* **`kube-connect`**: Connects to kubernetes environment.
* **`kube-intercept`**: Intercepts a service running in Kubernetes environment.
* **`list-module-sources`**: Lists the remote module sources.
* **`add-module-source`**: Adds a remote module source.
* **`delete-module-source`**: Deletes a remote module source.
* **`generate-proxy`**: Generates client side proxies to use HTTP API endpoints.
* **`remove-proxy`**: Removes previously generated client side proxies.
* **`switch-to-preview`**: Switches to the latest preview version of the ABP.
@ -110,8 +121,10 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md
#### Options
* `--template` or `-t`: Specifies the template name. Default template name is `app`, which generates a web application. Available templates:
* **`app`** (default): [Application template](../solution-templates/layered-web-application). Additional options:
* `--template` or `-t`: Specifies the template name. Default template name is `app`, which generates a application solution. Available templates:
* **`empty`**: Empty solution template.
* **`app`**: Application template. Additional options:
* `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks:
* `mvc`: ASP.NET Core MVC. There are some additional options for this template:
* `--tiered`: Creates a tiered solution where Web and Http API layers are physically separated. If not specified, it creates a layered solution which is less complex and suitable for most scenarios.
@ -123,54 +136,160 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md
* `--pwa`: Specifies the project as Progressive Web Application.
* `blazor-server`: Blazor Server UI. There are some additional options for this template:
* `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project.
* `none`: Without UI. No front-end layer will be created. There are some additional options for this template:
* `maui-blazor`: Blazor Maui UI. There are some additional options for this template:
* `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project.
* `no-ui`: Without UI. No front-end layer will be created. There are some additional options for this template:
* `--separate-auth-server`: The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side.
* `--mobile` or `-m`: Specifies the mobile application framework. If not specified, no mobile application will be created. Available options:
* `--mobile` or `-m`: Specifies the mobile application framework. Default value is `react-native`. Available frameworks:
* `none`: Without any mobile application.
* `react-native`: React Native.
* `maui`: MAUI. This mobile option is only available for ABP.
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
* `--theme`: Specifes the theme. Default theme is `leptonx-lite`. Available themes:
* `leptonx-lite`: [LeptonX Lite Theme](../ui-themes/lepton-x-lite/asp-net-core.md).
* `basic`: [Basic Theme](../framework/ui/mvc-razor-pages/basic-theme.md).
* **`module`**: [Module template](../solution-templates/application-module). Additional options:
* `--no-ui`: Specifies to not include the UI. This makes possible to create service-only modules (a.k.a. microservices - without UI).
* **`console`**: [Console template](../get-started/console.md).
* **`app-nolayers`**: [Single-layer application template](../solution-templates/single-layer-web-application). Additional options:
* `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](Entity-Framework-Core-Other-DBMS.md) (after creating the solution).
* `--public-website`: Public Website is a front-facing website for describing your project, listing your products and doing SEO for marketing purposes. Users can login and register on your website with this website. This option is only included in PRO templates.
* `--separate-tenant-schema`: Creates a different DbContext for tenant schema. If not specified, the tenant schema is shared with the host schema. This option is only included in PRO templates.
* `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
* `leptonx`: LeptonX Theme.
* `basic`: Basic Theme.
* **`app-nolayers`**: Single-layer application template. Additional options:
* `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks:
* `mvc`: ASP.NET Core MVC.
* `angular`: Angular UI.
* `blazor`: Blazor UI.
* `blazor-server`: Blazor Server UI.
* `none`: Without UI.
* `mvc`: ASP.NET Core MVC. There are some additional options for this template:
* `angular`: Angular UI. There are some additional options for this template:
* `blazor`: Blazor UI. There are some additional options for this template:
* `blazor-server`: Blazor Server UI. There are some additional options for this template:
* `no-ui`: Without UI. No front-end layer will be created. There are some additional options for this template:
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
* `--theme`: Specifes the theme. Default theme is `leptonx-lite`. Available themes:
* `leptonx-lite`: [LeptonX Lite Theme](../ui-themes/lepton-x-lite).
* `basic`: [Basic Theme](../framework/ui/mvc-razor-pages/basic-theme.md).
* **`maui`**: .NET MAUI. A minimalist .NET MAUI application will be created if you specify this option.
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
* `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](Entity-Framework-Core-Other-DBMS.md) (after creating the solution).
* `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
* `leptonx`: LeptonX Theme.
* `basic`: Basic Theme.
* **`microservice-pro`**: Microservice solution template. Additional options:
* `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks:
* `mvc`: ASP.NET Core MVC. There are some additional options for this template:
* `angular`: Angular UI. There are some additional options for this template:
* `blazor`: Blazor UI. There are some additional options for this template:
* `blazor-server`: Blazor Server UI. There are some additional options for this template:
* `maui-blazor`: Blazor Maui UI. There are some additional options for this template:
* `no-ui`: Without UI. No front-end layer will be created. There are some additional options for this template:
* `--mobile` or `-m`: Specifies the mobile application framework. Default value is `react-native`. Available frameworks:
* `none`: Without any mobile application.
* `react-native`: React Native.
* `maui`: MAUI.
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
* `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
* `leptonx`: LeptonX Theme.
* `basic`: Basic Theme.
* `--public-website`: Public Website is a front-facing website for describing your project, listing your products and doing SEO for marketing purposes. Users can login and register on your website with this website. This option is only included in PRO templates.
* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
* `--version` or `-v`: Specifies the ABP & template version. It can be a [release tag](https://github.com/abpframework/abp/releases) or a [branch name](https://github.com/abpframework/abp/branches). Uses the latest release if not specified. Most of the times, you will want to use the latest version.
* `--preview`: Use latest preview version.
* `--template-source` or `-ts`: Specifies a custom template source to use to build the project. Local and network sources can be used(Like `D:\local-template` or `https://.../my-template-file.zip`).
* `--local-framework-ref` or `-lfr`: Uses local projects references to the ABP framework instead of using the NuGet packages. It tries to find the paths from `ide-state.json`. The file is located at `%UserProfile%\.abp\studio\ui\ide-state.json` (for Windows) and `~/.abp/studio/ui/ide-state.json` (for MAC).
* `--create-solution-folder` or `-csf`: Specifies if the project will be in a new folder in the output folder or directly the output folder.
* `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](../framework/data/entity-framework-core/other-dbms.md) (after creating the solution).
* `--database-management-system` or `-dbms`: Sets the database management system. Default is **SQL Server**. Supported DBMS's:
* `SqlServer`
* `MySQL`
* `SQLite`
* `Oracle`
* `Oracle-Devart`
* `PostgreSQL`
* `--local-framework-ref --abp-path`: Uses local projects references to the ABP instead of using the NuGet packages. This can be useful if you download the ABP source code and have a local reference to the framework from your application.
* `--no-random-port`: Uses template's default ports.
* `--skip-installing-libs` or `-sib`: Skip installing client side packages.
* `--skip-cache` or `-sc`: Always download the latest from our server and refresh their templates folder cache.
* `--with-public-website`: **Public Website** is a front-facing website for describing your project, listing your products and doing SEO for marketing purposes. Users can login and register on your website with this website.
* `SQLite` (`app` & `app-nolayers`)
* `Oracle` (`app` & `app-nolayers`)
* `Oracle-Devart` (`app` & `app-nolayers`)
* `--dont-run-install-libs`: Skip installing client side packages.
* `--dont-run-bundling`: Skip bundling for Blazor packages.
* `--no-kubernetes-configuration` or `-nkc`: Skips the Kubernetes configuration files.
* *Module Options*: You can skip some modules if you don't want to add them to your solution. Available commands:
* `-no-saas`: Skips the Saas module.
* `-no-gdpr`: Skips the GDPR module.
* `-no-openiddict-admin-ui`: Skips the OpenIddict Admin UI module.
* `-no-audit-logging`: Skips the Audit Logging module.
* `-no-file-management`: Skips the File Management module.
* `-no-language-management`: Skips the Language Management module.
* `-no-text-template-management`: Skips the Text Template Management module.
* `-no-chat`: Skips the Chat module.
* `--legacy`: Generates a legacy solution.
### new-module
Generates a new module.
See some [examples for the new command](./new-command-samples.md) here.
````bash
abp new-module <module-name> [options]
````
Example:
````bash
abp new-module Acme.BookStore -t module:ddd
````
#### options
* `--template` or `-t`: Specifies the template name. Default template name is `module:ddd`, which generates a DDD module. Module templates are provided by the main template, see their own startup template documentation for available modules. `empty:empty` and `module:ddd` template is available for all solution structure.
* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
* `--target-solution` or `-ts`: If set, the new module will be added to the given solution. Otherwise the new module will added to the closest solution in the file system. If no solution found, it will throw an error.
* `--solution-folder` or `-sf`: Specifies the target folder in the [Solution Explorer](./solution-explorer.md#folder) virtual folder system.
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. This option is only available if the module template supports it. You can add multiple values separated by commas, such as `ef, mongodb` if the module template supports it. Available providers:
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
* `--ui-framework` or `-u`: Specifies the UI framework. This option is only available if the module template supports it. You can add multiple values separated by commas, such as `mvc,angular` if the module template supports it. Available frameworks:
* `mvc`: ASP.NET Core MVC.
* `angular`: Angular UI.
* `blazor`: Blazor UI.
* `blazor-server`: Blazor Server UI.
### new-package
Generates a new package.
````bash
abp new-package [options]
````
Example:
````bash
abp new-package --name Acme.BookStore.Domain --template lib.domain
````
#### options
* `--template` or `-t`: Specifies the template name. This parameter doesn't have a default value and must be set. Available templates and their sub-options:
* `lib.class-library`
* `lib.domain-shared`
* `lib.domain`
* `lib.application-contracts`
* `lib.application`
* `--with-automapper`: Adds automapper configuration.
* `lib.ef`
* `--include-migrations`: Allows migration operations on this package.
* `--connection-string-name`: Default value is the last part of the package's namespace (or package name simply).
* `--connection-string`: Connection string value. Defaut value is null. You can set it alter.
* `lib.mongodb`
* `lib.http-api`
* `lib.http-api-client`
* `lib.mvc`
* `lib.blazor`
* `lib.blazor-wasm`
* `lib.blazor-server`
* `host.http-api`
* `--with-serilog`: Includes Serilog configuration.
* `--with-swagger`: Includes Swagger configuration.
* `host.mvc`
* `--with-serilog`: Includes Serilog configuration.
* `--with-swagger`: Includes Swagger configuration.
* `host.blazor-wasm`
* `--backend`: Name of the backend project in the module (not path).
* `host.blazor-server`
* `csharp.console`
* `csharp.library`
* `--module-file` or `-m`: If set, the new package will be added to the given module. Otherwise the new package will added to the closest module in the file system. If no module found, it will throw an error.
* `--name` or `-n`: Specifies the name of the package. If not set, a name based on the template type and module name will be generated.
* `--folder` or `-f`: Specifies the target folder in the target module's virtual folder system.
### update
@ -243,44 +362,65 @@ abp add-package Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic
> - Volo.Abp.AspNetCore.Components.Web.BasicTheme
> - Volo.Abp.AspNetCore.Components.Server.BasicTheme
### add-package-ref
Adds one or more package reference to target project, also adds ABP module dependency. Both reference and target projects must belong to same module.
````bash
abp add-package-ref <package-names> [options]
````
### add-module
Example:
````bash
abp add-package-ref Acme.BookStore.Domain
abp add-package-ref "Acme.BookStore.Domain Acme.BookStore.Domain.Shared" -t Acme.BookStore.Web
````
Adds a [multi-package application module](../modules) to a solution by finding all packages of the module, finding related projects in the solution and adding each package to the corresponding project in the solution.
#### Options
It can also create a new module for your solution and add it to your solution. See `--new` option.
* `--target-project` or `-t`: Name of the project that reference will be added. If not set, project in the current directory will be used.
> A business module generally consists of several packages (because of layering, different database provider options or other reasons). Using `add-module` command dramatically simplifies adding a module to a solution. However, each module may require some additional configurations which is generally indicated in the documentation of the related module.
### install-module
Usage:
Installs a module, that is published as nuget packages, to a local module. Project relations are created according the types of the projects. For example: a `lib.domain-shared` project is added to `lib.domain-shared` project
````bash
abp add-module <module-name> [options]
abp install-module <module-name> [options]
````
Examples:
Example:
```bash
abp add-module Volo.Blogging
```
````bash
abp install-module Volo.Blogging
* This example adds the `Volo.Blogging` module to the solution.
abp install-module Volo.Blogging -t "modules/crm/Acme.Crm.abpmdl"
````
```bash
abp add-module ProductManagement --new --add-to-solution-file
```
#### Options
* `--target-module` or `-t`: Path (or folder path) of the target module that the other module will be installed to. If not set, the closest module to the current directory will be used.
* `--version` or `-v`: Nuget version of the module to be installed.
* This command creates a fresh new module customized for your solution (named `ProductManagement`) and adds it to your solution.
### install-local-module
Installs one module to another. Project relations are created according the types of the projects. For example: a `lib.domain-shared` project is added to `lib.domain-shared` project
````bash
abp install-local-module <module-path> [options]
````
Example:
````bash
abp install-local-module Acme.OrderManagement
abp install-local-module Acme.OrderManagement -t "modules/crm/Acme.Crm.abpmdl"
````
#### Options
* `--solution` or `-s`: Specifies the solution (.sln) file path. If not specified, CLI tries to find a .sln file in the current directory.
* `--skip-db-migrations`: For EF Core database provider, it automatically adds a new code first migration (`Add-Migration`) and updates the database (`Update-Database`) if necessary. Specify this option to skip this operation.
* `-sp` or `--startup-project`: Relative path to the project folder of the startup project. Default value is the current folder.
* `--new`: Creates a fresh new module (customized for your solution) and adds it to your solution.
* `--with-source-code`: Downloads the source code of the module to your solution folder and uses local project references instead of NuGet/NPM packages. This options is always `True` if `--new` is used.
* `--add-to-solution-file`: Adds the downloaded/created module to your solution file, so you will also see the projects of the module when you open the solution on a IDE. (only available when `--with-source-code` is `True`.)
* `--target-module` or `-t`: Path (or folder path) of the target module that the other module will be installed to. If not set, the closest module to the current directory will be used.
### list-modules
@ -337,6 +477,157 @@ abp get-source Volo.Blogging --local-framework-ref --abp-path D:\GitHub\abp
* `--preview`: If no version option is specified, this option specifies if latest [preview version](../release-info/previews.md) will be used instead of latest stable version.
* `--local-framework-ref --abp-path`: Path of [ABP GitHub repository](https://github.com/abpframework/abp) in your computer. This will be used for converting project references to your local system. If this is not specified, project references will be converted to NuGet references.
### add-source-code
Downloads the source code of a module and replaces package references with project references. This command only works if your ABP Commercial License has source-code access, or if source-code of the target module is free to all type of ABP Commercial Licenses.
````bash
abp add-source-code <module-name> [options]
````
Example:
````bash
abp add-source-code Volo.Chat --add-to-solution-file
````
#### Options
* `--target-module` or `-t`: The module that will refer the downloaded source code. If not set, the module in the current directory will be used.
* `--add-to-solution-file`: Adds the downloaded source code to C# solution file and ABP Studio solution file.
### init-solution
Creates necessary files for a solution to be readable by ABP Studio. If the solution is generated via ABP Studio, you don't need this command. But it is not generated by ABP Studio, you need this command to make it work with ABP Studio.
````bash
abp init-solution [options]
````
Example:
````bash
abp init-solution --name Acme.BookStore
````
#### Options
* `--name` or `-n`: Name for the solution. If not set, it will be the same as the name of closest c# solution in the file system.
### kube-connect
Connects to Kubernetes cluster. Press `ctrl+c` to disconnect.
````bash
abp kube-connect [options]
````
Example:
````bash
abp kube-connect
abp kube-connect -p Default.abpk8s.json
abp kube-connect -c docker-desktop -ns mycrm-local
````
#### Options
* `--profile` or `-p`: Kubernetes Profile path or name to be used. Path can be relative (to current directory) or full path, or you can simply give the name of profile if you run this command in same directory with the solution or profile. This parameter is not needed if you use `--namespace` and `--context` parameters.
* `--namespace` or `-ns`: The namespace that services running on.
* `--context` or `-c`: The context that services running in.
* `--wireguard-password` or `-wp`: Wireguard password for the profile. This is not needed if you already set it on the ABP Studio user interface.
* `--solution-id` or `-si`: Id of the solution. If not set, the closest solution in file system will be used.
### kube-intercept
Intercepts a service running in Kubernetes environment. Press `ctrl+c` to stop interception.
````bash
abp kube-intercept <service-name> [options]
````
Example:
````bash
abp kube-intercept mycrm-product-service -ns mycrm-local
abp kube-intercept mycrm-product-service -ns mycrm-local -a MyCrm.ProductService.HttpApi.Host.csproj
abp kube-intercept mycrm-product-service -ns mycrm-local -a MyCrm.ProductService.HttpApi.Host.csproj -pm 8080:80,8081:443
````
#### Options
* `--application` or `-a`: Relative or full path of the project that will intercept the service. If not set, the project in the current directory will be used.
* `--namespace` or `-ns`: The namespace that service running on.
* `--context` or `-sc`: The context that service running in. Default value is `docker-desktop`.
* `--port-mappings` or `-pm`: Port mappings for the service.
### list-module-sources
With this command, you can see the list of remote module sources that you can use to install modules. It is similar to the NuGet feed list in Visual Studio.
````bash
abp list-module-sources
````
### add-module-source
Adds a remote module source to the list of sources that you can use to install modules.
````bash
abp add-module-source [options]
````
You can create your own module source and add it to the list. It accepts a name and a url or a path as parameter. If you provide a path, it should be a local path that contains the modules json file. If you provide a url, it should be a url that contains the modules json file. The json file should be in the following format:
````json
{
"name": "ABP Open Source Modules",
"modules" : {
"Volo.Abp.Account": {},
"Volo.Abp.AuditLogging": {},
"Volo.Abp.Identity": {},
...
}
}
````
When you add a module source, you can install modules from that source using the `install-module` command. It attempts to find the package from NuGet, such as `Volo.Abp.Account.Installer`. You can configure a private NuGet feed and publish your modules to that feed. Each module has an installer package that is utilized to install the module into a solution. When you publish your module to a private feed, you should also publish the installer package to the same feed.
Example:
````bash
abp add-module-source -n "Custom Source" -p "D:\packages\abp\modules.json"
abp add-module-source -n "Custom Http Source" -p "https://raw.githubusercontent.com/x/abp-module-store/main/abp-module-store.json"
````
#### Options
* `--name` or `-n`: The name of the module source.
* `--path` or `-p`: The path of the module source. It can be a local path or a url.
### delete-module-source
Deletes a remote module source from the list of sources that you can use to install modules.
````bash
abp delete-module-source [options]
````
Example:
````bash
abp delete-module-source -n "Custom Source"
````
#### Options
* `--name` or `-n`: The name of the module source.
### generate-proxy
Generates Angular, C# or JavaScript service proxies for your HTTP APIs to make easy to consume your services from the client side. Your host (server) application must be up and running before running this command.

67
docs/en/cli/new-command-samples.md

@ -67,7 +67,7 @@ The following commands are for creating MVC UI projects:
* **Public Website**, Entity Framework Core, no mobile app, creates the project in a new folder:
```bash
abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef -csf --with-public-website
abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef -csf --public-website
```
_Note that Public Website is only included in PRO templates._
@ -146,61 +146,18 @@ It's a template of a basic .NET console application with ABP module architecture
## Module
Module are reusable sub applications used by your main project. Using ABP Module is a best practice if you are building a microservice solution. As modules are not final applications, each module has all the frontend UI projects and database providers. The module template comes with an MVC UI to be able to develop without the final solution. But if you will develop your module under a final solution, you add `--no-ui` parameter to exclude MVC UI project.
Module are reusable sub applications used by your main project. Using ABP Module is a best practice if you are building a microservice solution. As modules are not final applications, each module could contains different frontend UI projects and database providers.
* Included frontends: `MVC`, `Angular`, `Blazor`. Included database providers: `Entity Framework Core`, `MongoDB`. Includes MVC startup project.
* Available frontends: `MVC`, `Angular`, `Blazor`. Available database providers: `Entity Framework Core`, `MongoDB`.
```bash
abp new Acme.IssueManagement -t module
abp new-module Acme.IssueManagement
```
* The same with the upper but doesn't include MVC startup project.
```bash
abp new Acme.IssueManagement -t module --no-ui
```
* Creates the module and adds it to your solution
```bash
abp new Acme.IssueManagement -t module --add-to-solution-file
```
## Create a solution from a specific version
When you create a solution, it always creates with the latest version. To create a project from an older version, you can pass the `--version` parameter.
* Create a solution from v3.3.0, with Angular UI and Entity Framework Core.
```bash
abp new Acme.BookStore -t app -u angular -m none --database-provider ef -csf --version 3.3.0
```
To get the ABP version list, checkout following link: https://www.nuget.org/packages/Volo.Abp.Core/
## Create from a custom template
ABP CLI uses the default [app template](https://github.com/abpframework/abp/tree/dev/templates/app) to create your project. If you want to create a new solution from your customized template, you can use the parameter `--template-source`.
* MVC UI, Entity Framework Core, no mobile app, using the template in `c:\MyProjects\templates\app` directory.
```bash
abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef --template-source "c:\MyProjects\templates\app"
```
* Same with the previous one except this command retrieves the template from the URL `https://myabp.com/app-template.zip`.
```bash
abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef --template-source https://myabp.com/app-template.zip
```
## Create a preview version
ABP CLI always uses the latest version. In order to create a solution from a preview (RC) version add the `--preview` parameter.
* Blazor UI, Entity Framework Core, no mobile, **preview version**, creates the project in a new folder:
* The same with the upper but includes MVC and angular projects.
```bash
abp new Acme.BookStore -t app -u blazor --mobile none -csf --preview
abp new-module Acme.IssueManagement -u mvc,angular
```
## Choose database management system
@ -213,18 +170,6 @@ The default database management system (DBMS) is `Entity Framework Core` / ` SQL
abp new Acme.BookStore -u angular --database-management-system PostgreSQL -csf
```
## Use static HTTP ports
ABP CLI always assigns random ports to the hostable projects. If you need to keep the default ports and create a solution always with the same HTTP ports, add the parameter `--no-random-port`.
* MVC UI, Entity Framework Core, **static ports**, creates the project in a new folder:
```bash
abp new Acme.BookStore --no-random-port -csf
```
## Use local ABP references
ABP libraries are referenced from NuGet by default in the ABP solutions. Sometimes you need to reference ABP libraries locally to your solution. This is useful to debug the framework itself. Your local ABP 's root directory must have the `Volo.Abp.sln` file. You can copy the content of the following directory to your file system https://github.com/abpframework/abp/tree/dev/framework

4
docs/en/modules/audit-logging-pro.md

@ -1,4 +1,6 @@
# Audit Logging module
# Audit Logging Module (Pro)
> You must have an ABP Team or a higher license to use this module.
This module implements the Audit Logging system of an application;

4
docs/en/modules/chat.md

@ -1,4 +1,6 @@
# Chat module
# Chat Module (Pro)
> You must have an ABP Team or a higher license to use this module.
This module implements real time messaging between users for an application.

4
docs/en/modules/cms-kit-pro/index.md

@ -1,4 +1,6 @@
# CMS Kit Pro Module
# CMS Kit Pro Module (Pro)
> You must have an ABP Team or a higher license to use this module.
This module extends the [open-source CMS Kit module](../cms-kit) and adds additional CMS (Content Management System) capabilities to your application.

2
docs/en/modules/cms-kit-pro/newsletter.md

@ -1,6 +1,6 @@
# Newsletter System
CMS kit provides a **newsletter** system to allow users to subscribe to newsletters. Here a screenshot of the newsletter subscription widget:
CMS Kit provides a **newsletter** system to allow users to subscribe to newsletters. Here a screenshot of the newsletter subscription widget:
![cmskit-module-newsletter-widget](../../images/cmskit-module-newsletter-widget.png)

2
docs/en/modules/cms-kit-pro/page-feedback.md

@ -1,6 +1,6 @@
# Page Feedback System
The CMS kit provides a **Page Feedback** system to collect feedback from users about pages.
The CMS Kit provides a **Page Feedback** system to collect feedback from users about pages.
| ![cmskit-module-page-feedback-widget](../../images/cmskit-module-page-feedback-widget.png) |![cmskit-module-page-feedback-widget](../../images/cmskit-module-page-feedback-widget-2.png) |
| --- | --- |

2
docs/en/modules/cms-kit-pro/poll.md

@ -1,6 +1,6 @@
# Poll System
CMS kit provides a **poll** system to allow users to create, edit and delete polls. Here is a screenshot of the poll widget:
CMS Kit provides a **poll** system to allow users to create, edit and delete polls. Here is a screenshot of the poll widget:
![cmskit-module-poll-widget](../../images/cmskit-module-poll-widget.png)

2
docs/en/modules/cms-kit-pro/url-forwarding.md

@ -1,6 +1,6 @@
# URL Forwarding System
CMS kit provides a **URL forwarding** system to create URLs that redirect to other pages or external websites.
CMS Kit provides a **URL forwarding** system to create URLs that redirect to other pages or external websites.
## Enabling the URL Forwarding System

2
docs/en/modules/cms-kit/comments.md

@ -1,6 +1,6 @@
# CMS Kit: Comments
CMS kit provides a **comment** system to add the comment feature to any kind of resource, like blog posts, products, etc.
CMS Kit provides a **comment** system to add the comment feature to any kind of resource, like blog posts, products, etc.
## Enabling the Comment Feature

2
docs/en/modules/cms-kit/dynamic-widget.md

@ -1,6 +1,6 @@
# Dynamic Widget
CMS kit provides a dynamic [widget](../../framework/ui/mvc-razor-pages/widgets.md) used to render the components previously developed by the software in the content of the pages and blog posts. Its means, that in static content you can use dynamic content. We will mention how you can do it. You have two choices to define the widget in the system: Writing and UI.
CMS Kit provides a dynamic [widget](../../framework/ui/mvc-razor-pages/widgets.md) used to render the components previously developed by the software in the content of the pages and blog posts. Its means, that in static content you can use dynamic content. We will mention how you can do it. You have two choices to define the widget in the system: Writing and UI.
### Adding the widget
Firstly we will show how to use the widget system via writing manually in the page and blog post contents.

2
docs/en/modules/cms-kit/ratings.md

@ -1,6 +1,6 @@
# Rating System
CMS kit provides a **rating** system to to add ratings feature to any kind of resource like blog posts, comments, etc. Here how the rating component looks like on a sample page:
CMS Kit provides a **rating** system to to add ratings feature to any kind of resource like blog posts, comments, etc. Here how the rating component looks like on a sample page:
![ratings](../../images/cmskit-module-ratings.png)

2
docs/en/modules/cms-kit/reactions.md

@ -1,6 +1,6 @@
# Reaction System
CMS kit provides a **reaction** system to add reactions feature to any kind of resource, like blog posts or comments.
CMS Kit provides a **reaction** system to add reactions feature to any kind of resource, like blog posts or comments.
Reaction component allows users to react to your content via pre-defined icons/emojis. Here how the reactions component may looks like:

2
docs/en/modules/cms-kit/tags.md

@ -1,6 +1,6 @@
# Tag Management
CMS kit provides a **tag** system to tag any kind of resources, like a blog post.
CMS Kit provides a **tag** system to tag any kind of resources, like a blog post.
## Enabling the Tag Management Feature

4
docs/en/modules/file-management.md

@ -1,4 +1,6 @@
# File Management Module
# File Management Module (Pro)
> You must have an ABP Team or a higher license to use this module.
This module is used to upload, download and organize files in a hierarchical folder structure. It is also compatible to multi-tenancy and you can determine total size limit for your tenants.

4
docs/en/modules/forms.md

@ -1,4 +1,6 @@
# Forms Module
# Forms Module (Pro)
> You must have an ABP Team or a higher license to use this module.
This module allows you to create questionnaires to gather information. The forms module can store responses as they come in and you can export the data to a CSV file. You can share your form with others with your form unique link. You can request authentication or allow anonymous reply. It is similar to the Google Form application. Usage area is quite wide, you can create surveys, manage event registrations, collect email addresses for a newsletter, create a quiz, and even receive an order request.

4
docs/en/modules/gdpr.md

@ -1,4 +1,6 @@
# GDPR Module
# GDPR Module (Pro)
> You must have an ABP Team or a higher license to use this module.
This module allows users to download and delete their personal data collected by the application.

4
docs/en/modules/identity-pro.md

@ -1,4 +1,6 @@
# Identity module
# Identity Module (Pro)
> You must have an ABP Team or a higher license to use this module.
This module implements the User and Role system of an application;

4
docs/en/modules/identity-server-pro.md

@ -1,4 +1,6 @@
# Identity Server Module
# Identity Server Module (Pro)
> You must have an ABP Team or a higher license to use this module.
This module provides integration and management functionality for Identity Server;

2
docs/en/modules/identity/idap.md

@ -1,4 +1,4 @@
# LDAP External login Provider
# LDAP External Login Provider
## Introduction

4
docs/en/modules/language-management.md

@ -1,4 +1,6 @@
# Language Management Module
# Language Management Module (Pro)
> You must have an ABP Team or a higher license to use this module.
This module implements the Language management system of an application;

4
docs/en/modules/openiddict-pro.md

@ -1,4 +1,6 @@
# OpenIddict Module
# OpenIddict Module (Pro)
> You must have an ABP Team or a higher license to use this module.
This module provides integration and management functionality for the OpenIddict library;

2
docs/en/modules/payment-custom-gateway.md

@ -1,7 +1,9 @@
# Creating a Custom Payment Gateway
This document explains creating custom a payment gateway that's different than the existing ones in the [Payment Module](payment#packages).
## Creating Core Operations
- Create **MyPaymentGateway.cs** and implement `IPaymentGateway`
```csharp

4
docs/en/modules/payment.md

@ -1,4 +1,6 @@
# Payment module
# Payment Module (Pro)
> You must have an ABP Team or a higher license to use this module.
Payment module implements payment gateway integration of an application. It provides one time payment and recurring payment options.

4
docs/en/modules/saas.md

@ -1,4 +1,6 @@
# SaaS module
# SaaS Module (Pro)
> You must have an ABP Team or a higher license to use this module.
This module is used to manage your tenants and editions in multi-tenant applications;

4
docs/en/modules/text-template-management.md

@ -1,4 +1,6 @@
# Text Template Management Module
# Text Template Management Module (Pro)
> You must have an ABP Team or a higher license to use this module.
This module is used to store and edit template contents for [the text templating system](https://docs.abp.io/en/abp/latest/Text-Templating) of the ABP. So, you may need to understand it to better understand the purpose of this module.

4
docs/en/modules/twilio-sms.md

@ -1,4 +1,6 @@
# Twilio SMS Module
# Twilio SMS Module (Pro)
> You must have an ABP Team or a higher license to use this module.
[Twilio](https://www.twilio.com) is a cloud communication provider that makes it easy to send and receive SMS. ABP Twilio SMS module implements the SMS sending feature of `ISmsSender` interface with Twilio.

30
docs/en/solution-templates/microservice/authentication.md

@ -1,3 +1,31 @@
# Microservice Solution: Authentication
*TODO*
The [microservice solution template](index.md) is fully configured for authentication. All the services and applications are configured to use the [OpenIddict](https://documentation.openiddict.com) library for authentication and authorization. They are configured in a common way for authentication. This document explains that common authentication structure.
## OpenIddict
[OpenIddict](https://documentation.openiddict.com) is an open-source library that provides a simple and easy way to implement an OpenID Connect server in your application. ABP has built-in modules ([OpenIddict](../../modules/openiddict.md), [OpenIddict UI](../../modules/openiddict-pro.md)) to integrate OpenIddict into the solution.
## Identity Service
The microservice solution template has the [identity](microservices.md#identity-microservice) service that is responsible for the OpenIddict definitions (Applications, Scopes, etc.). Also, it provides the *OpenIddictDataSeeder* class to seed the initial data. It creates the default clients(applications) and scopes for the solution. Each microservice has its own scope and the web applications use these scopes to get access to the microservices, so when you add a new microservice, you should add a new scope and add the allowed scopes for related clients(applications).
The [OpenIddict UI](../../modules/openiddict-pro.md) module gonna be added to the identity service only if you choose the OpenIddict UI module while creating the solution.
![new-solution-openiddict-module](images/new-solution-openiddict-module.png)
The OpenIddict UI module provides a user interface to manage the OpenIddict entities such as applications, scopes, etc. You can manage these entities from application.
![openiddict-ui](images/openiddict-ui.png)
## Authentication Server
The solution has an authentication server(auth-server) application to provide the token generation, validation and login page. Additionally, it adds the [account](../../modules/account-pro.md) module to the auth-server application to provide the such as register, forgot password and etc features.
Also, the [account](../../modules/account-pro.md) module provides the [social logins](../../modules/account-pro.md#social--external-logins) (Google, Facebook, etc.) feature. You can enable/disable and configure the social logins from the application UI.
![account-external-provider](images/account-external-provider.png)
## Authentication Flow
The applications use several flows to authenticate users based on the application type. The MVC UI web application uses the [hybrid flow](https://openid.net/specs/openid-connect-core-1_0.html#HybridFlowAuth) (OpenID Connect Authentication) to authenticate users, while the SPA and Swagger applications use the [authorization code flow](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth) to authenticate users. After the user logs into the system and receives the token from the authentication server, the applications (microservices) use [JWT Bearer Authentication](https://jwt.io/introduction/) to authorize users.

18
docs/en/solution-templates/microservice/database-configurations.md

@ -71,7 +71,7 @@ Let's examine that class. The first important thing is the `ConnectionStringName
[ConnectionStringName(DatabaseName)]
````
[The `ConnectionStringName` attribute](https://docs.abp.io/en/abp/latest/Connection-Strings#set-the-connection-string-name) defines the unique name of the connection string that is being used by that `DbContext` class. It matches with the connection string defined in the `appsettings.json` file. That name is also used in database migrations to distinguish different database schemas, and used as the key while storing tenant connection strings for a multi-tenant system. So, each physically separate database should have a unique connection string / database name as here.
[The `ConnectionStringName` attribute](../../framework/fundamentals/connection-strings.md#set-the-connection-string-name) defines the unique name of the connection string that is being used by that `DbContext` class. It matches with the connection string defined in the `appsettings.json` file. That name is also used in database migrations to distinguish different database schemas, and used as the key while storing tenant connection strings for a multi-tenant system. So, each physically separate database should have a unique connection string / database name as here.
The `DatabaseName` constant is defined in the `DbContext` class:
@ -88,7 +88,7 @@ The second important part of that class is the `ReplaceDbContext` attribute's us
)]
````
The Identity microservice utilizes the [Identity](../../modules/identity.md) and [OpenIddict](../../modules/openiddict.md) modules and creates a single database that contains these modules' database schemas. These modules define their own `DbContext` class normally. But [the `ReplaceDbContext` attribute](https://docs.abp.io/en/abp/8.0/Entity-Framework-Core#replace-other-dbcontextes) tells to ABP to use this (`IdentityServiceDbContext`) `DbContext` class instead of the `DbContext` classes defined by these modules. Technically, it replaces the given `DbContext` classes on runtime. We are doing that to ensure that we have a single (merged) database schema, single database migration path and a single database transaction operation when we work these multiple modules. When we replace a `DbContext`, we should implement its interface as done with the `IdentityServiceDbContext` class:
The Identity microservice utilizes the [Identity](../../modules/identity.md) and [OpenIddict](../../modules/openiddict.md) modules and creates a single database that contains these modules' database schemas. These modules define their own `DbContext` class normally. But [the `ReplaceDbContext` attribute](../../framework/data/entity-framework-core/index.md#replace-other-dbcontextes) tells to ABP to use this (`IdentityServiceDbContext`) `DbContext` class instead of the `DbContext` classes defined by these modules. Technically, it replaces the given `DbContext` classes on runtime. We are doing that to ensure that we have a single (merged) database schema, single database migration path and a single database transaction operation when we work these multiple modules. When we replace a `DbContext`, we should implement its interface as done with the `IdentityServiceDbContext` class:
````csharp
public class IdentityServiceDbContext :
@ -188,7 +188,7 @@ There are two important points in that class:
### The AbpDbConnectionOptions Configuration
Every microservice (and the other applications that touches to a database) configures the `AbpDbConnectionOptions` [options class](https://docs.abp.io/en/abp/latest/Options). It is typically done in a method (named `ConfigureDatabase`) defined in the service's (or application's) [module class](https://docs.abp.io/en/abp/latest/Module-Development-Basics). For example, the Identity microservices has a `CloudCrmIdentityServiceModule` class that defines a `ConfigureDatabase` method:
Every microservice (and the other applications that touches to a database) configures the `AbpDbConnectionOptions` [options class](../../framework/fundamentals/options.md). It is typically done in a method (named `ConfigureDatabase`) defined in the service's (or application's) [module class](../../framework/architecture/modularity/basics.md). For example, the Identity microservices has a `CloudCrmIdentityServiceModule` class that defines a `ConfigureDatabase` method:
````csharp
private void ConfigureDatabase(ServiceConfigurationContext context)
@ -236,7 +236,7 @@ Configure<AbpDbConnectionOptions>(options =>
});
````
That configuration basically defines the different databases that is accessed by that service/application and defines [the mapping](https://docs.abp.io/en/abp/latest/Connection-Strings#configuring-the-database-structures) between module database schemas to physical databases.
That configuration basically defines the different databases that is accessed by that service/application and defines [the mapping](../../framework/fundamentals/connection-strings.md#configuring-the-database-structures) between module database schemas to physical databases.
For example, Permission Management, Feature Management, Setting Management and the Language Management modules will use the `Administration` database, because we have merged that modules into the Administration microservice - we don't wanted to create separate services and databases for them.
@ -271,7 +271,7 @@ We are basically setting the SQL Server as the default DBMS for this service (or
### Registering the `DbContext` Class
Finally, the `ConfigureDatabase` method registers `IdentityServiceDbContext` class to the [dependency injection](https://docs.abp.io/en/abp/latest/Dependency-Injection) system and configures it:
Finally, the `ConfigureDatabase` method registers `IdentityServiceDbContext` class to the [dependency injection](../../framework/fundamentals/dependency-injection.md) system and configures it:
````csharp
context.Services.AddAbpDbContext<IdentityServiceDbContext>(options =>
@ -280,7 +280,7 @@ context.Services.AddAbpDbContext<IdentityServiceDbContext>(options =>
});
````
`AddDefaultRepositories` is used to register the default [repository](https://docs.abp.io/en/abp/latest/Best-Practices/Repositories) implementations for all the aggregate root [entities](https://docs.abp.io/en/abp/latest/Best-Practices/Entities).
`AddDefaultRepositories` is used to register the default [repository](../../framework/architecture/best-practices/repositories.md) implementations for all the aggregate root [entities](../../framework/architecture/best-practices/entities.md).
## Database Migrations
@ -290,7 +290,7 @@ For example, if you have added a new field to a database table, you should also
Managing the schema changes manually is not a good practice and error-prone in a highly dynamic system like a microservice solution. The Microservice solution template uses [Entity Framework migrations](https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/) to maintain the database schema and automatically migrate it whenever you deploy a new version of your service/application.
In addition to the schema changes, you may also need to insert some initial (seed) data to some tables in order to make your server properly works. That process is called as [data seeding](https://docs.abp.io/en/abp/latest/Data-Seeding). The Microservice solution is also configured so it can seed such initial data on the application startup.
In addition to the schema changes, you may also need to insert some initial (seed) data to some tables in order to make your server properly works. That process is called as [data seeding](../../framework/infrastructure/data-seeding.md). The Microservice solution is also configured so it can seed such initial data on the application startup.
> If you are using **MongoDB** as your database provider, the schema migration is not needed (But you should care about some kind of data and schema migrations in case of you made a breaking change on your database schema - this is something depends on your application, so you should understand how to work with a document database like MongoDB). However, the data seeding system is still used to insert initial data to the database.
@ -337,7 +337,7 @@ Here, we are just overriding the `SeedAsync` method that runs just after the dat
Let's explain how `EfCoreRuntimeDatabaseMigratorBase` behaves:
* First of all, **it re-tries the migration operation** in case of any failure. It tries 3 times in total, then re-throws the exception and causes the application crash. Since Kubernetes (or ABP Studio [solution runner](../../studio/running-applications.md)) will re-start it on crash, it will continue to try until it succeed. Temporary failures are especially expected if the database server is not ready when the service starts. It waits a random value between 5 and 15 seconds before the next try.
* It uses a [distributed lock](https://docs.abp.io/en/abp/latest/Distributed-Locking) to ensure that the migration operation is performed only by one service instance in a time. This is especially important if you run multiple instances of your service, which is usual in a microservice system. It uses a unique distributed key name based on the `DatabaseName` property, so different databases can be migrated in parallel.
* It uses a [distributed lock](../../framework/infrastructure/distributed-locking.md) to ensure that the migration operation is performed only by one service instance in a time. This is especially important if you run multiple instances of your service, which is usual in a microservice system. It uses a unique distributed key name based on the `DatabaseName` property, so different databases can be migrated in parallel.
* It uses Entity Framework's API to get a list of pending migrations and migrates the database if there were pending migrations.
* It then seeds the database by calling the virtual `SeedAsync` method. Remember that we have overridden that method to seed the initial data for the identity microservice.
* Finally, if a database schema migration has applied, it publishes a distributed event, `AppliedDatabaseMigrationsEto`, with the `DatabaseName`. This event is then used by the [SaaS module](../../modules/saas.md) to trigger migration of tenant databases in a multi-tenant system. See the *Database Migrations for Tenants* section in this document.
@ -371,7 +371,7 @@ As explained above, `EfCoreRuntimeDatabaseMigratorBase` publishes a distributed
For all that events, we need to migrate the related database for the tenant (the migration system creates the initial database if it doesn't exists). The migration logic is like that:
* Switches to the related tenant context using the [`ICurrentTenant.Change` method](https://docs.abp.io/en/abp/latest/Multi-Tenancy#change-the-current-tenant).
* Switches to the related tenant context using the [`ICurrentTenant.Change` method](../../framework/architecture/multi-tenancy/index.md#change-the-current-tenant).
* If the given tenant has a dedicated connection string for the current microservice, it migrates the database schema and seeds the initial data.
* In case a failure, it re-tries a maximum of 3 times by waiting a random duration between 5 and 15 seconds. It does that by ignoring the error and re-publishing the event that is handled.

BIN
docs/en/solution-templates/microservice/images/account-external-provider.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
docs/en/solution-templates/microservice/images/grafana-dashboard.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

BIN
docs/en/solution-templates/microservice/images/new-solution-openiddict-module.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
docs/en/solution-templates/microservice/images/openiddict-ui.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

2
docs/en/solution-templates/microservice/index.md

@ -21,7 +21,7 @@ ABP Studio provides pre-architected and production-ready templates to jump start
* [Authentication](authentication.md)
* [Database configurations](database-configurations.md)
* [Logging (with Serilog and Elasticsearch)](logging.md)
* Monitoring (with Prometheus and Grafana)
* [Monitoring (with Prometheus and Grafana)](monitoring.md)
* Swagger integration
* Permission management
* Feature management

6
docs/en/solution-templates/microservice/logging.md

@ -1,6 +1,6 @@
# Microservice Solution: Logging
The ABP Studio [microservice solution template](index.md) is fully configured for [logging](https://docs.abp.io/en/abp/latest/Logging). All the services, applications and gateways are configured to use the [Serilog](https://serilog.net/) library for structured logging. They are configured in a common way for logging. This document explains that common logging structure.
The ABP Studio [microservice solution template](index.md) is fully configured for [logging](../../framework/fundamentals/logging.md). All the services, applications and gateways are configured to use the [Serilog](https://serilog.net/) library for structured logging. They are configured in a common way for logging. This document explains that common logging structure.
## The Serilog Sinks
@ -21,6 +21,6 @@ The `Program.cs` file is the main point that configures the logging system. It i
You can easily understand the Serilog configuration when you check your `Program.cs`. However, there are a few things worth mentioning here:
* We are adding an `Application` property to every log record, so you can filter logs by the application name. It is done in the `Program.cs` file with the `.Enrich.WithProperty("Application", applicationName)` line. The `applicationName` value is taken from [the `IApplicationInfoAccessor` service](https://docs.abp.io/en/abp/8.0/Application-Startup#the-applicationname-option) of ABP. By default, it is the name of the entrance assembly (that contains the `Program.cs` file) of the application.
* We are using ABP Serilog Enrichers in the module class of the application. It is done by the `app.UseAbpSerilogEnrichers();` line in the `OnApplicationInitialization` method of your module class. That ASP.NET Core middleware adds current [tenant](https://docs.abp.io/en/abp/latest/Multi-Tenancy), [user](https://docs.abp.io/en/abp/latest/CurrentUser), client and correlation id information to the log records.
* We are adding an `Application` property to every log record, so you can filter logs by the application name. It is done in the `Program.cs` file with the `.Enrich.WithProperty("Application", applicationName)` line. The `applicationName` value is taken from [the `IApplicationInfoAccessor` service](../../framework/fundamentals/application-startup.md#the-applicationname-option) of ABP. By default, it is the name of the entrance assembly (that contains the `Program.cs` file) of the application.
* We are using ABP Serilog Enrichers in the module class of the application. It is done by the `app.UseAbpSerilogEnrichers();` line in the `OnApplicationInitialization` method of your module class. That ASP.NET Core middleware adds current [tenant](../../framework/architecture/multi-tenancy/index.md), [user](../../framework/infrastructure/current-user.md), client and correlation id information to the log records.

6
docs/en/solution-templates/microservice/microservices.md

@ -43,9 +43,9 @@ The following figure shows the Administration microservice's module structure in
![administration-microservice-in-solution-explorer](images/administration-microservice-in-solution-explorer.png)
Administration service is basically used to to manage **permissions** (using the [Permission Management](https://docs.abp.io/en/abp/latest/Modules/Permission-Management) module), **features** (using the [Feature Management](https://docs.abp.io/en/abp/latest/Modules/Feature-Management) module), **settings** (using the [Setting Management](https://docs.abp.io/en/abp/latest/Modules/Setting-Management) module) and **languages** (using the [Language Management](../../modules/language-management.md) module) (maybe some others based on your preferences) of the system. These are the common infrastructure services that are used by all the services and applications in the solution. Administration service is responsible to serve management HTTP APIs to UI for these services, and it also maintains the database schema for them.
Administration service is basically used to to manage **permissions** (using the [Permission Management](../../modules/permission-management.md) module), **features** (using the [Feature Management](../../modules/feature-management.md) module), **settings** (using the [Setting Management](../../modules/setting-management.md) module) and **languages** (using the [Language Management](../../modules/language-management.md) module) (maybe some others based on your preferences) of the system. These are the common infrastructure services that are used by all the services and applications in the solution. Administration service is responsible to serve management HTTP APIs to UI for these services, and it also maintains the database schema for them.
In addition to these fundamental infrastructure services, Administration service also creates the [BLOB Storing database](https://docs.abp.io/en/abp/latest/Blob-Storing-Database), so other services can easily store BLOBs.
In addition to these fundamental infrastructure services, Administration service also creates the [BLOB Storing database](../../framework/infrastructure/blob-storing/database.md), so other services can easily store BLOBs.
### Identity Microservice
@ -63,7 +63,7 @@ If you've selected the [SaaS](../../modules/saas.md) module while [creating your
This microservice serves the [SaaS](../../modules/saas.md) module's HTTP API, creates and manages its database.
> [Multi-Tenancy](https://docs.abp.io/en/abp/latest/Multi-Tenancy) is a common feature of the solution. If you install the SaaS module, multi-tenancy is automatically enabled for all the services and applications in the solution and the necessary configurations are done for you.
> [Multi-Tenancy](../../framework/architecture/multi-tenancy/index.md) is a common feature of the solution. If you install the SaaS module, multi-tenancy is automatically enabled for all the services and applications in the solution and the necessary configurations are done for you.
### Audit Logging Microservice (optional)

62
docs/en/solution-templates/microservice/monitoring.md

@ -0,0 +1,62 @@
# Microservice Solution: Monitoring
In a distributed system it is important to monitor the health of the system and the services. Monitoring helps to detect issues before they become problems and helps to understand the system's behavior. All the services, applications and gateways are configured to use the [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/) libraries for monitoring. They are configured in a common way for monitoring. This document explains that common monitoring structure.
## Configuration
The monitoring configuration is done in the each *Module* class of the project. The `OnApplicationInitialization` method of the module class is used to set the monitoring system. We're adding the `prometheus-net.AspNetCore` package to the project to use Prometheus. The `prometheus-net.AspNetCore` package is a library that provides a middleware to expose metrics for Prometheus. The `app.UseHttpMetrics();` line is collect the HTTP request metrics. The `endpoints.MapMetrics();` line is used to expose the metrics to the `/metrics` endpoint. Existing templates includes the prometheus and grafana configurations in the `docker-compose` file. So, you can visit the `http://localhost:9090` to see the [Prometheus](https://prometheus.io/) dashboard and `http://localhost:3001` to see the [Grafana](https://grafana.com/) dashboard.
> Default username and password for Grafana is `admin` and `admin`. You can change the password after the first login.
After you login to the Grafana dashboard, you can add a new data source to connect to the Prometheus server and create a new dashboard to monitor the system.
![grafana-dashboard](./images/grafana-dashboard.png)
## Custom Metrics
To create custom metrics, you can use the [IMeterFactory](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.metrics.imeterfactory) interface. Basically, you can follow the steps in the [official documentation](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/metrics-instrumentation) to create custom metrics. For example, you can create a custom metric to monitor the number of requests to a specific endpoint.
```csharp
public class AdministrationMetrics : ISingletonDependency
{
private readonly Counter<int> _demoRequested;
public AdministrationMetrics(IMeterFactory meterFactory)
{
var meter = meterFactory.Create("Microservice.Administration");
_demoRequested = meter.CreateCounter<int>("demo_controller.requested");
}
public void DemoRequested()
{
_demoRequested.Add(1);
}
}
```
In the demo controller, you can inject the `AdministrationMetrics` class and use the `DemoRequested` method to increase the counter.
```csharp
[Route("api/administration/demo")]
public class DemoController : AbpController
{
public AdministrationMetrics AdministrationMetrics { get; }
public DemoController(AdministrationMetrics administrationMetrics)
{
AdministrationMetrics = administrationMetrics;
}
[HttpGet]
[Route("requested")]
public Task DemoRequested()
{
AdministrationMetrics.DemoRequested();
return Task.CompletedTask;
}
}
```
## Kubernetes Monitoring
If you check the *Kubernetes Configuration* option during project creation, the monitoring system is automatically configured for Kubernetes. The `prometheus` and `grafana` configurations are added to the `helm` chart.

26
docs/en/solution-templates/microservice/overview.md

@ -10,13 +10,13 @@ In this document, you will learn what the Microservice solution template offers
All the following **libraries and services** are **pre-installed** and **configured** for both of **development** and **production** environments. After creating your solution, you can **change** to **remove** most of them.
* **[Autofac](https://autofac.org/)** for [Dependency Injection](https://docs.abp.io/en/abp/latest/Dependency-Injection)
* **[Serilog](https://serilog.net/)** with File, Console and Elasticsearch [logging](https://docs.abp.io/en/abp/latest/Logging) providers
* **[Autofac](https://autofac.org/)** for [Dependency Injection](../../framework/fundamentals/dependency-injection.md)
* **[Serilog](https://serilog.net/)** with File, Console and Elasticsearch [logging](../../framework/fundamentals/logging.md) providers
* **[Prometheus](https://prometheus.io/)** for collecting metrics
* **[Grafana](https://grafana.com/)** to visualize the collected metrics
* **[Redis](https://redis.io/)** for [distributed caching](https://docs.abp.io/en/abp/latest/Caching) and [distributed locking](https://docs.abp.io/en/abp/latest/Distributed-Locking)
* **[Redis](https://redis.io/)** for [distributed caching](../../framework/fundamentals/caching.md) and [distributed locking](../../framework/infrastructure/distributed-locking.md)
* **[Swagger](https://swagger.io/)** to explore and test HTTP APIs
* **[RabbitMQ](https://www.rabbitmq.com/)** as the [distributed event bus](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus)
* **[RabbitMQ](https://www.rabbitmq.com/)** as the [distributed event bus](../../framework/infrastructure/event-bus/distributed/index.md)
* **[YARP](https://microsoft.github.io/reverse-proxy/)** to implement the API Gateways
* **[OpenIddict](https://github.com/openiddict/openiddict-core)** as the in-house authentication server.
@ -29,14 +29,14 @@ The following features are built and pre-configured for you in the solution.
* **OpenId Connect Authentication**, if you have selected the MVC UI.
* **Authorization code flow** is implemented, if you have selected a SPA UI (Angular or Blazor WASM).
* Other flows (resource owner password, client credentials...) are easy to use when you need them.
* **[Permission](https://docs.abp.io/en/abp/latest/Authorization)** (authorization), **[setting](https://docs.abp.io/en/abp/latest/Settings)**, **[feature](https://docs.abp.io/en/abp/latest/Features)** and the **[localization](https://docs.abp.io/en/abp/latest/Localization)** management systems are pre-configured and ready to use.
* **[Background job system](https://docs.abp.io/en/abp/latest/Background-Jobs)** with [RabbitMQ integrated](https://docs.abp.io/en/abp/latest/Background-Jobs-RabbitMq).
* **[BLOB storge](https://docs.abp.io/en/abp/latest/Blob-Storing)** system is installed with the [database provider](https://docs.abp.io/en/abp/latest/Blob-Storing-Database) and a separate database.
* **[Permission](../../framework/fundamentals/authorization.md)** (authorization), **[setting](../../framework/fundamentals/settings.md)**, **[feature](../../framework/infrastructure/features.md)** and the **[localization](../../framework/fundamentals/localization.md)** management systems are pre-configured and ready to use.
* **[Background job system](../../framework/infrastructure/background-jobs/index.md)** with [RabbitMQ integrated](../../framework/infrastructure/background-jobs/rabbitmq.md).
* **[BLOB storge](../../framework/infrastructure/blob-storing/index.md)** system is installed with the [database provider](../../framework/infrastructure/blob-storing/database.md) and a separate database.
* **On-the-fly database migration** system (services automatically migrated their database schema when you deploy a new version)
* Infrastructure dependencies are configured via **[docker-compose](https://docs.docker.com/compose/)** for running the solution in local environment.
* **[Helm](https://helm.sh/)** charts are included to deploy the solution to **[Kubernetes](https://kubernetes.io/)**.
* **[Swagger](https://swagger.io/)** authentication is configured to test the authorized HTTP APIs.
* Configured the **[Inbox & Outbox patterns](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus#outbox-inbox-for-transactional-events)** for [distributed event bus](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus).
* Configured the **[Inbox & Outbox patterns](../../framework/infrastructure/event-bus/distributed/index.md#outbox--inbox-for-transactional-events)** for [distributed event bus](../../framework/infrastructure/event-bus/distributed/index.md).
## Fundamental Modules
@ -44,9 +44,9 @@ The following modules are pre-installed and configured for the solution:
* **[Account](../../modules/account.md)** to authenticate users (login, register, two factor auth, etc)
* **[Identity](../../modules/identity.md)** to manage roles and users
* **[OpenIddict](https://docs.abp.io/en/abp/latest/Modules/OpenIddict)** (the core part) to implement the OAuth authentication flows
* **[OpenIddict](../../modules/openiddict.md)** (the core part) to implement the OAuth authentication flows
In addition these, [Feature Management](https://docs.abp.io/en/abp/latest/Modules/Feature-Management), [Permission Management](https://docs.abp.io/en/abp/latest/Modules/Permission-Management) and [Setting Management](https://docs.abp.io/en/abp/latest/Modules/Setting-Management) modules are pre-installed as they are the fundamental feature modules of the ABP.
In addition these, [Feature Management](../../modules/feature-management.md), [Permission Management](../../modules/permission-management.md) and [Setting Management](../../modules/setting-management.md) modules are pre-installed as they are the fundamental feature modules of the ABP.
## Optional Modules
@ -71,8 +71,8 @@ Microservice startup template asks for some preferences while creating your solu
There are two database provider options are provided on a new microservice solution creation:
* **[Entity Framework Core](https://docs.abp.io/en/abp/latest/Entity-Framework-Core)** with SQL Server, MySQL and PostgreSQL DBMS options. You can [switch to anther DBMS](https://docs.abp.io/en/abp/latest/Entity-Framework-Core-Other-DBMS) manually after creating your solution.
* **[MongoDB](https://docs.abp.io/en/abp/latest/MongoDB)**
* **[Entity Framework Core](../../framework/data/entity-framework-core/index.md)** with SQL Server, MySQL and PostgreSQL DBMS options. You can [switch to anther DBMS](../../framework/data/entity-framework-core/other-dbms.md) manually after creating your solution.
* **[MongoDB](../../framework/data/mongodb/index.md)**
### UI Frameworks
@ -95,7 +95,7 @@ If you prefer, the solution includes a mobile application with its dedicated API
### Multi-Tenancy & SaaS Module
The **[SaaS module](../../modules/saas.md)** is included as an option. When you select it, the **[multi-tenancy](https://docs.abp.io/en/abp/latest/Multi-Tenancy)** system is automatically configured. Otherwise, the system will not include any multi-tenancy overhead.
The **[SaaS module](../../modules/saas.md)** is included as an option. When you select it, the **[multi-tenancy](../../framework/architecture/multi-tenancy/index.md)** system is automatically configured. Otherwise, the system will not include any multi-tenancy overhead.
## Next

2
docs/en/solution-templates/microservice/solution-structure.md

@ -37,7 +37,7 @@ The folder structure basically matches to the solution in ABP Studio's *Solution
* `k8s` folder contains some additional files to setup *Kubernetes Dashboard* on your local machine.
* `gateways` folder contains one or more API Gateways (the count depends on if you've selected mobile application or other applications if available). This solution implements the [BFF](https://learn.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontends) (Backend for frontend pattern), that means it has a dedicated API Gateway for each different UI application.
* `services` folder contains the microservices. The microservice count varies based on the options you've selected during the solution creation. However, the following microservices are always included:
* `adminstration` microservice is used to manage permissions, languages and other fundamental settings of the system.
* `administration` microservice is used to manage permissions, languages and other fundamental settings of the system.
* `identity` microservice is used to manage users, roles and their permissions. It basically serves to the [Identity](../../modules/identity.md) module's UI (and [OpenIddict](../../modules/openiddict.md) module's UI, if selected).
## Next

376
docs/en/studio/cli.md

@ -1,376 +0,0 @@
# ABP Studio CLI
ABP Studio CLI is a command line tool that extends [ABP CLI](../cli) by adding more commands to perform operations of ABP Studio features.
## Installation
ABP Studio CLI is installed automatically when you install ABP Studio.
## Commands
As ABP Studio CLI extends [ABP CLI](../cli), all commands provided by [ABP CLI](../cli) is also valid for ABP Studio CLI. Here, is the list of additional commands before explaining their details:
* new-solution: Generates a new solution based on the ABP Studio [startup templates](../solution-templates).
* new-module: Generates a new module based on the given template.
* new-package: Generates a new package based on the given template.
* add-package-ref: Adds package to given project.
* add-source: Downloads the source code and replaces package references with project references.
* init-solution: Creates ABP Studio configuration files for a given solution.
* install-local-module: Installs a local module to given module.
* install-module: Installs a module to given module via NuGet packages.
* upgrade: Upgrades solution with Pro modules
* kube-connect: Connects to kubernetes environment.
* kube-intercept: Intercepts a service running in Kubernetes environment.
### new-solution
Generates a new solution based on the ABP Studio [startup templates](../solution-templates).
````bash
abpc new-solution <solution-name> [options]
````
Example:
````bash
abpc new-solution Acme.BookStore
````
* `Acme.BookStore` is the solution name here.
* Common convention is to name a solution is like *YourCompany.YourProject*. However, you can use different naming like *YourProject* (single level namespacing) or *YourCompany.YourProduct.YourModule* (three levels namespacing).
#### options
* `--template` or `-t`: Specifies the template name. Default template name is `empty`, which generates a empty solution. Available templates:
* **`empty`**: Empty solution template.
* **`app-pro`**: Application template. Additional options:
* `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks:
* `mvc`: ASP.NET Core MVC. There are some additional options for this template:
* `--tiered`: Creates a tiered solution where Web and Http API layers are physically separated. If not specified, it creates a layered solution which is less complex and suitable for most scenarios.
* `angular`: Angular UI. There are some additional options for this template:
* `--separate-auth-server`: The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side.
* `--pwa`: Specifies the project as Progressive Web Application.
* `blazor`: Blazor UI. There are some additional options for this template:
* `--separate-auth-server`The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side.
* `--pwa`: Specifies the project as Progressive Web Application.
* `blazor-server`: Blazor Server UI. There are some additional options for this template:
* `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project.
* `maui-blazor`: Blazor Maui UI. There are some additional options for this template:
* `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project.
* `no-ui`: Without UI. No front-end layer will be created. There are some additional options for this template:
* `--separate-auth-server`: The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side.
* `--mobile` or `-m`: Specifies the mobile application framework. Default value is `react-native`. Available frameworks:
* `none`: Without any mobile application.
* `react-native`: React Native.
* `maui`: MAUI.
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
* `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](../framework/data/entity-framework-core/other-dbms.md) (after creating the solution).
* `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
* `leptonx`: LeptonX Theme.
* `basic`: Basic Theme.
* **`app-nolayers-pro`**: Single-layer application template. Additional options:
* `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks:
* `mvc`: ASP.NET Core MVC. There are some additional options for this template:
* `angular`: Angular UI. There are some additional options for this template:
* `blazor`: Blazor UI. There are some additional options for this template:
* `blazor-server`: Blazor Server UI. There are some additional options for this template:
* `no-ui`: Without UI. No front-end layer will be created. There are some additional options for this template:
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
* `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](../framework/data/entity-framework-core/other-dbms.md) (after creating the solution).
* `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
* `leptonx`: LeptonX Theme.
* `basic`: Basic Theme.
* **`microservice-pro`**: Microservice solution template. Additional options:
* `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks:
* `mvc`: ASP.NET Core MVC. There are some additional options for this template:
* `angular`: Angular UI. There are some additional options for this template:
* `blazor`: Blazor UI. There are some additional options for this template:
* `blazor-server`: Blazor Server UI. There are some additional options for this template:
* `maui-blazor`: Blazor Maui UI. There are some additional options for this template:
* `no-ui`: Without UI. No front-end layer will be created. There are some additional options for this template:
* `--mobile` or `-m`: Specifies the mobile application framework. Default value is `react-native`. Available frameworks:
* `none`: Without any mobile application.
* `react-native`: React Native.
* `maui`: MAUI.
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
* `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes:
* `leptonx`: LeptonX Theme.
* `basic`: Basic Theme.
* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
* `--database-management-system` or `-dbms`: Sets the database management system. Default is **SQL Server**. Supported DBMS's:
* `SqlServer`
* `MySQL`
* `PostgreSQL`
* `SQLite` (`app-pro` & `app-nolayers-pro`)
* `Oracle` (`app-pro` & `app-nolayers-pro`)
* `Oracle-Devart` (`app-pro` & `app-nolayers-pro`)
* `--dont-run-install-libs`: Skip installing client side packages.
* `--dont-run-bundling`: Skip bundling for Blazor packages.
* `--no-kubernetes-configuration` or `-nkc`: Skips the Kubernetes configuration files.
* *Module Options*: You can skip some modules if you don't want to add them to your solution. Available commands:
* `-no-saas`: Skips the Saas module.
* `-no-gdpr`: Skips the GDPR module.
* `-no-openiddict-admin-ui`: Skips the OpenIddict Admin UI module.
* `-no-audit-logging`: Skips the Audit Logging module.
* `-no-file-management`: Skips the File Management module.
* `-no-language-management`: Skips the Language Management module.
* `-no-text-template-management`: Skips the Text Template Management module.
* `-no-chat`: Skips the Chat module.
### new-module
Generates a new module.
````bash
abpc new-module <module-name> [options]
````
Example:
````bash
abpc new-module Acme.BookStore -t module:ddd
````
#### options
* `--template` or `-t`: Specifies the template name. Default template name is `empty`, which generates a empty module. Module templates are provided by the main template, see their own startup template documentation for available modules. `empty` and `module:ddd` template is available for all solution structure.
* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
* `--target-solution` or `-ts`: If set, the new module will be added to the given solution. Otherwise the new module will added to the closest solution in the file system. If no solution found, it will throw an error.
* `--solution-folder` or `-sf`: Specifies the target folder in the [Solution Explorer](./solution-explorer.md#folder) virtual folder system.
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. This option is only available if the module template supports it. You can add multiple values separated by commas, such as `ef, mongodb` if the module template supports it. Available providers:
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
* `--ui-framework` or `-u`: Specifies the UI framework. Default framework is `mvc`. This option is only available if the module template supports it. You can add multiple values separated by commas, such as `mvc,angular` if the module template supports it. Available frameworks:
* `mvc`: ASP.NET Core MVC.
* `angular`: Angular UI.
* `blazor`: Blazor UI.
* `blazor-server`: Blazor Server UI.
### new-package
Generates a new package.
````bash
abpc new-package [options]
````
Example:
````bash
abpc new-package --name Acme.BookStore.Domain --template lib.domain
````
#### options
* `--template` or `-t`: Specifies the template name. This parameter doesn't have a default value and must be set. Available templates and their sub-options:
* `lib.class-library`
* `lib.domain-shared`
* `lib.domain`
* `lib.application-contracts`
* `lib.application`
* `--with-automapper`: Adds automapper configuration.
* `lib.ef`
* `--include-migrations`: Allows migration operations on this package.
* `--connection-string-name`: Default value is the last part of the package's namespace (or package name simply).
* `--connection-string`: Connection string value. Defaut value is null. You can set it alter.
* `lib.mongodb`
* `lib.http-api`
* `lib.http-api-client`
* `lib.mvc`
* `lib.blazor`
* `lib.blazor-wasm`
* `lib.blazor-server`
* `host.http-api`
* `--with-serilog`: Includes Serilog configuration.
* `--with-swagger`: Includes Swagger configuration.
* `host.mvc`
* `--with-serilog`: Includes Serilog configuration.
* `--with-swagger`: Includes Swagger configuration.
* `host.blazor-wasm`
* `--backend`: Name of the backend project in the module (not path).
* `host.blazor-server`
* `csharp.console`
* `csharp.library`
* `--module-file` or `-m`: If set, the new package will be added to the given module. Otherwise the new package will added to the closest module in the file system. If no module found, it will throw an error.
* `--name` or `-n`: Specifies the name of the package. If not set, a name based on the template type and module name will be generated.
* `--folder` or `-f`: Specifies the target folder in the target module's virtual folder system.
### add-package-ref
Adds one or more package reference to target project, also adds ABP module dependency. Both reference and target projects must belong to same module.
````bash
abpc add-package-ref <package-names> [options]
````
Example:
````bash
abpc add-package-ref Acme.BookStore.Domain
abpc add-package-ref "Acme.BookStore.Domain Acme.BookStore.Domain.Shared" -t Acme.BookStore.Web
````
#### options
* `--target-project` or `-t`: Name of the project that reference will be added. If not set, project in the current directory will be used.
### add-source
Downloads the source code of a module and replaces package references with project references. This command only works if your ABP License has source-code access, or if source-code of the target module is free to all type of ABP Licenses.
````bash
abpc add-source <module-name> [options]
````
Example:
````bash
abpc add-source Volo.Chat --add-to-solution-file
````
#### options
* `--target-module` or `-t`: The module that will refer the downloaded source code. If not set, the module in the current directory will be used.
* `--add-to-solution-file`: Adds the downloaded source code to C# solution file and ABP Studio solution file.
### init-solution
Creates necessary files for a solution to be readable by ABP Studio. If the solution is generated via ABP Studio, you don't need this command. But it is not generated by ABP Studio, you need this command to make it work with ABP Studio.
````bash
abpc init-solution [options]
````
Example:
````bash
abpc init-solution --name Acme.BookStore
````
#### options
* `--name` or `-n`: Name for the solution. If not set, it will be the same as the name of closest c# solution in the file system.
### install-local-module
Installs one module to another. Project relations are created according the types of the projects. For example: a `lib.domain-shared` project is added to `lib.domain-shared` project
````bash
abpc install-local-module <module-path> [options]
````
Example:
````bash
abpc install-local-module Acme.OrderManagement
abpc install-local-module Acme.OrderManagement -t "modules/crm/Acme.Crm.abpmdl"
````
#### options
* `--target-module` or `-t`: Path (or folder path) of the target module that the other module will be installed to. If not set, the closest module to the current directory will be used.
### install-module
Installs a module, that is published as nuget packages, to a local module. Project relations are created according the types of the projects. For example: a `lib.domain-shared` project is added to `lib.domain-shared` project
````bash
abpc install-module <module-name> [options]
````
Example:
````bash
abpc install-module Volo.Blogging
abpc install-module Volo.Blogging -t "modules/crm/Acme.Crm.abpmdl"
````
#### options
* `--target-module` or `-t`: Path (or folder path) of the target module that the other module will be installed to. If not set, the closest module to the current directory will be used.
* `--version` or `-v`: Nuget version of the module to be installed.
### upgrade
Upgrades the solution with Pro modules. Especially designed for users who already started their development before having a license. Therefore this command requires license. For more info, see the related document.
````bash
abpc upgrade [options]
````
Example:
````bash
abpc upgrade -t app
abpc upgrade -t app-nolayers
````
#### options
* `--template` or `-t`: The template type of the solution. Only `app` and `app-nolayers` are valid currently.
### kube-connect
Connects to Kubernetes cluster. Press `ctrl+c` to disconnect.
````bash
abpc kube-connect [options]
````
Example:
````bash
abpc kube-connect
abpc kube-connect -p Default.abpk8s.json
abpc kube-connect -c docker-desktop -ns mycrm-local
````
#### options
* `--profile` or `-p`: Kubernetes Profile path or name to be used. Path can be relative (to current directory) or full path, or you can simply give the name of profile if you run this command in same directory with the solution or profile. This parameter is not needed if you use `--namespace` and `--context` parameters.
* `--namespace` or `-ns`: The namespace that services running on.
* `--context` or `-c`: The context that services running in.
* `--wireguard-password` or `-wp`: Wireguard password for the profile. This is not needed if you already set it on the ABP Studio user interface.
* `--solution-id` or `-si`: Id of the solution. If not set, the closest solution in file system will be used.
### kube-intercept
Intercepts a service running in Kubernetes environment. Press `ctrl+c` to stop interception.
````bash
abpc kube-intercept <service-name> [options]
````
Example:
````bash
abpc kube-intercept mycrm-product-service -ns mycrm-local
abpc kube-intercept mycrm-product-service -ns mycrm-local -a MyCrm.ProductService.HttpApi.Host.csproj
abpc kube-intercept mycrm-product-service -ns mycrm-local -a MyCrm.ProductService.HttpApi.Host.csproj -pm 8080:80,8081:443
````
#### options
* `--application` or `-a`: Relative or full path of the project that will intercept the service. If not set, the project in the current directory will be used.
* `--namespace` or `-ns`: The namespace that service running on.
* `--context` or `-sc`: The context that service running in. Default value is `docker-desktop`.
* `--port-mappings` or `-pm`: Port mappings for the service.
## See Also
* [ABP CLI](../cli)

BIN
docs/en/studio/images/preference-theme-change.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 16 KiB

3
docs/en/studio/index.md

@ -16,5 +16,4 @@ If you haven't installed yet, please see [the installation guide](installation.m
- Fundamentals
- [Solution Explorer](./solution-explorer.md)
- [Running Applications](./running-applications.md)
- [Working with Kubernetes](./kubernetes.md)
- [CLI](./cli.md)
- [Working with Kubernetes](./kubernetes.md)

17
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs

@ -31,24 +31,11 @@ public class ClientProxyExceptionEventHandler : ILocalEventHandler<ClientProxyEx
case 401:
{
var options = scope.ServiceProvider.GetRequiredService<IOptions<AbpAspNetCoreComponentsWebOptions>>();
if (!options.Value.IsBlazorWebApp)
{
var navigationManager = scope.ServiceProvider.GetRequiredService<NavigationManager>();
var accessTokenProvider = scope.ServiceProvider.GetRequiredService<IAccessTokenProvider>();
var authenticationOptions = scope.ServiceProvider.GetRequiredService<IOptions<AbpAuthenticationOptions>>();
var result = await accessTokenProvider.RequestAccessToken();
if (result.Status != AccessTokenResultStatus.Success)
{
navigationManager.NavigateToLogout(authenticationOptions.Value.LogoutUrl);
return;
}
result.TryGetToken(out var token);
if (token != null && DateTimeOffset.Now >= token.Expires.AddMinutes(-5))
{
navigationManager.NavigateToLogout(authenticationOptions.Value.LogoutUrl);
}
var navigationManager = scope.ServiceProvider.GetRequiredService<NavigationManager>();
navigationManager.NavigateToLogout(authenticationOptions.Value.LogoutUrl, "/");
}
else
{

1
framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs

@ -102,6 +102,7 @@ public static class AbpApplicationBuilderExtensions
return app.UseMiddleware<AbpExceptionHandlingMiddleware>();
}
[Obsolete("Replace with AbpClaimsTransformation")]
public static IApplicationBuilder UseAbpClaimsMap(this IApplicationBuilder app)
{
return app.UseMiddleware<AbpClaimsMapMiddleware>();

8
framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs

@ -1,6 +1,7 @@
using System.Linq;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Volo.Abp.AspNetCore.Security.Claims;
namespace Microsoft.Extensions.DependencyInjection;
@ -20,4 +21,9 @@ public static class AbpAspNetCoreServiceCollectionExtensions
return hostingEnvironment;
}
public static IServiceCollection TransformAbpClaims(this IServiceCollection services)
{
return services.AddTransient<IClaimsTransformation, AbpClaimsTransformation>();
}
}

4
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs

@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
@ -10,6 +11,7 @@ using Volo.Abp.Security.Claims;
namespace Volo.Abp.AspNetCore.Security.Claims;
[Obsolete("Replace with AbpClaimsTransformation")]
public class AbpClaimsMapMiddleware : AbpMiddlewareBase, ITransientDependency
{
public async override Task InvokeAsync(HttpContext context, RequestDelegate next)

35
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsTransformation.cs

@ -0,0 +1,35 @@
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
namespace Volo.Abp.AspNetCore.Security.Claims;
public class AbpClaimsTransformation : IClaimsTransformation
{
protected IOptions<AbpClaimsMapOptions> AbpClaimsMapOptions { get; }
public AbpClaimsTransformation(IOptions<AbpClaimsMapOptions> abpClaimsMapOptions)
{
AbpClaimsMapOptions = abpClaimsMapOptions;
}
public virtual Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var mapClaims = principal.Claims.Where(claim => AbpClaimsMapOptions.Value.Maps.Keys.Contains(claim.Type));
principal.AddIdentity(new ClaimsIdentity(mapClaims.Select(
claim => new Claim(
AbpClaimsMapOptions.Value.Maps[claim.Type](),
claim.Value,
claim.ValueType,
claim.Issuer
)
)
)
);
return Task.FromResult(principal);
}
}

8
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs

@ -107,9 +107,15 @@ public class BundlingService : IBundlingService, ITransientDependency
if (!bundleConfig.InteractiveAuto)
{
var fileName = bundleConfig.IsBlazorWebApp
? Directory.GetFiles(Path.GetDirectoryName(projectFilePath)!.Replace(".Client", ""), "App.razor", SearchOption.AllDirectories).FirstOrDefault()
? Directory.GetFiles(Path.GetDirectoryName(projectFilePath)!.Replace(".Client", ""), "App.razor", SearchOption.AllDirectories).FirstOrDefault() ??
Directory.GetFiles(Path.GetDirectoryName(projectFilePath)!.Replace(".Blazor", ".Host"), "App.razor", SearchOption.AllDirectories).FirstOrDefault()
: Path.Combine(PathHelper.GetWwwRootPath(directory), "index.html");
if (fileName == null)
{
throw new BundlingException($"App.razor file could not be found in the {projectFilePath} directory.");
}
await UpdateDependenciesInBlazorFileAsync(fileName, styleDefinitions, scriptDefinitions);
Logger.LogInformation($"Script and style references in the {fileName} file have been updated.");

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeThemeStep.cs

@ -702,7 +702,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
context,
$"_Host.cshtml",
$"{defaultThemeName}Theme.Components",
Basic
"BasicTheme.Themes.Basic"
);
ReplaceAllKeywords(

7
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs

@ -73,9 +73,10 @@ public class AbpAspNetCoreMvcTestModule : AbpModule
context.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = FakeAuthenticationSchemeDefaults.Scheme;
options.DefaultChallengeScheme = "Bearer";
options.DefaultForbidScheme = "Cookie";
}).AddCookie("Cookie").AddJwtBearer("Bearer", _ => { });
}).AddFakeAuthentication().AddCookie("Cookie").AddJwtBearer("Bearer", _ => { });
context.Services.AddAuthorization(options =>
{
@ -137,6 +138,8 @@ public class AbpAspNetCoreMvcTestModule : AbpModule
{
options.Contributors.Add(new TestApplicationConfigurationContributor());
});
context.Services.TransformAbpClaims();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
@ -148,8 +151,6 @@ public class AbpAspNetCoreMvcTestModule : AbpModule
app.UseAbpRequestLocalization();
app.UseAbpSecurityHeaders();
app.UseRouting();
app.UseMiddleware<FakeAuthenticationMiddleware>();
app.UseAbpClaimsMap();
app.UseAuthentication();
app.UseAuthorization();
app.UseAuditing();

4
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
@ -8,6 +9,7 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc;
[Obsolete("Use FakeAuthenticationScheme instead.")]
public class FakeAuthenticationMiddleware : AbpMiddlewareBase, ITransientDependency
{
private readonly FakeUserClaims _fakeUserClaims;

68
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationScheme.cs

@ -0,0 +1,68 @@
using System;
using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using DeviceDetectorNET;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Volo.Abp.AspNetCore.Mvc;
public static class FakeAuthenticationSchemeDefaults
{
public static string Scheme => "FakeAuthenticationScheme";
}
public static class FakeAuthenticationBuilderExtensions
{
public static AuthenticationBuilder AddFakeAuthentication(this AuthenticationBuilder builder)
{
return builder.AddScheme<FakeAuthenticationOptions, FakeAuthenticationHandler>(FakeAuthenticationSchemeDefaults.Scheme, _ => { });
}
}
public class FakeAuthenticationOptions : AuthenticationSchemeOptions
{
}
public class FakeAuthenticationHandler : AuthenticationHandler<FakeAuthenticationOptions>
{
private readonly FakeUserClaims _fakeUserClaims;
[Obsolete]
public FakeAuthenticationHandler(
IOptionsMonitor<FakeAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock,
FakeUserClaims fakeUserClaims) : base(options, logger, encoder, clock)
{
_fakeUserClaims = fakeUserClaims;
}
public FakeAuthenticationHandler(
IOptionsMonitor<FakeAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
FakeUserClaims fakeUserClaims)
: base(options, logger, encoder)
{
_fakeUserClaims = fakeUserClaims;
}
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
if (_fakeUserClaims.Claims.Any())
{
return Task.FromResult(AuthenticateResult.Success(
new AuthenticationTicket(
new ClaimsPrincipal(new ClaimsIdentity(_fakeUserClaims.Claims,
FakeAuthenticationSchemeDefaults.Scheme)),
FakeAuthenticationSchemeDefaults.Scheme)));
}
return Task.FromResult(AuthenticateResult.NoResult());
}
}

2
modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/wwwroot/themes/basic/layout.js

@ -1,5 +1,7 @@
$(function () {
$('.dropdown-menu a.dropdown-toggle').on('click', function (e) {
$(this).next().toggleClass('show');
if (!$(this).next().hasClass('show')) {
$(this).parents('.dropdown-menu').first().find('.show').removeClass("show");
}

2
npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html

@ -17,7 +17,7 @@
*ngTemplateOutlet="actionsTemplate || gridActions; context: { $implicit: row, index: i }"
></ng-container>
<ng-template #gridActions>
@if (hasAvailableActions(i, row)) {
@if (hasAvailableActions(row)) {
<abp-grid-actions [index]="i" [record]="row" text="AbpUi::Actions"></abp-grid-actions>
}
</ng-template>

20
npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts

@ -206,12 +206,20 @@ export class ExtensibleTableComponent<R = any> implements OnChanges {
});
}
hasAvailableActions(index, data): boolean {
const { permission, visible } = this.actionList.get(index)?.value || {};
let isActionAvailable = this.permissionService.getGrantedPolicy(permission);
if (data && data.record) {
isActionAvailable &&= visible(data);
}
hasAvailableActions(rowData): boolean {
let isActionAvailable = true;
this.actionList.toArray().map(action => {
const { visible, permission } = action;
if (rowData && action) {
const visibilityCheck = visible({
record: rowData,
getInjected: this.getInjected,
});
const permissionCheck = this.permissionService.getGrantedPolicy(permission);
isActionAvailable = visibilityCheck && permissionCheck;
}
});
return isActionAvailable;
}
}

1
templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/Components/Routes.razor

@ -9,6 +9,5 @@
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

1
templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Components/Routes.razor

@ -9,6 +9,5 @@
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

1
templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Client/Routes.razor

@ -7,6 +7,5 @@
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

1
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Client/Routes.razor

@ -7,6 +7,5 @@
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

1
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Components/Routes.razor

@ -9,6 +9,5 @@
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

1
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Components/Routes.razor

@ -9,6 +9,5 @@
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

1
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Client/Routes.razor

@ -9,6 +9,5 @@
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

1
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client/Routes.razor

@ -9,6 +9,5 @@
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

1
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host.Client/Routes.razor

@ -7,6 +7,5 @@
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

1
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Components/Routes.razor

@ -9,6 +9,5 @@
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

Loading…
Cancel
Save