@ -1,24 +1,24 @@ |
|||
name: Merge branch rel-4.0 with rel-3.3 |
|||
name: Merge branch rel-4.1 with rel-4.0 |
|||
on: |
|||
push: |
|||
branches: |
|||
- rel-3.3 |
|||
- rel-4.0 |
|||
jobs: |
|||
merge-rel-4-0-with-rel-3-3: |
|||
merge-rel-4-1-with-rel-4-0: |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- uses: actions/checkout@v2 |
|||
with: |
|||
ref: rel-4.0 |
|||
ref: rel-4.1 |
|||
- name: Reset promotion branch |
|||
run: | |
|||
git fetch origin rel-3.3:rel-3.3 |
|||
git reset --hard rel-3.3 |
|||
git fetch origin rel-4.0:rel-4.0 |
|||
git reset --hard rel-4.0 |
|||
- name: Create Pull Request |
|||
uses: peter-evans/create-pull-request@v3 |
|||
with: |
|||
branch: auto-merge/rel-3-3/${{github.run_number}} |
|||
title: Merge branch rel-4.0 with rel-3.3 |
|||
body: This PR generated automatically to merge rel-4.0 with rel-3.3. Please review the changed files before merging to prevent any errors that may occur. |
|||
branch: auto-rel-4-0-merge-pr-${{github.run_number}} |
|||
title: Merge branch rel-4.1 with ${{github.ref}} |
|||
body: This PR generated automatically to merge rel-4.1 with rel-4.0. Please review the changed files before merging to prevent any errors that may occur. |
|||
reviewers: ${{github.actor}} |
|||
token: ${{ github.token }} |
|||
|
|||
@ -0,0 +1,7 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<configuration> |
|||
<packageSources> |
|||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> |
|||
<add key="BlazoriseMyGet" value="https://www.myget.org/F/blazorise/api/v3/index.json" /> |
|||
</packageSources> |
|||
</configuration> |
|||
@ -0,0 +1,14 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"Account": "ABP Benutzerkonto - Anmeldung & Registrierung | ABP.IO", |
|||
"Welcome": "Willkommen", |
|||
"UseOneOfTheFollowingLinksToContinue": "Nutzen Sie einen der nachfolgenden Links um fortzusetzen", |
|||
"FrameworkHomePage": "Framework Website", |
|||
"FrameworkDocumentation": "Framework Dokumentation", |
|||
"OfficialBlog": "Offizieller Blog", |
|||
"CommercialHomePage": "Commercial Website", |
|||
"CommercialSupportWebSite": "Commercial Support-Website", |
|||
"CommunityWebSite": "ABP Community-Website" |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
{ |
|||
"culture": "es", |
|||
"texts": { |
|||
"Account": "Cuenta de ABP - Iniciar sesión y registrarse | ABP.IO", |
|||
"Welcome": "Bienvenido", |
|||
"UseOneOfTheFollowingLinksToContinue": "Usa uno de los siguientes links para continuar", |
|||
"FrameworkHomePage": "Página de inicio del framework", |
|||
"FrameworkDocumentation": "Documentación del framework", |
|||
"OfficialBlog": "Blog Oficial", |
|||
"CommercialHomePage": "Página de inicio comercial", |
|||
"CommercialSupportWebSite": "Sitio web de soporte comercial", |
|||
"CommunityWebSite": "Sitio web comunidad ABP" |
|||
} |
|||
} |
|||
@ -0,0 +1,199 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"Permission:Organizations": "Organisationen", |
|||
"Permission:Manage": "Organisationen verwalten", |
|||
"Permission:DiscountRequests": "Rabattanfragen", |
|||
"Permission:DiscountManage": "Rabattanfragen verwalten", |
|||
"Permission:Disable": "Deaktivieren", |
|||
"Permission:Enable": "Aktivieren", |
|||
"Permission:EnableSendEmail": "E-Mail-Senden aktivieren", |
|||
"Permission:SendEmail": "E-Mail senden", |
|||
"Permission:NpmPackages": "NPM-Pakete", |
|||
"Permission:NugetPackages": "Nuget-Pakete", |
|||
"Permission:Maintenance": "Wartung", |
|||
"Permission:Maintain": "Warten", |
|||
"Permission:ClearCaches": "Caches leeren", |
|||
"Permission:Modules": "Module", |
|||
"Permission:Packages": "Pakete", |
|||
"Permission:Edit": "Bearbeiten", |
|||
"Permission:Delete": "Löschen", |
|||
"Permission:Create": "Erstellen", |
|||
"Permission:Accounting": "Abrechnung", |
|||
"Permission:Accounting:Quotation": "Angebot", |
|||
"Permission:Accounting:Invoice": "Rechnung", |
|||
"Menu:Organizations": "Organisationen", |
|||
"Menu:Accounting": "Abrechnung", |
|||
"Menu:Packages": "Pakete", |
|||
"Menu:DiscountRequests": "Rabattanfragen", |
|||
"NpmPackageDeletionWarningMessage": "Dieses NPM-Paket wird entfernt. Bestätigen Sie das?", |
|||
"NugetPackageDeletionWarningMessage": "Dieses Nuget-Paket wird entfernt. Bestägiten Sie das?", |
|||
"ModuleDeletionWarningMessage": "Dieses Modul wird entfernt. Bestätigen Sie das?", |
|||
"Name": "Name", |
|||
"DisplayName": "Anzeigename", |
|||
"ShortDescription": "Kurzbeschreibung", |
|||
"NameFilter": "Name", |
|||
"CreationTime": "Erstellungszeitpunkt", |
|||
"IsPro": "Ist pro", |
|||
"ShowOnModuleList": "In Modulliste anzeigen", |
|||
"EfCoreConfigureMethodName": "Methodenname konfigurieren", |
|||
"IsProFilter": "Ist pro", |
|||
"ApplicationType": "Anwendungstyp", |
|||
"Target": "Ziel", |
|||
"TargetFilter": "Ziel", |
|||
"ModuleClass": "Modulklasse", |
|||
"NugetPackageTarget.DomainShared": "Gemeinsame Domain", |
|||
"NugetPackageTarget.Domain": "Domain", |
|||
"NugetPackageTarget.Application": "Anwendung", |
|||
"NugetPackageTarget.ApplicationContracts": "Anwedungsverträge", |
|||
"NugetPackageTarget.HttpApi": "HTTP-API", |
|||
"NugetPackageTarget.HttpApiClient": "HTTP-API-Client", |
|||
"NugetPackageTarget.Web": "Web", |
|||
"NugetPackageTarget.EntityFrameworkCore": "DeleteAllEntityFramework Core", |
|||
"NugetPackageTarget.MongoDB": "MongoDB", |
|||
"Edit": "Bearbeiten", |
|||
"Delete": "Löschen", |
|||
"Refresh": "Aktualisieren", |
|||
"NpmPackages": "NPM-Pakete", |
|||
"NugetPackages": "Nuget-Pakete", |
|||
"NpmPackageCount": "NPM-Paketanzahl", |
|||
"NugetPackageCount": "Nuget-Paketanzahl", |
|||
"Module": "Module", |
|||
"ModuleInfo": "Modulinfo", |
|||
"CreateANpmPackage": "Erstellen Sie ein NPM Paket", |
|||
"CreateAModule": "Erstellen Sie in Modul", |
|||
"CreateANugetPackage": "Erstellen Sei ein Nuget-Paket", |
|||
"AddNew": "Neu hinzufügen", |
|||
"PackageAlreadyExist{0}": "\"{0}\" Paket ist bereits hinzugefügt.", |
|||
"ModuleAlreadyExist{0}": "\"{0}\" Modul ist bereits hinzugefügt.", |
|||
"ClearCache": "Cache leeren", |
|||
"SuccessfullyCleared": "Erfolgreich geleert", |
|||
"Menu:NpmPackages": "NPM-Pakete", |
|||
"Menu:Modules": "Module", |
|||
"Menu:Maintenance": "Wartung", |
|||
"Menu:NugetPackages": "Nuget-Pakete", |
|||
"CreateAnOrganization": "Erstellen Sie eine Organisation", |
|||
"Organizations": "Organisationen", |
|||
"LongName": "Lange Name", |
|||
"LicenseType": "Lizenztyp", |
|||
"MissingLicenseTypeField": "Das Feld Lizenztyp ist erforderlich!", |
|||
"LicenseStartTime": "Startzeit der Lizenz", |
|||
"LicenseEndTime": "Endzeit der Lizenz", |
|||
"AllowedDeveloperCount": "Zulässige Entwickleranzahl", |
|||
"UserNameOrEmailAddress": "Benutzername oder E-Mail-Adresse", |
|||
"AddOwner": "Besitzer hinzufügen", |
|||
"UserName": "Benutzername", |
|||
"Email": "E-Mail", |
|||
"Developers": "Entwickler", |
|||
"AddDeveloper": "Entwickler hinzufügen", |
|||
"Create": "Erstellen", |
|||
"UserNotFound": "Benutzer nicht gefunden", |
|||
"{0}WillBeRemovedFromDevelopers": "{0} wird von den Entwicklern entfernt. Bestätigen Sie das?", |
|||
"{0}WillBeRemovedFromOwners": "{0} wird von den Besitzern entfernt. Bestätigen Sie das?", |
|||
"Computers": "Computer", |
|||
"UniqueComputerId": "Eindeutig Computer-ID", |
|||
"LastSeenDate": "Zuletzt gesehenes Datum", |
|||
"{0}Computer{1}WillBeRemovedFromRecords": "Computer von {0} ({1}) wird aus den Datensätzen entfernt", |
|||
"OrganizationDeletionWarningMessage": "Organisation wird gelöscht", |
|||
"DeletingLastOwnerWarningMessage": "Eine Organisation muss zumindest einen Besitzer aufweisen! Daher können Sie diesen Besitzer nicht entfernen", |
|||
"This{0}AlreadyExistInThisOrganization": "Dies {0} existiert bereits in dieser Organisation", |
|||
"AreYouSureYouWantToDeleteAllComputers": "Sind Sie sicher, dass Sie alle Computer löschen möchten?", |
|||
"DeleteAll": "Alles Löschen", |
|||
"DoYouWantToCreateNewUser": "Möchten Sie einen neuen Benutzer erstellen?", |
|||
"MasterModules": "Master-Module", |
|||
"OrganizationName": "Organisationsname", |
|||
"CreationDate": "Erstellungsdatum", |
|||
"LicenseStartDate": "Startdatum der Lizenz", |
|||
"LicenseEndDate": "Enddatum der Lizenz", |
|||
"OrganizationNamePlaceholder": "Organisationsname...", |
|||
"TotalQuestionCountPlaceholder": "Gesamtzahl der Fragen...", |
|||
"RemainingQuestionCountPlaceholder": "Anzahl verbleibender Fragen...", |
|||
"LicenseTypePlaceholder": "Lizenztyp...", |
|||
"CreationDatePlaceholder": "Erstellungsdatum...", |
|||
"LicenseStartDatePlaceholder": "Startdatum der Lizenz...", |
|||
"LicenseEndDatePlaceholder": "Enddatum der Lizenz...", |
|||
"UsernameOrEmail": "Benutzername oder E-Mail-Adresse", |
|||
"UsernameOrEmailPlaceholder": "Benutzername oder E-Mail-Adresse...", |
|||
"Member": "Mitglied", |
|||
"PurchaseOrderNo": "Bestellnummer", |
|||
"QuotationDate": "Angebotsdatum", |
|||
"CompanyName": "Firmenname", |
|||
"CompanyAddress": "Firmenanschrift", |
|||
"Price": "Preis", |
|||
"DiscountText": "Rabatttext", |
|||
"DiscountQuantity": "Rabattmenge", |
|||
"DiscountPrice": "Rabattpreis", |
|||
"Quotation": "Angebot", |
|||
"ExtraText": "Zusätzlicher Text", |
|||
"ExtraAmount": "Zusätzliche Menge", |
|||
"DownloadQuotation": "Angebot herunterladen", |
|||
"Invoice": "Rechnung", |
|||
"TaxNumber": "Steuernummer", |
|||
"InvoiceNumber": "Rechnungsnummer", |
|||
"InvoiceDate": "Rechnungsdatum", |
|||
"InvoiceNote": "Rechnungsnotiz", |
|||
"Quantity": "Menge", |
|||
"AddProduct": "Produkt hinzufügen", |
|||
"AddProductWarning": "Sie müssen ein Produkt hinzufügen!", |
|||
"TotalPrice": "Gesamtpreis", |
|||
"Generate": "Generieren", |
|||
"MissingQuantityField": "Das Feld Menge ist erforderlich!", |
|||
"MissingPriceField": "Das Feld Preis ist erforderlich!", |
|||
"CodeUsageStatus": "Status", |
|||
"Country": "Land", |
|||
"DeveloperCount": "Entwickleranzahl", |
|||
"RequestCode": "Anfrage-Code", |
|||
"WebSite": "Webseite", |
|||
"GithubUsername": "Github Benutzername", |
|||
"PhoneNumber": "Telefonnummer", |
|||
"ProjectDescription": "Projektbeschreibung", |
|||
"Referrer": "Referrer", |
|||
"DiscountRequests": "Rabattanfrage", |
|||
"Copylink": "Link kopieren", |
|||
"Disable": "Deaktivieren", |
|||
"Enable": "Aktivieren", |
|||
"EnableSendEmail": "E-Mail-Senden aktivieren", |
|||
"SendEmail": "E-Mail senden", |
|||
"SuccessfullyDisabled": "Erfolgreich deaktiviert", |
|||
"SuccessfullyEnabled": "Erfolgreich aktiviert", |
|||
"EmailSent": "E-Mail gesendet", |
|||
"SuccessfullySent": "Erfolgreich gesendet", |
|||
"SuccessfullyDeleted": "Erfolgreich gelöscht", |
|||
"DiscountRequestDeletionWarningMessage": "Rabattanfrage wird gelöscht", |
|||
"BusinessType": "Unternehmensart", |
|||
"TotalQuestionCount": "Gesamtzahl der Fragen", |
|||
"RemainingQuestionCount": "Anzahl verbleibender Fragen", |
|||
"TotalQuestionMustBeGreaterWarningMessage": "TotalQuestionCount muss größer sein als RemainingQuestionCount !", |
|||
"QuestionCountsMustBeGreaterThanZero": "TotalQuestionCount und RemainingQuestionCount müssen Null oder größer als Null sein !", |
|||
"UnlimitedQuestionCount": "Unbegrenzte Anzahl von Fragen", |
|||
"Notes": "Anmerkungen", |
|||
"Menu:Community": "Community", |
|||
"Menu:Articles": "Beiträge", |
|||
"Wait": "Warten", |
|||
"Approve": "Genehmigen", |
|||
"Reject": "Ablehnen", |
|||
"Details": "Details", |
|||
"Url": "URL", |
|||
"Title": "Titel", |
|||
"ContentSource": "Inhaltsquelle", |
|||
"Status": "Status", |
|||
"ReadArticle": "Beitrag lesen", |
|||
"ArticleHasBeenWaiting": "Beitrag hat gewartet", |
|||
"ArticleHasBeenApproved": "Beitrag wurde genehmigt", |
|||
"ArticleHasBeenRejected": "Beitrag wurde abgelehnt", |
|||
"Permission:Community": "Community", |
|||
"Permission:CommunityArticle": "Beitrag", |
|||
"Link": "Link", |
|||
"Enum:ContentSource:0": "Github", |
|||
"Enum:ContentSource:1": "Extern", |
|||
"Enum:Status:0": "Wartend", |
|||
"Enum:Status:1": "Abgelehnt", |
|||
"Enum:Status:2": "Genehmigt", |
|||
"Summary": "Zusammenfassung", |
|||
"AuthorName": "Autorenname", |
|||
"CoverImage": "Titelbild", |
|||
"RemoveCacheConfirmationMessage": "Sind Sie sicher, dass Sie den Cache für den Artikel \"{0}\" entfernen wollen?", |
|||
"SuccessfullyRemoved": "Erfolgreich geleert", |
|||
"RemoveCache": "Cache entfernen" |
|||
} |
|||
} |
|||
@ -0,0 +1,199 @@ |
|||
{ |
|||
"culture": "es", |
|||
"texts": { |
|||
"Permission:Organizations": "Organizaciones", |
|||
"Permission:Manage": "Gestionar organizaciones", |
|||
"Permission:DiscountRequests": "Solicitudes de descuento", |
|||
"Permission:DiscountManage": "Gestionar solicitudes de descuento", |
|||
"Permission:Disable": "Desactivar", |
|||
"Permission:Enable": "Activar", |
|||
"Permission:EnableSendEmail": "Activar enviar email", |
|||
"Permission:SendEmail": "Enviar email", |
|||
"Permission:NpmPackages": "Paquetes NPM", |
|||
"Permission:NugetPackages": "Paquetes Nuget", |
|||
"Permission:Maintenance": "Mantenimiento", |
|||
"Permission:Maintain": "Mantener", |
|||
"Permission:ClearCaches": "Borrar cachés", |
|||
"Permission:Modules": "Módulos", |
|||
"Permission:Packages": "Paquetes", |
|||
"Permission:Edit": "Editar", |
|||
"Permission:Delete": "Borrar", |
|||
"Permission:Create": "Crear", |
|||
"Permission:Accounting": "Contabilidad", |
|||
"Permission:Accounting:Quotation": "Cotización", |
|||
"Permission:Accounting:Invoice": "Factura", |
|||
"Menu:Organizations": "Organizaciones", |
|||
"Menu:Accounting": "Contabilidad", |
|||
"Menu:Packages": "Paquetes", |
|||
"Menu:DiscountRequests": "Solicitudes de descuento", |
|||
"NpmPackageDeletionWarningMessage": "Este NPM paquete será borrado. ¿Quieres confirmar?", |
|||
"NugetPackageDeletionWarningMessage": "Este NPM paquete será borrado. ¿Quieres confirmar?", |
|||
"ModuleDeletionWarningMessage": "Este NPM paquete será borrado. ¿Quieres confirmar?", |
|||
"Name": "Nombre", |
|||
"DisplayName": "Nombre para mostrar", |
|||
"ShortDescription": "Descripción corta", |
|||
"NameFilter": "Nombre", |
|||
"CreationTime": "Fecha de creación", |
|||
"IsPro": "Es pro", |
|||
"ShowOnModuleList": "Mostrar en la lista de módulos", |
|||
"EfCoreConfigureMethodName": "configurar nombre de método", |
|||
"IsProFilter": "Es pro", |
|||
"ApplicationType": "tipo de aplicación", |
|||
"Target": "Destino", |
|||
"TargetFilter": "Destino", |
|||
"ModuleClass": "Módulo de clase", |
|||
"NugetPackageTarget.DomainShared": "Dominio compartido", |
|||
"NugetPackageTarget.Domain": "Dominio", |
|||
"NugetPackageTarget.Application": "Aplicación", |
|||
"NugetPackageTarget.ApplicationContracts": "Contratos de aplicación", |
|||
"NugetPackageTarget.HttpApi": "Http Api", |
|||
"NugetPackageTarget.HttpApiClient": "Cliente Http Api", |
|||
"NugetPackageTarget.Web": "Web", |
|||
"NugetPackageTarget.EntityFrameworkCore": "Delete todo EntityFramework Core", |
|||
"NugetPackageTarget.MongoDB": "MongoDB", |
|||
"Edit": "Editar", |
|||
"Delete": "Borrar", |
|||
"Refresh": "Refrescar", |
|||
"NpmPackages": "Paquetes NPM", |
|||
"NugetPackages": "Paquetes Nuget", |
|||
"NpmPackageCount": "Número de paquetes NPM", |
|||
"NugetPackageCount": "Número de paquetes Nuget", |
|||
"Module": "Módulos", |
|||
"ModuleInfo": "Info de módulo", |
|||
"CreateANpmPackage": "Crear un paquete NPM", |
|||
"CreateAModule": "Crear un módulo", |
|||
"CreateANugetPackage": "Crear un paquete de Nuget", |
|||
"AddNew": "Añadir nuevo", |
|||
"PackageAlreadyExist{0}": "\"{0}\" paquete ya se encuentra añadido", |
|||
"ModuleAlreadyExist{0}": "\"{0}\" módulo ya se encuentra añadido.", |
|||
"ClearCache": "Borrar caché", |
|||
"SuccessfullyCleared": "Borrado satisfactoriamente", |
|||
"Menu:NpmPackages": "Paquetes de NPM", |
|||
"Menu:Modules": "Módulos", |
|||
"Menu:Maintenance": "Mantenimiento", |
|||
"Menu:NugetPackages": "Paquetes Nuget", |
|||
"CreateAnOrganization": "Crear una organización", |
|||
"Organizations": "Organizaciones", |
|||
"LongName": "Nombre largo", |
|||
"LicenseType": "Tipo de licencia", |
|||
"MissingLicenseTypeField": "El campo tipo de licencia es requerido!", |
|||
"LicenseStartTime": "Fecha de inicio de licencia", |
|||
"LicenseEndTime": "Fecha de caducidad de licencia", |
|||
"AllowedDeveloperCount": "Número de desarrolladores permitidos", |
|||
"UserNameOrEmailAddress": "Nombre de usuario o", |
|||
"AddOwner": "Añadir propietario", |
|||
"UserName": "Nombre de usuario", |
|||
"Email": "Email", |
|||
"Developers": "Desarrolladores", |
|||
"AddDeveloper": "Añadir desarrollador", |
|||
"Create": "Crear", |
|||
"UserNotFound": "Usuario no encontrado", |
|||
"{0}WillBeRemovedFromDevelopers": "{0} será eliminado de desarrolladores, ¿deseas continuar?", |
|||
"{0}WillBeRemovedFromOwners": "{0} será eliminado de propietarios, ¿deseas continuar?", |
|||
"Computers": "Ordenadores", |
|||
"UniqueComputerId": "Id única de ordenador", |
|||
"LastSeenDate": "Fecha de visto por última vez", |
|||
"{0}Computer{1}WillBeRemovedFromRecords": "El ordenador {0} ({1}) será eliminado de los registros", |
|||
"OrganizationDeletionWarningMessage": "La organización será eliminada", |
|||
"DeletingLastOwnerWarningMessage": "Una organización debe tener al menos un propietario!. Por lo tanto, tu no puedes eliminar este propietario", |
|||
"This{0}AlreadyExistInThisOrganization": "Este/a {0} ya existe en esta organización", |
|||
"AreYouSureYouWantToDeleteAllComputers": "Estás seguro tu quieres eliminar todos los ordenadores", |
|||
"DeleteAll": "Eliminar todo", |
|||
"DoYouWantToCreateNewUser": "¿Quieres crear un nuevo usuario?", |
|||
"MasterModules": "Módulos maestros", |
|||
"OrganizationName": "Nombre de organización", |
|||
"CreationDate": "Fecha de creación", |
|||
"LicenseStartDate": "Fecha de inicio de licencia", |
|||
"LicenseEndDate": "Fecha de caducidad de licencia", |
|||
"OrganizationNamePlaceholder": "Nombre de organización...", |
|||
"TotalQuestionCountPlaceholder": "Número total de preguntas...", |
|||
"RemainingQuestionCountPlaceholder": "Número de preguntas pendientes", |
|||
"LicenseTypePlaceholder": "Tipo de licencia...", |
|||
"CreationDatePlaceholder": "Fecha de creación...", |
|||
"LicenseStartDatePlaceholder": "Fecha de inicio de licencia...", |
|||
"LicenseEndDatePlaceholder": "Fecha de caducidad de licencia...", |
|||
"UsernameOrEmail": "Usuario o email", |
|||
"UsernameOrEmailPlaceholder": "Usuario o email...", |
|||
"Member": "Miembro", |
|||
"PurchaseOrderNo": "Número de orden de compra", |
|||
"QuotationDate": "", |
|||
"CompanyName": "", |
|||
"CompanyAddress": "", |
|||
"Price": "", |
|||
"DiscountText": "", |
|||
"DiscountQuantity": "", |
|||
"DiscountPrice": "", |
|||
"Quotation": "", |
|||
"ExtraText": "", |
|||
"ExtraAmount": "", |
|||
"DownloadQuotation": "", |
|||
"Invoice": "", |
|||
"TaxNumber": "", |
|||
"InvoiceNumber": "", |
|||
"InvoiceDate": "", |
|||
"InvoiceNote": "", |
|||
"Quantity": "", |
|||
"AddProduct": "", |
|||
"AddProductWarning": "", |
|||
"TotalPrice": "", |
|||
"Generate": "", |
|||
"MissingQuantityField": "", |
|||
"MissingPriceField": "", |
|||
"CodeUsageStatus": "", |
|||
"Country": "", |
|||
"DeveloperCount": "", |
|||
"RequestCode": "", |
|||
"WebSite": "", |
|||
"GithubUsername": "", |
|||
"PhoneNumber": "", |
|||
"ProjectDescription": "", |
|||
"Referrer": "", |
|||
"DiscountRequests": "", |
|||
"Copylink": "", |
|||
"Disable": "", |
|||
"Enable": "", |
|||
"EnableSendEmail": "", |
|||
"SendEmail": "", |
|||
"SuccessfullyDisabled": "", |
|||
"SuccessfullyEnabled": "", |
|||
"EmailSent": "", |
|||
"SuccessfullySent": "", |
|||
"SuccessfullyDeleted": "", |
|||
"DiscountRequestDeletionWarningMessage": "", |
|||
"BusinessType": "", |
|||
"TotalQuestionCount": "", |
|||
"RemainingQuestionCount": "", |
|||
"TotalQuestionMustBeGreaterWarningMessage": "", |
|||
"QuestionCountsMustBeGreaterThanZero": "", |
|||
"UnlimitedQuestionCount": "", |
|||
"Notes": "", |
|||
"Menu:Community": "", |
|||
"Menu:Articles": "", |
|||
"Wait": "", |
|||
"Approve": "", |
|||
"Reject": "", |
|||
"Details": "", |
|||
"Url": "", |
|||
"Title": "", |
|||
"ContentSource": "", |
|||
"Status": "", |
|||
"ReadArticle": "", |
|||
"ArticleHasBeenWaiting": "", |
|||
"ArticleHasBeenApproved": "", |
|||
"ArticleHasBeenRejected": "", |
|||
"Permission:Community": "", |
|||
"Permission:CommunityArticle": "", |
|||
"Link": "", |
|||
"Enum:ContentSource:0": "", |
|||
"Enum:ContentSource:1": "", |
|||
"Enum:Status:0": "", |
|||
"Enum:Status:1": "", |
|||
"Enum:Status:2": "", |
|||
"Summary": "", |
|||
"AuthorName": "", |
|||
"CoverImage": "", |
|||
"RemoveCacheConfirmationMessage": "", |
|||
"SuccessfullyRemoved": "", |
|||
"RemoveCache": "" |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"Volo.AbpIo.Domain:010004": "Maximale Mitgliederanzahl erreicht!", |
|||
"Volo.AbpIo.Domain:010005": "Miximale Besizeranzahl erreicht!", |
|||
"Volo.AbpIo.Domain:010006": "Dieser Benutzer ist bereits ein Besitzer in dieser Organisation!", |
|||
"Volo.AbpIo.Domain:010007": "Dieser Benutzer ist bereits ein Entwickler in dieser Organisation!", |
|||
"Volo.AbpIo.Domain:010008": "Die zulässige Entwickleranzahl darf nicht geringer sein als die aktuelle Entwickleranzahl!", |
|||
"Volo.AbpIo.Domain:010009": "Die zulässige Entwickleranzahl darf nicht kleiner als 0 sein!", |
|||
"Volo.AbpIo.Domain:010010": "Die maximale Anzahl der Mac-Adressen ist überschritten!", |
|||
"Volo.AbpIo.Domain:010011": "Die persönliche Lizenz kann nicht mehr als 1 Entwickler haben!", |
|||
"Volo.AbpIo.Domain:010012": "Die Lizenz kann nicht einen Monat nach Ablauf der Lizenz verlängert werden!", |
|||
"Volo.AbpIo.Domain:020001": "Dieses NPM-Paket konnte nicht gelöscht werden, da \"{NugetPackages}\" Nuget-Pakete von diesem Paket abhängig sind.", |
|||
"Volo.AbpIo.Domain:020002": "Dieses NPM-Paket konnte nicht gelöscht werden, da \"{Module}\" Module dieses Paket verwenden.", |
|||
"Volo.AbpIo.Domain:020003": "Dieses NPM-Paket konnte nicht gelöscht werden, da \"{Module}\" Module dieses Paket verwenden und \"{NugetPackages}\" Nuget-Pakete von diesem Paket abhängig sind.", |
|||
"Volo.AbpIo.Domain:020004": "Dieses Nuget-Paket konnte nicht gelöscht werden, da \"{Module}\" Module dieses Paket verwenden.", |
|||
"WantToLearn?": "Wollen Sie sich einlernen?", |
|||
"ReadyToGetStarted?": "Bereit anzufangen?", |
|||
"JoinOurCommunity": "Tritt unserer Community bei", |
|||
"GetStartedUpper": "LOSLEGEN", |
|||
"ForkMeOnGitHub": "Fork me on GitHub", |
|||
"Features": "Features", |
|||
"GetStarted": "Loslegen", |
|||
"Documents": "Unterlagen", |
|||
"Community": "Community", |
|||
"ContributionGuide": "Leitfaden für Mitwirkende", |
|||
"Blog": "Blog", |
|||
"Commercial": "Commercial", |
|||
"MyAccount": "Mein Benutzerkonto", |
|||
"SeeDocuments": "Siehe Unterlagen", |
|||
"Samples": "Beispiele" |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
{ |
|||
"culture": "es", |
|||
"texts": { |
|||
"Volo.AbpIo.Domain:010004": "", |
|||
"Volo.AbpIo.Domain:010005": "", |
|||
"Volo.AbpIo.Domain:010006": "", |
|||
"Volo.AbpIo.Domain:010007": "", |
|||
"Volo.AbpIo.Domain:010008": "", |
|||
"Volo.AbpIo.Domain:010009": "", |
|||
"Volo.AbpIo.Domain:010010": "", |
|||
"Volo.AbpIo.Domain:010011": "", |
|||
"Volo.AbpIo.Domain:010012": "", |
|||
"Volo.AbpIo.Domain:020001": "", |
|||
"Volo.AbpIo.Domain:020002": "", |
|||
"Volo.AbpIo.Domain:020003": "", |
|||
"Volo.AbpIo.Domain:020004": "", |
|||
"WantToLearn?": "", |
|||
"ReadyToGetStarted?": "", |
|||
"JoinOurCommunity": "", |
|||
"GetStartedUpper": "", |
|||
"ForkMeOnGitHub": "", |
|||
"Features": "", |
|||
"GetStarted": "", |
|||
"Documents": "", |
|||
"Community": "", |
|||
"ContributionGuide": "", |
|||
"Blog": "", |
|||
"Commercial": "", |
|||
"MyAccount": "", |
|||
"SeeDocuments": "", |
|||
"Samples": "" |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"OrganizationManagement": "Organisationsverwaltung", |
|||
"OrganizationList": "Organisationsauflistung", |
|||
"Volo.AbpIo.Commercial:010003": "Sie sind der Besitzer dieser Organisation!", |
|||
"OrganizationNotFoundMessage": "Keine Organisation gefunden!", |
|||
"DeveloperCount": "Zugeordnete / Gesamte Entwickler", |
|||
"QuestionCount": "Verbleibende / Gesamte Fragen", |
|||
"Unlimited": "Unbegrenzt", |
|||
"Owners": "Besitzer", |
|||
"AddMember": "Mitglied hinzufügen", |
|||
"AddOwner": "Besizer hinzufügen", |
|||
"AddDeveloper": "Entwickler hinzufügen", |
|||
"UserName": "Benutzername", |
|||
"Name": "Name", |
|||
"EmailAddress": "E-Mail-Adress", |
|||
"Developers": "Entwickler", |
|||
"LicenseType": "Lizenztyp", |
|||
"Manage": "Verwalten", |
|||
"StartDate": "Startdatum", |
|||
"EndDate": "Enddatum", |
|||
"Modules": "Module", |
|||
"LicenseExtendMessage": "Ihr Lizenzenddatum wird auf {0} verlängert", |
|||
"LicenseUpgradeMessage": "Ihre Lizenz wird auf {0} aktualisiert", |
|||
"LicenseAddDeveloperMessage": "{0} Entwickler zu Ihrer Lizenz hinzugefügt", |
|||
"Volo.AbpIo.Commercial:010004": "Kann den angegebenen Benutzer nicht finden! Der Benutzer muss sich bereits registriert haben.", |
|||
"MyOrganizations": "Meine Organisationen", |
|||
"ApiKey": "API-Schlüssel", |
|||
"UserNameNotFound": "Es gibt keinen Benutzer mit dem Benutzernamen {0}", |
|||
"SuccessfullyAddedToNewsletter": "Vielen Dank, dass Sie unseren Newsletter abonniert haben!", |
|||
"MyProfile": "Mein Profil", |
|||
"EmailNotValid": "Bitte geben Sie eine gültige E-Mail-Adresse ein." |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
{ |
|||
"culture": "es", |
|||
"texts": { |
|||
"OrganizationManagement": "", |
|||
"OrganizationList": "", |
|||
"Volo.AbpIo.Commercial:010003": "", |
|||
"OrganizationNotFoundMessage": "", |
|||
"DeveloperCount": "", |
|||
"QuestionCount": "", |
|||
"Unlimited": "", |
|||
"Owners": "", |
|||
"AddMember": "", |
|||
"AddOwner": "", |
|||
"AddDeveloper": "", |
|||
"UserName": "", |
|||
"Name": "", |
|||
"EmailAddress": "", |
|||
"Developers": "", |
|||
"LicenseType": "Tipo de licencia", |
|||
"Manage": "", |
|||
"StartDate": "", |
|||
"EndDate": "", |
|||
"Modules": "Módulos", |
|||
"LicenseExtendMessage": "", |
|||
"LicenseUpgradeMessage": "", |
|||
"LicenseAddDeveloperMessage": "", |
|||
"Volo.AbpIo.Commercial:010004": "", |
|||
"MyOrganizations": "", |
|||
"ApiKey": "", |
|||
"UserNameNotFound": "", |
|||
"SuccessfullyAddedToNewsletter": "", |
|||
"MyProfile": "", |
|||
"EmailNotValid": "" |
|||
} |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"Permission:CommunityArticle": "Community-Beitrag", |
|||
"Permission:Edit": "Bearbeiten", |
|||
"Waiting": "Wartend", |
|||
"Approved": "Genehmigt", |
|||
"Rejected": "Abgelehnt", |
|||
"Wait": "Warten", |
|||
"Approve": "Genehmigen", |
|||
"Reject": "Ablehnen", |
|||
"ReadArticle": "Beitrag lesen", |
|||
"Status": "Status", |
|||
"ContentSource": "Inhaltsquelle", |
|||
"Details": "Details", |
|||
"Url": "URL", |
|||
"Title": "Titel", |
|||
"CreationTime": "Erstellungszeitpunkt", |
|||
"Save": "Speichern", |
|||
"SameUrlAlreadyExist": "Dieselbe URL existiert bereits, wenn Sie diesen Beitrag hinzufügen möchten, sollten Sie die URL ändern!", |
|||
"UrlIsNotValid": "Der URL ist nicht korrekt.", |
|||
"UrlNotFound": "URL nicht gefunden.", |
|||
"UrlContentNotFound": "URL-Inhalt nicht gefunden", |
|||
"Summary": "Zusammenfassung", |
|||
"MostRead": "Meist gelesen", |
|||
"Latest": "Neueste", |
|||
"ContributeAbpCommunity": "Tragen Sie zur ABP Community bei", |
|||
"SubmitYourArticle": "Reichen Sie Ihren Beitrag ein", |
|||
"ContributionGuide": "Leitfaden für Mitwirkende", |
|||
"BugReport": "Fehler melden", |
|||
"SeeAllArticles": "Alle Beiträge anzeigen", |
|||
"WelcomeToABPCommunity!": "Willkommen in der ABP Community!", |
|||
"MyProfile": "Mein Profil", |
|||
"MyOrganizations": "Meine Organisationen", |
|||
"EmailNotValid": "Bitte geben Sie eine gültige E-Mail-Adresse ein.", |
|||
"FeatureRequest": "Featureanfrage", |
|||
"CreateArticleTitleInfo": "Titel des Beitrags, der in der Beitragsliste angezeigt werden soll.", |
|||
"CreateArticleUrlInfo": "Original GitHub-/externe URL des Beitrags.", |
|||
"CreateArticleSummaryInfo": "Eine kurze Zusammenfassung des Beitrags, der in der Beitragsliste angezeigt werden soll.", |
|||
"CreateArticleCoverInfo": "Fügen Sie zum Erstellen eines effektiven Beitrags ein Titelbild hinzu. Laden Sie Bilder mit einem Seitenverhältnis von 16: 9 hoch, um die beste Ansicht zu erhalten.", |
|||
"ThisExtensionIsNotAllowed": "Diese Erweiterung ist nicht zulässig.", |
|||
"TheFileIsTooLarge": "Die Datei ist zu groß.", |
|||
"GoToTheArticle": "Gehe zum Beitrag", |
|||
"Contribute": "Beitragen", |
|||
"OverallProgress": "Gesamtfortschritt", |
|||
"Done": "Ferig", |
|||
"Open": "Offen", |
|||
"Closed": "Geschlossen", |
|||
"LatestQuestionOnThe": "Letzte Frage zum", |
|||
"Stackoverflow": "Stackoverflow", |
|||
"Votes": "Stimmen", |
|||
"Answer": "Antworten", |
|||
"Views": "Ansichten", |
|||
"Answered": "Beantwortet", |
|||
"WaitingForYourAnswer": "Warten auf Ihre Antwort", |
|||
"Asked": "gefragt", |
|||
"AllQuestions": "Alle Fragen", |
|||
"NextVersion": "Nächste Version", |
|||
"MilestoneErrorMessage": "Die aktuellen Meilensteindetails konnten von Github nicht abgerufen werden.", |
|||
"QuestionItemErrorMessage": "Die neuesten Fragendetails konnten von Stackoverflow nicht abgerufen werden.", |
|||
"Oops": "Hoppla!", |
|||
"CreateArticleSuccessMessage": "Der Beitrag wurde erfolgreich eingereicht. Er wird nach einer Überprüfung durch den Site-Administrator veröffentlicht.", |
|||
"ChooseCoverImage": "Wählen Sie ein Titelbild ...", |
|||
"CoverImage": "Titelbild", |
|||
"ShareYourExperiencesWithTheABPFramework": "Teilen Sie Ihre Erfahrungen mit dem ABP Framework!", |
|||
"Optional": "Optional", |
|||
"UpdateUserWebSiteInfo": "Beispiel: https://johndoe.com", |
|||
"UpdateUserTwitterInfo": "Beispiel: johndoe", |
|||
"UpdateUserGithubInfo": "Beispiel: johndoe", |
|||
"UpdateUserLinkedinInfo": "Beispiel: https://www.linkedin.com/...", |
|||
"UpdateUserCompanyInfo": "Beispiel: Volosoft", |
|||
"UpdateUserJobTitleInfo": "Beispiel: Software Developer", |
|||
"UserName": "Benutzername", |
|||
"Company": "Firma", |
|||
"PersonalWebsite": "Persönliche Website", |
|||
"RegistrationDate": "Registrierungsdatum", |
|||
"Social": "Social", |
|||
"Biography": "Biographie", |
|||
"HasNoPublishedArticlesYet": "hat noch keine Beiträge veröffentlicht", |
|||
"Author": "Autor", |
|||
"LatestGithubAnnouncements": "Neueste Github-Ankündigungen", |
|||
"SeeAllAnnouncements": "Alle Ankündigungen anzeigen", |
|||
"LatestBlogPost": "Letzter Blog-Beitrag", |
|||
"Edit": "Bearbeiten", |
|||
"ProfileImageChange": "Ändern Sie das Profilbild", |
|||
"BlogItemErrorMessage": "Die neuesten Blogpost-Details konnten von ABP nicht abgerufen werden.", |
|||
"PlannedReleaseDate": "Geplantes Erscheinungsdatum", |
|||
"CommunityArticleRequestErrorMessage": "Die Anfrage nach den neuesten Beiträgen von Github konnte nicht abgerufen werden." |
|||
} |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
{ |
|||
"culture": "es", |
|||
"texts": { |
|||
"Permission:CommunityArticle": "", |
|||
"Permission:Edit": "", |
|||
"Waiting": "", |
|||
"Approved": "", |
|||
"Rejected": "", |
|||
"Wait": "", |
|||
"Approve": "", |
|||
"Reject": "", |
|||
"ReadArticle": "", |
|||
"Status": "", |
|||
"ContentSource": "", |
|||
"Details": "", |
|||
"Url": "", |
|||
"Title": "", |
|||
"CreationTime": "", |
|||
"Save": "Guardar", |
|||
"SameUrlAlreadyExist": "", |
|||
"UrlIsNotValid": "", |
|||
"UrlNotFound": "", |
|||
"UrlContentNotFound": "", |
|||
"Summary": "", |
|||
"MostRead": "", |
|||
"Latest": "", |
|||
"ContributeAbpCommunity": "", |
|||
"SubmitYourArticle": "", |
|||
"ContributionGuide": "", |
|||
"BugReport": "", |
|||
"SeeAllArticles": "", |
|||
"WelcomeToABPCommunity!": "", |
|||
"MyProfile": "", |
|||
"MyOrganizations": "", |
|||
"EmailNotValid": "", |
|||
"FeatureRequest": "", |
|||
"CreateArticleTitleInfo": "", |
|||
"CreateArticleUrlInfo": "", |
|||
"CreateArticleSummaryInfo": "", |
|||
"CreateArticleCoverInfo": "", |
|||
"ThisExtensionIsNotAllowed": "", |
|||
"TheFileIsTooLarge": "", |
|||
"GoToTheArticle": "", |
|||
"Contribute": "", |
|||
"OverallProgress": "", |
|||
"Done": "", |
|||
"Open": "", |
|||
"Closed": "", |
|||
"LatestQuestionOnThe": "", |
|||
"Stackoverflow": "", |
|||
"Votes": "", |
|||
"Answer": "", |
|||
"Views": "", |
|||
"Answered": "", |
|||
"WaitingForYourAnswer": "", |
|||
"Asked": "", |
|||
"AllQuestions": "", |
|||
"NextVersion": "", |
|||
"MilestoneErrorMessage": "", |
|||
"QuestionItemErrorMessage": "", |
|||
"Oops": "", |
|||
"CreateArticleSuccessMessage": "", |
|||
"ChooseCoverImage": "", |
|||
"CoverImage": "", |
|||
"ShareYourExperiencesWithTheABPFramework": "", |
|||
"Optional": "", |
|||
"UpdateUserWebSiteInfo": "", |
|||
"UpdateUserTwitterInfo": "", |
|||
"UpdateUserGithubInfo": "", |
|||
"UpdateUserLinkedinInfo": "", |
|||
"UpdateUserCompanyInfo": "", |
|||
"UpdateUserJobTitleInfo": "", |
|||
"UserName": "", |
|||
"Company": "", |
|||
"PersonalWebsite": "", |
|||
"RegistrationDate": "", |
|||
"Social": "", |
|||
"Biography": "", |
|||
"HasNoPublishedArticlesYet": "", |
|||
"Author": "", |
|||
"LatestGithubAnnouncements": "", |
|||
"SeeAllAnnouncements": "", |
|||
"LatestBlogPost": "", |
|||
"Edit": "", |
|||
"ProfileImageChange": "", |
|||
"BlogItemErrorMessage": "", |
|||
"PlannedReleaseDate": "", |
|||
"CommunityArticleRequestErrorMessage": "" |
|||
} |
|||
} |
|||
@ -0,0 +1,189 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"GetStarted": "Erste Schritte - Startvorlagen", |
|||
"Create": "Erstellen", |
|||
"NewProject": "Neues Projekt", |
|||
"DirectDownload": "Direkter Download", |
|||
"ProjectName": "Proejktname", |
|||
"ProjectType": "Projekttyp", |
|||
"DatabaseProvider": "Datenbankanbieter", |
|||
"NTier": "N-Tier", |
|||
"IncludeUserInterface": "Benutzeroberfläche einschließen", |
|||
"CreateNow": "Jetzt erstellen", |
|||
"TheStartupProject": "Das Startprojekt", |
|||
"Tutorial": "Lernprogramm", |
|||
"UsingCLI": "mit CLI", |
|||
"SeeDetails": "Details ansehen", |
|||
"AbpShortDescription": "ABP Framework ist eine vollständige Infrastruktur zum Erstellen moderner Webanwendungen unter Befolgung von Best Practices und Konventionen für Softwareentwicklung.", |
|||
"SourceCodeUpper": "QUELLCODE", |
|||
"LatestReleaseLogs": "Akteulle Release", |
|||
"Infrastructure": "Infrastrutkur", |
|||
"Architecture": "Architektur", |
|||
"Modular": "Modular", |
|||
"DontRepeatYourself": "Don't Repeat Yourself", |
|||
"DeveloperFocused": "Entwickler-Zentriert", |
|||
"FullStackApplicationInfrastructure": "Full-Stack-Anwendungsinfrastruktur.", |
|||
"DomainDrivenDesign": "Domain Driven Design", |
|||
"DomainDrivenDesignExplanation": "Entworfen und entwickelt basierend auf DDD-Mustern und -Prinzipien. Bietet ein Schichtenmodell für Ihre Anwendung.", |
|||
"Authorization": "Authorization", |
|||
"AuthorizationExplanation": "Erweiterte Autorisierung mit Benutzer-, Rollen- und fein abgestimmtem Berechtigungssystem. Aufbauend auf der Microsoft Identity-Bibliothek.", |
|||
"MultiTenancy": "Multi-Tenancy", |
|||
"MultiTenancyExplanationShort": "SaaS-Anwendungen leicht gemacht! Integrierte Mandantenfähigkeit von der Datenbank bis zur Benutzeroberfläche.", |
|||
"CrossCuttingConcerns": "Cross Cutting Concerns", |
|||
"CrossCuttingConcernsExplanationShort": "Komplette Infrastruktur für Autorisierung, Validierung, Ausnahmebehandlung, Caching, Überwachungsprotokollierung, Transaktionsverwaltung und mehr.", |
|||
"BuiltInBundlingMinification": "Built-In Bundling & Minification", |
|||
"BuiltInBundlingMinificationExplanation": "Für die Bundling und Minification müssen keine externen Tools verwendet werden. ABP bietet eine einfachere, dynamische, leistungsstarke, modulare und integrierte Methode!", |
|||
"VirtualFileSystem": "Virtual File System", |
|||
"VirtualFileSystemExplanation": "Betten Sie Ansichten, Skripte, Stile, Bilder ... in Pakete/Bibliotheken ein und verwenden Sie sie in verschiedenen Anwendungen wieder.", |
|||
"Theming": "Theming", |
|||
"ThemingExplanationShort": "Verwenden und passen Sie das Bootstrap-basierte Standard-UI-Design an oder erstellen Sie Ihr eigenes.", |
|||
"BootstrapTagHelpersDynamicForms": "Bootstrap Tag Helpers & Dynamic Forms", |
|||
"BootstrapTagHelpersDynamicFormsExplanation": "Anstatt die sich wiederholenden Details von Bootstrap-Komponenten manuell zu schreiben, verwenden Sie die Tag-Helper von ABP, um diese zu vereinfachen und dabei die Vorteile von Intellisense zu nutzen. Erstellen Sie mit dem dynamischen Formular-Tag-Helfer schnell UI-Formulare basierend auf einem C#-Modell.", |
|||
"HTTPAPIsDynamicProxies": "HTTP APIs & Dynamic Proxies", |
|||
"HTTPAPIsDynamicProxiesExplanation": "Stellen Sie Anwendungsdienste automatisch als HTTP-APIs im REST-Stil bereit und verwenden Sie diese mit dynamischen JavaScript- und C#-Proxys.", |
|||
"CompleteArchitectureInfo": "Moderne Architektur zur Erstellung wartbarer Softwarelösungen.", |
|||
"DomainDrivenDesignBasedLayeringModelExplanation": "Hilft Ihnen bei der Implementierung einer DDD-basierten Schichtarchitektur und beim Aufbau einer wartbaren Codebasis.", |
|||
"DomainDrivenDesignBasedLayeringModelExplanationCont": "Bietet Startvorlagen, Abstraktionen, Basisklassen, Dienste, Dokumentation und Anleitungen, mit denen Sie Ihre Anwendung basierend auf DDD-Mustern und -Prinzipien entwickeln können.", |
|||
"MicroserviceCompatibleModelExplanation": "Das Kernframework und die vorgefertigten Module sind unter Berücksichtigung der Microservice-Architektur konzipiert.", |
|||
"MicroserviceCompatibleModelExplanationCont": "Bietet Infrastruktur, Integrationen, Beispiele und Dokumentation zur einfacheren Implementierung von Microservice-Lösungen, ohne zusätzliche Komplexität zu verursachen, wenn Sie eine monolithische Anwendung wünschen.", |
|||
"ModularInfo": "ABP bietet ein Modulsystem, mit dem Sie wiederverwendbare Anwendungsmodule entwickeln, Ereignisse im Anwendungslebenszyklus verknüpfen und Abhängigkeiten zwischen Kernteilen Ihres Systems ausdrücken können.", |
|||
"PreBuiltModulesThemes": "Vorgefertigte Module & Themes", |
|||
"PreBuiltModulesThemesExplanation": "Open Source- und kommerzielle Module und Themes stehen bereit, um in Ihrer Geschäftsanwendung verwendet zu werden.", |
|||
"NuGetNPMPackages": "NuGet- & NPM-Pakete", |
|||
"NuGetNPMPackagesExplanation": "Bereitgestellt als NuGet- & NPM-Pakete. Einfach zu installieren und zu aktualisieren.", |
|||
"ExtensibleReplaceable": "Erweiterbar/Austauschbar", |
|||
"ExtensibleReplaceableExplanation": "Alle Dienste und Module sind auf Erweiterbarkeit ausgelegt. Sie können Dienste, Seiten, Stile und Komponenten ersetzen.", |
|||
"CrossCuttingConcernsExplanation2": "Halten Sie Ihre Codebasis kleiner, damit Sie sich auf ihre geschäftsspezifischen Code konzentrieren können.", |
|||
"CrossCuttingConcernsExplanation3": "Verbringen Sie keine Zeit damit, grundlegende Anwendungsanforderungen für jedes neue Projekte zu implementieren.", |
|||
"AuthenticationAuthorization": "Authentifizierung & Autorisierung", |
|||
"ExceptionHandling": "Fehlerbehandlung", |
|||
"Validation": "Validierung", |
|||
"DatabaseConnection": "Datenbankverbindung", |
|||
"TransactionManagement": "Transaktionsmanagement", |
|||
"AuditLogging": "Audit Logging", |
|||
"Caching": "Caching", |
|||
"Multitenancy": "Multimandantenfähigkeit", |
|||
"DataFiltering": "Datenfilterung", |
|||
"ConventionOverConfiguration": "Convention Over Configuration", |
|||
"ConventionOverConfigurationExplanation": "ABP implementiert standardmäßig allgemeine Anwendungskonventionen mit einer minimalen oder Null-Konfiguration.", |
|||
"ConventionOverConfigurationExplanationList1": "Automatische Registrierung bekannter Services für Dependency Injection.", |
|||
"ConventionOverConfigurationExplanationList2": "Stellt Anwendungsdienste mittels Namenskonventionen als HTTP-APIs bereit.", |
|||
"ConventionOverConfigurationExplanationList3": "Erstellt dynamische HTTP-Client-Proxys für C# und JavaScript.", |
|||
"ConventionOverConfigurationExplanationList4": "Bietet Standard-Repositorys für Ihre Entities.", |
|||
"ConventionOverConfigurationExplanationList5": "Verwaltet die Unit-of-Work gemäß Webanforderung oder Anwendungsdienstmethode.", |
|||
"ConventionOverConfigurationExplanationList6": "Triggert Erstellungs-, Aktualisierungs- und Lösch-Events für Ihre Entities.", |
|||
"BaseClasses": "Basisklassen", |
|||
"BaseClassesExplanation": "Vorgefertigte Basisklassen für gängige Anwendungsmuster.", |
|||
"DeveloperFocusedExplanation": "ABP ist für Entwickler", |
|||
"DeveloperFocusedExplanationCont": "Es zielt darauf ab, Ihre tägliche Softwareentwicklung zu vereinfachen, ohne Sie daran zu hindern, Low-Level-Code zu schreiben.", |
|||
"SeeAllFeatures": "Alle Features anzeigen", |
|||
"CLI_CommandLineInterface": "CLI (Command Line Interface)", |
|||
"CLI_CommandLineInterfaceExplanation": "Enthält eine CLI, mit der Sie die Erstellung neuer Projekte und das Hinzufügen neuer Module automatisieren können.", |
|||
"StartupTemplates": "Startvorlagen", |
|||
"StartupTemplatesExplanation": "Verschiedene Startvorlagen bieten eine vollständig konfigurierte Lösung, um Ihre Entwicklung zu beschleunigen.", |
|||
"BasedOnFamiliarTools": "Basierend auf vertrauten Tools", |
|||
"BasedOnFamiliarToolsExplanation": "Aufbauend auf und integriert mit beliebten Tools, die Sie bereits kennen. Geringe Lernkurve, einfache Anpassung, komfortable Entwicklung.", |
|||
"ORMIndependent": "ORM-unabhängig", |
|||
"ORMIndependentExplanation": "Das Kernframework ist ORM-/datenbankunabhängig und kann mit jeder Datenquelle arbeiten. Entity Framework Core- und MongoDB-Anbieter sind bereits verfügbar.", |
|||
"Features": "Entdecken Sie die ABP Framework-Features", |
|||
"ABPCLI": "ABP CLI", |
|||
"Modularity": "Modularität", |
|||
"BootstrapTagHelpers": "Bootstrap Tag Helpers", |
|||
"DynamicForms": "Dynamische Formulare", |
|||
"BundlingMinification": "Bundling & Minification", |
|||
"BackgroundJobs": "Background Jobs", |
|||
"BackgroundJobsExplanation": "Definieren Sie einfache Klassen, um Jobs im Hintergrund in der Warteschlange auszuführen. Verwenden Sie den integrierten Jobmanager oder integrieren Sie Ihren eigenen. <a href=\"{0}\"> Hangfire </a> & <a href=\"{1}\"> RabbitMQ </a> -Integrationen sind bereits verfügbar.", |
|||
"DDDInfrastructure": "DDD-Infrastruktur", |
|||
"DomainDrivenDesignInfrastructure": "Domain Driven Design-Infrastruktur", |
|||
"AutoRESTAPIs": "Auto REST APIs", |
|||
"DynamicClientProxies": "Dynamische Client-Proxies", |
|||
"DistributedEventBus": "Distributed Event Bus", |
|||
"DistributedEventBusWithRabbitMQIntegration": "Distributed Event Bus mit RabbitMQ-Integration", |
|||
"TestInfrastructure": "Test-Infrastruktur", |
|||
"AuditLoggingEntityHistories": "Audit Logging & Entity Histories", |
|||
"ObjectToObjectMapping": "Object to Object Mapping", |
|||
"ObjectToObjectMappingExplanation": "<a href=\"{0}\"> Object to Object Mapping </a> Abstraktion mit AutoMapper-Integration.", |
|||
"EmailSMSAbstractions": "E-Mail & SMS Abstraktionen", |
|||
"EmailSMSAbstractionsWithTemplatingSupport": "E-Mail- und SMS-Abstraktionen mit Vorlagenunterstützung", |
|||
"Localization": "Lokalisierung", |
|||
"SettingManagement": "Einstellungsverwaltung", |
|||
"ExtensionMethods": "Erweiterungsmethoden", |
|||
"ExtensionMethodsHelpers": "Erweiterungsmethoden & Helfer", |
|||
"AspectOrientedProgramming": "Aspektorientierte Programmierung", |
|||
"DependencyInjection": "Dependency Injection", |
|||
"DependencyInjectionByConventions": "Dependency Injection durch Konventionen", |
|||
"ABPCLIExplanation": "ABP CLI (Command Line Interface) ist ein Befehlszeilenprogramm zum Ausführen einiger gängiger Vorgänge für ABP-basierte Lösungen.", |
|||
"ModularityExplanation": "ABP bietet eine vollständige Infrastruktur zum Erstellen eigener Anwendungsmodule, die Entities, Services, Datenbankintegration, APIs, UI-Komponenten usw. enthalten können.", |
|||
"MultiTenancyExplanation": "Das ABP-Framework unterstützt nicht nur die Entwicklung von Multi-Mandantenanwendungen, sondern macht Ihren Code von der Mandantenfähigkeit auch weitgehend unabhängig.", |
|||
"MultiTenancyExplanation2": "Kann den aktuellen Mandanten automatisch ermitteln und Daten verschiedener Mandanten voneinander isolieren.", |
|||
"MultiTenancyExplanation3": "Unterstützt einzelne Datenbank-, Datenbank-pro-Mandanten- und Hybrid-Ansätze.", |
|||
"MultiTenancyExplanation4": "Sie konzentrieren sich auf Ihren geschäftsspezifischen Code und lassen das Framework die Mandantenfähigkeit für Sie übernehmen.", |
|||
"BootstrapTagHelpersExplanation": "Anstatt die sich wiederholenden Details von Bootstrap-Komponenten manuell zu schreiben, verwenden Sie die Tag-Helper von ABP, um diese zu vereinfachen und dabei die Vorteile von Intellisense zu nutzen. Sie können Bootstrap weitherhin verwenden, wann immer Sie es benötigen.", |
|||
"DynamicFormsExplanation": "Helfer für dynamische Formular- und Input-Tags können das vollständige Formular anhand einer C#-Klasse als Model erstellen.", |
|||
"AuthenticationAuthorizationExplanation": "Umfangreiche Authentifizierungs- und Autorisierungsoptionen, die in ASP.NET Core Identity & IdentityServer4 integriert sind. Bietet ein erweiterbares und detailliertes Berechtigungssystem.", |
|||
"CrossCuttingConcernsExplanation": "Wiederholen Sie sich nicht, um all diese allgemeinen Dinge immer wieder zu implementieren. Konzentrieren Sie sich auf Ihren geschäftsspezifischen Code und lassen Sie ihn von ABP durch Konventionen automatisieren.", |
|||
"DatabaseConnectionTransactionManagement": "Datenbankverbindungs- und Transaktionsmanagement", |
|||
"CorrelationIdTracking": "Correlation-ID-Verfolgung", |
|||
"BundlingMinificationExplanation": "ABP bietet ein einfaches, dynamisches, leistungsstarkes, modulares und integriertes Bundling- und Minification-System.", |
|||
"VirtualFileSystemnExplanation": "Das virtuelle Dateisystem ermöglicht die Verwaltung von Dateien, die physisch nicht auf dem Dateisystem (Datenträger) vorhanden sind. Es wird hauptsächlich verwendet, um Dateien (js, css, image, cshtml ...) in Assemblys einzubetten und sie zur Laufzeit wie physische Dateien zu verwenden.", |
|||
"ThemingExplanation": "Mit dem Theming-System können Sie Ihre Anwendung & Module Theme-unabhängig entwickeln, indem Sie eine Reihe gemeinsamer Basisbibliotheken und Layouts definieren, die auf dem neuesten Bootstrap-Framework basieren.", |
|||
"DomainDrivenDesignInfrastructureExplanation": "Eine vollständige Infrastruktur zum Erstellen von mehrschichtigen Anwendungen basierend auf den Domain Driven Design Entwurfsmustern und -prinzipien;", |
|||
"Specification": "Specification", |
|||
"Repository": "Repository", |
|||
"DomainService": "Domain Service", |
|||
"ValueObject": "Value Object", |
|||
"ApplicationService": "Application Service", |
|||
"DataTransferObject": "Data Transfer Object", |
|||
"AggregateRootEntity": "Aggregate Root, Entity", |
|||
"AutoRESTAPIsExplanation": "ABP kann Ihre Anwendungsservices gemäß Konvention automatisch als API-Controller konfigurieren.", |
|||
"DynamicClientProxiesExplanation": "Verwenden Sie Ihre APIs ganz einfach in JavaScript- und C#-Clients.", |
|||
"DistributedEventBusWithRabbitMQIntegrationExplanation": "Veröffentlichen und konsumieren Sie Distributed Events einfach mithilfe des integrierten Distributed Event Bus mit verfügbarer RabbitMQ-Integration.", |
|||
"TestInfrastructureExplanation": "Das Framework wurde unter Berücksichtigung von Unit- und Integrationstests entwickelt. Bietet Ihnen Basisklassen, um es einfacher zu machen. Startvorlagen werden mit vorkonfiguriert Tests geliefert.", |
|||
"AuditLoggingEntityHistoriesExplanation": "Integriertes Audit Logging für geschäftskritische Anwendungen. Audit Logging auf Request-, Service-, und Methodenebene sowie Entity-Historien mit Details auf Property-Ebene.", |
|||
"EmailSMSAbstractionsWithTemplatingSupportExplanation": "IEmailSender- und ISmsSender-Abstraktionen entkoppeln Ihre Anwendungslogik von der Infrastruktur. Das erweiterte E-Mail-Vorlagensystem ermöglicht das Erstellen und Lokalisieren von E-Mail-Vorlagen und deren einfache Verwendung bei Bedarf.", |
|||
"LocalizationExplanation": "Das Lokalisierungssystem ermöglicht das Erstellen von Ressourcen in einfachen JSON-Dateien und die Lokalisierung Ihrer Benutzeroberfläche. Es unterstützt erweiterte Szenarien wie Vererbung, Erweiterungen und JavaScript-Integration und ist vollständig mit dem Lokalisierungssystem von AspNet Core kompatibel.", |
|||
"SettingManagementExplanation": "Definieren Sie Einstellungen für Ihre Anwendung und erhalten Sie zur Laufzeit Werte basierend auf der aktuellen Konfiguration, dem Mandanten und dem Benutzer.", |
|||
"ExtensionMethodsHelpersExplanation": "Wiederholen Sie sich nicht einmal für triviale Codeteile. Erweiterungen und Helfer für Standardtypen machen Ihren Code viel sauberer und einfacher zu schreiben.", |
|||
"AspectOrientedProgrammingExplanation": "Bietet eine komfortable Infrastruktur zum Erstellen dynamischer Proxys und zum Implementieren der aspektorientierten Programmierung. Fangen Sie eine Klasse ab und führen Sie Ihren Code vor und nach jeder Methodenausführung aus.", |
|||
"DependencyInjectionByConventionsExplanation": "Sie müssen Ihre Klassen nicht manuell für die Dependency Injection registrieren. Registriert gängige Servicetypen automatisch gemäß Konvention. Für andere Arten von Services können Sie Schnittstellen und Attribute verwenden, um dies einfacher gestalten und an Ort und Stelle zu ermöglichen.", |
|||
"DataFilteringExplanation": "Definieren und verwenden Sie Datenfilter, die automatisch angewendet werden, wenn Sie Entities aus der Datenbank abfragen. Soft Delete- und Multimandanten-Filter sind sofort verfügbar, wenn Sie einfache Schnittstellen implementieren.", |
|||
"PublishEvents": "Events veröffentlichen", |
|||
"HandleEvents": "Auf Events reagieren", |
|||
"AndMore": "und mehr...", |
|||
"Code": "Code", |
|||
"Result": "Resultat", |
|||
"SeeTheDocumentForMoreInformation": "Weitere Informationen finden Sie in der <a href=\"{1}\"> {0} -Dokumentation </a>", |
|||
"IndexPageHeroSection": "<span class=\"first-line shine\"><strong>Open Source</strong></span><span class=\"second-line text-uppercase\">Webanwendung<br />Framework </span><span class=\"third-line shine2\"><strong>für ASP.Net Core</strong></span>", |
|||
"UiFramework": "UI-Framework", |
|||
"EmailAddress": "E-Mail-Adresse", |
|||
"Mobile": "Mobile", |
|||
"ReactNative": "React Native", |
|||
"Strong": "Stark", |
|||
"Complete": "Vollständig", |
|||
"BasedLayeringModel": "Based Layering Model", |
|||
"Microservice": "Microservice", |
|||
"Compatible": "Kompatibel", |
|||
"MeeTTheABPCommunityInfo": "Unsere Mission ist es, eine Umgebung zu schaffen, in der Entwickler sich gegenseitig mit Beiträgen, Tutorials, Fallstudien usw. helfen und Gleichgesinnte treffen können.", |
|||
"JoinTheABPCommunityInfo": "Beteiligen Sie sich an einer lebendigen Community und tragen Sie zum ABP Framework bei!", |
|||
"AllArticles": "Alle Beiträge", |
|||
"SubmitYourArticle": "Reichen Sie Ihren Beitrag ein", |
|||
"DynamicClientProxyDocument": "In der Dokumentation zu den Dynamischen Client-Proxies finden Sie Informationen zu <a href=\"{0}\">JavaScript</a> & <a href=\"{1}\">C#</a>.", |
|||
"EmailSMSAbstractionsDocument": "Weitere Informationen finden Sie in den Unterlagen <a href=\"{0}\">E-Mail-Senden</a> and <a href=\"{1}\">SMS-Senden</a>.", |
|||
"CreateProjectWizard": "Dieser Assistent erstellt ein neues Projekt aus der Startvorlage, die ordnungsgemäß konfiguriert ist, um Ihr Projekt zu starten.", |
|||
"TieredOption": "Erstellt eine Tiered Lösung, bei der Web- und HTTP-API-Ebenen physisch getrennt sind. Wenn diese Option nicht aktiviert ist, wird eine mehrschichtige Lösung erstellt, die weniger komplex und für die meisten Szenarien geeignet ist.", |
|||
"SeparateIdentityServerOption": "Trennt die Serverseite in zwei Anwendungen: Die erste ist für den Identitätsserver und die zweite für die serverseitige HTTP-API.", |
|||
"UseslatestPreVersion": "Verwendet die neueste Vorabversion", |
|||
"ReadTheDocumentation": "<span class=\"text-primary\">Lesen Sie</span><span class=\"text-success\">Die Dokumentation</span>", |
|||
"Documentation": "Dokumentation", |
|||
"GettingStartedTutorial": "Erste Schritte Tutorial", |
|||
"ApplicationDevelopmentTutorial": "Tutorial zur Anwendungsentwicklung", |
|||
"TheStartupTemplate": "Die Startvorlage", |
|||
"InstallABPCLIInfo": "ABP CLI ist der schnellste Weg, um eine neue Lösung mit dem ABP-Framework zu starten. Installieren Sie die ABP-CLI über die Eingabeaufforderung:", |
|||
"DifferentLevelOfNamespaces": "Sie können verschiedene Ebenen von Namespaces verwenden; z.B. BookStore, Acme.BookStore or Acme.Retail.BookStore.", |
|||
"ABPCLIExamplesInfo": "Der Befehl <strong>new</strong> erstellt eine <strong>mehrschichtige MVC-Anwendung</strong> mit <strong>Entity Framework Core</strong> als Datenbankanbieter. Es gibt jedoch zusätzliche Optionen. Beispiele:", |
|||
"SeeCliDocumentForMoreInformation": "Weitere Optionen finden Sie im <a href=\"{0}\">ABP CLI-Dokument</a> oder wählen Sie oben die Registerkarte \"Direkter Download\".", |
|||
"Optional": "Optional", |
|||
"LocalFrameworkRef": "Behalten Sie die lokale Projektreferenz für die Framework-Pakete bei." |
|||
} |
|||
} |
|||
@ -0,0 +1,189 @@ |
|||
{ |
|||
"culture": "es", |
|||
"texts": { |
|||
"GetStarted": "", |
|||
"Create": "", |
|||
"NewProject": "", |
|||
"DirectDownload": "", |
|||
"ProjectName": "", |
|||
"ProjectType": "", |
|||
"DatabaseProvider": "", |
|||
"NTier": "", |
|||
"IncludeUserInterface": "", |
|||
"CreateNow": "", |
|||
"TheStartupProject": "", |
|||
"Tutorial": "", |
|||
"UsingCLI": "", |
|||
"SeeDetails": "", |
|||
"AbpShortDescription": "", |
|||
"SourceCodeUpper": "", |
|||
"LatestReleaseLogs": "", |
|||
"Infrastructure": "", |
|||
"Architecture": "", |
|||
"Modular": "", |
|||
"DontRepeatYourself": "", |
|||
"DeveloperFocused": "", |
|||
"FullStackApplicationInfrastructure": "", |
|||
"DomainDrivenDesign": "", |
|||
"DomainDrivenDesignExplanation": "", |
|||
"Authorization": "", |
|||
"AuthorizationExplanation": "", |
|||
"MultiTenancy": "", |
|||
"MultiTenancyExplanationShort": "", |
|||
"CrossCuttingConcerns": "", |
|||
"CrossCuttingConcernsExplanationShort": "", |
|||
"BuiltInBundlingMinification": "", |
|||
"BuiltInBundlingMinificationExplanation": "", |
|||
"VirtualFileSystem": "", |
|||
"VirtualFileSystemExplanation": "", |
|||
"Theming": "", |
|||
"ThemingExplanationShort": "", |
|||
"BootstrapTagHelpersDynamicForms": "", |
|||
"BootstrapTagHelpersDynamicFormsExplanation": "", |
|||
"HTTPAPIsDynamicProxies": "", |
|||
"HTTPAPIsDynamicProxiesExplanation": "", |
|||
"CompleteArchitectureInfo": "", |
|||
"DomainDrivenDesignBasedLayeringModelExplanation": "", |
|||
"DomainDrivenDesignBasedLayeringModelExplanationCont": "", |
|||
"MicroserviceCompatibleModelExplanation": "", |
|||
"MicroserviceCompatibleModelExplanationCont": "", |
|||
"ModularInfo": "", |
|||
"PreBuiltModulesThemes": "", |
|||
"PreBuiltModulesThemesExplanation": "", |
|||
"NuGetNPMPackages": "", |
|||
"NuGetNPMPackagesExplanation": "", |
|||
"ExtensibleReplaceable": "", |
|||
"ExtensibleReplaceableExplanation": "", |
|||
"CrossCuttingConcernsExplanation2": "", |
|||
"CrossCuttingConcernsExplanation3": "", |
|||
"AuthenticationAuthorization": "", |
|||
"ExceptionHandling": "", |
|||
"Validation": "", |
|||
"DatabaseConnection": "", |
|||
"TransactionManagement": "", |
|||
"AuditLogging": "", |
|||
"Caching": "", |
|||
"Multitenancy": "", |
|||
"DataFiltering": "", |
|||
"ConventionOverConfiguration": "", |
|||
"ConventionOverConfigurationExplanation": "", |
|||
"ConventionOverConfigurationExplanationList1": "", |
|||
"ConventionOverConfigurationExplanationList2": "", |
|||
"ConventionOverConfigurationExplanationList3": "", |
|||
"ConventionOverConfigurationExplanationList4": "", |
|||
"ConventionOverConfigurationExplanationList5": "", |
|||
"ConventionOverConfigurationExplanationList6": "", |
|||
"BaseClasses": "", |
|||
"BaseClassesExplanation": "", |
|||
"DeveloperFocusedExplanation": "", |
|||
"DeveloperFocusedExplanationCont": "", |
|||
"SeeAllFeatures": "", |
|||
"CLI_CommandLineInterface": "", |
|||
"CLI_CommandLineInterfaceExplanation": "", |
|||
"StartupTemplates": "", |
|||
"StartupTemplatesExplanation": "", |
|||
"BasedOnFamiliarTools": "", |
|||
"BasedOnFamiliarToolsExplanation": "", |
|||
"ORMIndependent": "", |
|||
"ORMIndependentExplanation": "", |
|||
"Features": "", |
|||
"ABPCLI": "", |
|||
"Modularity": "", |
|||
"BootstrapTagHelpers": "", |
|||
"DynamicForms": "", |
|||
"BundlingMinification": "", |
|||
"BackgroundJobs": "", |
|||
"BackgroundJobsExplanation": "", |
|||
"DDDInfrastructure": "", |
|||
"DomainDrivenDesignInfrastructure": "", |
|||
"AutoRESTAPIs": "", |
|||
"DynamicClientProxies": "", |
|||
"DistributedEventBus": "", |
|||
"DistributedEventBusWithRabbitMQIntegration": "", |
|||
"TestInfrastructure": "", |
|||
"AuditLoggingEntityHistories": "", |
|||
"ObjectToObjectMapping": "", |
|||
"ObjectToObjectMappingExplanation": "", |
|||
"EmailSMSAbstractions": "", |
|||
"EmailSMSAbstractionsWithTemplatingSupport": "", |
|||
"Localization": "", |
|||
"SettingManagement": "", |
|||
"ExtensionMethods": "", |
|||
"ExtensionMethodsHelpers": "", |
|||
"AspectOrientedProgramming": "", |
|||
"DependencyInjection": "", |
|||
"DependencyInjectionByConventions": "", |
|||
"ABPCLIExplanation": "", |
|||
"ModularityExplanation": "", |
|||
"MultiTenancyExplanation": "", |
|||
"MultiTenancyExplanation2": "", |
|||
"MultiTenancyExplanation3": "", |
|||
"MultiTenancyExplanation4": "", |
|||
"BootstrapTagHelpersExplanation": "", |
|||
"DynamicFormsExplanation": "", |
|||
"AuthenticationAuthorizationExplanation": "", |
|||
"CrossCuttingConcernsExplanation": "", |
|||
"DatabaseConnectionTransactionManagement": "", |
|||
"CorrelationIdTracking": "", |
|||
"BundlingMinificationExplanation": "", |
|||
"VirtualFileSystemnExplanation": "", |
|||
"ThemingExplanation": "", |
|||
"DomainDrivenDesignInfrastructureExplanation": "", |
|||
"Specification": "", |
|||
"Repository": "", |
|||
"DomainService": "", |
|||
"ValueObject": "", |
|||
"ApplicationService": "", |
|||
"DataTransferObject": "", |
|||
"AggregateRootEntity": "", |
|||
"AutoRESTAPIsExplanation": "", |
|||
"DynamicClientProxiesExplanation": "", |
|||
"DistributedEventBusWithRabbitMQIntegrationExplanation": "", |
|||
"TestInfrastructureExplanation": "", |
|||
"AuditLoggingEntityHistoriesExplanation": "", |
|||
"EmailSMSAbstractionsWithTemplatingSupportExplanation": "", |
|||
"LocalizationExplanation": "", |
|||
"SettingManagementExplanation": "", |
|||
"ExtensionMethodsHelpersExplanation": "", |
|||
"AspectOrientedProgrammingExplanation": "", |
|||
"DependencyInjectionByConventionsExplanation": "", |
|||
"DataFilteringExplanation": "", |
|||
"PublishEvents": "", |
|||
"HandleEvents": "", |
|||
"AndMore": "", |
|||
"Code": "", |
|||
"Result": "", |
|||
"SeeTheDocumentForMoreInformation": "", |
|||
"IndexPageHeroSection": "", |
|||
"UiFramework": "", |
|||
"EmailAddress": "", |
|||
"Mobile": "", |
|||
"ReactNative": "", |
|||
"Strong": "", |
|||
"Complete": "", |
|||
"BasedLayeringModel": "", |
|||
"Microservice": "", |
|||
"Compatible": "", |
|||
"MeeTTheABPCommunityInfo": "", |
|||
"JoinTheABPCommunityInfo": "", |
|||
"AllArticles": "", |
|||
"SubmitYourArticle": "", |
|||
"DynamicClientProxyDocument": "", |
|||
"EmailSMSAbstractionsDocument": "", |
|||
"CreateProjectWizard": "", |
|||
"TieredOption": "", |
|||
"SeparateIdentityServerOption": "", |
|||
"UseslatestPreVersion": "", |
|||
"ReadTheDocumentation": "", |
|||
"Documentation": "", |
|||
"GettingStartedTutorial": "", |
|||
"ApplicationDevelopmentTutorial": "", |
|||
"TheStartupTemplate": "", |
|||
"InstallABPCLIInfo": "", |
|||
"DifferentLevelOfNamespaces": "", |
|||
"ABPCLIExamplesInfo": "", |
|||
"SeeCliDocumentForMoreInformation": "", |
|||
"Optional": "", |
|||
"LocalFrameworkRef": "" |
|||
} |
|||
} |
|||
@ -1,32 +1,3 @@ |
|||
# Social/External Logins |
|||
|
|||
The [Account Module](../Modules/Account.md) has already configured to handle social or external logins out of the box. You can follow the ASP.NET Core documentation to add a social/external login provider to your application. |
|||
|
|||
## Example: Facebook Authentication |
|||
|
|||
Follow the [ASP.NET Core Facebook integration document](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/facebook-logins) to support the Facebook login for your application. |
|||
|
|||
#### Add the NuGet Package |
|||
|
|||
Add the [Microsoft.AspNetCore.Authentication.Facebook](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.Facebook) package to your project. Based on your architecture, this can be `.Web`, `.IdentityServer` (for tiered setup) or `.Host` project. |
|||
|
|||
#### Configure the Provider |
|||
|
|||
Use the `.AddFacebook(...)` extension method in the `ConfigureServices` method of your [module](../Module-Development-Basics.md), to configure the client: |
|||
|
|||
````csharp |
|||
context.Services.AddAuthentication() |
|||
.AddFacebook(facebook => |
|||
{ |
|||
facebook.AppId = "..."; |
|||
facebook.AppSecret = "..."; |
|||
facebook.Scope.Add("email"); |
|||
facebook.Scope.Add("public_profile"); |
|||
}); |
|||
```` |
|||
|
|||
> It would be a better practice to use the `appsettings.json` or the ASP.NET Core User Secrets system to store your credentials, instead of a hard-coded value like that. Follow the [Microsoft's document](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/facebook-logins) to learn the user secrets usage. |
|||
|
|||
## Angular UI |
|||
|
|||
Beginning from the v3.1, the Angular UI uses authorization code flow (as a best practice) to authenticate the user by redirecting to the MVC UI login page. So, even if you are using the Angular UI, social/external login integration is same as explained above and it will work out of the box. |
|||
> This document has been moved. See the [Account Module](../Modules/Account.md) documentation. |
|||
@ -0,0 +1,47 @@ |
|||
# ABP Framework & ABP Commercial 3.3 Final Have Been Released |
|||
|
|||
ABP Framework & ABP Commercial 3.3.0 have been released today. |
|||
|
|||
Since all the new features are already explained in details with the [3.3 RC Announcement Post](https://blog.abp.io/abp/ABP-Framework-ABP-Commercial-v3.3-RC-Have-Been-Released), I will not repeat all the details again. Please read [the RC post](https://blog.abp.io/abp/ABP-Framework-ABP-Commercial-v3.3-RC-Have-Been-Released) for **new feature and changes** you may need to do for your solution while upgrading to the version 3.3. |
|||
|
|||
## Creating New Solutions |
|||
|
|||
You can create a new solution with the ABP Framework version 3.3 by either using the `abp new` command or using the **direct download** tab on the [get started page](https://abp.io/get-started). |
|||
|
|||
> See the [getting started document](https://docs.abp.io/en/abp/latest/Getting-Started) for details. |
|||
|
|||
## How to Upgrade an Existing Solution |
|||
|
|||
### Install/Update the ABP CLI |
|||
|
|||
First of all, install the ABP CLI or upgrade to the latest version. |
|||
|
|||
If you haven't installed yet: |
|||
|
|||
````bash |
|||
dotnet tool install -g Volo.Abp.Cli |
|||
```` |
|||
|
|||
To update an existing installation: |
|||
|
|||
```bash |
|||
dotnet tool update -g Volo.Abp.Cli |
|||
``` |
|||
|
|||
### ABP UPDATE Command |
|||
|
|||
[ABP CLI](https://docs.abp.io/en/abp/latest/CLI) provides a handy command to update all the ABP related NuGet and NPM packages in your solution with a single command: |
|||
|
|||
````bash |
|||
abp update |
|||
```` |
|||
|
|||
Run this command in the root folder of your solution. After the update command, check [the RC blog post](https://blog.abp.io/abp/ABP-Framework-ABP-Commercial-v3.3-RC-Have-Been-Released) to learn if you need to make any changes in your solution. |
|||
|
|||
> You may want to see the new [upgrading document](https://docs.abp.io/en/abp/latest/Upgrading). |
|||
|
|||
## About the Next Version: 4.0 |
|||
|
|||
The next version will be 4.0 and it will be mostly related to completing the Blazor UI features and upgrading the ABP Framework & ecosystem to the .NET 5.0. |
|||
|
|||
The goal is to complete the version 4.0 with a stable Blazor UI with the fundamental features implemented and publish it just after the Microsoft lunches .NET 5 in this November. The planned 4.0 preview release date is November 11th. |
|||
@ -0,0 +1,143 @@ |
|||
# ABP Framework 4.0 RC Has Been Published based on .NET 5.0! |
|||
|
|||
Today, we have released the [ABP Framework](https://abp.io/) (and the [ABP Commercial](https://commercial.abp.io/)) `4.0.0-rc.1` that is based on the **.NET 5.0**. This blog post introduces the new features and important changes in the new version. |
|||
|
|||
> **The planned release date for the [4.0.0 final](https://github.com/abpframework/abp/milestone/45) version is November 26, 2020**. |
|||
|
|||
## Get Started with the 4.0 RC.1 |
|||
|
|||
If you want to try the version `4.0.0-rc.1` today, follow the steps below; |
|||
|
|||
1) **Upgrade** the ABP CLI to the version `4.0.0-rc.1` using a command line terminal: |
|||
|
|||
````bash |
|||
dotnet tool update Volo.Abp.Cli -g --version 4.0.0-rc.1 |
|||
```` |
|||
|
|||
**or install** if you haven't installed before: |
|||
|
|||
````bash |
|||
dotnet tool install Volo.Abp.Cli -g --version 4.0.0-rc.1 |
|||
```` |
|||
|
|||
2) Create a **new application** with the `--preview` option: |
|||
|
|||
````bash |
|||
abp new BookStore --preview |
|||
```` |
|||
|
|||
See the [ABP CLI documentation](https://docs.abp.io/en/abp/3.3/CLI) for all the available options. |
|||
|
|||
> You can also use the *Direct Download* tab on the [Get Started](https://abp.io/get-started) page by selecting the **Preview checkbox**. |
|||
|
|||
## Migrating From 3.x to 4.0 |
|||
|
|||
The version 4.0 comes with some major changes including the **migration from .NET Core 3.1 to .NET 5.0**. |
|||
|
|||
We've prepared a **detailed [migration document](https://docs.abp.io/en/abp/4.0/Migration-Guides/Abp-4_0)** to explain all the changes and the actions you need to take while upgrading your existing solutions. |
|||
|
|||
## What's new with the ABP Framework 4.0 |
|||
|
|||
### The Blazor UI |
|||
|
|||
The Blazor UI is now stable and officially supported. The [web application development tutorial](https://docs.abp.io/en/abp/4.0/Tutorials/Part-1?UI=Blazor) has been updated based on the version 4.0. |
|||
|
|||
#### abp bundle command |
|||
|
|||
Introducing the `abp bundle` CLI command to manage static JavaScript & CSS file dependencies of a Blazor application. This command is currently used to add the dependencies to the `index.html` file in the dependency order by respecting to modularity. In the next version it will automatically unify & minify the files. The documentation is being prepared. |
|||
|
|||
#### Removed the JQuery & Bootstrap JavaScript |
|||
|
|||
Removed JQuery & Bootstrap JavaScript dependencies for the Blazor UI. |
|||
|
|||
>There are some other changes in the startup template and some public APIs. Follow the [Migration Guide](https://docs.abp.io/en/abp/4.0/Migration-Guides/Abp-4_0) to apply changes for existing solutions that you're upgrading from the version 3.3. While we will continue to make improvements add new features, we no longer make breaking changes on the existing APIs until the version 5.0. |
|||
|
|||
#### Others |
|||
|
|||
A lot of minor and major improvements have been done for the Blazor UI. Some of them are listed below: |
|||
|
|||
* Implemented `IComponentActivator` to resolve the component from the `IServiceProvider`. So, you can now inject dependencies into the constructor of your razor component. |
|||
* Introduced the `AbpComponentBase` base class that you derive your components from. It has useful base properties that you can use in your pages/components. |
|||
* Introduced `IUiNotificationService` service to show toast notifications on the UI. |
|||
* Improved the `IUiMessageService` to show message & confirmation dialogs. |
|||
|
|||
### System.Text.Json |
|||
|
|||
ABP Framework 4.0 uses the System.Text.Json by default as the JSON serialization library. It, actually, using a hybrid approach: Continues to use the Newtonsoft.Json when it needs to use the features not supported by the System.Text.Json. |
|||
|
|||
Follow the [Migration Guide](https://docs.abp.io/en/abp/4.0/Migration-Guides/Abp-4_0) to learn how to configure to use the Newtonsoft.Json for some specific types or switch back to the Newtonsoft.Json as the default JSON serializer. |
|||
|
|||
### Identity Server 4 Upgrade |
|||
|
|||
ABP Framework upgrades the [IdentityServer4](https://www.nuget.org/packages/IdentityServer4) library from 3.x to 4.1.1 with the ABP Framework version 4.0. IdentityServer 4.x has a lot of changes. Some of them are **breaking changes in the data structure**. |
|||
|
|||
Follow the [Migration Guide](https://docs.abp.io/en/abp/4.0/Migration-Guides/Abp-4_0) to upgrade existing solutions. |
|||
|
|||
### Creating a New Module Inside the Application |
|||
|
|||
ABP CLI has now a command to create a new module and add it to an existing solution. In this way, you can create modular applications easier than before. |
|||
|
|||
Example: Create a *ProductManagement* module into your solution. |
|||
|
|||
````bash |
|||
abp add-module ProductManagement --new --add-to-solution-file |
|||
```` |
|||
|
|||
Execute this command in a terminal in the root folder of your solution. If you don't specify the `--add-to-solution-file` option, then the module projects will not be added to the main solution, but the project references still be added. In this case, you need to open the module's solution to develop the module. |
|||
|
|||
See the [CLI document](https://docs.abp.io/en/abp/4.0/CLI) for other options. |
|||
|
|||
### WPF Startup Template |
|||
|
|||
Introducing the WPF startup template for the ABP Framework. Use the ABP CLI new command to create a new WPF application: |
|||
|
|||
````bash |
|||
abp new MyWpfApp -t wpf |
|||
```` |
|||
|
|||
This is a minimalist, empty project template that is integrated to the ABP Framework. |
|||
|
|||
### New Languages |
|||
|
|||
**Thanks to the contributors** from the ABP Community, the framework modules and the startup template have been localized to **German** language by [Alexander Pilhar](https://github.com/alexanderpilhar) & [Nico Lachmuth](https://github.com/tntwist). |
|||
|
|||
### Other Notes |
|||
|
|||
* Upgraded to Angular 11. |
|||
* Since [Mongo2Go](https://github.com/Mongo2Go/Mongo2Go) library not supports transactions, you can use transactions in unit tests for MongoDB. |
|||
|
|||
## What's new with the ABP Commercial 4.0 |
|||
|
|||
### The Blazor UI |
|||
|
|||
The Blazor UI for the ABP Commercial is also becomes stable and feature rich with the version 4.0; |
|||
|
|||
* [ABP Suite](https://commercial.abp.io/tools/suite) now supports to generate CRUD pages for the Blazor UI. |
|||
* Completed the [Lepton Theme](https://commercial.abp.io/themes) for the Blazor UI. |
|||
* Implemented the [File Management](https://commercial.abp.io/modules/Volo.FileManagement) module for the Blazor UI. |
|||
|
|||
### The ABP Suite |
|||
|
|||
While creating create/edit modals with a navigation property, we had two options: A dropdown to select the target entity and a modal to select the entity by searching with a data table. |
|||
|
|||
Dropdown option now supports **lazy load, search and auto-complete**. In this way, selecting a navigation property becomes much easier and supports large data sets on the dropdown. |
|||
|
|||
**Example: Select an author while creating a new book** |
|||
|
|||
 |
|||
|
|||
With the new version, you can **disable backend code generation** on CRUD page generation. This is especially useful if you want to regenerate the page with a different UI framework, but don't want to regenerate the server side code. |
|||
|
|||
### Identity Server Management UI Revised |
|||
|
|||
Completely revised the Identity Server Management UI based on the IDS 4.x changes. |
|||
|
|||
## About the Next Release |
|||
|
|||
The next feature version, `4.1.0`, will mostly focus on completing the missing documents, fixing bugs, performance optimizations and improving the Blazor UI features. The planned preview release date for the version `4.1.0` is December 10 and the final (stable) version release date is December 24. |
|||
|
|||
Follow the [GitHub milestones](https://github.com/abpframework/abp/milestones) for all the planned ABP Framework version release dates. |
|||
|
|||
## Feedback |
|||
|
|||
Please check out the ABP Framework 4.0.0 RC and [provide feedback](https://github.com/abpframework/abp/issues/new) to help us to release a more stable version. **The planned release date for the [4.0.0 final](https://github.com/abpframework/abp/milestone/45) version is November 26**. |
|||
|
After Width: | Height: | Size: 28 KiB |
@ -0,0 +1,46 @@ |
|||
# How to add a new language to your ABP project? |
|||
|
|||
Adding a new language to your ABP project is pretty simple. Let's add the German language to our ABP project: |
|||
|
|||
|
|||
|
|||
1. Go to your solution's root folder and write the following CLI command. This command will generate an empty translation file from English. |
|||
```bash |
|||
abp translate -c de-DE |
|||
``` |
|||
|
|||
Check out for [the complete supported culture codes](https://docs.microsoft.com/en-us/bingmaps/rest-services/common-parameters-and-types/supported-culture-codes). |
|||
(For internal development `D:\Github\abp` and `D:\Github\volo\abp`) |
|||
|
|||
2. Fill the `target` fields in your target language. |
|||
|
|||
 |
|||
|
|||
3. Copy `abp-translation.json` your solution's root folder (Do not change the filename!) |
|||
|
|||
4. Run the following command. This command will create the necessary `json` files. |
|||
```bash |
|||
abp translate --apply |
|||
``` |
|||
|
|||
5. Open your solution and add the new language to the language list. To do this; |
|||
|
|||
* open `MyProjectNameDomainModule.cs` and in `ConfigureServices` you'll find `Configure<AbpLocalizationOptions>`. If you have `HttpApi.Host` project then you need to add this in `MyProjectNameHttpApiHostModule.cs` |
|||
|
|||
``` |
|||
options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch", "de")); |
|||
``` |
|||
|
|||
 |
|||
|
|||
The last parameter is the flag icon. You can find the list of flag icons on https://flagicons.lipis.dev/ |
|||
|
|||
6. The last step is running the DbMigrator project. It will seed the database for the new language. |
|||
 |
|||
|
|||
|
|||
|
|||
Close the IIS Express / Kestrel to invalidate the language cache and run the project. You will see the new language on your website. |
|||
|
|||
 |
|||
|
|||
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 26 KiB |
@ -1,15 +1,13 @@ |
|||
# Data Access |
|||
|
|||
## Database Providers |
|||
|
|||
ABP framework was designed as database agnostic. It can work any type of data source by the help of the [repository](Repositories.md) and [unit of work](Unit-Of-Work.md) abstractions. However, currently the following providers are implemented: |
|||
ABP framework was designed as database agnostic. It can work any type of data source by the help of the [repository](Repositories.md) and [unit of work](Unit-Of-Work.md) abstractions. Currently, the following providers are implemented as official: |
|||
|
|||
* [Entity Framework Core](Entity-Framework-Core.md) (works with [various DBMS and providers](https://docs.microsoft.com/en-us/ef/core/providers/).) |
|||
* [MongoDB](MongoDB.md) |
|||
* [Dapper](Dapper.md) |
|||
|
|||
More providers will be added in the future. |
|||
|
|||
## See Also |
|||
|
|||
* [Connection Strings](Connection-Strings.md) |
|||
* [Connection Strings](Connection-Strings.md) |
|||
* [Data Seeding](Data-Seeding.md) |
|||
* [Data Filtering](Data-Filtering.md) |
|||
@ -0,0 +1,65 @@ |
|||
# Getting Started |
|||
|
|||
````json |
|||
//[doc-params] |
|||
{ |
|||
"UI": ["MVC", "Blazor", "NG"], |
|||
"DB": ["EF", "Mongo"], |
|||
"Tiered": ["Yes", "No"] |
|||
} |
|||
```` |
|||
|
|||
> This document assumes that you prefer to use **{{ UI_Value }}** as the UI framework and **{{ DB_Value }}** as the database provider. For other options, please change the preference on top of this document. |
|||
|
|||
## Create a New Project |
|||
|
|||
Use the `new` command of the ABP CLI to create a new project: |
|||
|
|||
````shell |
|||
abp new Acme.BookStore{{if UI == "NG"}} -u angular{{else if UI == "Blazor"}} -u blazor{{end}}{{if DB == "Mongo"}} -d mongodb{{end}}{{if Tiered == "Yes"}}{{if UI == "MVC"}} --tiered{{else}} --separate-identity-server{{end}}{{end}} |
|||
```` |
|||
|
|||
*You can use different level of namespaces; e.g. BookStore, Acme.BookStore or Acme.Retail.BookStore.* |
|||
|
|||
{{ if Tiered == "Yes" }} |
|||
|
|||
{{ if UI == "MVC" }} |
|||
|
|||
* `--tiered` argument is used to create N-tiered solution where authentication server, UI and API layers are physically separated. |
|||
|
|||
{{ else }} |
|||
|
|||
* `--separate-identity-server` argument is used to separate the identity server application from the API host application. If not specified, you will have a single endpoint on the server. |
|||
|
|||
{{ end }} |
|||
|
|||
{{ end }} |
|||
|
|||
> [ABP CLI document](./CLI.md) covers all of the available commands and options. |
|||
|
|||
> Alternatively, you can **create and download** projects from [ABP Framework website](https://abp.io/get-started) by easily selecting the all the options from the page. |
|||
|
|||
### The Solution Structure |
|||
|
|||
The solution has a layered structure (based on the [Domain Driven Design](Domain-Driven-Design.md)) and contains unit & integration test projects. See the [application template document](Startup-Templates/Application.md) to understand the solution structure in details. |
|||
|
|||
{{ if DB == "Mongo" }} |
|||
|
|||
#### MongoDB Transactions |
|||
|
|||
The [startup template](Startup-templates/Index.md) **disables** transactions in the `.MongoDB` project by default. If your MongoDB server supports transactions, you can enable the it in the *YourProjectMongoDbModule* class's `ConfigureServices` method: |
|||
|
|||
```csharp |
|||
Configure<AbpUnitOfWorkDefaultOptions>(options => |
|||
{ |
|||
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Auto; |
|||
}); |
|||
``` |
|||
|
|||
> Or you can delete that code since `Auto` is already the default behavior. |
|||
|
|||
{{ end }} |
|||
|
|||
## Next Step |
|||
|
|||
* [Running the solution](Getting-Started-Running-Solution.md) |
|||
@ -0,0 +1,217 @@ |
|||
# Getting Started |
|||
|
|||
````json |
|||
//[doc-params] |
|||
{ |
|||
"UI": ["MVC", "Blazor", "NG"], |
|||
"DB": ["EF", "Mongo"], |
|||
"Tiered": ["Yes", "No"] |
|||
} |
|||
```` |
|||
|
|||
> This document assumes that you prefer to use **{{ UI_Value }}** as the UI framework and **{{ DB_Value }}** as the database provider. For other options, please change the preference on top of this document. |
|||
|
|||
## Create the Database |
|||
|
|||
### Connection String |
|||
|
|||
Check the **connection string** in the `appsettings.json` file under the {{if Tiered == "Yes"}}`.IdentityServer` and `.HttpApi.Host` projects{{else}}{{if UI=="MVC"}}`.Web` project{{else}}`.HttpApi.Host` project{{end}}{{end}} |
|||
|
|||
{{ if DB == "EF" }} |
|||
|
|||
````json |
|||
"ConnectionStrings": { |
|||
"Default": "Server=localhost;Database=BookStore;Trusted_Connection=True" |
|||
} |
|||
```` |
|||
|
|||
The solution is configured to use **Entity Framework Core** with **MS SQL Server** by default. EF Core supports [various](https://docs.microsoft.com/en-us/ef/core/providers/) database providers, so you can use any supported DBMS. See [the Entity Framework integration document](Entity-Framework-Core.md) to learn how to [switch to another DBMS](Entity-Framework-Core-Other-DBMS.md). |
|||
|
|||
### Apply the Migrations |
|||
|
|||
The solution uses the [Entity Framework Core Code First Migrations](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli). So, you need to apply migrations to create the database. There are two ways of applying the database migrations. |
|||
|
|||
#### Apply Migrations Using the DbMigrator |
|||
|
|||
The solution comes with a `.DbMigrator` console application which applies migrations and also **seeds the initial data**. It is useful on **development** as well as on **production** environment. |
|||
|
|||
> `.DbMigrator` project has its own `appsettings.json`. So, if you have changed the connection string above, you should also change this one. |
|||
|
|||
Right click to the `.DbMigrator` project and select **Set as StartUp Project** |
|||
|
|||
 |
|||
|
|||
Hit F5 (or Ctrl+F5) to run the application. It will have an output like shown below: |
|||
|
|||
 |
|||
|
|||
> Initial [seed data](Data-Seeding.md) creates the `admin` user in the database (with the password is `1q2w3E*`) which is then used to login to the application. So, you need to use `.DbMigrator` at least once for a new database. |
|||
|
|||
#### Using EF Core Update-Database Command |
|||
|
|||
Ef Core has `Update-Database` command which creates database if necessary and applies pending migrations. |
|||
|
|||
{{ if UI == "MVC" }} |
|||
|
|||
Right click to the {{if Tiered == "Yes"}}`.IdentityServer`{{else}}`.Web`{{end}} project and select **Set as StartUp project**: |
|||
|
|||
{{ else if UI != "MVC" }} |
|||
|
|||
Right click to the `.HttpApi.Host` project and select **Set as StartUp Project**: |
|||
|
|||
{{ end }} |
|||
|
|||
 |
|||
|
|||
Open the **Package Manager Console**, select `.EntityFrameworkCore.DbMigrations` project as the **Default Project** and run the `Update-Database` command: |
|||
|
|||
 |
|||
|
|||
This will create a new database based on the configured connection string. |
|||
|
|||
> **Using the `.DbMigrator` tool is the suggested way**, because it also seeds the initial data to be able to properly run the web application. |
|||
> |
|||
> If you just use the `Update-Database` command, you will have an empty database, so you can not login to the application since there is no initial admin user in the database. You can use the `Update-Database` command in development time when you don't need to seed the database. However, using the `.DbMigrator` application is easier and you can always use it to migrate the schema and seed the database. |
|||
|
|||
{{ else if DB == "Mongo" }} |
|||
|
|||
````json |
|||
"ConnectionStrings": { |
|||
"Default": "mongodb://localhost:27017/BookStore" |
|||
} |
|||
```` |
|||
|
|||
The solution is configured to use **MongoDB** in your local computer, so you need to have a MongoDB server instance up and running or change the connection string to another MongoDB server. |
|||
|
|||
### Seed Initial Data |
|||
|
|||
The solution comes with a `.DbMigrator` console application which **seeds the initial data**. It is useful on **development** as well as on **production** environment. |
|||
|
|||
> `.DbMigrator` project has its own `appsettings.json`. So, if you have changed the connection string above, you should also change this one. |
|||
|
|||
Right click to the `.DbMigrator` project and select **Set as StartUp Project** |
|||
|
|||
 |
|||
|
|||
Hit F5 (or Ctrl+F5) to run the application. It will have an output like shown below: |
|||
|
|||
 |
|||
|
|||
> Initial [seed data](Data-Seeding.md) creates the `admin` user in the database (with the password is `1q2w3E*`) which is then used to login to the application. So, you need to use `.DbMigrator` at least once for a new database. |
|||
|
|||
{{ end }} |
|||
|
|||
## Run the Application |
|||
|
|||
{{ if UI == "MVC" }} |
|||
|
|||
{{ if Tiered == "Yes" }} |
|||
|
|||
> Tiered solutions use **Redis** as the distributed cache. Ensure that it is installed and running in your local computer. If you are using a remote Redis Server, set the configuration in the `appsettings.json` files of the projects below. |
|||
|
|||
1. Ensure that the `.IdentityServer` project is the startup project. Run this application that will open a **login** page in your browser. |
|||
|
|||
> Use Ctrl+F5 in Visual Studio (instead of F5) to run the application without debugging. If you don't have a debug purpose, this will be faster. |
|||
|
|||
You can login, but you cannot enter to the main application here. This is **just the authentication server**. |
|||
|
|||
2. Ensure that the `.HttpApi.Host` project is the startup project and run the application which will open a **Swagger UI** in your browser. |
|||
|
|||
 |
|||
|
|||
This is the HTTP API that is used by the web application. |
|||
|
|||
3. Lastly, ensure that the `.Web` project is the startup project and run the application which will open a **welcome** page in your browser |
|||
|
|||
 |
|||
|
|||
Click to the **login** button which will redirect you to the *authentication server* to login to the application: |
|||
|
|||
 |
|||
|
|||
{{ else # Tiered != "Yes" }} |
|||
|
|||
Ensure that the `.Web` project is the startup project. Run the application which will open the **login** page in your browser: |
|||
|
|||
> Use Ctrl+F5 in Visual Studio (instead of F5) to run the application without debugging. If you don't have a debug purpose, this will be faster. |
|||
|
|||
 |
|||
|
|||
{{ end # Tiered }} |
|||
|
|||
{{ else # UI != "MVC" }} |
|||
|
|||
### Running the HTTP API Host (Server Side) |
|||
|
|||
{{ if Tiered == "Yes" }} |
|||
|
|||
> Tiered solutions use Redis as the distributed cache. Ensure that it is installed and running in your local computer. If you are using a remote Redis Server, set the configuration in the `appsettings.json` files of the projects below. |
|||
|
|||
Ensure that the `.IdentityServer` project is the startup project. Run the application which will open a **login** page in your browser. |
|||
|
|||
> Use Ctrl+F5 in Visual Studio (instead of F5) to run the application without debugging. If you don't have a debug purpose, this will be faster. |
|||
|
|||
You can login, but you cannot enter to the main application here. This is just the authentication server. |
|||
|
|||
Ensure that the `.HttpApi.Host` project is the startup project and run the application which will open a Swagger UI: |
|||
|
|||
{{ else # Tiered == "No" }} |
|||
|
|||
Ensure that the `.HttpApi.Host` project is the startup project and run the application which will open a Swagger UI: |
|||
|
|||
> Use Ctrl+F5 in Visual Studio (instead of F5) to run the application without debugging. If you don't have a debug purpose, this will be faster. |
|||
|
|||
{{ end # Tiered }} |
|||
|
|||
 |
|||
|
|||
You can see the application APIs and test them here. Get [more info](https://swagger.io/tools/swagger-ui/) about the Swagger UI. |
|||
|
|||
{{ end # UI }} |
|||
|
|||
{{ if UI == "Blazor" }} |
|||
|
|||
### Running the Blazor Application (Client Side) |
|||
|
|||
Ensure that the `.Blazor` project is the startup project and run the application. |
|||
|
|||
> Use Ctrl+F5 in Visual Studio (instead of F5) to run the application without debugging. If you don't have a debug purpose, this will be faster. |
|||
|
|||
Once the application starts, click to the **Login** link on to header, which redirects you to the authentication server to enter a username and password: |
|||
|
|||
 |
|||
|
|||
{{ else if UI == "NG" }} |
|||
|
|||
### Running the Angular Application (Client Side) |
|||
|
|||
Go to the `angular` folder, open a command line terminal, type the `yarn` command (we suggest to the [yarn](https://yarnpkg.com/) package manager while `npm install` will also work) |
|||
|
|||
```bash |
|||
yarn |
|||
``` |
|||
|
|||
Once all node modules are loaded, execute `yarn start` (or `npm start`) command: |
|||
|
|||
```bash |
|||
yarn start |
|||
``` |
|||
|
|||
It may take a longer time for the first build. Once it finishes, it opens the Angular UI in your default browser with the [localhost:4200](http://localhost:4200/) address. |
|||
|
|||
 |
|||
|
|||
{{ end }} |
|||
|
|||
Enter **admin** as the username and **1q2w3E*** as the password to login to the application. The application is up and running. You can start developing your application based on this startup template. |
|||
|
|||
## Mobile Development |
|||
|
|||
If you want to include a [React Native](https://reactnative.dev/) project in your solution, add `-m react-native` (or `--mobile react-native`) argument to project creation command. This is a basic React Native startup template to develop mobile applications integrated to your ABP based backends. |
|||
|
|||
See the [Getting Started with the React Native](Getting-Started-React-Native.md) document to learn how to configure and run the React Native application. |
|||
|
|||
## See Also |
|||
|
|||
* [Web Application Development Tutorial](Tutorials/Part-1.md) |
|||
* [Application Startup Template](Startup-Templates/Application.md) |
|||
@ -0,0 +1,56 @@ |
|||
# Getting Started |
|||
|
|||
````json |
|||
//[doc-params] |
|||
{ |
|||
"UI": ["MVC", "Blazor", "NG"], |
|||
"DB": ["EF", "Mongo"], |
|||
"Tiered": ["Yes", "No"] |
|||
} |
|||
```` |
|||
|
|||
> This document assumes that you prefer to use **{{ UI_Value }}** as the UI framework and **{{ DB_Value }}** as the database provider. For other options, please change the preference on top of this document. |
|||
|
|||
## Setup Your Development Environment |
|||
|
|||
First things first! Let's setup your development environment before creating the project. |
|||
|
|||
### Pre-Requirements |
|||
|
|||
The following tools should be installed on your development machine: |
|||
|
|||
* [Visual Studio 2019](https://visualstudio.microsoft.com/vs/) (v16.8+) for Windows / [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/). <sup id="a-editor">[1](#f-editor)</sup> |
|||
* [.NET Core 5.0+](https://www.microsoft.com/net/download/dotnet-core/) |
|||
{{ if UI != "Blazor" }} |
|||
* [Node v12 or v14](https://nodejs.org/) |
|||
* [Yarn v1.20+ (not v2)](https://classic.yarnpkg.com/en/docs/install) <sup id="a-yarn">[2](#f-yarn)</sup> or npm v6+ (already installed with Node) |
|||
{{ end }} |
|||
{{ if Tiered == "Yes" }} |
|||
* [Redis](https://redis.io/) (the startup solution uses the Redis as the [distributed cache](Caching.md)). |
|||
{{ end }} |
|||
|
|||
<sup id="f-editor"><b>1</b></sup> _You can use another editor instead of Visual Studio as long as it supports .NET Core and ASP.NET Core._ <sup>[↩](#a-editor)</sup> |
|||
|
|||
{{ if UI != "Blazor" }} |
|||
|
|||
<sup id="f-yarn"><b>2</b></sup> _Yarn v2 works differently and is not supported._ <sup>[↩](#a-yarn)</sup> |
|||
|
|||
{{ end }} |
|||
|
|||
### Install the ABP CLI |
|||
|
|||
[ABP CLI](./CLI.md) is a command line interface that is used to automate some common tasks for ABP based solutions. First, you need to install the ABP CLI using the following command: |
|||
|
|||
````shell |
|||
dotnet tool install -g Volo.Abp.Cli |
|||
```` |
|||
|
|||
If you've already installed, you can update it using the following command: |
|||
|
|||
````shell |
|||
dotnet tool update -g Volo.Abp.Cli |
|||
```` |
|||
|
|||
## Next Step |
|||
|
|||
* [Creating a new solution](Getting-Started-Create-Solution.md) |
|||
@ -1,31 +1,73 @@ |
|||
# ABP Documentation |
|||
|
|||
ABP is an **open source application framework** focused on **ASP.NET Core** based **web application development**. It also supports developing other type of applications. |
|||
|
|||
Explore the navigation menu to deep dive in the documentation. |
|||
ABP Framework is a complete **infrastructure** based on the **ASP.NET Core** to create **modern web applications** and **APIs** by following the software development **best practices** and the **latest technologies**. |
|||
|
|||
## Getting Started |
|||
|
|||
The easiest way to start a new web application with the ABP Framework is to use the [getting started](Getting-Started.md) guide. |
|||
* [Getting Started Guide](Getting-Started.md) is the easiest way to start a new web application with the ABP Framework. |
|||
* [Web Application Development Tutorial](Tutorials/Part-1.md) is a complete tutorial to develop a full stack web application. |
|||
|
|||
## Tutorials / Articles |
|||
### UI Framework Options |
|||
|
|||
### Web Application Development |
|||
<img width="500" src="images/ui-options.png"> |
|||
|
|||
[Web application development tutorial](Tutorials/Part-1.md) is a complete tutorial to develop a full stack application using the ABP Framework. |
|||
### Database Provider Options |
|||
|
|||
### ABP Community Articles |
|||
<img width="500" src="images/db-options.png"> |
|||
|
|||
See also the [ABP Community](https://community.abp.io/) articles. |
|||
## Exploring the Documentation |
|||
|
|||
## Samples |
|||
ABP has a **comprehensive documentation** that not only explains the ABP Framework, but also includes **guides** and **samples** to help you on creating a **maintainable solution** by introducing and discussing common **software development principle and best practices**. |
|||
|
|||
See the [sample projects](Samples/Index.md) built with the ABP Framework. |
|||
### Architecture |
|||
|
|||
ABP offers a complete, modular and layered software architecture based on [Domain Driven Design](Domain-Driven-Design.md) principles and patterns. It also provides the necessary infrastructure to implement this architecture. |
|||
|
|||
* See the [Modularity](Module-Development-Basics.md) document to understand the module system. |
|||
* [Implementing Domain Driven Design](Domain-Driven-Design-Implementation-Guide.md) document is an ultimate guide for who want to understand and implement the DDD. |
|||
* [Microservice Architecture](Microservice-Architecture.md) document explains how ABP helps to create a microservice solution. |
|||
|
|||
### Infrastructure |
|||
|
|||
There are a lot of features provided by the ABP Framework to achieve real world scenarios easier, like [Event Bus](Event-Bus.md), [Background Job System](Background-Jobs.md), [Audit Logging](Audit-Logging.md), [BLOB Storing](Blob-Storing.md), [Data Seeding](Data-Seeding.md), [Data Filtering](Data-Filtering.md). |
|||
|
|||
### Cross Cutting Concerns |
|||
|
|||
ABP also simplifies (and even automates wherever possible) cross cutting concerns and common non-functional requirements like [Exception Handling](Exception-Handling.md), [Validation](Validation.md), [Authorization](Authorization.md), [Localization](Localization.md), [Caching](Caching.md), [Dependency Injection](Dependency-Injection.md), [Setting Management](Settings.md), etc. |
|||
|
|||
### Application Modules |
|||
|
|||
Application Modules provides pre-built application functionalities; |
|||
|
|||
* [**Account**](Modules/Account.md): Provides UI for the account management and allows user to login/register to the application. |
|||
* **[Identity](Modules/Identity.md)**: Manages organization units, roles, users and their permissions, based on the Microsoft Identity library. |
|||
* [**IdentityServer**](Modules/IdentityServer.md): Integrates to IdentityServer4. |
|||
* [**Tenant Management**](Modules/Tenant-Management.md): Manages tenants for a [multi-tenant](Multi-Tenancy.md) (SaaS) application. |
|||
|
|||
## Source Code |
|||
See the [Application Modules](Modules/Index.md) document for all pre-built modules. |
|||
|
|||
### Startup Templates |
|||
|
|||
The [Startup templates](Startup-Templates/Index.md) are pre-built Visual Studio solution templates. You can create your own solution based on these templates to **immediately start your development**. |
|||
|
|||
## ABP Community |
|||
|
|||
### The Source Code |
|||
|
|||
ABP is hosted on GitHub. See [the source code](https://github.com/abpframework). |
|||
|
|||
## Want to Contribute? |
|||
### ABP Community Web Site |
|||
|
|||
The [ABP Community](https://community.abp.io/) is a website to publish articles and share knowledge about the ABP Framework. You can also create content for the community! |
|||
|
|||
### Blog |
|||
|
|||
Follow the [ABP Blog](https://blog.abp.io/) to learn the latest happenings in the ABP Framework. |
|||
|
|||
### Samples |
|||
|
|||
See the [sample projects](Samples/Index.md) built with the ABP Framework. |
|||
|
|||
### Want to Contribute? |
|||
|
|||
ABP is a community-driven open source project. See [the contribution guide](Contribution/Index.md) if you want to be a part of this project. |
|||
|
|||
@ -0,0 +1,121 @@ |
|||
# Angular UI 3.3 to 4.0 Migration Guide |
|||
|
|||
## Angular v11 |
|||
|
|||
The new ABP Angular UI is based on Angular v11 and TypeScript v4. The difference between v10 and v11 is non-breaking so you do not have to update right away but it is recommended. Nevertheless, ABP modules will keep working with Angular v10. Therefore, if your project is Angular v10, you do not need to update to Angular 11. The update is usually very easy though. |
|||
|
|||
You can read more about Angular v11 [here](https://blog.angular.io/version-11-of-angular-now-available-74721b7952f7) |
|||
|
|||
## **Breaking Changes** |
|||
|
|||
### **Localization** |
|||
|
|||
Prior to ABP 4.x, we'd handled what locale files of Angular should be created to load them lazily. However, this made it impossible to add new locale files (to be lazily loaded) for our users. With ABP 4.x, we enabled an option to pass a function to `CoreModule`. |
|||
|
|||
The quickest solution is as follows: |
|||
|
|||
```typescript |
|||
// app.module.ts |
|||
|
|||
import { registerLocale } from '@abp/ng.core/locale'; |
|||
// or |
|||
// import { registerLocale } from '@volo/abp.ng.language-management/locale'; |
|||
// if you have commercial license |
|||
|
|||
|
|||
@NgModule({ |
|||
imports: [ |
|||
// ... |
|||
CoreModule.forRoot({ |
|||
// ...other options, |
|||
registerLocaleFn: registerLocale() |
|||
}), |
|||
//... |
|||
] |
|||
export class AppModule {} |
|||
``` |
|||
|
|||
You can find the related issue [here](https://github.com/abpframework/abp/issues/6066) |
|||
Also, please refer to [the docs](https://docs.abp.io/en/abp/latest/UI/Angular/Localization#registering-a-new-locale) for more information. |
|||
|
|||
### **Removed the Angular Account Module Public UI** |
|||
|
|||
With ABP 4.x, we have retired `@abp/ng.account`, it is no longer a part of our framework. There won't be any newer versions of this package as well. Therefore, you can delete anything related to this package. |
|||
There should be a config in `app-routing.module` for path `account` and `AccountConfigModule` import in `app.module` |
|||
|
|||
However, if you are using the commercial version of this package, a.k.a `@volo/abp.ng.account`, this package will continue to exist because it contains `AccountAdminModule` which is still being maintained and developed. You only need to delete the route config from `app-routing.module` |
|||
|
|||
You can find the related issue [here](https://github.com/abpframework/abp/issues/5652) |
|||
|
|||
Angular UI is using the Authorization Code Flow to authenticate since version 3.1.0 by default. Starting from version 4.0, this is becoming the only option, because it is the recommended way of authenticating SPAs. |
|||
|
|||
If you haven't done it yet, see [this post](https://blog.abp.io/abp/ABP-Framework-v3.1-RC-Has-Been-Released) to change the authentication of your application. |
|||
|
|||
### State Management |
|||
|
|||
In the ABP Angular UI, we've been using `NGXS` for state management. However, we've decided that the Angular UI should be agnostic with regard to state management. Our users should be able to handle the state in any way they prefer. They should be able to use any library other than `NGXS` or no library at all. That's why we have created our internal store in version 3.2. It is a simple utility class that employs `BehaviorSubject` internally. |
|||
|
|||
You can examine it [here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/utils/internal-store-utils.ts) |
|||
|
|||
With version 4.0, we will keep utilizing our `InternalStore` instead of `@ngxs/store` in our services and move away from `@ngxs/store`. We plan to remove any dependency of `NGXS` by version 5.0. |
|||
|
|||
With this in mind, we've already deprecated some services and implemented some breaking changes. |
|||
|
|||
#### Removed the `SessionState` |
|||
|
|||
Use `SessionStateService` instead of the `SessionState`. See [this issue](https://github.com/abpframework/abp/issues/5606) for details. |
|||
|
|||
#### Deprecated the `ConfigState` |
|||
|
|||
`ConfigState` is now deprecated and should not be used. |
|||
|
|||
`ConfigState` reference removed from `CoreModule`. If you want to use the `ConfigState` (not recommended), you should pass the state to `NgxsModule` as shown below: |
|||
|
|||
```typescript |
|||
//app.module.ts |
|||
|
|||
import { ConfigState } from '@abp/ng.core'; |
|||
|
|||
// ... |
|||
|
|||
imports: [ |
|||
NgxsModule.forRoot([ConfigState]), |
|||
// ... |
|||
``` |
|||
|
|||
Moving away from the global store, we create small services with a single responsibility. There are two new services available in version 4.0 which are `EnvironmentService` and `PermissionService`. |
|||
|
|||
See [the related issue](https://github.com/abpframework/abp/issues/6154) |
|||
|
|||
Please refer to the following docs for detail information and examples |
|||
- [`ConfigStateService`](../UI/Angular/Config-State-Service) |
|||
- [`EnvironmentService`](../UI/Angular/Environment#EnvironmentService) |
|||
- [`PermissionService`](../UI/Angular/Permission-Management#) |
|||
|
|||
### Deprecated Interfaces |
|||
|
|||
Some interfaces have long been marked as deprecated and now they are removed. |
|||
|
|||
- Removed replaceable components state. |
|||
- Removed legacy identity types and service. |
|||
- Removed legacy tenant management types and service. |
|||
- Removed legacy feature management types and services. |
|||
- Removed legacy permission management types and service. |
|||
|
|||
### Deprecated commercial interfaces |
|||
- Removed legacy audit logging types and services. |
|||
- Removed legacy identity types and services. |
|||
- Removed legacy language management types and services. |
|||
- Removed legacy saas types and services. |
|||
|
|||
### Identity Server [COMMERCIAL] |
|||
|
|||
With the new version of Identity Server, there happened some breaking changes in the backend (also in the database). We've implemented those in the Angular UI. |
|||
If you are just using the package `@volo/abp.ng.identity-server` as is, you will not need to do anything. |
|||
However, there are a couple of breaking changes we need to mention. |
|||
|
|||
- As we have stated above, we want to remove the dependency of `NGXS`. Thus, we have deleted all of the actions defined in `identity-server.actions`. Those actions are not needed anymore and the state is managed locally. With the actions gone, `IdentityServerStateService` became unused and got deleted as well. |
|||
|
|||
- `ApiScope` is also available as a new entity (It was part of `ApiResource` before). It provides tokens for entity prop, entity actions, toolbar, edit and create form contributors like the existing ones which are `Client`, `IdentityResource` and `ApiResource` |
|||
|
|||
- There were some deprecated interfaces within the `IdentityServer` namespace. Those are no longer being used, instead, their replacements were generated by `ABP Cli` using the `generate-proxy` command. |
|||
@ -0,0 +1,88 @@ |
|||
# Blazor UI 3.3 to 4.0 Migration Guide |
|||
|
|||
## Startup Template Changes |
|||
|
|||
These changes are required to manually applied in your own solution. It would be easier if you create a new solution based on 4.0 with the same name of your current solution then compare the files. |
|||
|
|||
### Csproj File / Dependencies |
|||
|
|||
* Add `<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>` to the `PropertyGroup` section of your project (`.csproj`) file. |
|||
* Update the `Blazorise.*` packages to the latest version (to the latest RC for the ABP 4.0 preview). |
|||
|
|||
### wwwroot/index.html |
|||
|
|||
There are some changes made in the index.html file; |
|||
|
|||
* Removed JQuery & Bootstrap JavaScript dependencies |
|||
* Replaced Bootstrap and FontAwesome imports with local files instead of CDN usages. |
|||
* Re-arranged some ABP CSS file locations. |
|||
* Introduced the `abp bundle` CLI command to manage global Style/Script file imports. |
|||
|
|||
Follow the steps below to apply the changes; |
|||
|
|||
1. Add the bundle contributor class into your project (it will be slightly different based on your solution namespaces): |
|||
|
|||
````csharp |
|||
using Volo.Abp.Bundling; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor |
|||
{ |
|||
public class MyProjectNameBundleContributor : IBundleContributor |
|||
{ |
|||
public void AddScripts(BundleContext context) |
|||
{ |
|||
} |
|||
|
|||
public void AddStyles(BundleContext context) |
|||
{ |
|||
context.Add("main.css"); |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
If you are using another global style/script files, add them here. |
|||
|
|||
2. Remove all the `<link...>` elements and replace with the following comment tags: |
|||
|
|||
````html |
|||
<!--ABP:Styles--> |
|||
<!--/ABP:Styles--> |
|||
```` |
|||
|
|||
3. Remove all the `<script...>` elements and replace with the following comment tags: |
|||
|
|||
````html |
|||
<!--ABP:Scripts--> |
|||
<!--/ABP:Scripts--> |
|||
```` |
|||
|
|||
4. Execute the following command in a terminal in the root folder of the Blazor project (`.csproj`) file (ensure that you're using the ABP CLI version 4.0): |
|||
|
|||
````bash |
|||
abp bundle |
|||
```` |
|||
|
|||
This will fill in the `Styles` and `Scripts` tags based on the dependencies. |
|||
|
|||
5. You can clean the `blazor-error-ui` related sections from your `main.css` file since they are not needed anymore. |
|||
|
|||
### The Root Element |
|||
|
|||
This change is optional but recommended. |
|||
|
|||
* Change `<app>...</app>` to `<div id="ApplicationContainer">...</div>` in the `wwwroot/index.html`. |
|||
* Change `builder.RootComponents.Add<App>("app");` to `builder.RootComponents.Add<App>("#ApplicationContainer");` in the *YourProjectBlazorModule.cs*. |
|||
|
|||
## AbpCrudPageBase Changes |
|||
|
|||
If you've derived your pages from the `AbpCrudPageBase` class, then you may need to apply the following changes; |
|||
|
|||
- `OpenEditModalAsync` method gets `EntityDto` instead of id (`Guid`) parameter. Pass `context` instead of `context.Id`. |
|||
- `DeleteEntityAsync` method doesn't display confirmation dialog anymore. You can use the new `EntityActions` component in Data Grids to show confirmation messages. You can also inject `IUiMessageService` to your page or component and call the `ConfirmAsync` explicitly. |
|||
- Added `GetListInput` as a base property that is used to filter while getting the entities from the server. |
|||
|
|||
## Others |
|||
|
|||
- Refactored namespaces for some Blazor components ([#6015](https://github.com/abpframework/abp/issues/6015)). |
|||
- Removed Async Suffix from IUiMessageService methods ([#6123](https://github.com/abpframework/abp/pull/6123)). |
|||
@ -0,0 +1,6 @@ |
|||
# MVC / Razor Pages UI 3.3 to 4.0 Migration Guide |
|||
|
|||
## Use IBrandingProvider in the Volo.Abp.UI Package |
|||
|
|||
This will be a breaking change for MVC UI, but very easy to fix. `IBrandingProvider` is being moved from `Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components` to `Volo.Abp.Ui.Branding` namespace. So, just update the namespace imports. |
|||
|
|||
@ -0,0 +1,280 @@ |
|||
# ABP Framework 3.3 to 4.0 Migration Guide |
|||
|
|||
This document introduces the breaking changes done in the ABP Framework 4.0 and explains how to fix your 3.x based solutions while upgrading to the ABP Framework 4.0. |
|||
|
|||
> See [the blog post](https://blog.abp.io/abp/ABP.IO-Platform-v4.0-RC-Has-Been-Released-based-on-.NET-5.0) to learn what's new with the ABP Framework 4.0. This document only focuses on the breaking changes. |
|||
|
|||
## Overall |
|||
|
|||
Here, the overall list of the changes; |
|||
|
|||
* Upgraded to the .NET 5.0 [(#6118](https://github.com/abpframework/abp/issues/6118)). |
|||
* Moved from Newtonsoft.Json to System.Text.Json [(#1198](https://github.com/abpframework/abp/issues/1198)). |
|||
* Upgraded to the Identity Server 4.1.1 ([#4461](https://github.com/abpframework/abp/issues/4461)). |
|||
* Switched to `kebab-case` for conventional URLs for the auto API controller routes ([#5325](https://github.com/abpframework/abp/issues/5325)). |
|||
* Removed Retry for the Dynamic HTTP Client Proxies ([#6090](https://github.com/abpframework/abp/issues/6090)). |
|||
* Creation audit properties of the entities made read-only ([#6020](https://github.com/abpframework/abp/issues/6020)). |
|||
* Changed type of the IHasExtraProperties.ExtraProperties ([#3751](https://github.com/abpframework/abp/issues/3751)). |
|||
* Use IBrandingProvider in the Volo.Abp.UI package and remove the one in the Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared ([#5375](https://github.com/abpframework/abp/issues/5375)). |
|||
* Removed the Angular Account Module Public UI (login, register... pages) since they are not being used in the default (authorization code) flow ([#5652](https://github.com/abpframework/abp/issues/5652)). |
|||
* Removed the SessionState in the @abp/ng.core package ([#5606](https://github.com/abpframework/abp/issues/5606)). |
|||
* Made some API revisions & startup template changes for the Blazor UI. |
|||
|
|||
## Upgraded to .NET 5.0 |
|||
|
|||
ABP Framework has been moved to .NET 5.0. So, if you want to upgrade to the ABP Framework 4.0, you also need to upgrade to .NET 5.0. |
|||
|
|||
See the [Migrate from ASP.NET Core 3.1 to 5.0](https://docs.microsoft.com/en-us/aspnet/core/migration/31-to-50) document to learn how to upgrade your solution to .NET 5.0. |
|||
|
|||
## Moved to System.Text.Json |
|||
|
|||
ABP Framework 4.0 uses the System.Text.Json by default as the JSON serialization library. It, actually, using a hybrid approach: Continues to use the Newtonsoft.Json when it needs to use features not supported by the System.Text.Json. |
|||
|
|||
### Unsupported Types |
|||
|
|||
If you want to use the Newtonsoft.Json to serialize/deserialize for some specific types, you can configure the `AbpSystemTextJsonSerializerOptions` in your module's `ConfigureServices` method. |
|||
|
|||
**Example: Use Newtonsoft.Json for `MySpecialClass`** |
|||
|
|||
````csharp |
|||
Configure<AbpSystemTextJsonSerializerOptions>(options => |
|||
{ |
|||
options.UnsupportedTypes.AddIfNotContains(typeof(MySpecialClass)); |
|||
}); |
|||
```` |
|||
|
|||
### Always Use the Newtonsoft.Json |
|||
|
|||
If you want to continue to use the Newtonsoft.Json library for all the types, you can set `UseHybridSerializer` to false in the `PreConfigureServices` method of your module class: |
|||
|
|||
````csharp |
|||
PreConfigure<AbpJsonOptions>(options => |
|||
{ |
|||
options.UseHybridSerializer = false; |
|||
}); |
|||
```` |
|||
|
|||
## Upgraded to Identity Server 4.1.1 |
|||
|
|||
ABP Framework upgrades the [IdentityServer4](https://www.nuget.org/packages/IdentityServer4) library from 3.x to 4.1.1 with the ABP Framework version 4.0. IdentityServer 4.x has a lot of changes. Some of them are **breaking changes in the data structure**. |
|||
|
|||
### Entity Changes |
|||
|
|||
Entity changes don't directly affect your application; however, it is good to know. |
|||
|
|||
#### ApiScope |
|||
|
|||
As the **most critical breaking change**; Identity Server 4.x defines the `ApiScope` as an independent aggregate root. Previously, it was the child entity of the `ApiResource`. This change requires manual operation. See the _Database Changes_ section. |
|||
|
|||
Also, added `Enabled(string)` and `Description(bool,true)` properties. |
|||
|
|||
#### ApiResource |
|||
|
|||
- Added `AllowedAccessTokenSigningAlgorithms (string)` and `ShowInDiscoveryDocument(bool, default: true)` properties |
|||
|
|||
#### Client |
|||
|
|||
- Added `RequireRequestObject <bool>` and `AllowedIdentityTokenSigningAlgorithms <string>` properties. |
|||
- Changed the default value of `RequireConsent` from `true` to `false`. |
|||
- Changed the default value of `RequirePkce` from `false` to `true`. |
|||
|
|||
#### DeviceFlowCodes |
|||
|
|||
- Added `SessionId <string>` and `Description <string>` properties. |
|||
|
|||
#### PersistedGrant |
|||
|
|||
- Added `SessionId <string>`, `Description <string>` and `ConsumedTime <DateTime?>` properties |
|||
|
|||
### Database Changes |
|||
|
|||
> Attention: **Please backup your database** before the migration! |
|||
|
|||
**If you are upgrading from 3.x, then there are some steps should be done in your database.** |
|||
|
|||
#### Database Schema Migration |
|||
|
|||
If you are using **Entity Framework Core**, you need to add a new database migration, using the `Add-Migration` command, and apply changes to the database. Please **review the migration** script and read the sections below to understand if it affects your existing data. Otherwise, you may **lose some of your configuration**, which may not be easy to remember and re-configure. |
|||
|
|||
#### Seed Code |
|||
|
|||
If you haven't customized the `IdentityServerDataSeedContributor` and haven't customized the initial data inside the `IdentityServer*` tables; |
|||
|
|||
1. Update `IdentityServerDataSeedContributor` class by comparing to [the latest code](https://github.com/abpframework/abp/blob/dev/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/IdentityServer/IdentityServerDataSeedContributor.cs). You probably only need to add the `CreateApiScopesAsync` method and the code related to it. |
|||
2. Then you can simply clear all the **data** in these tables then execute the `DbMigrator` application to fill it with the new configuration. |
|||
|
|||
#### Migrating the Configuration Data |
|||
|
|||
If you've customized your IdentityServer configuration in the database or in the seed data, you should understand the changes and upgrade your code/data accordingly. Especially, the following changes will affect your application: |
|||
|
|||
- `IdentityServerApiScopes` table's `Enabled` field is dropped and re-created. So, you need to enable the API scopes again manually. |
|||
- `IdentityServerApiResourceScopes` table is dropped and recreated. So, you need to backup and move your current data to the new table. |
|||
- `IdentityServerIdentityResourceClaims` table is dropped and recreated. So, you need to backup and move your current data to the new table. |
|||
|
|||
You may need to perform additional steps based on how much you made custom configurations. |
|||
|
|||
### Other IdentityServer Changes |
|||
|
|||
IdentityServer has removed the [public origin option](https://github.com/IdentityServer/IdentityServer4/pull/4335). It was resolving HTTP/HTTPS conversion issues, but they decided to leave this to the developer. This is especially needed if you use a reverse proxy where your external protocol is HTTPS but internal protocol is HTTP. |
|||
|
|||
One simple solution is to add such a middleware at the begingning of your ASP.NET Core pipeline. |
|||
|
|||
```csharp |
|||
app.Use((httpContext, next) => |
|||
{ |
|||
httpContext.Request.Scheme = "https"; |
|||
return next(); |
|||
}); |
|||
``` |
|||
|
|||
> This sample is obtained from the [ASP.NET Core documentation](https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer#scenarios-and-use-cases). You can use it if you always use HTTPS in all environments. |
|||
|
|||
### Related Resources |
|||
|
|||
- https://leastprivilege.com/2020/06/19/announcing-identityserver4-v4-0/ |
|||
- https://github.com/IdentityServer/IdentityServer4/issues/4592 |
|||
|
|||
## Auto API Controller Route Changes |
|||
|
|||
The route calculation for the [Auto API Controllers](https://docs.abp.io/en/abp/latest/API/Auto-API-Controllers) is changing with the ABP Framework version 4.0 ([#5325](https://github.com/abpframework/abp/issues/5325)). Before v4.0 the route paths were **camelCase**. After version 4.0, it's changed to **kebab-case** route paths where it is possible. |
|||
|
|||
**A typical auto API before v4.0** |
|||
|
|||
 |
|||
|
|||
**camelCase route parts become kebab-case with 4.0** |
|||
|
|||
 |
|||
|
|||
### How to Fix? |
|||
|
|||
You may not take any action for the MVC & Blazor UI projects. |
|||
|
|||
For the Angular UI, this change may effect your client UI. If you have used the [ABP CLI Service Proxy Generation](../UI/Angular/Service-Proxies.md), you can run the server side and re-generate the service proxies. If you haven't used this tool, you should manually update the related URLs in your application. |
|||
|
|||
If there are other type of clients (e.g. 3rd-party companies) using your APIs, they also need to update the URLs. |
|||
|
|||
### Use the v3.x style URLs |
|||
|
|||
If it is hard to change it in your application, you can still to use the version 3.x route strategy, by following one of the approaches; |
|||
|
|||
- Set `UseV3UrlStyle` to `true` in the options of the `options.ConventionalControllers.Create(...)` method. Example: |
|||
|
|||
```csharp |
|||
options.ConventionalControllers |
|||
.Create(typeof(BookStoreApplicationModule).Assembly, opts => |
|||
{ |
|||
opts.UseV3UrlStyle = true; |
|||
}); |
|||
``` |
|||
|
|||
This approach affects only the controllers for the `BookStoreApplicationModule`. |
|||
|
|||
- Set `UseV3UrlStyle` to `true` for the `AbpConventionalControllerOptions` to set it globally. Example: |
|||
|
|||
```csharp |
|||
Configure<AbpConventionalControllerOptions>(options => |
|||
{ |
|||
options.UseV3UrlStyle = true; |
|||
}); |
|||
``` |
|||
|
|||
Setting it globally affects all the modules in a modular application. |
|||
|
|||
## Removed Retry for the Dynamic HTTP Client Proxies |
|||
|
|||
[Dynamic C# HTTP Client Proxies](../API/Dynamic-CSharp-API-Clients.md) were trying up to 3 times if a request fails using the [Polly](https://github.com/App-vNext/Polly) library. Starting from the version 4.0, this logic has been removed. If you need it, you should configure it in your own application, by configuring the `AbpHttpClientBuilderOptions` in the `PreConfigureServices` method of your module. |
|||
|
|||
**Example: Retry 3 times on failure by incremental waiting between tries** |
|||
|
|||
````csharp |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<AbpHttpClientBuilderOptions>(options => |
|||
{ |
|||
options.ProxyClientBuildActions.Add((remoteServiceName, clientBuilder) => |
|||
{ |
|||
clientBuilder.AddTransientHttpErrorPolicy( |
|||
policyBuilder => policyBuilder |
|||
.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i))) |
|||
); |
|||
}); |
|||
}); |
|||
} |
|||
```` |
|||
|
|||
This example uses the Microsoft.Extensions.Http.Polly NuGet package. |
|||
|
|||
If you create a new solution, you can find the same configuration in the `.HttpApi.Client.ConsoleTestApp` project's module class, as an example. |
|||
|
|||
## Creation Audit Properties Made Read-Only |
|||
|
|||
Removed setters from the `IHasCreationTime.CreationTime`, ` IMustHaveCreator.CreatorId` and `IMayHaveCreator.CreatorId` properties to accidently set the creation properties while updating an existing entity. |
|||
|
|||
Since the ABP Framework automatically sets these properties, you normally don't need to directly set them. If you want to set them, as a best practice, it is suggested to make it in the constructor to not provide a way to change it later. |
|||
|
|||
These properties implemented with `protected set` in the `Entity` and `AggregateRoot` base classes. That means you can still set in a derived class, if you need it. Alternatively, you can use reflection to set them (Or use `ObjectHelper.TrySetProperty` which internally uses reflection) out of the class if you have to do. |
|||
|
|||
## Changed type of the IHasExtraProperties.ExtraProperties |
|||
|
|||
`IHasExtraProperties.ExtraProperties` was a regular `Dictionary<string, object>`. With the version 4.0, it is replaced with `ExtraPropertyDictionary` class which inherits the `Dictionary<string, object>`. |
|||
|
|||
Most of the applications don't be affected by this change. If you've directly implemented this interface, replace the standard dictionary to the `ExtraPropertyDictionary`. |
|||
|
|||
## Other Changes |
|||
|
|||
### IdentityOptions Usage |
|||
|
|||
Previously, when you inject `IOptions<IdentityOptions>`, you get a dynamically overridden options value. For example, when you get `IdentityOptions.Password.RequiredLength`, the value is being changed based on the setting (`IdentitySettingNames.Password.RequiredLength`) of the current tenant. That means `IdentityOptions` changes per tenant. However, this caused an [issue](https://github.com/abpframework/abp/issues/6318) and we [had to change](https://github.com/abpframework/abp/pull/6333) the usage. |
|||
|
|||
With the version 4.0, you need to inject `IOptions<IdentityOptions>` and call the new `SetAsync` method before using it, to be able to override the options by the settings. Otherwise, you get the default (statically configured) values of the options. |
|||
|
|||
Example usage: |
|||
|
|||
````csharp |
|||
public class MyService : ITransientDependency |
|||
{ |
|||
private readonly IOptions<IdentityOptions> _options; |
|||
|
|||
public MyService(IOptions<IdentityOptions> options) |
|||
{ |
|||
_options = options; |
|||
} |
|||
|
|||
public async Task DoItAsync() |
|||
{ |
|||
await _options.SetAsync(); |
|||
|
|||
var requiredLength = _options.Value.Password.RequiredLength; |
|||
} |
|||
} |
|||
```` |
|||
|
|||
Pre-built modules already handles this. However, if you have used `IdentityOptions` directly in your code, you also need to follow this new pattern. |
|||
Please make sure that the injected `IOptions<IdentityOptions>` service and the service consuming it are in the same scope of dependency injection container. |
|||
|
|||
### LDAP module full async |
|||
|
|||
In order to solve the problem of async over sync, `ILdapManager` uses async method instead of sync. And use [`ldap4net`](https://github.com/flamencist/ldap4net) to replace [`Novell.Directory.Ldap.NETStandard`](https://github.com/dsbenghe/Novell.Directory.Ldap.NETStandard) package. |
|||
|
|||
### Dynamic external login provider system |
|||
|
|||
You need to change the `WithDynamicOptions` method and pass the `Handler` class of the external login provider. |
|||
Use the `goto definition` function in Visual Studio or Rider to check `Handler` in the extension method like `AddGoogle`. |
|||
|
|||
```csharp |
|||
- WithDynamicOptions<GoogleOptions>() |
|||
+ WithDynamicOptions<GoogleOptions, GoogleHandler>() |
|||
```` |
|||
|
|||
## ASP.NET Core MVC / Razor Pages UI |
|||
|
|||
See the [ASP.NET Core MVC / Razor Pages UI Migration Guide](Abp-4_0-MVC-Razor-Pages.md). |
|||
|
|||
## Angular UI |
|||
|
|||
See the [Angular UI Migration Guide](Abp-4_0-Angular.md). |
|||
|
|||
## Blazor UI |
|||
|
|||
See the [Blazor UI Migration Guide](Abp-4_0-Blazor.md). |
|||
@ -0,0 +1,5 @@ |
|||
# ABP Framework Migration Guides |
|||
|
|||
* [3.3.x to 4.0 Migration Guide](Abp-4_0.md) |
|||
* [2.9.x to 3.0 Migration Guide](../UI/Angular/Migration-Guide-v3.md) |
|||
|
|||
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 44 KiB |
@ -1,3 +1,393 @@ |
|||
# Module Entity Extensions |
|||
|
|||
See https://docs.abp.io/en/commercial/latest/guides/module-entity-extensions (it will be moved here soon). |
|||
## Introduction |
|||
|
|||
Module entity extension system is a **high level** extension system that allows you to **define new properties** for existing entities of the depended modules. It automatically **adds properties to the entity, database, HTTP API and the user interface** in a single point. |
|||
|
|||
> The module must be developed the *Module Entity Extensions* system in mind. All the **official modules** supports this system wherever possible. |
|||
|
|||
## Quick Example |
|||
|
|||
Open the *YourProjectNameModuleExtensionConfigurator* class inside the `Domain.Shared` project of your solution and change the `ConfigureExtraProperties`method as shown below to add a `SocialSecurityNumber` property to the `IdentityUser` entity of the [Identity Module](Modules/Identity.md). |
|||
|
|||
````csharp |
|||
public static void ConfigureExtraProperties() |
|||
{ |
|||
OneTimeRunner.Run(() => |
|||
{ |
|||
ObjectExtensionManager.Instance.Modules() |
|||
.ConfigureIdentity(identity => |
|||
{ |
|||
identity.ConfigureUser(user => |
|||
{ |
|||
user.AddOrUpdateProperty<string>( //property type: string |
|||
"SocialSecurityNumber", //property name |
|||
property => |
|||
{ |
|||
//validation rules |
|||
property.Attributes.Add(new RequiredAttribute()); |
|||
property.Attributes.Add( |
|||
new StringLengthAttribute(64) { |
|||
MinimumLength = 4 |
|||
} |
|||
); |
|||
|
|||
//...other configurations for this property |
|||
} |
|||
); |
|||
}); |
|||
}); |
|||
}); |
|||
} |
|||
```` |
|||
|
|||
>This method is called inside the `YourProjectNameDomainSharedModule` at the beginning of the application. `OneTimeRunner` is a utility class that guarantees to execute this code only one time per application, since multiple calls are unnecessary. |
|||
|
|||
* `ObjectExtensionManager.Instance.Modules()` is the starting point to configure a module. `ConfigureIdentity(...)` method is used to configure the entities of the Identity Module. |
|||
* `identity.ConfigureUser(...)` is used to configure the user entity of the identity module. Not all entities are designed to be extensible (since it is not needed). Use the intellisense to discover the extensible modules and entities. |
|||
* `user.AddOrUpdateProperty<string>(...)` is used to add a new property to the user entity with the `string` type (`AddOrUpdateProperty` method can be called multiple times for the same property of the same entity. Each call can configure the options of the same property, but only one property is added to the entity with the same property name). You can call this method with different property names to add more properties. |
|||
* `SocialSecurityNumber` is the name of the new property. |
|||
* `AddOrUpdateProperty` gets a second argument (the `property =>` lambda expression) to configure additional options for the new property. |
|||
* We can add data annotation attributes like shown here, just like adding a data annotation attribute to a class property. |
|||
|
|||
#### Create & Update Forms |
|||
|
|||
Once you define a property, it appears in the create and update forms of the related entity: |
|||
|
|||
 |
|||
|
|||
`SocialSecurityNumber` field comes into the form. Next sections will explain the localization and the validation for this new property. |
|||
|
|||
### Data Table |
|||
|
|||
New properties also appear in the data table of the related page: |
|||
|
|||
 |
|||
|
|||
`SocialSecurityNumber` column comes into the table. Next sections will explain the option to hide this column from the data table. |
|||
|
|||
## Property Options |
|||
|
|||
There are some options that you can configure while defining a new property. |
|||
|
|||
### Display Name |
|||
|
|||
You probably want to set a different (human readable) display name for the property that is shown on the user interface. |
|||
|
|||
#### Don't Want to Localize? |
|||
|
|||
If your application is not localized, you can directly set the `DisplayName` for the property to a `FixedLocalizableString` object. Example: |
|||
|
|||
````csharp |
|||
property => |
|||
{ |
|||
property.DisplayName = new FixedLocalizableString("Social security no"); |
|||
} |
|||
```` |
|||
|
|||
#### Localizing the Display Name |
|||
|
|||
If you want to localize the display name, you have two options. |
|||
|
|||
##### Localize by Convention |
|||
|
|||
Instead of setting the `property.DisplayName`, you can directly open your localization file (like `en.json`) and add the following entry to the `texts` section: |
|||
|
|||
````json |
|||
"SocialSecurityNumber": "Social security no" |
|||
```` |
|||
|
|||
Define the same `SocialSecurityNumber` key (the property name you've defined before) in your localization file for each language you support. That's all! |
|||
|
|||
In some cases, the localization key may conflict with other keys in your localization files. In such cases, you can use the `DisplayName:` prefix for display names in the localization file (`DisplayName:SocialSecurityNumber` as the localization key for this example). Extension system looks for prefixed version first, then fallbacks to the non prefixed name (it then fallbacks to the property name if you haven't localized it). |
|||
|
|||
> This approach is recommended since it is simple and suitable for most scenarios. |
|||
|
|||
##### Localize using the `DisplayName` Property |
|||
|
|||
If you want to specify the localization key or the localization resource, you can still set the `DisplayName` option: |
|||
|
|||
````csharp |
|||
property => |
|||
{ |
|||
property.DisplayName = |
|||
LocalizableString.Create<MyProjectNameResource>( |
|||
"UserSocialSecurityNumberDisplayName" |
|||
); |
|||
} |
|||
```` |
|||
|
|||
* `MyProjectNameResource` is the localization resource and `UserSocialSecurityNumberDisplayName` is the localization key in the localization resource. |
|||
|
|||
> See [the localization document](Localization.md) if you want to learn more about the localization system. |
|||
|
|||
#### Default Value |
|||
|
|||
A default value is automatically set for the new property, which is the natural default value for the property type, like `null` for `string`, `false` for `bool` or `0` for `int`. |
|||
|
|||
There are two ways to override the default value: |
|||
|
|||
##### DefaultValue Option |
|||
|
|||
`DefaultValue` option can be set to any value: |
|||
|
|||
````csharp |
|||
property => |
|||
{ |
|||
property.DefaultValue = 42; |
|||
} |
|||
```` |
|||
|
|||
##### DefaultValueFactory Options |
|||
|
|||
`DefaultValueFactory` can be set to a function that returns the default value: |
|||
|
|||
````csharp |
|||
property => |
|||
{ |
|||
property.DefaultValueFactory = () => DateTime.Now; |
|||
} |
|||
```` |
|||
|
|||
`options.DefaultValueFactory` has a higher priority than the `options.DefaultValue` . |
|||
|
|||
> Tip: Use `DefaultValueFactory` option only if the default value may change over the time (like `DateTime.Now` in this example). If it is a constant value, then use the `DefaultValue` option. |
|||
|
|||
### Validation |
|||
|
|||
Entity extension system allows you to define validation for extension properties in a few ways. |
|||
|
|||
#### Data Annotation Attributes |
|||
|
|||
`Attributes` is a list of attributes associated to this property. The example code below adds two [data annotation validation attributes](https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation) to the property: |
|||
|
|||
````csharp |
|||
property => |
|||
{ |
|||
property.Attributes.Add(new RequiredAttribute()); |
|||
property.Attributes.Add(new StringLengthAttribute(64) {MinimumLength = 4}); |
|||
} |
|||
```` |
|||
|
|||
When you run the application, you see that the validation works out of the box: |
|||
|
|||
 |
|||
|
|||
Since we've added the `RequiredAttribute`, it doesn't allow to left it blank. The validation system works; |
|||
|
|||
* On the user interface (with automatic localization). |
|||
* On the HTTP API. Even if you directly perform an HTTP request, you get validation errors with a proper HTTP status code. |
|||
* On the `SetProperty(...)` method on the entity (see [the document](Entities.md) if you wonder what is the `SetProperty()` method). |
|||
|
|||
So, it automatically makes a full stack validation. |
|||
|
|||
> See the [ASP.NET Core MVC Validation document](https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation) to learn more about the attribute based validation. |
|||
|
|||
##### Default Validation Attributes |
|||
|
|||
There are some attributes **automatically added** when you create certain type of properties; |
|||
|
|||
* `RequiredAttribute` is added for **non nullable** primitive property types (e.g. `int`, `bool`, `DateTime`...) and `enum` types. If you want to allow nulls, make the property nullable (e.g. `int?`). |
|||
* `EnumDataTypeAttribute` is added for **enum types**, to prevent to set invalid enum values. |
|||
|
|||
Use `property.Attributes.Clear();` if you don't want these attributes. |
|||
|
|||
#### Validation Actions |
|||
|
|||
Validation actions allows you to execute a custom code to perform the validation. The example below checks if the `SocialSecurityNumber` starts with `B` and adds a validation error if so: |
|||
|
|||
````csharp |
|||
property => |
|||
{ |
|||
property.Attributes.Add(new RequiredAttribute()); |
|||
property.Attributes.Add(new StringLengthAttribute(64) {MinimumLength = 4}); |
|||
|
|||
property.Validators.Add(context => |
|||
{ |
|||
if (((string) context.Value).StartsWith("B")) |
|||
{ |
|||
context.ValidationErrors.Add( |
|||
new ValidationResult( |
|||
"Social security number can not start with the letter 'B', sorry!", |
|||
new[] {"extraProperties.SocialSecurityNumber"} |
|||
) |
|||
); |
|||
} |
|||
}); |
|||
|
|||
} |
|||
```` |
|||
|
|||
Using a `RegularExpressionAttribute` might be better in this case, but this is just an example. Anyway, if you enter a value starts with the letter `B` you get the following error **while saving the form**: |
|||
|
|||
 |
|||
|
|||
##### The Context Object |
|||
|
|||
The `context` object has useful properties that can be used in your custom validation action. For example, you can use the `context.ServiceProvider` to resolve services from the [dependency injection system](Dependency-Injection.md). The example below gets the localizer and adds a localized error message: |
|||
|
|||
````csharp |
|||
if (((string) context.Value).StartsWith("B")) |
|||
{ |
|||
var localizer = context.ServiceProvider |
|||
.GetRequiredService<IStringLocalizer<MyProjectNameResource>>(); |
|||
|
|||
context.ValidationErrors.Add( |
|||
new ValidationResult( |
|||
localizer["SocialSecurityNumberCanNotStartWithB"], |
|||
new[] {"extraProperties.SocialSecurityNumber"} |
|||
) |
|||
); |
|||
} |
|||
```` |
|||
|
|||
>`context.ServiceProvider` is nullable! It can be `null` only if you use the `SetProperty(...)` method on the object. Because DI system is not available on this time. While this is a rare case, you should perform a fallback logic when `context.ServiceProvider` is `null`. For this example, you would add a non-localized error message. This is not a problem since setting an invalid value to a property generally is a programmer mistake and you mostly don't need to localization in this case. In any way, you would not be able to use localization even in a regular property setter. But, if you are serious about localization, you can throw a business exception (see the [exception handling document](https://docs.abp.io/en/abp/latest/Exception-Handling) to learn how to localize a business exception). |
|||
|
|||
### UI Visibility |
|||
|
|||
When you define a property, it appears on the data table, create and edit forms on the related UI page. However, you can control each one individually. Example: |
|||
|
|||
````csharp |
|||
property => |
|||
{ |
|||
property.UI.OnTable.IsVisible = false; |
|||
//...other configurations |
|||
} |
|||
```` |
|||
|
|||
Use `property.UI.OnCreateForm` and `property.UI.OnEditForm` to control forms too. If a property is required, but not added to the create form, you definitely get a validation exception, so use this option carefully. But a required property may not be in the edit form if that's your requirement. |
|||
|
|||
### HTTP API Availability |
|||
|
|||
Even if you disable a property on UI, it can be still available through the HTTP API. By default, a property is available on all APIs. |
|||
|
|||
Use the `property.Api` options to make a property unavailable in some API endpoints. |
|||
|
|||
````csharp |
|||
property => |
|||
{ |
|||
property.Api.OnUpdate.IsAvailable = false; |
|||
} |
|||
```` |
|||
|
|||
In this example, Update HTTP API will not allow to set a new value to this property. In this case, you also want to disable this property on the edit form: |
|||
|
|||
````csharp |
|||
property => |
|||
{ |
|||
property.Api.OnUpdate.IsAvailable = false; |
|||
property.UI.OnEditForm.IsVisible = false; |
|||
} |
|||
```` |
|||
|
|||
In addition to the `property.Api.OnUpdate`, you can set `property.Api.OnCreate` and `property.Api.OnGet` for a fine control the API endpoint. |
|||
|
|||
## Special Types |
|||
|
|||
### Enum |
|||
|
|||
Module extension system naturally supports the `enum` types. |
|||
|
|||
An example enum type: |
|||
|
|||
````csharp |
|||
public enum UserType |
|||
{ |
|||
Regular, |
|||
Moderator, |
|||
SuperUser |
|||
} |
|||
```` |
|||
|
|||
You can add enum properties just like others: |
|||
|
|||
````csharp |
|||
user.AddOrUpdateProperty<UserType>("Type"); |
|||
```` |
|||
|
|||
An enum properties is shown as combobox (select) in the create/edit forms: |
|||
|
|||
 |
|||
|
|||
#### Localization |
|||
|
|||
Enum member name is shown on the table and forms by default. If you want to localize it, just create a new entry on your [localization](https://docs.abp.io/en/abp/latest/Localization) file: |
|||
|
|||
````json |
|||
"UserType.SuperUser": "Super user" |
|||
```` |
|||
|
|||
One of the following names can be used as the localization key: |
|||
|
|||
* `Enum:UserType.SuperUser` |
|||
* `UserType.SuperUser` |
|||
* `SuperUser` |
|||
|
|||
Localization system searches for the key with the given order. Localized text are used on the table and the create/edit forms. |
|||
|
|||
## Database Mapping |
|||
|
|||
For relational databases, all extension property values are stored in a single field in the table: |
|||
|
|||
 |
|||
|
|||
`ExtraProperties` field stores the properties as a JSON object. While that's fine for some scenarios, you may want to create a dedicated field for your new property. Fortunately, it is very easy to configure. |
|||
|
|||
If you are using the Entity Framework Core database provider, you can configure the database mapping as shown below: |
|||
|
|||
````csharp |
|||
ObjectExtensionManager.Instance |
|||
.MapEfCoreProperty<IdentityUser, string>( |
|||
"SocialSecurityNumber", |
|||
(entityBuilder, propertyBuilder) => |
|||
{ |
|||
propertyBuilder.HasMaxLength(64); |
|||
} |
|||
); |
|||
```` |
|||
|
|||
Write this inside the `YourProjectNameEfCoreEntityExtensionMappings` class in your `.EntityFrameworkCore` project. Then you need to use the standard `Add-Migration` and `Update-Database` commands to create a new database migration and apply the change to your database. |
|||
|
|||
Add-Migration create a new migration as shown below: |
|||
|
|||
````csharp |
|||
public partial class Added_SocialSecurityNumber_To_IdentityUser : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.AddColumn<string>( |
|||
name: "SocialSecurityNumber", |
|||
table: "AbpUsers", |
|||
maxLength: 128, |
|||
nullable: true); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropColumn( |
|||
name: "SocialSecurityNumber", |
|||
table: "AbpUsers"); |
|||
} |
|||
} |
|||
```` |
|||
|
|||
Once you update your database, you will see that the `AbpUsers` table has the new property as a standard table field: |
|||
|
|||
 |
|||
|
|||
> If you first created a property without a database table field, then you later needed to move this property to a database table field, it is suggested to execute an SQL command in your migration to copy the old values to the new field. |
|||
> |
|||
> However, if you don't make it, the ABP Framework seamlessly manages it. It uses the new database field, but fallbacks to the `ExtraProperties` field if it is null. When you save the entity, it moves the value to the new field. |
|||
|
|||
See the [Extending Entities](Customizing-Application-Modules-Extending-Entities.md) document for more. |
|||
|
|||
## More |
|||
|
|||
See the [Customizing the Modules](Customizing-Application-Modules-Guide.md) guide for an overall index for all the extensibility options. |
|||
|
|||
Here, a few things you can do: |
|||
|
|||
* You can create a second entity that maps to the same database table with the extra property as a standard class property (if you've defined the EF Core mapping). For the example above, you can add a `public string SocialSecurityNumber {get; set;}` property to the `AppUser` entity in your application, since the `AppUser` entity is mapped to the same `AbpUser` table. Do this only if you need it, since it brings more complexity to your application. |
|||
* You can override a domain or application service to perform custom logics with your new property. |
|||
* You can low level control how to add/render a field in the data table on the UI. |
|||
|
|||
|
|||
@ -1,3 +1,38 @@ |
|||
# Account Module |
|||
|
|||
TODO |
|||
This module provides necessary UI pages/components to make the user login and register to the application. |
|||
|
|||
> This document is incomplete. |
|||
|
|||
## Social/External Logins |
|||
|
|||
The [Account Module](../Modules/Account.md) has already configured to handle social or external logins out of the box. You can follow the ASP.NET Core documentation to add a social/external login provider to your application. |
|||
|
|||
### Example: Facebook Authentication |
|||
|
|||
Follow the [ASP.NET Core Facebook integration document](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/facebook-logins) to support the Facebook login for your application. |
|||
|
|||
#### Add the NuGet Package |
|||
|
|||
Add the [Microsoft.AspNetCore.Authentication.Facebook](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.Facebook) package to your project. Based on your architecture, this can be `.Web`, `.IdentityServer` (for tiered setup) or `.Host` project. |
|||
|
|||
#### Configure the Provider |
|||
|
|||
Use the `.AddFacebook(...)` extension method in the `ConfigureServices` method of your [module](../Module-Development-Basics.md), to configure the client: |
|||
|
|||
````csharp |
|||
context.Services.AddAuthentication() |
|||
.AddFacebook(facebook => |
|||
{ |
|||
facebook.AppId = "..."; |
|||
facebook.AppSecret = "..."; |
|||
facebook.Scope.Add("email"); |
|||
facebook.Scope.Add("public_profile"); |
|||
}); |
|||
```` |
|||
|
|||
> It would be a better practice to use the `appsettings.json` or the ASP.NET Core User Secrets system to store your credentials, instead of a hard-coded value like that. Follow the [Microsoft's document](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/facebook-logins) to learn the user secrets usage. |
|||
|
|||
### Other UI Types |
|||
|
|||
Beginning from the v3.1, the [Angular UI](../UI/Angular/Quick-Start.md) uses authorization code flow (as a best practice) to authenticate the user by redirecting to the MVC UI login page. So, even if you are using the Angular UI, social/external login integration is same as explained above and it will work out of the box. As similar, The [Blazor UI](../UI/Blazor/Overall.md) also uses the MVC UI to logic. |
|||
@ -0,0 +1,3 @@ |
|||
# Client Simulation Module |
|||
|
|||
TODO |
|||
@ -0,0 +1,3 @@ |
|||
# CMS Kit Module |
|||
|
|||
TODO |
|||
@ -1,47 +0,0 @@ |
|||
# Organization Unit Management |
|||
|
|||
Organization units (OU) is a part of **Identity Module** and can be used to **hierarchically group users and entities**. |
|||
|
|||
### OrganizationUnit Entity |
|||
|
|||
An OU is represented by the **OrganizationUnit** entity. The fundamental properties of this entity are: |
|||
|
|||
- **TenantId**: Tenant's Id of this OU. Can be null for host OUs. |
|||
- **ParentId**: Parent OU's Id. Can be null if this is a root OU. |
|||
- **Code**: A hierarchical string code that is unique for a tenant. |
|||
- **DisplayName**: Shown name of the OU. |
|||
|
|||
The OrganizationUnit entity's primary key (Id) is a **Guid** type and it derives from the [**FullAuditedAggregateRoot**](../Entities.md) class. |
|||
|
|||
#### Organization Tree |
|||
|
|||
Since an OU can have a parent, all OUs of a tenant are in a **tree** structure. There are some rules for this tree; |
|||
|
|||
- There can be more than one root (where the `ParentId` is `null`). |
|||
- There is a limit for the first-level children count of an OU (because of the fixed OU Code unit length explained below). |
|||
|
|||
#### OU Code |
|||
|
|||
OU code is automatically generated and maintained by the OrganizationUnit Manager. It's a string that looks something like this: |
|||
|
|||
"**00001.00042.00005**" |
|||
|
|||
This code can be used to easily query the database for all the children of an OU (recursively). There are some rules for this code: |
|||
|
|||
- It must be **unique** for a [tenant](../Multi-Tenancy.md). |
|||
- All the children of the same OU have codes that **start with the parent OU's code**. |
|||
- It's **fixed length** and based on the level of the OU in the tree, as shown in the sample. |
|||
- While the OU code is unique, it can be **changeable** if you move an OU. |
|||
- You must reference an OU by Id, not Code. |
|||
|
|||
### OrganizationUnit Manager |
|||
|
|||
The **OrganizationUnitManager** class can be [injected](../Dependency-Injection.md) and used to manage OUs. Common use cases are: |
|||
|
|||
- Create, Update or Delete an OU |
|||
- Move an OU in the OU tree. |
|||
- Getting information about the OU tree and its items. |
|||
|
|||
#### Multi-Tenancy |
|||
|
|||
The `OrganizationUnitManager` is designed to work for a **single tenant** at a time. It works for the **current tenant** by default. |
|||
@ -0,0 +1,3 @@ |
|||
# Users Module |
|||
|
|||
TODO |
|||
@ -0,0 +1,233 @@ |
|||
# Plug-In Modules |
|||
|
|||
It is possible to load [modules](Module-Development-Basics.md) as plug-ins. That means you may not reference to a module's assembly in your solution, but you can load that module in the application startup just like any other module. |
|||
|
|||
## Basic Usage |
|||
|
|||
`IServiceCollection.AddApplication<T>()` extension method can get options to configure the plug-in sources. |
|||
|
|||
**Example: Load plugins from a folder** |
|||
|
|||
````csharp |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity.PlugIns; |
|||
|
|||
namespace MyPlugInDemo.Web |
|||
{ |
|||
public class Startup |
|||
{ |
|||
public void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.AddApplication<MyPlugInDemoWebModule>(options => |
|||
{ |
|||
options.PlugInSources.AddFolder(@"D:\Temp\MyPlugIns"); |
|||
}); |
|||
} |
|||
|
|||
public void Configure(IApplicationBuilder app) |
|||
{ |
|||
app.InitializeApplication(); |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
* This is the `Startup` class of a typical ASP.NET Core application. |
|||
* `PlugInSources.AddFolder` gets a folder path and to load assemblies (typically `dll`s) in that folder. |
|||
|
|||
That's all. ABP will discover the modules in the given folder, configure and initialize them just like regular modules. |
|||
|
|||
### Plug-In Sources |
|||
|
|||
`options.PlugInSources` is actually a list of `IPlugInSource` implementations and `AddFolder` is just a shortcut for the following expression: |
|||
|
|||
````csharp |
|||
options.PlugInSources.Add(new FolderPlugInSource(@"D:\Temp\MyPlugIns")); |
|||
```` |
|||
|
|||
> `AddFolder()` only looks for the assembly file in the given folder, but not looks for the sub-folders. You can pass `SearchOption.AllDirectories` as a second parameter to explore plug-ins also from the sub-folders, recursively. |
|||
|
|||
There are two more built-in Plug-In Source implementations: |
|||
|
|||
* `PlugInSources.AddFiles()` gets a list of assembly (typically `dll`) files. This is a shortcut of using `FilePlugInSource` class. |
|||
* `PlugInSources.AddTypes()` gets a list of module class types. If you use this, you need to load the assemblies of the modules yourself, but it provides flexibility when needed. This is a shortcut of using `TypePlugInSource` class. |
|||
|
|||
If you need, you can create your own `IPlugInSource` implementation and add to the `options.PlugInSources` just like the others. |
|||
|
|||
## Example: Creating a Simple Plug-In |
|||
|
|||
Create a simple **Class Library Project** in a solution: |
|||
|
|||
 |
|||
|
|||
You can add ABP Framework packages you need to use in the module. At least, you should add the `Volo.Abp.Core` package to the project: |
|||
|
|||
```` |
|||
Install-Package Volo.Abp.Core |
|||
```` |
|||
|
|||
Every [module](Module-Development-Basics.md) must declare a class derived from the `AbpModule`. Here, a simple module class that resolves a service and initializes it on the application startup: |
|||
|
|||
````csharp |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace MyPlugIn |
|||
{ |
|||
public class MyPlungInModule : AbpModule |
|||
{ |
|||
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|||
{ |
|||
var myService = context.ServiceProvider |
|||
.GetRequiredService<MyService>(); |
|||
|
|||
myService.Initialize(); |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
`MyService` can be any class registered to [Dependency Injection](Dependency-Injection.md) system, as show below: |
|||
|
|||
````csharp |
|||
using Microsoft.Extensions.Logging; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace MyPlugIn |
|||
{ |
|||
public class MyService : ITransientDependency |
|||
{ |
|||
private readonly ILogger<MyService> _logger; |
|||
|
|||
public MyService(ILogger<MyService> logger) |
|||
{ |
|||
_logger = logger; |
|||
} |
|||
|
|||
public void Initialize() |
|||
{ |
|||
_logger.LogInformation("MyService has been initialized"); |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
Build the project, open the build folder, find the `MyPlugIn.dll`: |
|||
|
|||
 |
|||
|
|||
Copy `MyPlugIn.dll` into the plug-in folder (`D:\Temp\MyPlugIns` for this example). |
|||
|
|||
If you have configured the main application like described above (see Basic Usage section), you should see the `MyService has been initialized` log in the application startup. |
|||
|
|||
## Example: Creating a Plug-In With Razor Pages |
|||
|
|||
Creating plug-ins with views inside requires a bit more attention. |
|||
|
|||
> This example assumes you've [created a new web application](https://abp.io/get-started) using the application startup template and MVC / Razor Pages UI. |
|||
|
|||
Create a new **Class Library** project in a solution: |
|||
|
|||
 |
|||
|
|||
Edit the `.csproj` file content: |
|||
|
|||
````xml |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<OutputType>Library</OutputType> |
|||
<IsPackable>true</IsPackable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared" Version="4.0.1" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
```` |
|||
|
|||
* Changed `Sdk` to `Microsoft.NET.Sdk.Web`. |
|||
* Added `OutputType` and `IsPackable` properties. |
|||
* Added `Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared` NuGet package. |
|||
|
|||
> Depending on [Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared) package is not required. You can reference to a more base package like [Volo.Abp.AspNetCore.Mvc](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Mvc/). However, if you will build a UI page/component, it is suggested to reference to the [Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared) package since it is the most high-level package without depending on a particular [theme](UI/AspNetCore/Theming.md). If there is no problem to depend on a particular theme, you can directly reference to the theme's package to be able to use the theme-specific features in your plug-in. |
|||
|
|||
Then create your module class in the plug-in: |
|||
|
|||
````csharp |
|||
using System.IO; |
|||
using System.Reflection; |
|||
using Microsoft.AspNetCore.Mvc.ApplicationParts; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace MyMvcUIPlugIn |
|||
{ |
|||
[DependsOn(typeof(AbpAspNetCoreMvcUiThemeSharedModule))] |
|||
public class MyMvcUIPlugInModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<IMvcBuilder>(mvcBuilder => |
|||
{ |
|||
//Add plugin assembly |
|||
mvcBuilder.PartManager.ApplicationParts.Add(new AssemblyPart(typeof(MyMvcUIPlugInModule).Assembly)); |
|||
|
|||
//Add views assembly |
|||
var viewDllPath = Path.Combine(Path.GetDirectoryName(typeof(MyMvcUIPlugInModule).Assembly.Location), "MyMvcUIPlugIn.Views.dll"); |
|||
var viewAssembly = new CompiledRazorAssemblyPart(Assembly.LoadFrom(viewDllPath)); |
|||
mvcBuilder.PartManager.ApplicationParts.Add(viewAssembly); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
* Depending on the `AbpAspNetCoreMvcUiThemeSharedModule` since we added the related NuGet package. |
|||
* Adding the plug-in's assembly to the `PartManager` of ASP.NET Core MVC. This is required by ASP.NET Core. Otherwise, your controllers inside the plug-in doesn't work. |
|||
* Adding the plug-in's views assembly to the `PartManager` of ASP.NET Core MVC. This is required by ASP.NET Core. Otherwise, your views inside the plug-in doesn't work. |
|||
|
|||
You can now add a razor page, like `MyPlugInPage.cshtml` inside the `Pages` folder: |
|||
|
|||
````html |
|||
@page |
|||
@model MyMvcUIPlugIn.Pages.MyPlugInPage |
|||
<h1>Welcome to my plug-in page</h1> |
|||
<p>This page is located inside a plug-in module! :)</p> |
|||
```` |
|||
|
|||
Now, you can build the plug-in project. It will produce the following output: |
|||
|
|||
 |
|||
|
|||
Copy the `MyMvcUIPlugIn.dll` and `MyMvcUIPlugIn.Views.dll` into the plug-in folder (`D:\Temp\MyPlugIns` for this example). |
|||
|
|||
If you have configured the main application like described above (see Basic Usage section), you should be able to visit the `/MyPlugInPage` URL when your application: |
|||
|
|||
 |
|||
|
|||
## Discussions |
|||
|
|||
In real world, your plug-in may have some external dependencies. Also, your application might be designed to support plug-ins. All these are your own system requirements. What ABP does is just loading modules on the application startup. What you do inside that modules is up to you. |
|||
|
|||
However, we can provide a few suggestions for some common cases. |
|||
|
|||
### Library Dependencies |
|||
|
|||
For package/dll dependencies, you can copy the related dlls to the plug-in folder. ABP automatically loads all assemblies in the folder and your plug-in will work as expected. |
|||
|
|||
> See [Microsoft's documentation](https://docs.microsoft.com/en-us/dotnet/core/tutorials/creating-app-with-plugin-support#plugin-with-library-dependencies) for some additional explanations for that case. |
|||
|
|||
### Database Schema |
|||
|
|||
If your module uses a relational database and [Entity Framework Core](Entity-Framework-Core.md), it will need to have its tables available in the database. There are different ways to ensure the tables have been created when an application uses the plug-in. Some examples; |
|||
|
|||
1. The Plugin may check if the database tables does exists and create the tables on the application startup or migrate them if the plug-in has been updated and requires some schema changes. You can use EF Core's migration API to do that. |
|||
2. You can improve the `DbMigrator` application to find migrations of the plug-ins and execute them. |
|||
|
|||
There may be other solutions. For example, if your DB admin doesn't allow you to change the database schema in the application code, you may need to manually send a SQL file to the database admin to apply it to the database. |
|||
@ -0,0 +1,27 @@ |
|||
# WPF Application Startup Template |
|||
|
|||
This template is used to create a minimalist WPF application project. |
|||
|
|||
## How to Start With? |
|||
|
|||
First, install the [ABP CLI](../CLI.md) if you haven't installed before: |
|||
|
|||
````bash |
|||
dotnet tool install -g Volo.Abp.Cli |
|||
```` |
|||
|
|||
Then use the `abp new` command in an empty folder to create a new solution: |
|||
|
|||
````bash |
|||
abp new Acme.MyWpfApp -t wpf |
|||
```` |
|||
|
|||
`Acme.MyWpfApp` is the solution name, like *YourCompany.YourProduct*. You can use single level, two-levels or three-levels naming. |
|||
|
|||
## Solution Structure |
|||
|
|||
After you use the above command to create a solution, you will have a solution like shown below: |
|||
|
|||
 |
|||
|
|||
* `HelloWorldService` is a sample service that implements the `ITransientDependency` interface to register this service to the [dependency injection](../Dependency-Injection.md) system. |
|||
@ -0,0 +1,3 @@ |
|||
# Swagger UI Integration |
|||
|
|||
TODO |
|||
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 55 KiB |
@ -0,0 +1,135 @@ |
|||
# Config State Service |
|||
|
|||
`ConfigStateService` is a singleton service, i.e. provided in root level of your application, and keeps the application configuration response in the internal store. |
|||
|
|||
## Before Use |
|||
|
|||
In order to use the `ConfigStateService` you must inject it in your class as a dependency. |
|||
|
|||
```js |
|||
import { ConfigStateService } from '@abp/ng.core'; |
|||
|
|||
@Component({ |
|||
/* class metadata here */ |
|||
}) |
|||
class DemoComponent { |
|||
constructor(private config: ConfigStateService) {} |
|||
} |
|||
``` |
|||
|
|||
You do not have to provide the `ConfigStateService` at module or component/directive level, because it is already **provided in root**. |
|||
|
|||
## Get Methods |
|||
|
|||
`ConfigStateService` has numerous get methods which allow you to get a specific configuration or all configurations. |
|||
|
|||
Get methods with "$" at the end of the method name (e.g. `getAll$`) return an RxJs stream. The streams are triggered when set or patched the state. |
|||
|
|||
### How to Get All Configurations |
|||
|
|||
You can use the `getAll` or `getAll$` method of `ConfigStateService` to get all of the applcation configuration response object. It is used as follows: |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
const config = this.config.getAll(); |
|||
|
|||
// or |
|||
this.config.getAll$().subscribe(config => { |
|||
// use config here |
|||
}) |
|||
``` |
|||
|
|||
### How to Get a Specific Configuration |
|||
|
|||
You can use the `getOne` or `getOne$` method of `ConfigStateService` to get a specific configuration property. For that, the property name should be passed to the method as parameter. |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
const currentUser = this.config.getOne("currentUser"); |
|||
|
|||
// or |
|||
this.config.getOne$("currentUser").subscribe(currentUser => { |
|||
// use currentUser here |
|||
}) |
|||
``` |
|||
|
|||
On occasion, you will probably want to be more specific than getting just the current user. For example, here is how you can get the `tenantId`: |
|||
|
|||
```js |
|||
const tenantId = this.config.getDeep("currentUser.tenantId"); |
|||
|
|||
// or |
|||
this.config.getDeep$("currentUser.tenantId").subscribe(tenantId => { |
|||
// use tenantId here |
|||
}) |
|||
``` |
|||
|
|||
or by giving an array of keys as parameter: |
|||
|
|||
```js |
|||
const tenantId = this.config.getDeep(["currentUser", "tenantId"]); |
|||
``` |
|||
|
|||
FYI, `getDeep` is able to do everything `getOne` does. Just keep in mind that `getOne` is slightly faster. |
|||
|
|||
### How to Get a Feature |
|||
|
|||
You can use the `getFeature` or `getFeature$` method of `ConfigStateService` to get a feature value. For that, the feature name should be passed to the method as parameter. |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
const enableLdapLogin = this.configStateService.getFeature("Account.EnableLdapLogin"); |
|||
|
|||
// or |
|||
this.config.getFeature$("Account.EnableLdapLogin").subscribe(enableLdapLogin => { |
|||
// use enableLdapLogin here |
|||
}) |
|||
``` |
|||
|
|||
> For more information, see the [features document](./Features). |
|||
|
|||
### How to Get a Setting |
|||
|
|||
You can use the `getSetting` or `getSetting$` method of `ConfigStateService` to get a setting. For that, the setting name should be passed to the method as parameter. |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
const twoFactorBehaviour = this.configStateService.getSetting("Abp.Identity.TwoFactor.Behaviour"); |
|||
|
|||
// or |
|||
this.config.getSetting$("Abp.Identity.TwoFactor.Behaviour").subscribe(twoFactorBehaviour => { |
|||
// use twoFactorBehaviour here |
|||
}) |
|||
``` |
|||
|
|||
> For more information, see the [settings document](./Settings). |
|||
|
|||
#### State Properties |
|||
|
|||
Please refer to `ApplicationConfiguration.Response` type for all the properties you can get with `getOne` and `getDeep`. It can be found in the [application-configuration.ts file](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/application-configuration.ts#L4). |
|||
|
|||
|
|||
## Set State |
|||
|
|||
`ConfigStateService` has a method named `setState` which allow you to set the state value. |
|||
|
|||
You can get the application configuration response and set the `ConfigStateService` state value as shown below: |
|||
|
|||
```js |
|||
import {ApplicationConfigurationService, ConfigStateService} from '@abp/ng.core'; |
|||
|
|||
constructor(private applicationConfigurationService: ApplicationConfigurationService, private config: ConfigStateService) { |
|||
this.applicationConfigurationService.getConfiguration().subscribe(config => { |
|||
this.config.setState(config); |
|||
}) |
|||
} |
|||
``` |
|||
|
|||
## See Also |
|||
|
|||
- [Settings](./Settings.md) |
|||
- [Features](./Features.md) |
|||
@ -1,192 +1 @@ |
|||
# Config State |
|||
|
|||
`ConfigStateService` is a singleton service, i.e. provided in root level of your application, and is actually a façade for interacting with application configuration state in the `Store`. |
|||
|
|||
## Before Use |
|||
|
|||
In order to use the `ConfigStateService` you must inject it in your class as a dependency. |
|||
|
|||
```js |
|||
import { ConfigStateService } from '@abp/ng.core'; |
|||
|
|||
@Component({ |
|||
/* class metadata here */ |
|||
}) |
|||
class DemoComponent { |
|||
constructor(private config: ConfigStateService) {} |
|||
} |
|||
``` |
|||
|
|||
You do not have to provide the `ConfigStateService` at module or component/directive level, because it is already **provided in root**. |
|||
|
|||
## Selector Methods |
|||
|
|||
`ConfigStateService` has numerous selector methods which allow you to get a specific configuration or all configurations from the `Store`. |
|||
|
|||
### How to Get All Configurations From the Store |
|||
|
|||
You can use the `getAll` method of `ConfigStateService` to get all of the configuration object from the store. It is used as follows: |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
const config = this.config.getAll(); |
|||
``` |
|||
|
|||
### How to Get a Specific Configuration From the Store |
|||
|
|||
You can use the `getOne` method of `ConfigStateService` to get a specific configuration property from the store. For that, the property name should be passed to the method as parameter. |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
const currentUser = this.config.getOne("currentUser"); |
|||
``` |
|||
|
|||
On occasion, you will probably want to be more specific than getting just the current user. For example, here is how you can get the `tenantId`: |
|||
|
|||
```js |
|||
const tenantId = this.config.getDeep("currentUser.tenantId"); |
|||
``` |
|||
|
|||
or by giving an array of keys as parameter: |
|||
|
|||
```js |
|||
const tenantId = this.config.getDeep(["currentUser", "tenantId"]); |
|||
``` |
|||
|
|||
FYI, `getDeep` is able to do everything `getOne` does. Just keep in mind that `getOne` is slightly faster. |
|||
|
|||
#### Config State Properties |
|||
|
|||
Please refer to `Config.State` type for all the properties you can get with `getOne` and `getDeep`. It can be found in the [config.ts file](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/config.ts#L7). |
|||
|
|||
### How to Get the Application Information From the Store |
|||
|
|||
The `getApplicationInfo` method is used to get the application information from the environment variables stored as the config state. This is how you can use it: |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
const appInfo = this.config.getApplicationInfo(); |
|||
``` |
|||
|
|||
This method never returns `undefined` or `null` and returns an empty object literal (`{}`) instead. In other words, you will never get an error when referring to the properties of `appInfo` above. |
|||
|
|||
#### Application Information Properties |
|||
|
|||
Please refer to `Config.Application` type for all the properties you can get with `getApplicationInfo`. It can be found in the [config.ts file](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/config.ts#L21). |
|||
|
|||
### How to Get API URL From the Store |
|||
|
|||
The `getApplicationInfo` method is used to get a specific API URL from the environment variables stored as the config state. This is how you can use it: |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
const apiUrl = this.config.getApiUrl(); |
|||
// environment.apis.default.url |
|||
|
|||
const searchUrl = this.config.getApiUrl("search"); |
|||
// environment.apis.search.url |
|||
``` |
|||
|
|||
This method returns the `url` of a specific API based on the key given as its only parameter. If there is no key, `'default'` is used. |
|||
|
|||
### How to Get a Specific Permission From the Store |
|||
|
|||
You can use the `getGrantedPolicy` method of `ConfigStateService` to get a specific permission from the configuration state. For that, you should pass a policy key as parameter to the method. |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
const hasIdentityPermission = this.config.getGrantedPolicy("Abp.Identity"); |
|||
// true |
|||
``` |
|||
|
|||
You may also **combine policy keys** to fine tune your selection: |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
const hasIdentityAndAccountPermission = this.config.getGrantedPolicy( |
|||
"Abp.Identity && Abp.Account" |
|||
); |
|||
// false |
|||
|
|||
const hasIdentityOrAccountPermission = this.config.getGrantedPolicy( |
|||
"Abp.Identity || Abp.Account" |
|||
); |
|||
// true |
|||
``` |
|||
|
|||
Please consider the following **rules** when creating your permission selectors: |
|||
|
|||
- Maximum 2 keys can be combined. |
|||
- `&&` operator looks for both keys. |
|||
- `||` operator looks for either key. |
|||
- Empty string `''` as key will return `true` |
|||
- Using an operator without a second key will return `false` |
|||
|
|||
### How to Get Translations From the Store |
|||
|
|||
The `getLocalization` method of `ConfigStateService` is used for translations. Here are some examples: |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
const identity = this.config.getLocalization("AbpIdentity::Identity"); |
|||
// 'identity' |
|||
|
|||
const notFound = this.config.getLocalization("AbpIdentity::IDENTITY"); |
|||
// 'AbpIdentity::IDENTITY' |
|||
|
|||
const defaultValue = this.config.getLocalization({ |
|||
key: "AbpIdentity::IDENTITY", |
|||
defaultValue: "IDENTITY" |
|||
}); |
|||
// 'IDENTITY' |
|||
``` |
|||
|
|||
Please check out the [localization documentation](./Localization.md) for details. |
|||
|
|||
## Dispatch Methods |
|||
|
|||
`ConfigStateService` has several dispatch methods which allow you to conveniently dispatch predefined actions to the `Store`. |
|||
|
|||
### How to Get Application Configuration From Server |
|||
|
|||
The `dispatchGetAppConfiguration` triggers a request to an endpoint that responds with the application state and then places this response to the `Store` as configuration state. |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
this.config.dispatchGetAppConfiguration(); |
|||
// returns a state stream which emits after dispatch action is complete |
|||
``` |
|||
|
|||
Note that **you do not have to call this method at application initiation**, because the application configuration is already being received from the server at start. |
|||
|
|||
### How to Set the Environment |
|||
|
|||
The `dispatchSetEnvironment` places environment variables passed to it in the `Store` under the configuration state. Here is how it is used: |
|||
|
|||
```js |
|||
// this.config is instance of ConfigStateService |
|||
|
|||
this.config.dispatchSetEnvironment({ |
|||
/* environment properties here */ |
|||
}); |
|||
// returns a state stream which emits after dispatch action is complete |
|||
``` |
|||
|
|||
Note that **you do not have to call this method at application initiation**, because the environment variables are already being stored at start. |
|||
|
|||
#### Environment Properties |
|||
|
|||
Please refer to `Config.Environment` type for all the properties you can pass to `dispatchSetEnvironment` as parameter. It can be found in the [config.ts file](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/config.ts#L13). |
|||
|
|||
## See Also |
|||
|
|||
- [Settings](./Settings.md) |
|||
- [Features](./Features.md) |
|||
**ConfigState has been deprecated.** Use the [ConfigStateService](./Config-State-Service) instead. |
|||