diff --git a/README.BlazorWebAssembly.md b/README.BlazorWebAssembly.md index 303decc..3b63d66 100644 --- a/README.BlazorWebAssembly.md +++ b/README.BlazorWebAssembly.md @@ -7,9 +7,11 @@ The first step is to use ABP CLI to create a new project. **Replace LeptonXLiteTheme with AntBlazorTheme packages** * Replace `Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme` with `Lsw.Abp.AspnetCore.Components.WebAssembly.AntDesignTheme` +* Replace `Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme.Bundling` with `Lsw.Abp.AspnetCore.Components.WebAssembly.AntDesignTheme.Bundling` * Replace `Volo.Abp.Identity.Blazor.WebAssembly` with `Lsw.Abp.IdentityManagement.Blazor.WebAssembly.AntDesignUI` * Replace `Volo.Abp.SettingManagement.Blazor.WebAssembly` with `Lsw.Abp.SettingManagement.Blazor.WebAssembly.AntDesignUI` * Replace `Volo.Abp.TenantManagement.Blazor.WebAssembly` with `Lsw.Abp.TenantManagement.Blazor.WebAssembly.AntDesignUI` +* Replace `Volo.Abp.FeatureManagement.Blazor.WebAssembly` with `Lsw.Abp.FeatureManagement.Blazor.WebAssembly.AntDesignUI` ``` @@ -23,7 +25,7 @@ The first step is to use ABP CLI to create a new project. @using Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Bundling ``` -**Open `BookStoreBlazorModule` make the following changes:** +**Open `BookStoreBlazorClientModule` make the following changes:** * Remove the `ConfigureBlazorise` method * Fix wrong using namespace @@ -55,7 +57,25 @@ The first step is to use ABP CLI to create a new project. +``` + +**Open `Routes.razor` and replace with the following:** +```csharp +@using Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Routing +@using Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Themes.AntDesignTheme +@using Microsoft.Extensions.Options +@using Volo.Abp.AspNetCore.Components.WebAssembly.WebApp + + + + + + + + + + ``` Run the `dotnet build` & `abp bundle` command in the `BookStore.Blazor` folder. diff --git a/README.md b/README.md index 0c1c2a6..657bba9 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ ## Quick Start -[Change the theme of the ABP project to AntBlazorTheme for Blazor WebApp.](./README.WebApp.md) - -[Change the theme of the ABP project to AntBlazorTheme for Blazor Server.](./README.BlazorServer.md) +* [Change the theme of the ABP project to AntBlazorTheme for Blazor WebApp.](./README.WebApp.md) +* [Change the theme of the ABP project to AntBlazorTheme for Blazor Server.](./README.BlazorServer.md) +* [Change the theme of the ABP project to AntBlazorTheme for Blazor WebAssembly.](./README.BlazorWebAssembly.md) ## Road map diff --git a/samples/WebAppBlazorWebAssembly/.editorconfig b/samples/WebAppBlazorWebAssembly/.editorconfig new file mode 100644 index 0000000..3aa69ea --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/.editorconfig @@ -0,0 +1,2 @@ +[*.csproj] +indent_size = 2 \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/.gitattributes b/samples/WebAppBlazorWebAssembly/.gitattributes new file mode 100644 index 0000000..c941e52 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/.gitattributes @@ -0,0 +1 @@ +**/wwwroot/libs/** linguist-vendored diff --git a/samples/WebAppBlazorWebAssembly/.gitignore b/samples/WebAppBlazorWebAssembly/.gitignore new file mode 100644 index 0000000..042c08a --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/.gitignore @@ -0,0 +1,274 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +**/.idea/ +*.sln.iml + +# ABP Studio +**/.abpstudio/ + +# BookStore +src/BookStore.Web/Logs/* +src/BookStore.Web.Host/Logs/* +src/BookStore.Web.Public/Logs/* +src/BookStore.Web.Public.Host/Logs/* +src/BookStore.AuthServer/Logs/* +src/BookStore.HttpApi.Host/Logs/* +src/BookStore.HttpApi.Host/Logs/* +src/BookStore.DbMigrator/Logs/* +src/BookStore.Blazor.Server/Logs/* +src/BookStore.Blazor.Server.Tiered/Logs/* + +# Use abp install-libs to restore. +**/wwwroot/libs/* + +# IdentityServer temp files +tempkey.rsa +tempkey.jwk \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/BookStore.abpmdl b/samples/WebAppBlazorWebAssembly/BookStore.abpmdl new file mode 100644 index 0000000..e4aff21 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/BookStore.abpmdl @@ -0,0 +1,109 @@ +{ + "template": "app", + "imports": { + "Volo.Abp.LeptonXLiteTheme": { + "version": "4.2.0", + "isInstalled": true + }, + "Volo.Abp.Account": { + "version": "9.2.0", + "isInstalled": true + }, + "Volo.Abp.OpenIddict": { + "version": "9.2.0", + "isInstalled": true + }, + "Volo.Abp.Identity": { + "version": "9.2.0", + "isInstalled": true + }, + "Volo.Abp.TenantManagement": { + "version": "9.2.0", + "isInstalled": true + }, + "Volo.Abp.SettingManagement": { + "version": "9.2.0", + "isInstalled": true + }, + "Volo.Abp.PermissionManagement": { + "version": "9.2.0", + "isInstalled": true + }, + "Volo.Abp.FeatureManagement": { + "version": "9.2.0", + "isInstalled": true + } + }, + "folders": { + "items": { + "src": {}, + "test": {} + } + }, + "packages": { + "BookStore.Application": { + "path": "src/BookStore.Application/BookStore.Application.abppkg", + "folder": "src" + }, + "BookStore.Application.Tests": { + "path": "test/BookStore.Application.Tests/BookStore.Application.Tests.abppkg", + "folder": "test" + }, + "BookStore.MongoDB": { + "path": "src/BookStore.MongoDB/BookStore.MongoDB.abppkg", + "folder": "src" + }, + "BookStore.MongoDB.Tests": { + "path": "test/BookStore.MongoDB.Tests/BookStore.MongoDB.Tests.abppkg", + "folder": "test" + }, + "BookStore.Domain.Shared": { + "path": "src/BookStore.Domain.Shared/BookStore.Domain.Shared.abppkg", + "folder": "src" + }, + "BookStore.Application.Contracts": { + "path": "src/BookStore.Application.Contracts/BookStore.Application.Contracts.abppkg", + "folder": "src" + }, + "BookStore.HttpApi": { + "path": "src/BookStore.HttpApi/BookStore.HttpApi.abppkg", + "folder": "src" + }, + "BookStore.HttpApi.Client": { + "path": "src/BookStore.HttpApi.Client/BookStore.HttpApi.Client.abppkg", + "folder": "src" + }, + "BookStore.TestBase": { + "path": "test/BookStore.TestBase/BookStore.TestBase.abppkg", + "folder": "test" + }, + "BookStore.Domain.Tests": { + "path": "test/BookStore.Domain.Tests/BookStore.Domain.Tests.abppkg", + "folder": "test" + }, + "BookStore.HttpApi.Client.ConsoleTestApp": { + "path": "test/BookStore.HttpApi.Client.ConsoleTestApp/BookStore.HttpApi.Client.ConsoleTestApp.abppkg", + "folder": "test" + }, + "BookStore.DbMigrator": { + "path": "src/BookStore.DbMigrator/BookStore.DbMigrator.abppkg", + "folder": "src" + }, + "BookStore.HttpApi.Host": { + "path": "src/BookStore.HttpApi.Host/BookStore.HttpApi.Host.abppkg", + "folder": "src" + }, + "BookStore.Blazor": { + "path": "src/BookStore.Blazor/BookStore.Blazor.abppkg", + "folder": "src" + }, + "BookStore.Blazor.Client": { + "path": "src/BookStore.Blazor.Client/BookStore.Blazor.Client.abppkg", + "folder": "src" + }, + "BookStore.Domain": { + "path": "src/BookStore.Domain/BookStore.Domain.abppkg", + "folder": "src" + } + } +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/BookStore.abpsln b/samples/WebAppBlazorWebAssembly/BookStore.abpsln new file mode 100644 index 0000000..3b76ef0 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/BookStore.abpsln @@ -0,0 +1,53 @@ +{ + "id": "9776757a-16f5-4a1a-8449-62909978bb39", + "template": "app", + "versions": { + "AbpFramework": "9.2.0", + "AbpStudio": "1.0.1", + "TargetDotnetFramework": "net9.0" + }, + "modules": { + "BookStore": { + "path": "BookStore.abpmdl" + } + }, + "runProfiles": { + "Default": { + "path": "etc/abp-studio/run-profiles/Default.abprun.json" + } + }, + "options": { + "httpRequests": { + "ignoredUrls": [ + + ] + } + }, + "creatingStudioConfiguration": { + "template": "app", + "createdAbpStudioVersion": "1.0.1", + "tiered": "false", + "runInstallLibs": "true", + "runBundling": "true", + "useLocalReferences": "false", + "multiTenancy": "true", + "includeTests": "true", + "kubernetesConfiguration": "false", + "uiFramework": "blazor", + "mobileFramework": "none", + "distributedEventBus": "none", + "databaseProvider": "mongodb", + "runDbMigrator": "true", + "theme": "leptonx-lite", + "themeStyle": "", + "themeMenuPlacement": "", + "mobileFramework": "none", + "progressiveWebApp": "false", + "runProgressiveWebAppSupport": "false", + "publicWebsite": "false", + "socialLogin": "true", + "selectedLanguages": ["English", "English (United Kingdom)", "简体中文", "Español", "العربية", "हिन्दी", "Português (Brasil)", "Français", "Русский", "Deutsch (Deuthschland)", "Türkçe", "Italiano", "Čeština", "Magyar", "Română (România)", "Svenska", "Suomi", "Slovenčina", "Íslenska", "繁體中z文", ], + "defaultLanguage": "English", + "createCommand": "abp new BookStore -t app --ui-framework blazor --database-provider mongodb --theme leptonx-lite --skip-migration --without-cms-kit -no-file-management" + } +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/BookStore.sln b/samples/WebAppBlazorWebAssembly/BookStore.sln new file mode 100644 index 0000000..c5a1f62 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/BookStore.sln @@ -0,0 +1,137 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32611.2 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.Domain", "src\BookStore.Domain\BookStore.Domain.csproj", "{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.Application", "src\BookStore.Application\BookStore.Application.csproj", "{1A94A50E-06DC-43C1-80B5-B662820EC3EB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CA9AC87F-097E-4F15-8393-4BC07735A5B0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{04DBDB01-70F4-4E06-B468-8F87850B22BE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.Application.Tests", "test\BookStore.Application.Tests\BookStore.Application.Tests.csproj", "{50B2631D-129C-47B3-A587-029CCD6099BC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.MongoDB", "src\BookStore.MongoDB\BookStore.MongoDB.csproj", "{E3444355-D47E-431E-BDD0-DD3A7113B2AE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.Domain.Shared", "src\BookStore.Domain.Shared\BookStore.Domain.Shared.csproj", "{42F719ED-8413-4895-B5B4-5AB56079BC66}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.Application.Contracts", "src\BookStore.Application.Contracts\BookStore.Application.Contracts.csproj", "{520659C8-C734-4298-A3DA-B539DB9DFC0B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.HttpApi", "src\BookStore.HttpApi\BookStore.HttpApi.csproj", "{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.HttpApi.Client", "src\BookStore.HttpApi.Client\BookStore.HttpApi.Client.csproj", "{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.TestBase", "test\BookStore.TestBase\BookStore.TestBase.csproj", "{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.Domain.Tests", "test\BookStore.Domain.Tests\BookStore.Domain.Tests.csproj", "{E512F4D9-9375-480F-A2F6-A46509F9D824}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.MongoDB.Tests", "test\BookStore.MongoDB.Tests\BookStore.MongoDB.Tests.csproj", "{6015D17B-104B-4EC2-A9B7-D8A40C891458}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.HttpApi.Client.ConsoleTestApp", "test\BookStore.HttpApi.Client.ConsoleTestApp\BookStore.HttpApi.Client.ConsoleTestApp.csproj", "{EF480016-9127-4916-8735-D2466BDBC582}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.DbMigrator", "src\BookStore.DbMigrator\BookStore.DbMigrator.csproj", "{70680696-BB1E-4383-BCB2-42C3767171FB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.HttpApi.Host", "src\BookStore.HttpApi.Host\BookStore.HttpApi.Host.csproj", "{96E5259E-59A3-4FAF-BCD1-5BF8E74EF82C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.Blazor", "src\BookStore.Blazor\BookStore.Blazor.csproj", "{2DC842B5-1705-4097-AD37-E889C1B97950}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore.Blazor.Client", "src\BookStore.Blazor.Client\BookStore.Blazor.Client.csproj", "{9df63919-581a-488b-bfe3-0622a500a56c}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.Build.0 = Release|Any CPU + {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.Build.0 = Release|Any CPU + {50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.Build.0 = Release|Any CPU + {E3444355-D47E-431E-BDD0-DD3A7113B2AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E3444355-D47E-431E-BDD0-DD3A7113B2AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E3444355-D47E-431E-BDD0-DD3A7113B2AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E3444355-D47E-431E-BDD0-DD3A7113B2AE}.Release|Any CPU.Build.0 = Release|Any CPU + {42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.Build.0 = Release|Any CPU + {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.Build.0 = Release|Any CPU + {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.Build.0 = Release|Any CPU + {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.Build.0 = Release|Any CPU + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.Build.0 = Release|Any CPU + {E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.Build.0 = Release|Any CPU + {6015D17B-104B-4EC2-A9B7-D8A40C891458}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6015D17B-104B-4EC2-A9B7-D8A40C891458}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6015D17B-104B-4EC2-A9B7-D8A40C891458}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6015D17B-104B-4EC2-A9B7-D8A40C891458}.Release|Any CPU.Build.0 = Release|Any CPU + {EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.Build.0 = Release|Any CPU + {70680696-BB1E-4383-BCB2-42C3767171FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {70680696-BB1E-4383-BCB2-42C3767171FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {70680696-BB1E-4383-BCB2-42C3767171FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {70680696-BB1E-4383-BCB2-42C3767171FB}.Release|Any CPU.Build.0 = Release|Any CPU + {96E5259E-59A3-4FAF-BCD1-5BF8E74EF82C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96E5259E-59A3-4FAF-BCD1-5BF8E74EF82C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96E5259E-59A3-4FAF-BCD1-5BF8E74EF82C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96E5259E-59A3-4FAF-BCD1-5BF8E74EF82C}.Release|Any CPU.Build.0 = Release|Any CPU + {2DC842B5-1705-4097-AD37-E889C1B97950}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2DC842B5-1705-4097-AD37-E889C1B97950}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2DC842B5-1705-4097-AD37-E889C1B97950}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2DC842B5-1705-4097-AD37-E889C1B97950}.Release|Any CPU.Build.0 = Release|Any CPU + {9df63919-581a-488b-bfe3-0622a500a56c}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9df63919-581a-488b-bfe3-0622a500a56c}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9df63919-581a-488b-bfe3-0622a500a56c}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9df63919-581a-488b-bfe3-0622a500a56c}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {554AD327-6DBA-4F8F-96F8-81CE7A0C863F} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {1A94A50E-06DC-43C1-80B5-B662820EC3EB} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {50B2631D-129C-47B3-A587-029CCD6099BC} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {E3444355-D47E-431E-BDD0-DD3A7113B2AE} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {42F719ED-8413-4895-B5B4-5AB56079BC66} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {520659C8-C734-4298-A3DA-B539DB9DFC0B} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {4164BDF7-F527-4E85-9CE6-E3C2D7426A27} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {3B5A0094-670D-4BB1-BFDD-61B88A8773DC} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {E512F4D9-9375-480F-A2F6-A46509F9D824} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {6015D17B-104B-4EC2-A9B7-D8A40C891458} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {EF480016-9127-4916-8735-D2466BDBC582} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {70680696-BB1E-4383-BCB2-42C3767171FB} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {96E5259E-59A3-4FAF-BCD1-5BF8E74EF82C} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {2DC842B5-1705-4097-AD37-E889C1B97950} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {9df63919-581a-488b-bfe3-0622a500a56c} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} + EndGlobalSection +EndGlobal diff --git a/samples/WebAppBlazorWebAssembly/BookStore.sln.DotSettings b/samples/WebAppBlazorWebAssembly/BookStore.sln.DotSettings new file mode 100644 index 0000000..cb0b2c9 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/BookStore.sln.DotSettings @@ -0,0 +1,23 @@ + + True + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + Required + Required + Required + Required + False + True + False + False + True + False + False + SQL + \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/NuGet.Config b/samples/WebAppBlazorWebAssembly/NuGet.Config new file mode 100644 index 0000000..5107236 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/NuGet.Config @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/README.md b/samples/WebAppBlazorWebAssembly/README.md new file mode 100644 index 0000000..215b2d2 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/README.md @@ -0,0 +1,59 @@ +# BookStore + +## About this solution + +This is a layered startup solution based on [Domain Driven Design (DDD)](https://abp.io/docs/latest/framework/architecture/domain-driven-design) practises. All the fundamental ABP modules are already installed. Check the [Application Startup Template](https://abp.io/docs/latest/solution-templates/layered-web-application) documentation for more info. + +### Pre-requirements + +* [.NET9.0+ SDK](https://dotnet.microsoft.com/download/dotnet) +* [Node v18 or 20](https://nodejs.org/en) + +### Configurations + +The solution comes with a default configuration that works out of the box. However, you may consider to change the following configuration before running your solution: + +* Check the `ConnectionStrings` in `appsettings.json` files under the `BookStore.HttpApi.Host` and `BookStore.DbMigrator` projects and change it if you need. + +### Before running the application + +* Run `abp install-libs` command on your solution folder to install client-side package dependencies. This step is automatically done when you create a new solution, if you didn't especially disabled it. However, you should run it yourself if you have first cloned this solution from your source control, or added a new client-side package dependency to your solution. +* Run `BookStore.DbMigrator` to create the initial database. This step is also automatically done when you create a new solution, if you didn't especially disabled it. This should be done in the first run. It is also needed if a new database migration is added to the solution later. + +#### Generating a Signing Certificate + +In the production environment, you need to use a production signing certificate. ABP Framework sets up signing and encryption certificates in your application and expects an `openiddict.pfx` file in your application. + +To generate a signing certificate, you can use the following command: + +```bash +dotnet dev-certs https -v -ep openiddict.pfx -p 2dae3a4f-9e73-4cb7-b7b9-7ec95c44e1a3 +``` + +> `2dae3a4f-9e73-4cb7-b7b9-7ec95c44e1a3` is the password of the certificate, you can change it to any password you want. + +It is recommended to use **two** RSA certificates, distinct from the certificate(s) used for HTTPS: one for encryption, one for signing. + +For more information, please refer to: [OpenIddict Certificate Configuration](https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html#registering-a-certificate-recommended-for-production-ready-scenarios) + +> Also, see the [Configuring OpenIddict](https://abp.io/docs/latest/Deployment/Configuring-OpenIddict#production-environment) documentation for more information. + +### Solution structure + +This is a layered monolith application that consists of the following applications: + +* `BookStore.DbMigrator`: A console application which applies the migrations and also seeds the initial data. It is useful on development as well as on production environment. +* `BookStore.HttpApi.Host`: ASP.NET Core API application that is used to expose the APIs to the clients. +* `BookStore.Blazor`: ASP.NET Core Blazor Server application that is the essential web application of the solution. + + +## Deploying the application + +Deploying an ABP application follows the same process as deploying any .NET or ASP.NET Core application. However, there are important considerations to keep in mind. For detailed guidance, refer to ABP's [deployment documentation](https://abp.io/docs/latest/Deployment/Index). + +### Additional resources + +You can see the following resources to learn more about your solution and the ABP Framework: + +* [Web Application Development Tutorial](https://abp.io/docs/latest/tutorials/book-store/part-1) +* [Application Startup Template](https://abp.io/docs/latest/startup-templates/application/index) diff --git a/samples/WebAppBlazorWebAssembly/common.props b/samples/WebAppBlazorWebAssembly/common.props new file mode 100644 index 0000000..22d34c4 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/common.props @@ -0,0 +1,19 @@ + + + latest + 1.0.0 + $(NoWarn);CS1591 + app + + + + + $(NoWarn);0436 + + + + + + + + \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/etc/abp-studio/run-profiles/Default.abprun.json b/samples/WebAppBlazorWebAssembly/etc/abp-studio/run-profiles/Default.abprun.json new file mode 100644 index 0000000..1adf2f3 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/etc/abp-studio/run-profiles/Default.abprun.json @@ -0,0 +1,28 @@ +{ + "applications": { + "BookStore.HttpApi.Host": { + "type": "dotnet-project", + "launchUrl": "https://localhost:44318", + "path": "../../../src/BookStore.HttpApi.Host/BookStore.HttpApi.Host.csproj", + "kubernetesService": ".*-httpapihost$", + "healthCheckEndpoint": "/health-status", + "healthUiEndpoint": "/health-ui", + "execution": { + "order": 4 + } + }, + "BookStore.Blazor": { + "type": "dotnet-project", + "launchUrl": "https://localhost:44376", + "path": "../../../src/BookStore.Blazor/BookStore.Blazor.csproj", + "healthCheckEndpoint": "/", + "kubernetesService": ".*-blazor$", + "execution": { + "order": 2 + } + } + }, + "containers": { + "serviceName": "BookStore-Containers", + } +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStore.Application.Contracts.abppkg b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStore.Application.Contracts.abppkg new file mode 100644 index 0000000..4903279 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStore.Application.Contracts.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.application-contracts" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStore.Application.Contracts.abppkg.analyze.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStore.Application.Contracts.abppkg.analyze.json new file mode 100644 index 0000000..060ef71 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStore.Application.Contracts.abppkg.analyze.json @@ -0,0 +1,118 @@ +{ + "name": "BookStore.Application.Contracts", + "hash": "", + "contents": [ + { + "namespace": "BookStore", + "dependsOnModules": [ + { + "declaringAssemblyName": "BookStore.Domain.Shared", + "namespace": "BookStore", + "name": "BookStoreDomainSharedModule" + }, + { + "declaringAssemblyName": "Volo.Abp.FeatureManagement.Application.Contracts", + "namespace": "Volo.Abp.FeatureManagement", + "name": "AbpFeatureManagementApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.SettingManagement.Application.Contracts", + "namespace": "Volo.Abp.SettingManagement", + "name": "AbpSettingManagementApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Identity.Pro.Application.Contracts", + "namespace": "Volo.Abp.Identity", + "name": "AbpIdentityApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Account.Pro.Public.Application.Contracts", + "namespace": "Volo.Abp.Account", + "name": "AbpAccountPublicApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Account.Pro.Admin.Application.Contracts", + "namespace": "Volo.Abp.Account", + "name": "AbpAccountAdminApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.AuditLogging.Application.Contracts", + "namespace": "Volo.Abp.AuditLogging", + "name": "AbpAuditLoggingApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.OpenIddict.Pro.Application.Contracts", + "namespace": "Volo.Abp.OpenIddict", + "name": "AbpOpenIddictProApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.TextTemplateManagement.Application.Contracts", + "namespace": "Volo.Abp.TextTemplateManagement", + "name": "TextTemplateManagementApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.LanguageManagement.Application.Contracts", + "namespace": "Volo.Abp.LanguageManagement", + "name": "LanguageManagementApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Gdpr.Application.Contracts", + "namespace": "Volo.Abp.Gdpr", + "name": "AbpGdprApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.PermissionManagement.Application.Contracts", + "namespace": "Volo.Abp.PermissionManagement", + "name": "AbpPermissionManagementApplicationContractsModule" + } + ], + "implementingInterfaces": [ + { + "name": "IAbpModule", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IAbpModule" + }, + { + "name": "IOnPreApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPreApplicationInitialization" + }, + { + "name": "IOnApplicationInitialization", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationInitialization" + }, + { + "name": "IOnPostApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPostApplicationInitialization" + }, + { + "name": "IOnApplicationShutdown", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationShutdown" + }, + { + "name": "IPreConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPreConfigureServices" + }, + { + "name": "IPostConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPostConfigureServices" + } + ], + "contentType": "abpModule", + "name": "BookStoreApplicationContractsModule", + "summary": null + } + ] +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStore.Application.Contracts.csproj b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStore.Application.Contracts.csproj new file mode 100644 index 0000000..1041e77 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStore.Application.Contracts.csproj @@ -0,0 +1,24 @@ + + + + + + net9.0 + enable + BookStore + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStoreApplicationContractsModule.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStoreApplicationContractsModule.cs new file mode 100644 index 0000000..7bab31b --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStoreApplicationContractsModule.cs @@ -0,0 +1,26 @@ +using Volo.Abp.Account; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement; +using Volo.Abp.SettingManagement; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Identity; +using Volo.Abp.TenantManagement; + +namespace BookStore; + +[DependsOn( + typeof(BookStoreDomainSharedModule), + typeof(AbpFeatureManagementApplicationContractsModule), + typeof(AbpSettingManagementApplicationContractsModule), + typeof(AbpIdentityApplicationContractsModule), + typeof(AbpAccountApplicationContractsModule), + typeof(AbpTenantManagementApplicationContractsModule), + typeof(AbpPermissionManagementApplicationContractsModule) +)] +public class BookStoreApplicationContractsModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + BookStoreDtoExtensions.Configure(); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStoreDtoExtensions.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStoreDtoExtensions.cs new file mode 100644 index 0000000..7030268 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/BookStoreDtoExtensions.cs @@ -0,0 +1,28 @@ +using Volo.Abp.Identity; +using Volo.Abp.ObjectExtending; +using Volo.Abp.Threading; + +namespace BookStore; + +public static class BookStoreDtoExtensions +{ + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + public static void Configure() + { + OneTimeRunner.Run(() => + { + /* You can add extension properties to DTOs + * defined in the depended modules. + * + * Example: + * + * ObjectExtensionManager.Instance + * .AddOrUpdateProperty("Title"); + * + * See the documentation for more: + * https://docs.abp.io/en/abp/latest/Object-Extensions + */ + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/Permissions/BookStorePermissionDefinitionProvider.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/Permissions/BookStorePermissionDefinitionProvider.cs new file mode 100644 index 0000000..25b8f87 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/Permissions/BookStorePermissionDefinitionProvider.cs @@ -0,0 +1,22 @@ +using BookStore.Localization; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; + +namespace BookStore.Permissions; + +public class BookStorePermissionDefinitionProvider : PermissionDefinitionProvider +{ + public override void Define(IPermissionDefinitionContext context) + { + var myGroup = context.AddGroup(BookStorePermissions.GroupName); + + //Define your own permissions here. Example: + //myGroup.AddPermission(BookStorePermissions.MyPermission1, L("Permission:MyPermission1")); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/Permissions/BookStorePermissions.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/Permissions/BookStorePermissions.cs new file mode 100644 index 0000000..01445cb --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application.Contracts/Permissions/BookStorePermissions.cs @@ -0,0 +1,11 @@ +namespace BookStore.Permissions; + +public static class BookStorePermissions +{ + public const string GroupName = "BookStore"; + + + + //Add your own permission names. Example: + //public const string MyPermission1 = GroupName + ".MyPermission1"; +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStore.Application.abppkg b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStore.Application.abppkg new file mode 100644 index 0000000..412567a --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStore.Application.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.application" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStore.Application.abppkg.analyze.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStore.Application.abppkg.analyze.json new file mode 100644 index 0000000..db859aa --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStore.Application.abppkg.analyze.json @@ -0,0 +1,123 @@ +{ + "name": "BookStore.Application", + "hash": "", + "contents": [ + { + "namespace": "BookStore", + "dependsOnModules": [ + { + "declaringAssemblyName": "BookStore.Domain", + "namespace": "BookStore", + "name": "BookStoreDomainModule" + }, + { + "declaringAssemblyName": "BookStore.Application.Contracts", + "namespace": "BookStore", + "name": "BookStoreApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.PermissionManagement.Application", + "namespace": "Volo.Abp.PermissionManagement", + "name": "AbpPermissionManagementApplicationModule" + }, + { + "declaringAssemblyName": "Volo.Abp.FeatureManagement.Application", + "namespace": "Volo.Abp.FeatureManagement", + "name": "AbpFeatureManagementApplicationModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Identity.Pro.Application", + "namespace": "Volo.Abp.Identity", + "name": "AbpIdentityApplicationModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Account.Pro.Public.Application", + "namespace": "Volo.Abp.Account", + "name": "AbpAccountPublicApplicationModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Account.Pro.Admin.Application", + "namespace": "Volo.Abp.Account", + "name": "AbpAccountAdminApplicationModule" + }, + { + "declaringAssemblyName": "Volo.Abp.AuditLogging.Application", + "namespace": "Volo.Abp.AuditLogging", + "name": "AbpAuditLoggingApplicationModule" + }, + { + "declaringAssemblyName": "Volo.Abp.TextTemplateManagement.Application", + "namespace": "Volo.Abp.TextTemplateManagement", + "name": "TextTemplateManagementApplicationModule" + }, + { + "declaringAssemblyName": "Volo.Abp.OpenIddict.Pro.Application", + "namespace": "Volo.Abp.OpenIddict", + "name": "AbpOpenIddictProApplicationModule" + }, + { + "declaringAssemblyName": "Volo.Abp.LanguageManagement.Application", + "namespace": "Volo.Abp.LanguageManagement", + "name": "LanguageManagementApplicationModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Gdpr.Application", + "namespace": "Volo.Abp.Gdpr", + "name": "AbpGdprApplicationModule" + }, + { + "declaringAssemblyName": "Volo.Abp.SettingManagement.Application", + "namespace": "Volo.Abp.SettingManagement", + "name": "AbpSettingManagementApplicationModule" + } + ], + "implementingInterfaces": [ + { + "name": "IAbpModule", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IAbpModule" + }, + { + "name": "IOnPreApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPreApplicationInitialization" + }, + { + "name": "IOnApplicationInitialization", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationInitialization" + }, + { + "name": "IOnPostApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPostApplicationInitialization" + }, + { + "name": "IOnApplicationShutdown", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationShutdown" + }, + { + "name": "IPreConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPreConfigureServices" + }, + { + "name": "IPostConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPostConfigureServices" + } + ], + "contentType": "abpModule", + "name": "BookStoreApplicationModule", + "summary": null + } + ] +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStore.Application.csproj b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStore.Application.csproj new file mode 100644 index 0000000..b0ae1c8 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStore.Application.csproj @@ -0,0 +1,25 @@ + + + + + + net9.0 + enable + BookStore + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStoreAppService.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStoreAppService.cs new file mode 100644 index 0000000..2f12e97 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStoreAppService.cs @@ -0,0 +1,14 @@ +using BookStore.Localization; +using Volo.Abp.Application.Services; + +namespace BookStore; + +/* Inherit your application services from this class. + */ +public abstract class BookStoreAppService : ApplicationService +{ + protected BookStoreAppService() + { + LocalizationResource = typeof(BookStoreResource); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStoreApplicationAutoMapperProfile.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStoreApplicationAutoMapperProfile.cs new file mode 100644 index 0000000..8c6108c --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStoreApplicationAutoMapperProfile.cs @@ -0,0 +1,13 @@ +using AutoMapper; + +namespace BookStore; + +public class BookStoreApplicationAutoMapperProfile : Profile +{ + public BookStoreApplicationAutoMapperProfile() + { + /* You can configure your AutoMapper mapping configuration here. + * Alternatively, you can split your mapping configurations + * into multiple profile classes for a better organization. */ + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStoreApplicationModule.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStoreApplicationModule.cs new file mode 100644 index 0000000..add2aeb --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/BookStoreApplicationModule.cs @@ -0,0 +1,31 @@ +using Volo.Abp.PermissionManagement; +using Volo.Abp.SettingManagement; +using Volo.Abp.Account; +using Volo.Abp.Identity; +using Volo.Abp.AutoMapper; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Modularity; +using Volo.Abp.TenantManagement; + +namespace BookStore; + +[DependsOn( + typeof(BookStoreDomainModule), + typeof(BookStoreApplicationContractsModule), + typeof(AbpPermissionManagementApplicationModule), + typeof(AbpFeatureManagementApplicationModule), + typeof(AbpIdentityApplicationModule), + typeof(AbpAccountApplicationModule), + typeof(AbpTenantManagementApplicationModule), + typeof(AbpSettingManagementApplicationModule) + )] +public class BookStoreApplicationModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.AddMaps(); + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Application/Properties/AssemblyInfo.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..35a2447 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Application/Properties/AssemblyInfo.cs @@ -0,0 +1,2 @@ +using System.Runtime.CompilerServices; +[assembly:InternalsVisibleToAttribute("BookStore.Application.Tests")] diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStore.Blazor.Client.abppkg b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStore.Blazor.Client.abppkg new file mode 100644 index 0000000..6a7cb4b --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStore.Blazor.Client.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.blazor-wasm-client" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStore.Blazor.Client.csproj b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStore.Blazor.Client.csproj new file mode 100644 index 0000000..384a08c --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStore.Blazor.Client.csproj @@ -0,0 +1,38 @@ + + + + + + net9.0 + enable + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStoreBlazorAutoMapperProfile.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStoreBlazorAutoMapperProfile.cs new file mode 100644 index 0000000..058f1fb --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStoreBlazorAutoMapperProfile.cs @@ -0,0 +1,11 @@ +using AutoMapper; + +namespace BookStore.Blazor.Client; + +public class BookStoreBlazorAutoMapperProfile : Profile +{ + public BookStoreBlazorAutoMapperProfile() + { + //Define your AutoMapper configuration here for the Blazor project. + } +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStoreBlazorClientModule.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStoreBlazorClientModule.cs new file mode 100644 index 0000000..c0f0e94 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStoreBlazorClientModule.cs @@ -0,0 +1,112 @@ +using System; +using System.Net.Http; +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using BookStore.Blazor.Client.Navigation; +using Localization.Resources.AbpUi; +using Volo.Abp.Localization; +using BookStore.Localization; +using Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Routing; +using Lsw.Abp.AspnetCore.Components.WebAssembly.AntDesignTheme; +using Lsw.Abp.FeatureManagement.Blazor.WebAssembly.AntDesignUI; +using Lsw.Abp.IdentityManagement.Blazor.WebAssembly.AntDesignUI; +using Lsw.Abp.SettingManagement.Blazor.WebAssembly.AntDesignUI; +using Lsw.Abp.TenantManagement.Blazor.WebAssembly.AntDesignUI; +using OpenIddict.Abstractions; +using Volo.Abp.Autofac.WebAssembly; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; +using Volo.Abp.UI.Navigation; + +namespace BookStore.Blazor.Client; + +[DependsOn( + typeof(AbpAutofacWebAssemblyModule), + typeof(AbpIdentityBlazorWebAssemblyAntDesignModule), + typeof(AbpSettingManagementBlazorWebAssemblyAntDesignModule), + typeof(AbpFeatureManagementBlazorWebAssemblyAntDesignModule), + typeof(AbpTenantManagementBlazorWebAssemblyAntDesignModule), + typeof(AbpAspNetCoreComponentsWebAssemblyAntDesignThemeModule), + typeof(BookStoreHttpApiClientModule) +)] +public class BookStoreBlazorClientModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + var environment = context.Services.GetSingletonInstance(); + var builder = context.Services.GetSingletonInstance(); + + ConfigureLocalization(); + ConfigureAuthentication(builder); + ConfigureHttpClient(context, environment); + //ConfigureBlazorise(context); + ConfigureRouter(context); + ConfigureMenu(context); + ConfigureAutoMapper(context); + } + + private void ConfigureLocalization() + { + Configure(options => + { + options.Resources + .Get() + .AddBaseTypes(typeof(AbpUiResource)); + }); + } + + private void ConfigureRouter(ServiceConfigurationContext context) + { + Configure(options => + { + options.AppAssembly = typeof(BookStoreBlazorClientModule).Assembly; + }); + } + + private void ConfigureMenu(ServiceConfigurationContext context) + { + Configure(options => + { + options.MenuContributors.Add(new BookStoreMenuContributor(context.Services.GetConfiguration())); + }); + } + + // private void ConfigureBlazorise(ServiceConfigurationContext context) + // { + // context.Services + // .AddBootstrap5Providers() + // .AddFontAwesomeIcons(); + // } + + private static void ConfigureAuthentication(WebAssemblyHostBuilder builder) + { + builder.Services.AddOidcAuthentication(options => + { + builder.Configuration.Bind("AuthServer", options.ProviderOptions); + options.UserOptions.NameClaim = OpenIddictConstants.Claims.Name; + options.UserOptions.RoleClaim = OpenIddictConstants.Claims.Role; + + options.ProviderOptions.DefaultScopes.Add("BookStore"); + options.ProviderOptions.DefaultScopes.Add("roles"); + options.ProviderOptions.DefaultScopes.Add("email"); + options.ProviderOptions.DefaultScopes.Add("phone"); + }); + } + + private static void ConfigureHttpClient(ServiceConfigurationContext context, IWebAssemblyHostEnvironment environment) + { + context.Services.AddTransient(sp => new HttpClient + { + BaseAddress = new Uri(environment.BaseAddress) + }); + } + + private void ConfigureAutoMapper(ServiceConfigurationContext context) + { + Configure(options => + { + options.AddMaps(); + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStoreBrandingProvider.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStoreBrandingProvider.cs new file mode 100644 index 0000000..4a47f52 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStoreBrandingProvider.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.Localization; +using BookStore.Localization; +using Microsoft.Extensions.Localization; +using BookStore.Localization; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Ui.Branding; + +namespace BookStore.Blazor.Client; + +[Dependency(ReplaceServices = true)] +public class BookStoreBrandingProvider : DefaultBrandingProvider +{ + private IStringLocalizer _localizer; + + public BookStoreBrandingProvider(IStringLocalizer localizer) + { + _localizer = localizer; + } + + public override string AppName => _localizer["AppName"]; +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStoreComponentBase.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStoreComponentBase.cs new file mode 100644 index 0000000..3857592 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/BookStoreComponentBase.cs @@ -0,0 +1,12 @@ +using BookStore.Localization; +using Volo.Abp.AspNetCore.Components; + +namespace BookStore.Blazor.Client; + +public abstract class BookStoreComponentBase : AbpComponentBase +{ + protected BookStoreComponentBase() + { + LocalizationResource = typeof(BookStoreResource); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Navigation/BookStoreMenuContributor.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Navigation/BookStoreMenuContributor.cs new file mode 100644 index 0000000..cc71052 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Navigation/BookStoreMenuContributor.cs @@ -0,0 +1,81 @@ +using System; +using System.Threading.Tasks; +using AntDesign; +using Microsoft.Extensions.Configuration; +using BookStore.Localization; +using BookStore.Permissions; +using BookStore.MultiTenancy; +using Lsw.Abp.IdentityManagement.Blazor.AntDesignUI; +using Lsw.Abp.SettingManagement.Blazor.AntDesignUI; +using Lsw.Abp.TenantManagement.Blazor.AntDesignUI; +using Volo.Abp.Account.Localization; +using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; + +namespace BookStore.Blazor.Client.Navigation; + +public class BookStoreMenuContributor : IMenuContributor +{ + private readonly IConfiguration _configuration; + + public BookStoreMenuContributor(IConfiguration configuration) + { + _configuration = configuration; + } + + public async Task ConfigureMenuAsync(MenuConfigurationContext context) + { + if (context.Menu.Name == StandardMenus.Main) + { + await ConfigureMainMenuAsync(context); + } + else if (context.Menu.Name == StandardMenus.User) + { + await ConfigureUserMenuAsync(context); + } + } + + private static async Task ConfigureMainMenuAsync(MenuConfigurationContext context) + { + var l = context.GetLocalizer(); + + //Administration + var administration = context.Menu.GetAdministration(); + administration.Order = 6; + + context.Menu.AddItem(new ApplicationMenuItem( + BookStoreMenus.Home, + l["Menu:Home"], + "/", + icon: IconType.Outline.Home, + order: 1 + )); + if (MultiTenancyConsts.IsEnabled) + { + administration.SetSubItemOrder(TenantManagementMenuNames.GroupName, 1); + } + else + { + administration.TryRemoveMenuItem(TenantManagementMenuNames.GroupName); + } + + administration.SetSubItemOrder(IdentityMenuNames.GroupName, 2); + administration.SetSubItemOrder(SettingManagementMenus.GroupName, 3); + } + + private async Task ConfigureUserMenuAsync(MenuConfigurationContext context) + { + var accountStringLocalizer = context.GetLocalizer(); + var authServerUrl = _configuration["AuthServer:Authority"] ?? ""; + + context.Menu.AddItem(new ApplicationMenuItem( + "Account.Manage", + accountStringLocalizer["MyAccount"], + $"{authServerUrl.EnsureEndsWith('/')}Account/Manage", + icon: IconType.Outline.Setting, + order: 1000, + target: "_blank").RequireAuthenticated()); + + await Task.CompletedTask; + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Navigation/BookStoreMenus.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Navigation/BookStoreMenus.cs new file mode 100644 index 0000000..02cd3c0 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Navigation/BookStoreMenus.cs @@ -0,0 +1,8 @@ +namespace BookStore.Blazor.Client.Navigation; + +public class BookStoreMenus +{ + private const string Prefix = "BookStore"; + + public const string Home = Prefix + ".Home"; +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Pages/Index.razor b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Pages/Index.razor new file mode 100644 index 0000000..93e5b20 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Pages/Index.razor @@ -0,0 +1,17 @@ +@page "/" +@inherits BookStoreComponentBase + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Pages/Index.razor.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Pages/Index.razor.cs new file mode 100644 index 0000000..affed1d --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Pages/Index.razor.cs @@ -0,0 +1,6 @@ +namespace BookStore.Blazor.Client.Pages; + +public partial class Index +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Pages/Index.razor.css b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Pages/Index.razor.css new file mode 100644 index 0000000..4ef771b --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Pages/Index.razor.css @@ -0,0 +1,17 @@ +/* Getting-Started */ +.card-bg-image { + pointer-events: none; + position: absolute; + width: 630px; + height: auto; + bottom: 0; + right: 0; + z-index: 1; +} +.starting-content { + position: relative; + z-index: 2; +} +/* Getting-Started End */ + +/* Write here your styles for the Index page */ \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Program.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Program.cs new file mode 100644 index 0000000..788e5ee --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Program.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; + +namespace BookStore.Blazor.Client; + +public class Program +{ + public async static Task Main(string[] args) + { + var builder = WebAssemblyHostBuilder.CreateDefault(args); + + var application = await builder.AddApplicationAsync(options => + { + options.UseAutofac(); + }); + + var host = builder.Build(); + + await application.InitializeApplicationAsync(host.Services); + + await host.RunAsync(); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Routes.razor b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Routes.razor new file mode 100644 index 0000000..7e128b7 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/Routes.razor @@ -0,0 +1,14 @@ +@using Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Routing +@using Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Themes.AntDesignTheme +@using Microsoft.Extensions.Options +@using Volo.Abp.AspNetCore.Components.WebAssembly.WebApp + + + + + + + + + + \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/_Imports.razor b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/_Imports.razor new file mode 100644 index 0000000..c882df1 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/_Imports.razor @@ -0,0 +1,16 @@ +@using System.Net.Http +@using Microsoft.AspNetCore.Components.Authorization +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.WebAssembly.Http +@using static Microsoft.AspNetCore.Components.Web.RenderMode +@using Microsoft.JSInterop +@using Volo.Abp.AspNetCore.Components +@using Volo.Abp.AspNetCore.Components.WebAssembly +@using BookStore.Blazor.Client +@using AntDesign +@using Lsw.Abp.AntDesignUI +@using Lsw.Abp.AntDesignUI.Components +@using Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Layout +@using Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Bundling \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/appsettings.Development.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/appsettings.Development.json new file mode 100644 index 0000000..0db3279 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/appsettings.Development.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/appsettings.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/appsettings.json new file mode 100644 index 0000000..249e3b7 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/appsettings.json @@ -0,0 +1,18 @@ +{ + "App": { + "SelfUrl": "https://localhost:44376" + }, + "AuthServer": { + "Authority": "https://localhost:44318", + "ClientId": "BookStore_Blazor", + "ResponseType": "code" + }, + "RemoteServices": { + "Default": { + "BaseUrl": "https://localhost:44318" + }, + "AbpAccountPublic": { + "BaseUrl": "https://localhost:44318" + } + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/favicon.ico b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/favicon.ico new file mode 100644 index 0000000..450151f Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/favicon.ico differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/icon-192.png b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/icon-192.png new file mode 100644 index 0000000..166f56d Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/icon-192.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/icon-512.png b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/icon-512.png new file mode 100644 index 0000000..c2dd484 Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/icon-512.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/bg-01.png b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/bg-01.png new file mode 100644 index 0000000..ac6b323 Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/bg-01.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/book.png b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/book.png new file mode 100644 index 0000000..58afe9e Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/book.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/discord.svg b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/discord.svg new file mode 100644 index 0000000..3b03f76 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/discord.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/img-blog.png b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/img-blog.png new file mode 100644 index 0000000..37fc5be Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/img-blog.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/img-community.png b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/img-community.png new file mode 100644 index 0000000..e9d9671 Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/img-community.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/img-support.png b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/img-support.png new file mode 100644 index 0000000..27f4f13 Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/img-support.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/instagram.svg b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/instagram.svg new file mode 100644 index 0000000..f13e484 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/instagram.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/stack-overflow.svg b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/stack-overflow.svg new file mode 100644 index 0000000..2b09789 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/stack-overflow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/x-white.svg b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/x-white.svg new file mode 100644 index 0000000..38b09ee --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/x-white.svg @@ -0,0 +1,3 @@ + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/youtube.svg b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/youtube.svg new file mode 100644 index 0000000..1d38b17 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/getting-started/youtube.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/logo/leptonxlite/logo-dark-thumbnail.png b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/logo/leptonxlite/logo-dark-thumbnail.png new file mode 100644 index 0000000..9734a07 Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/logo/leptonxlite/logo-dark-thumbnail.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/logo/leptonxlite/logo-dark.png b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/logo/leptonxlite/logo-dark.png new file mode 100644 index 0000000..a3bbe82 Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/logo/leptonxlite/logo-dark.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/logo/leptonxlite/logo-light-thumbnail.png b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/logo/leptonxlite/logo-light-thumbnail.png new file mode 100644 index 0000000..ca39184 Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/logo/leptonxlite/logo-light-thumbnail.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/logo/leptonxlite/logo-light.png b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/logo/leptonxlite/logo-light.png new file mode 100644 index 0000000..761fb44 Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/images/logo/leptonxlite/logo-light.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/main.css b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/main.css new file mode 100644 index 0000000..09b3585 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/main.css @@ -0,0 +1,45 @@ +/* + loader +*/ +.loader { + position: fixed; + top: 0; + right: 0; + left: 0; + bottom: 0; + width: 100vw; + height: 100vh; + z-index: 999; + background-color: #f1f1f2; + } + +#ApplicationContainer > div:first-child:not(:only-child) { + display: none !important; +} + +#blazor-error-ui { + background: lightyellow; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); + display: none; + left: 0; + padding: 0.6rem 1.25rem 0.7rem 1.25rem; + position: fixed; + width: 100%; + z-index: 1000; +} + +#blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; +} + +:root { + --lpx-logo: url('/images/logo/leptonxlite/logo-light.png'); + --lpx-logo-icon: url('/images/logo/leptonxlite/logo-light-thumbnail.png'); +} +:root .abp-account-layout .lpx-brand-logo{ + --lpx-logo: url('/images/logo/leptonxlite/logo-dark.png'); +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/manifest.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/manifest.json new file mode 100644 index 0000000..89e5235 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/manifest.json @@ -0,0 +1,21 @@ +{ + "name": "BookStore", + "short_name": "BookStore", + "start_url": "./", + "display": "standalone", + "background_color": "#ffffff", + "theme_color": "#03173d", + "prefer_related_applications": false, + "icons": [ + { + "src": "icon-512.png", + "type": "image/png", + "sizes": "512x512" + }, + { + "src": "icon-192.png", + "type": "image/png", + "sizes": "192x192" + } + ] +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/service-worker.js b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/service-worker.js new file mode 100644 index 0000000..fe614da --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/service-worker.js @@ -0,0 +1,4 @@ +// In development, always fetch from the network and do not enable offline support. +// This is because caching would make development more difficult (changes would not +// be reflected on the first load after each change). +self.addEventListener('fetch', () => { }); diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/service-worker.published.js b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/service-worker.published.js new file mode 100644 index 0000000..0d9986f --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor.Client/wwwroot/service-worker.published.js @@ -0,0 +1,48 @@ +// Caution! Be sure you understand the caveats before publishing an application with +// offline support. See https://aka.ms/blazor-offline-considerations + +self.importScripts('./service-worker-assets.js'); +self.addEventListener('install', event => event.waitUntil(onInstall(event))); +self.addEventListener('activate', event => event.waitUntil(onActivate(event))); +self.addEventListener('fetch', event => event.respondWith(onFetch(event))); + +const cacheNamePrefix = 'offline-cache-'; +const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`; +const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ]; +const offlineAssetsExclude = [ /^service-worker\.js$/ ]; + +async function onInstall(event) { + console.info('Service worker: Install'); + + // Fetch and cache all matching items from the assets manifest + const assetsRequests = self.assetsManifest.assets + .filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url))) + .filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url))) + .map(asset => new Request(asset.url, { integrity: asset.hash, cache: 'no-cache' })); + await caches.open(cacheName).then(cache => cache.addAll(assetsRequests)); +} + +async function onActivate(event) { + console.info('Service worker: Activate'); + + // Delete unused caches + const cacheKeys = await caches.keys(); + await Promise.all(cacheKeys + .filter(key => key.startsWith(cacheNamePrefix) && key !== cacheName) + .map(key => caches.delete(key))); +} + +async function onFetch(event) { + let cachedResponse = null; + if (event.request.method === 'GET') { + // For all navigation requests, try to serve index.html from cache + // If you need some URLs to be server-rendered, edit the following check to exclude those URLs + const shouldServeIndexHtml = event.request.mode === 'navigate'; + + const request = shouldServeIndexHtml ? 'index.html' : event.request; + const cache = await caches.open(cacheName); + cachedResponse = await cache.match(request); + } + + return cachedResponse || fetch(event.request); +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStore.Blazor.abppkg b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStore.Blazor.abppkg new file mode 100644 index 0000000..7d929dc --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStore.Blazor.abppkg @@ -0,0 +1,3 @@ +{ + "role": "host.blazor-wasm" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStore.Blazor.csproj b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStore.Blazor.csproj new file mode 100644 index 0000000..788f3ca --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStore.Blazor.csproj @@ -0,0 +1,27 @@ + + + + + + net9.0 + enable + enable + + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStoreBlazorModule.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStoreBlazorModule.cs new file mode 100644 index 0000000..2f95902 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStoreBlazorModule.cs @@ -0,0 +1,76 @@ +using BookStore.Blazor.Components; +using BookStore.Blazor.Client; +using Lsw.Abp.AspnetCore.Components.WebAssembly.AntDesignTheme.Bundling; +using Volo.Abp; +using Volo.Abp.AspNetCore.Components.WebAssembly.WebApp; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.Libs; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace BookStore.Blazor; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(AbpAspNetCoreComponentsWebAssemblyAntDesignThemeBundlingModule), + typeof(AbpAspNetCoreMvcUiBundlingModule) +)] +public class BookStoreBlazorModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + //https://github.com/dotnet/aspnetcore/issues/52530 + Configure(options => + { + options.SuppressCheckForUnhandledSecurityMetadata = true; + }); + + // Add services to the container. + context.Services.AddRazorComponents() + .AddInteractiveWebAssemblyComponents(); + + Configure(options => + { + options.CheckLibs = false; + }); + + Configure(options => + { + var globalStyles = options.StyleBundles.Get(BlazorWebAssemblyStandardBundles.Styles.Global); + globalStyles.AddContributors(typeof(BookStoreStyleBundleContributor)); + + var globalScripts = options.ScriptBundles.Get(BlazorWebAssemblyStandardBundles.Scripts.Global); + globalScripts.AddContributors(typeof(BookStoreScriptBundleContributor)); + + }); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var env = context.GetEnvironment(); + var app = context.GetApplicationBuilder(); + + // Configure the HTTP request pipeline. + if (env.IsDevelopment()) + { + app.UseWebAssemblyDebugging(); + } + else + { + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); + } + + app.UseHttpsRedirection(); + app.UseRouting(); + app.MapAbpStaticAssets(); + app.UseAntiforgery(); + + app.UseConfiguredEndpoints(builder => + { + builder.MapRazorComponents() + .AddInteractiveWebAssemblyRenderMode() + .AddAdditionalAssemblies(WebAppAdditionalAssembliesHelper.GetAssemblies()); + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStoreScriptBundleContributor.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStoreScriptBundleContributor.cs new file mode 100644 index 0000000..28f3c69 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStoreScriptBundleContributor.cs @@ -0,0 +1,11 @@ +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; + +namespace BookStore.Blazor; + +public class BookStoreScriptBundleContributor : BundleContributor +{ + public override void ConfigureBundle(BundleConfigurationContext context) + { + + } +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStoreStyleBundleContributor.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStoreStyleBundleContributor.cs new file mode 100644 index 0000000..9cfa18b --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/BookStoreStyleBundleContributor.cs @@ -0,0 +1,11 @@ +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; + +namespace BookStore.Blazor; + +public class BookStoreStyleBundleContributor : BundleContributor +{ + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.Add(new BundleFile("main.css", true)); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Components/App.razor b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Components/App.razor new file mode 100644 index 0000000..11704dc --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Components/App.razor @@ -0,0 +1,38 @@ + + + + + + + MyCompanyName + + + + + + + @* *@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Dockerfile b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Dockerfile new file mode 100644 index 0000000..1bd4eef --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Dockerfile @@ -0,0 +1,5 @@ +FROM mcr.microsoft.com/dotnet/aspnet:9.0 +COPY bin/Release/net9.0/publish/ app/ +WORKDIR /app +ENV ASPNETCORE_URLS=http://+:80 +ENTRYPOINT ["dotnet", "BookStore.Blazor.dll"] \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Dockerfile.local b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Dockerfile.local new file mode 100644 index 0000000..a550a69 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Dockerfile.local @@ -0,0 +1,8 @@ +FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS build +USER $APP_UID +EXPOSE 8080 +EXPOSE 8081 + +COPY bin/Release/net9.0/publish/ app/ +WORKDIR /app +ENTRYPOINT ["dotnet", "BookStore.Blazor.dll"] \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Program.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Program.cs new file mode 100644 index 0000000..a23d781 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Program.cs @@ -0,0 +1,56 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using BookStore.Blazor; +using Serilog; +using Serilog.Events; + +namespace BookStore.Blazor; + +public class Program +{ + public async static Task Main(string[] args) + { + Log.Logger = new LoggerConfiguration() +#if DEBUG + .MinimumLevel.Debug() +#else + .MinimumLevel.Information() +#endif + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .Enrich.FromLogContext() + .WriteTo.Async(c => c.File("Logs/logs.txt")) + .WriteTo.Async(c => c.Console()) + .CreateLogger(); + + try + { + Log.Information("Starting web host."); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.AddApplicationAsync(); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); + return 0; + } + catch (Exception ex) + { + if (ex is HostAbortedException) + { + throw; + } + + Log.Fatal(ex, "Host terminated unexpectedly!"); + return 1; + } + finally + { + Log.CloseAndFlush(); + } + } +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Properties/launchSettings.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Properties/launchSettings.json new file mode 100644 index 0000000..c6d36bf --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/Properties/launchSettings.json @@ -0,0 +1,29 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "https://localhost:44376", + "sslPort": 44376 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "BookStore.Blazor": { + "commandName": "Project", + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "https://localhost:44376", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/_Imports.razor b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/_Imports.razor new file mode 100644 index 0000000..b954cf0 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Blazor/_Imports.razor @@ -0,0 +1,9 @@ +@using System.Net.Http +@using System.Net.Http.Json +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using static Microsoft.AspNetCore.Components.Web.RenderMode +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop +@using BookStore.Blazor.Client \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/BookStore.DbMigrator.abppkg b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/BookStore.DbMigrator.abppkg new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/BookStore.DbMigrator.abppkg @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/BookStore.DbMigrator.csproj b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/BookStore.DbMigrator.csproj new file mode 100644 index 0000000..f02d482 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/BookStore.DbMigrator.csproj @@ -0,0 +1,46 @@ + + + + + + Exe + net9.0 + enable + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + Always + + + + PreserveNewest + Always + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/BookStoreDbMigratorModule.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/BookStoreDbMigratorModule.cs new file mode 100644 index 0000000..05a84e5 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/BookStoreDbMigratorModule.cs @@ -0,0 +1,14 @@ +using BookStore.MongoDB; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace BookStore.DbMigrator; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(BookStoreMongoDbModule), + typeof(BookStoreApplicationContractsModule) +)] +public class BookStoreDbMigratorModule : AbpModule +{ +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/DbMigratorHostedService.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/DbMigratorHostedService.cs new file mode 100644 index 0000000..5de5140 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/DbMigratorHostedService.cs @@ -0,0 +1,51 @@ +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using BookStore.Data; +using Serilog; +using Volo.Abp; +using Volo.Abp.Data; + +namespace BookStore.DbMigrator; + +public class DbMigratorHostedService : IHostedService +{ + private readonly IHostApplicationLifetime _hostApplicationLifetime; + private readonly IConfiguration _configuration; + + public DbMigratorHostedService(IHostApplicationLifetime hostApplicationLifetime, IConfiguration configuration) + { + _hostApplicationLifetime = hostApplicationLifetime; + _configuration = configuration; + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + using (var application = await AbpApplicationFactory.CreateAsync(options => + { + options.Services.ReplaceConfiguration(_configuration); + options.UseAutofac(); + options.Services.AddLogging(c => c.AddSerilog()); + options.AddDataMigrationEnvironment(); + })) + { + await application.InitializeAsync(); + + await application + .ServiceProvider + .GetRequiredService() + .MigrateAsync(); + + await application.ShutdownAsync(); + + _hostApplicationLifetime.StopApplication(); + } + } + + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/Dockerfile b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/Dockerfile new file mode 100644 index 0000000..f4c5d31 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/Dockerfile @@ -0,0 +1,5 @@ +FROM mcr.microsoft.com/dotnet/aspnet:9.0 +COPY bin/Release/net9.0/publish/ app/ +WORKDIR /app +ENV ASPNETCORE_URLS=http://+:80 +ENTRYPOINT ["dotnet", "BookStore.DbMigrator.dll"] \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/Dockerfile.local b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/Dockerfile.local new file mode 100644 index 0000000..82052b7 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/Dockerfile.local @@ -0,0 +1,6 @@ + FROM mcr.microsoft.com/dotnet/aspnet:9.0 + USER $APP_UID + + COPY bin/Release/net9.0/publish/ app/ + WORKDIR /app + ENTRYPOINT ["dotnet", "BookStore.DbMigrator.dll"] \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/Program.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/Program.cs new file mode 100644 index 0000000..7fa2ec0 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/Program.cs @@ -0,0 +1,39 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Serilog; +using Serilog.Events; + +namespace BookStore.DbMigrator; + +class Program +{ + static async Task Main(string[] args) + { + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Information() + .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) + .MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning) +#if DEBUG + .MinimumLevel.Override("BookStore", LogEventLevel.Debug) +#else + .MinimumLevel.Override("BookStore", LogEventLevel.Information) +#endif + .Enrich.FromLogContext() + .WriteTo.Async(c => c.File("Logs/logs.txt")) + .WriteTo.Async(c => c.Console()) + .CreateLogger(); + + await CreateHostBuilder(args).RunConsoleAsync(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .AddAppSettingsSecretsJson() + .ConfigureLogging((context, logging) => logging.ClearProviders()) + .ConfigureServices((hostContext, services) => + { + services.AddHostedService(); + }); +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/appsettings.json b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/appsettings.json new file mode 100644 index 0000000..a3a6440 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/appsettings.json @@ -0,0 +1,19 @@ +{ + "ConnectionStrings": { + "Default": "mongodb://localhost:27017/BookStore" + }, + "OpenIddict": { + "Applications": { + "BookStore_App": { + "ClientId": "BookStore_App" }, + "BookStore_Blazor": { + "ClientId": "BookStore_Blazor", + "RootUrl": "https://localhost:44376" + }, + "BookStore_Swagger": { + "ClientId": "BookStore_Swagger", + "RootUrl": "https://localhost:44318/" + } + } + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/appsettings.secrets.json b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/appsettings.secrets.json new file mode 100644 index 0000000..2c63c08 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.DbMigrator/appsettings.secrets.json @@ -0,0 +1,2 @@ +{ +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStore.Domain.Shared.abppkg b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStore.Domain.Shared.abppkg new file mode 100644 index 0000000..8b3de05 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStore.Domain.Shared.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.domain-shared" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStore.Domain.Shared.abppkg.analyze.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStore.Domain.Shared.abppkg.analyze.json new file mode 100644 index 0000000..c9c6442 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStore.Domain.Shared.abppkg.analyze.json @@ -0,0 +1,118 @@ +{ + "name": "BookStore.Domain.Shared", + "hash": "", + "contents": [ + { + "namespace": "BookStore", + "dependsOnModules": [ + { + "declaringAssemblyName": "Volo.Abp.AuditLogging.Domain.Shared", + "namespace": "Volo.Abp.AuditLogging", + "name": "AbpAuditLoggingDomainSharedModule" + }, + { + "declaringAssemblyName": "Volo.Abp.BackgroundJobs.Domain.Shared", + "namespace": "Volo.Abp.BackgroundJobs", + "name": "AbpBackgroundJobsDomainSharedModule" + }, + { + "declaringAssemblyName": "Volo.Abp.FeatureManagement.Domain.Shared", + "namespace": "Volo.Abp.FeatureManagement", + "name": "AbpFeatureManagementDomainSharedModule" + }, + { + "declaringAssemblyName": "Volo.Abp.PermissionManagement.Domain.Shared", + "namespace": "Volo.Abp.PermissionManagement", + "name": "AbpPermissionManagementDomainSharedModule" + }, + { + "declaringAssemblyName": "Volo.Abp.SettingManagement.Domain.Shared", + "namespace": "Volo.Abp.SettingManagement", + "name": "AbpSettingManagementDomainSharedModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Identity.Pro.Domain.Shared", + "namespace": "Volo.Abp.Identity", + "name": "AbpIdentityProDomainSharedModule" + }, + { + "declaringAssemblyName": "Volo.Abp.OpenIddict.Pro.Domain.Shared", + "namespace": "Volo.Abp.OpenIddict", + "name": "AbpOpenIddictProDomainSharedModule" + }, + { + "declaringAssemblyName": "Volo.Abp.LanguageManagement.Domain.Shared", + "namespace": "Volo.Abp.LanguageManagement", + "name": "LanguageManagementDomainSharedModule" + }, + { + "declaringAssemblyName": "Volo.Abp.TextTemplateManagement.Domain.Shared", + "namespace": "Volo.Abp.TextTemplateManagement", + "name": "TextTemplateManagementDomainSharedModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Gdpr.Domain.Shared", + "namespace": "Volo.Abp.Gdpr", + "name": "AbpGdprDomainSharedModule" + }, + { + "declaringAssemblyName": "Volo.Abp.GlobalFeatures", + "namespace": "Volo.Abp.GlobalFeatures", + "name": "AbpGlobalFeaturesModule" + }, + { + "declaringAssemblyName": "Volo.Abp.BlobStoring.Database.Domain.Shared", + "namespace": "Volo.Abp.BlobStoring.Database", + "name": "BlobStoringDatabaseDomainSharedModule" + } + ], + "implementingInterfaces": [ + { + "name": "IAbpModule", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IAbpModule" + }, + { + "name": "IOnPreApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPreApplicationInitialization" + }, + { + "name": "IOnApplicationInitialization", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationInitialization" + }, + { + "name": "IOnPostApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPostApplicationInitialization" + }, + { + "name": "IOnApplicationShutdown", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationShutdown" + }, + { + "name": "IPreConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPreConfigureServices" + }, + { + "name": "IPostConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPostConfigureServices" + } + ], + "contentType": "abpModule", + "name": "BookStoreDomainSharedModule", + "summary": null + } + ] +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStore.Domain.Shared.csproj b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStore.Domain.Shared.csproj new file mode 100644 index 0000000..9a95879 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStore.Domain.Shared.csproj @@ -0,0 +1,37 @@ + + + + + + net9.0 + enable + BookStore + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStoreDomainErrorCodes.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStoreDomainErrorCodes.cs new file mode 100644 index 0000000..1be85b8 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStoreDomainErrorCodes.cs @@ -0,0 +1,6 @@ +namespace BookStore; + +public static class BookStoreDomainErrorCodes +{ + /* You can add your business exception error codes here, as constants */ +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStoreDomainSharedModule.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStoreDomainSharedModule.cs new file mode 100644 index 0000000..051cf45 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStoreDomainSharedModule.cs @@ -0,0 +1,82 @@ +using BookStore.Localization; +using Volo.Abp.AuditLogging; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Identity; +using Volo.Abp.Localization; +using Volo.Abp.Localization.ExceptionHandling; +using Volo.Abp.Validation.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement; +using Volo.Abp.SettingManagement; +using Volo.Abp.VirtualFileSystem; +using Volo.Abp.OpenIddict; +using Volo.Abp.BlobStoring.Database; +using Volo.Abp.TenantManagement; + +namespace BookStore; + +[DependsOn( + typeof(AbpAuditLoggingDomainSharedModule), + typeof(AbpBackgroundJobsDomainSharedModule), + typeof(AbpFeatureManagementDomainSharedModule), + typeof(AbpPermissionManagementDomainSharedModule), + typeof(AbpSettingManagementDomainSharedModule), + typeof(AbpIdentityDomainSharedModule), + typeof(AbpOpenIddictDomainSharedModule), + typeof(AbpTenantManagementDomainSharedModule), + typeof(BlobStoringDatabaseDomainSharedModule) + )] +public class BookStoreDomainSharedModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + BookStoreGlobalFeatureConfigurator.Configure(); + BookStoreModuleExtensionConfigurator.Configure(); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Add("en") + .AddBaseTypes(typeof(AbpValidationResource)) + .AddVirtualJson("/Localization/BookStore"); + + options.DefaultResourceType = typeof(BookStoreResource); + + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (United Kingdom)")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + options.Languages.Add(new LanguageInfo("es", "es", "Español")); + options.Languages.Add(new LanguageInfo("ar", "ar", "العربية")); + options.Languages.Add(new LanguageInfo("hi", "hi", "हिन्दी")); + options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português (Brasil)")); + options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); + options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch (Deuthschland)")); + options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); + options.Languages.Add(new LanguageInfo("it", "it", "Italiano")); + options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); + options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); + options.Languages.Add(new LanguageInfo("ro-RO", "ro-RO", "Română (România)")); + options.Languages.Add(new LanguageInfo("sv", "sv", "Svenska")); + options.Languages.Add(new LanguageInfo("fi", "fi", "Suomi")); + options.Languages.Add(new LanguageInfo("sk", "sk", "Slovenčina")); + options.Languages.Add(new LanguageInfo("is", "is", "Íslenska")); + options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中z文")); + + }); + + Configure(options => + { + options.MapCodeNamespace("BookStore", typeof(BookStoreResource)); + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStoreGlobalFeatureConfigurator.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStoreGlobalFeatureConfigurator.cs new file mode 100644 index 0000000..167a72f --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStoreGlobalFeatureConfigurator.cs @@ -0,0 +1,20 @@ +using Volo.Abp.GlobalFeatures; +using Volo.Abp.Threading; + +namespace BookStore; + +public static class BookStoreGlobalFeatureConfigurator +{ + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + public static void Configure() + { + OneTimeRunner.Run(() => + { + /* You can configure (enable/disable) global features of the used modules here. + * Please refer to the documentation to learn more about the Global Features System: + * https://docs.abp.io/en/abp/latest/Global-Features + */ + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStoreModuleExtensionConfigurator.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStoreModuleExtensionConfigurator.cs new file mode 100644 index 0000000..f5f40bc --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/BookStoreModuleExtensionConfigurator.cs @@ -0,0 +1,71 @@ +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Identity; +using Volo.Abp.ObjectExtending; +using Volo.Abp.Threading; + +namespace BookStore; + +public static class BookStoreModuleExtensionConfigurator +{ + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + public static void Configure() + { + OneTimeRunner.Run(() => + { + ConfigureExistingProperties(); + ConfigureExtraProperties(); + }); + } + + private static void ConfigureExistingProperties() + { + /* You can change max lengths for properties of the + * entities defined in the modules used by your application. + * + * Example: Change user and role name max lengths + + AbpUserConsts.MaxNameLength = 99; + IdentityRoleConsts.MaxNameLength = 99; + + * Notice: It is not suggested to change property lengths + * unless you really need it. Go with the standard values wherever possible. + * + * If you are using EF Core, you will need to run the add-migration command after your changes. + */ + } + + private static void ConfigureExtraProperties() + { + /* You can configure extra properties for the + * entities defined in the modules used by your application. + * + * This class can be used to define these extra properties + * with a high level, easy to use API. + * + * Example: Add a new property to the user entity of the identity module + + ObjectExtensionManager.Instance.Modules() + .ConfigureIdentity(identity => + { + identity.ConfigureUser(user => + { + user.AddOrUpdateProperty( //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 + } + ); + }); + }); + + * See the documentation for more: + * https://docs.abp.io/en/abp/latest/Module-Entity-Extensions + */ + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/ar.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/ar.json new file mode 100644 index 0000000..dfb6c89 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/ar.json @@ -0,0 +1,42 @@ +{ + "culture": "ar", + "texts": { + "AppName": "BookStore", + "Menu:Home": "منزل، بيت", + "Menu:ContactUs": "اتصل بنا", + "Menu:ArticleSample": "عينة المادة", + "Home": "منزل، بيت", + "Welcome": "مرحبا", + "LongWelcomeMessage": "مرحبا بكم في التطبيق. هذا مشروع بدء التشغيل يعتمد على إطار عمل برنامج ABP. لمزيد من المعلومات قم بزيارة", + "Date": "تاريخ", + "Permission:Dashboard": "لوحة القيادة", + "Menu:Dashboard": "لوحة القيادة", + "Menu:HomePage": "الصفحة الرئيسية", + "Dashboard": "لوحة القيادة", + "ExternalProvider:Google": "جوجل", + "ExternalProvider:Google:ClientId": "معرف العميل", + "ExternalProvider:Google:ClientSecret": "سر العميل", + "ExternalProvider:Microsoft": "مايكروسوفت", + "ExternalProvider:Microsoft:ClientId": "معرف العميل", + "ExternalProvider:Microsoft:ClientSecret": "سر العميل", + "ExternalProvider:Twitter": "تويتر", + "ExternalProvider:Twitter:ConsumerKey": "مفتاح المستهلك", + "ExternalProvider:Twitter:ConsumerSecret": "سر المستهلك", + "NewsletterHeader": "اشترك في النشرة الإخبارية!", + "NewsletterInfo": "احصل على معلومات حول آخر الأحداث.", + "NewsletterPreference_Default": "النشرة الإخبارية الافتراضية", + "NewsletterPrivacyAcceptMessage": "أوافق على سياسة الخصوصية .", + "Language": "لغة", + "Search": "يبحث", + "LoadMore": "تحميل المزيد", + "Settings": "إعدادات", + "Theme": "سمة", + "DeviceTheme": "موضوع الجهاز", + "Dark": "مظلم", + "Light": "ضوء", + "Unspecified": "نظام", + "SeeAllUsers": "رؤية كافة المستخدمين", + "TakePhoto": "تصوير", + "ChoosePhoto": "اختر صورة" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/cs.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/cs.json new file mode 100644 index 0000000..96d3df1 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/cs.json @@ -0,0 +1,9 @@ +{ + "Culture": "cs", + "Texts": { + "AppName": "BookStore", + "Menu:Home": "Home", + "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information visit", + "Welcome": "Welcome" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/de-DE.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/de-DE.json new file mode 100644 index 0000000..91727da --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/de-DE.json @@ -0,0 +1,42 @@ +{ + "culture": "de-DE", + "texts": { + "AppName": "BookStore", + "Menu:Home": "Home", + "Menu:ContactUs": "Kontaktiere uns", + "Menu:ArticleSample": "Artikelmuster", + "Home": "Home", + "Welcome": "Willkommen", + "LongWelcomeMessage": "Willkommen in der Anwendung. Dies ist ein Startup-Projekt basierend auf dem ABP-Framework. Weitere Informationen finden Sie unter", + "Date": "Datum", + "Permission:Dashboard": "Dashboard", + "Menu:Dashboard": "Dashboard", + "Menu:HomePage": "Startseite", + "Dashboard": "Dashboard", + "ExternalProvider:Google": "Google", + "ExternalProvider:Google:ClientId": "Kunden ID", + "ExternalProvider:Google:ClientSecret": "Client-Geheimnis", + "ExternalProvider:Microsoft": "Microsoft", + "ExternalProvider:Microsoft:ClientId": "Kunden ID", + "ExternalProvider:Microsoft:ClientSecret": "Client-Geheimnis", + "ExternalProvider:Twitter": "Twitter", + "ExternalProvider:Twitter:ConsumerKey": "Verbraucherschlüssel", + "ExternalProvider:Twitter:ConsumerSecret": "Verbrauchergeheimnis", + "NewsletterHeader": "Abonnieren Sie den Newsletter!", + "NewsletterInfo": "Informieren Sie sich über aktuelle Ereignisse.", + "NewsletterPreference_Default": "Standard-Newsletter", + "NewsletterPrivacyAcceptMessage": "Ich akzeptiere die Datenschutzerklärung.", + "Language": "Sprache", + "Search": "Suchen", + "LoadMore": "Mehr laden", + "Settings": "Einstellungen", + "Theme": "Thema", + "DeviceTheme": "Gerätethema", + "Dark": "Dunkel", + "Light": "Licht", + "Unspecified": "System", + "SeeAllUsers": "Alle Benutzer anzeigen", + "TakePhoto": "Foto machen", + "ChoosePhoto": "Wähle ein Foto aus" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/en-GB.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/en-GB.json new file mode 100644 index 0000000..9ce52ca --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/en-GB.json @@ -0,0 +1,9 @@ +{ + "Culture": "en-GB", + "Texts": { + "AppName": "BookStore", + "Menu:Home": "Home", + "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information visit", + "Welcome": "Welcome" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/en.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/en.json new file mode 100644 index 0000000..90874f6 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/en.json @@ -0,0 +1,9 @@ +{ + "Culture": "en", + "Texts": { + "AppName": "BookStore", + "Menu:Home": "Home", + "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information visit", + "Welcome": "Welcome" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/es.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/es.json new file mode 100644 index 0000000..43f20ea --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/es.json @@ -0,0 +1,42 @@ +{ + "culture": "es", + "texts": { + "AppName": "BookStore", + "Menu:Home": "Hogar", + "Menu:ContactUs": "Contáctenos", + "Menu:ArticleSample": "Muestra de artículo", + "Home": "Hogar", + "Welcome": "Bienvenido", + "LongWelcomeMessage": "Bienvenido a la aplicacion. Este es un proyecto de inicio basado en el marco ABP. Para obtener mas informacion, visite", + "Date": "Fecha", + "Permission:Dashboard": "Panel de control", + "Menu:Dashboard": "Panel de control", + "Menu:HomePage": "Página de inicio", + "Dashboard": "Panel de control", + "ExternalProvider:Google": "Google", + "ExternalProvider:Google:ClientId": "ID de cliente", + "ExternalProvider:Google:ClientSecret": "Client Secret", + "ExternalProvider:Microsoft": "Microsoft", + "ExternalProvider:Microsoft:ClientId": "ID de cliente", + "ExternalProvider:Microsoft:ClientSecret": "Client Secret", + "ExternalProvider:Twitter": "Twitter", + "ExternalProvider:Twitter:ConsumerKey": "Clave de consumidor", + "ExternalProvider:Twitter:ConsumerSecret": "Consumer Secret", + "NewsletterHeader": "Suscríbete a la newsletter!", + "NewsletterInfo": "Obtenga información sobre los últimos acontecimientos.", + "NewsletterPreference_Default": "Boletín de noticias predeterminado", + "NewsletterPrivacyAcceptMessage": "Acepto la Política de privacidad .", + "Language": "Idioma", + "Search": "Buscar", + "LoadMore": "Carga más", + "Settings": "Ajustes", + "Theme": "Tema", + "DeviceTheme": "Tema del dispositivo", + "Dark": "Oscuro", + "Light": "Luz", + "Unspecified": "Sistema", + "SeeAllUsers": "Ver todos los usuarios", + "TakePhoto": "Tomar foto", + "ChoosePhoto": "Escoge una foto" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/fi.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/fi.json new file mode 100644 index 0000000..306a774 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/fi.json @@ -0,0 +1,42 @@ +{ + "culture": "fi", + "texts": { + "AppName": "BookStore", + "Menu:Home": "Koti", + "Menu:ContactUs": "Ota meihin yhteyttä", + "Menu:ArticleSample": "Artikkelinäyte", + "Home": "Koti", + "Welcome": "Tervetuloa", + "LongWelcomeMessage": "Tervetuloa sovellukseen. Tämä on ABP-kehykseen perustuva käynnistysprojekti. Lisätietoja on osoitteessa", + "Date": "Päivämäärä", + "Permission:Dashboard": "Kojelauta", + "Menu:Dashboard": "Kojelauta", + "Menu:HomePage": "Kotisivu", + "Dashboard": "Kojelauta", + "ExternalProvider:Google": "Google", + "ExternalProvider:Google:ClientId": "Asiakastunnus", + "ExternalProvider:Google:ClientSecret": "Asiakkaan salaisuus", + "ExternalProvider:Microsoft": "Microsoft", + "ExternalProvider:Microsoft:ClientId": "Asiakastunnus", + "ExternalProvider:Microsoft:ClientSecret": "Asiakkaan salaisuus", + "ExternalProvider:Twitter": "Viserrys", + "ExternalProvider:Twitter:ConsumerKey": "Kuluttaja-avain", + "ExternalProvider:Twitter:ConsumerSecret": "Kuluttajan salaisuus", + "NewsletterHeader": "Tilaa uutiskirje!", + "NewsletterInfo": "Hanki tietoa viimeisimmistä tapahtumista.", + "NewsletterPreference_Default": "Oletusuutiskirje", + "NewsletterPrivacyAcceptMessage": "Hyväksyn tietosuojakäytännön .", + "Language": "Kieli", + "Search": "Hae", + "LoadMore": "Lataa lisää", + "Settings": "asetukset", + "Theme": "Teema", + "DeviceTheme": "Laitteen teema", + "Dark": "Tumma", + "Light": "Kevyt", + "Unspecified": "Järjestelmä", + "SeeAllUsers": "Katso Kaikki käyttäjät", + "TakePhoto": "Ota valokuva", + "ChoosePhoto": "Valitse Valokuva" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/fr.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/fr.json new file mode 100644 index 0000000..e498f7e --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/fr.json @@ -0,0 +1,42 @@ +{ + "culture": "fr", + "texts": { + "AppName": "BookStore", + "Menu:Home": "Acceuil", + "Menu:ContactUs": "Nous contacter", + "Menu:ArticleSample": "Échantillon d'article", + "Home": "Acceuil", + "Welcome": "Bienvenue", + "LongWelcomeMessage": "Bienvenue dans l'application. Il s'agit d'un projet de démarrage basé sur le framework ABP. Pour plus d'informations, visitez", + "Date": "Date", + "Permission:Dashboard": "Tableau de bord", + "Menu:Dashboard": "Tableau de bord", + "Menu:HomePage": "Page d'accueil", + "Dashboard": "Tableau de bord", + "ExternalProvider:Google": "Google", + "ExternalProvider:Google:ClientId": "identité du client", + "ExternalProvider:Google:ClientSecret": "Secret du client", + "ExternalProvider:Microsoft": "Microsoft", + "ExternalProvider:Microsoft:ClientId": "identité du client", + "ExternalProvider:Microsoft:ClientSecret": "Secret du client", + "ExternalProvider:Twitter": "Twitter", + "ExternalProvider:Twitter:ConsumerKey": "La clé du consommateur", + "ExternalProvider:Twitter:ConsumerSecret": "Secret du consommateur", + "NewsletterHeader": "Abonnez-vous à la newsletter!", + "NewsletterInfo": "Obtenez des informations sur les derniers événements.", + "NewsletterPreference_Default": "Newsletter par défaut", + "NewsletterPrivacyAcceptMessage": "J'accepte la Politique de confidentialité .", + "Language": "Langue", + "Search": "Recherche", + "LoadMore": "Charger plus", + "Settings": "Paramètres", + "Theme": "Thème", + "DeviceTheme": "Thème de l'appareil", + "Dark": "Sombre", + "Light": "Lumière", + "Unspecified": "Système", + "SeeAllUsers": "Voir tous les utilisateurs", + "TakePhoto": "Prendre une photo", + "ChoosePhoto": "Choisissez une photo" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/hi.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/hi.json new file mode 100644 index 0000000..c98acd5 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/hi.json @@ -0,0 +1,42 @@ +{ + "culture": "hi", + "texts": { + "AppName": "BookStore", + "Menu:Home": "घर", + "Menu:ContactUs": "संपर्क करें", + "Menu:ArticleSample": "आलेख नमूना", + "Home": "घर", + "Welcome": "स्वागत हे", + "LongWelcomeMessage": "आवेदन करने के लिए आपका स्वागत है। यह एबीपी ढांचे पर आधारित एक स्टार्टअप परियोजना है। अधिक जानकारी के लिए पर जाएँ।", + "Date": "दिनांक", + "Permission:Dashboard": "डैशबोर्ड", + "Menu:Dashboard": "डैशबोर्ड", + "Menu:HomePage": "मुख पृष्ठ", + "Dashboard": "डैशबोर्ड", + "ExternalProvider:Google": "गूगल", + "ExternalProvider:Google:ClientId": "ग्राहक ID", + "ExternalProvider:Google:ClientSecret": "ग्राहक गुप्त", + "ExternalProvider:Microsoft": "माइक्रोसॉफ्ट", + "ExternalProvider:Microsoft:ClientId": "ग्राहक ID", + "ExternalProvider:Microsoft:ClientSecret": "ग्राहक गुप्त", + "ExternalProvider:Twitter": "ट्विटर", + "ExternalProvider:Twitter:ConsumerKey": "उपभोक्ता कुंजी", + "ExternalProvider:Twitter:ConsumerSecret": "उपभोक्ता रहस्य", + "NewsletterHeader": "न्यूज़लेटर की सदस्यता लें!", + "NewsletterInfo": "नवीनतम घटनाओं के बारे में जानकारी प्राप्त करें।", + "NewsletterPreference_Default": "डिफ़ॉल्ट न्यूज़लैटर", + "NewsletterPrivacyAcceptMessage": "मैं गोपनीयता नीति स्वीकार करता हूं।", + "Language": "भाषा", + "Search": "खोज", + "LoadMore": "और लोड करें", + "Settings": "समायोजन", + "Theme": "विषय", + "DeviceTheme": "डिवाइस थीम", + "Dark": "अँधेरा", + "Light": "रोशनी", + "Unspecified": "प्रणाली", + "SeeAllUsers": "सभी उपयोगकर्ता देखें", + "TakePhoto": "फोटो लो", + "ChoosePhoto": "तस्विर का चयन करो" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/hu.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/hu.json new file mode 100644 index 0000000..0e38e37 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/hu.json @@ -0,0 +1,42 @@ +{ + "culture": "hu", + "texts": { + "AppName": "BookStore", + "Menu:Home": "Kezdőlap", + "Menu:ContactUs": "Lépjen kapcsolatba velünk", + "Menu:ArticleSample": "Cikkminta", + "Home": "Kezdőlap", + "Welcome": "Üdvözöljük", + "LongWelcomeMessage": "Üdvözöljük az alkalmazásban. Ez egy ABP keretrendszeren alapuló startup projekt. További információért látogasson el az oldalra", + "Date": "dátum", + "Permission:Dashboard": "Irányítópult", + "Menu:Dashboard": "Irányítópult", + "Menu:HomePage": "Kezdőlap", + "Dashboard": "Irányítópult", + "ExternalProvider:Google": "Google", + "ExternalProvider:Google:ClientId": "Ügyfélazonosító", + "ExternalProvider:Google:ClientSecret": "Ügyfél titkos kulcs", + "ExternalProvider:Microsoft": "Microsoft", + "ExternalProvider:Microsoft:ClientId": "Ügyfélazonosító", + "ExternalProvider:Microsoft:ClientSecret": "Ügyfél titkos kulcs", + "ExternalProvider:Twitter": "Twitter", + "ExternalProvider:Twitter:ConsumerKey": "Fogyasztói kulcs", + "ExternalProvider:Twitter:ConsumerSecret": "Fogyasztói titkos kulcs", + "NewsletterHeader": "Iratkozz fel a hírlevélre!", + "NewsletterInfo": "Tájékozódjon a legfrissebb eseményekről.", + "NewsletterPreference_Default": "Alapértelmezett hírlevél", + "NewsletterPrivacyAcceptMessage": "Elfogadom az Adatvédelmi szabályzatot .", + "Language": "Nyelv", + "Search": "Keresés", + "LoadMore": "Load More", + "Settings": "Beállítások", + "Theme": "Téma", + "DeviceTheme": "Eszköz téma", + "Dark": "Sötét", + "Light": "Fény", + "Unspecified": "Rendszer", + "SeeAllUsers": "Lásd: Összes felhasználó", + "TakePhoto": "Fotót készíteni", + "ChoosePhoto": "Válassz képet" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/is.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/is.json new file mode 100644 index 0000000..1ed7e68 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/is.json @@ -0,0 +1,9 @@ +{ + "Culture": "is", + "Texts": { + "AppName": "BookStore", + "Menu:Home": "Home", + "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information visit", + "Welcome": "Welcome" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/it.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/it.json new file mode 100644 index 0000000..42806bc --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/it.json @@ -0,0 +1,42 @@ +{ + "culture": "it", + "texts": { + "AppName": "BookStore", + "Menu:Home": "Home", + "Menu:ContactUs": "Contattaci", + "Menu:ArticleSample": "Esempio di articolo", + "Home": "Home", + "Welcome": "Benvenuto", + "LongWelcomeMessage": "Benvenuto nell'applicazione. Questo è un progetto di avvio basato sul framework ABP. Per maggiori informazioni visita", + "Date": "Data", + "Permission:Dashboard": "Cruscotto", + "Menu:Dashboard": "Cruscotto", + "Menu:HomePage": "Pagina iniziale", + "Dashboard": "Cruscotto", + "ExternalProvider:Google": "Google", + "ExternalProvider:Google:ClientId": "Client ID", + "ExternalProvider:Google:ClientSecret": "Client Secret", + "ExternalProvider:Microsoft": "Microsoft", + "ExternalProvider:Microsoft:ClientId": "Client ID", + "ExternalProvider:Microsoft:ClientSecret": "Client Secret", + "ExternalProvider:Twitter": "Twitter", + "ExternalProvider:Twitter:ConsumerKey": "Consumer Key", + "ExternalProvider:Twitter:ConsumerSecret": "Consumer Secret", + "NewsletterHeader": "Iscriviti alla newsletter!", + "NewsletterInfo": "Ottieni informazioni sugli ultimi avvenimenti.", + "NewsletterPreference_Default": "Newsletter predefinita", + "NewsletterPrivacyAcceptMessage": "Accetto la Informativa sulla privacy.", + "Language": "Lingua", + "Search": "Ricerca", + "LoadMore": "Carica altro", + "Settings": "Impostazioni", + "Theme": "Tema", + "DeviceTheme": "Tema del dispositivo", + "Dark": "Buio", + "Light": "Leggero", + "Unspecified": "Sistema", + "SeeAllUsers": "Visualizza tutti gli utenti", + "TakePhoto": "Fare foto", + "ChoosePhoto": "Scegli la foto" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/pt-BR.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/pt-BR.json new file mode 100644 index 0000000..4d3ae19 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/pt-BR.json @@ -0,0 +1,42 @@ +{ + "culture": "pt-BR", + "texts": { + "AppName": "BookStore", + "Menu:Home": "Principal", + "Menu:ContactUs": "Entre em contato conosco", + "Menu:ArticleSample": "Amostra de Artigo", + "Home": "Casa", + "Welcome": "Seja bem-vindo!", + "LongWelcomeMessage": "Bem-vindo a esta aplicação. Este é um projeto inicial baseado no ABP framework. Para mais informações, visite", + "Date": "Data", + "Permission:Dashboard": "Painel", + "Menu:Dashboard": "Painel", + "Menu:HomePage": "Pagina inicial", + "Dashboard": "Painel", + "ExternalProvider:Google": "Google", + "ExternalProvider:Google:ClientId": "ID do Cliente", + "ExternalProvider:Google:ClientSecret": "Segredo do cliente", + "ExternalProvider:Microsoft": "Microsoft", + "ExternalProvider:Microsoft:ClientId": "ID do Cliente", + "ExternalProvider:Microsoft:ClientSecret": "Segredo do cliente", + "ExternalProvider:Twitter": "Twitter", + "ExternalProvider:Twitter:ConsumerKey": "Chave do consumidor", + "ExternalProvider:Twitter:ConsumerSecret": "consumidor secreto", + "NewsletterHeader": "Assine a newsletter!", + "NewsletterInfo": "Obtenha informações sobre os últimos acontecimentos.", + "NewsletterPreference_Default": "Boletim informativo padrão", + "NewsletterPrivacyAcceptMessage": "Eu aceito a Política de Privacidade .", + "Language": "Linguagem", + "Search": "Procurar", + "LoadMore": "Carregue mais", + "Settings": "Configurações", + "Theme": "Tema", + "DeviceTheme": "Tema do dispositivo", + "Dark": "Escuro", + "Light": "Luz", + "Unspecified": "Sistema", + "SeeAllUsers": "Ver todos os usuários", + "TakePhoto": "Tirar fotos", + "ChoosePhoto": "Escolher Foto" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/ro-RO.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/ro-RO.json new file mode 100644 index 0000000..19a18cb --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/ro-RO.json @@ -0,0 +1,9 @@ +{ + "Culture": "ro-RO", + "Texts": { + "AppName": "BookStore", + "Menu:Home": "Home", + "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information visit", + "Welcome": "Welcome" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/ru.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/ru.json new file mode 100644 index 0000000..b97912e --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/ru.json @@ -0,0 +1,42 @@ +{ + "culture": "ru", + "texts": { + "AppName": "BookStore", + "Menu:Home": "Дома", + "Menu:ContactUs": "Связаться с нами", + "Menu:ArticleSample": "Образец статьи", + "Home": "Дома", + "Welcome": "Добро пожаловать", + "LongWelcomeMessage": "Добро пожаловать в приложение. Это стартап-проект, основанный на структуре ABP. Для получения дополнительной информации посетите сайт", + "Date": "датировать", + "Permission:Dashboard": "Панель приборов", + "Menu:Dashboard": "Панель приборов", + "Menu:HomePage": "Домашняя страница", + "Dashboard": "Панель приборов", + "ExternalProvider:Google": "Google", + "ExternalProvider:Google:ClientId": "ID клиента", + "ExternalProvider:Google:ClientSecret": "Секрет клиента", + "ExternalProvider:Microsoft": "Майкрософт", + "ExternalProvider:Microsoft:ClientId": "ID клиента", + "ExternalProvider:Microsoft:ClientSecret": "Секрет клиента", + "ExternalProvider:Twitter": "Твиттер", + "ExternalProvider:Twitter:ConsumerKey": "Потребительский ключ", + "ExternalProvider:Twitter:ConsumerSecret": "Потребительский секрет", + "NewsletterHeader": "Подпишитесь на рассылку!", + "NewsletterInfo": "Получайте информацию о последних событиях.", + "NewsletterPreference_Default": "Информационный бюллетень по умолчанию", + "NewsletterPrivacyAcceptMessage": "Я принимаю Политику конфиденциальности.", + "Language": "Язык", + "Search": "Поиск", + "LoadMore": "Загрузи больше", + "Settings": "Настройки", + "Theme": "Тема", + "DeviceTheme": "Тема устройства", + "Dark": "Темный", + "Light": "Свет", + "Unspecified": "Система", + "SeeAllUsers": "Просмотреть всех пользователей", + "TakePhoto": "Сделать фотографию", + "ChoosePhoto": "Выбрать фото" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/sk.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/sk.json new file mode 100644 index 0000000..cfa4247 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/sk.json @@ -0,0 +1,42 @@ +{ + "culture": "sk", + "texts": { + "AppName": "BookStore", + "Menu:Home": "Domov", + "Menu:ContactUs": "Kontaktujte nás", + "Menu:ArticleSample": "Ukážka článku", + "Home": "Domov", + "Welcome": "Vitajte", + "LongWelcomeMessage": "Vitajte v aplikácii. Toto je štartovací projekt založený na ABP frameworku. Viac informácií nájdete na stránke", + "Date": "Dátum", + "Permission:Dashboard": "Dashboard", + "Menu:Dashboard": "Dashboard", + "Menu:HomePage": "Domovská stránka", + "Dashboard": "Dashboard", + "ExternalProvider:Google": "Google", + "ExternalProvider:Google:ClientId": "Client ID", + "ExternalProvider:Google:ClientSecret": "Client Secret", + "ExternalProvider:Microsoft": "Microsoft", + "ExternalProvider:Microsoft:ClientId": "Client ID", + "ExternalProvider:Microsoft:ClientSecret": "Client Secret", + "ExternalProvider:Twitter": "Twitter", + "ExternalProvider:Twitter:ConsumerKey": "Consumer Key", + "ExternalProvider:Twitter:ConsumerSecret": "Consumer Secret", + "NewsletterHeader": "Prihláste sa na odber noviniek!", + "NewsletterInfo": "Získajte informácie o najnovšiom dianí.", + "NewsletterPreference_Default": "Predvolený odber noviniek", + "NewsletterPrivacyAcceptMessage": "Súhlasím so Zásadami ochrany osobných údajov.", + "Language": "Jazyk", + "Search": "Vyhľadávanie", + "LoadMore": "Načítať viac", + "Settings": "nastavenie", + "Theme": "Téma", + "DeviceTheme": "Téma zariadenia", + "Dark": "Tmavý", + "Light": "Svetlo", + "Unspecified": "Systém", + "SeeAllUsers": "Pozrite si Všetci používatelia", + "TakePhoto": "Odfoť", + "ChoosePhoto": "Vyberte fotografiu" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/sv.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/sv.json new file mode 100644 index 0000000..f5c6717 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/sv.json @@ -0,0 +1,42 @@ +{ + "Culture": "sv", + "Texts": { + "AppName": "BookStore", + "Menu:ContactUs": "Kontakta oss", + "Menu:ArticleSample": "Artikelexempel", + "Home": "Hem", + "Date": "Datum", + "Permission:Dashboard": "Dashboard", + "Menu:Dashboard": "Dashboard", + "Menu:HomePage": "Hemsida", + "Dashboard": "Dashboard", + "ExternalProvider:Google": "Google", + "ExternalProvider:Google:ClientId": "Klient-ID", + "ExternalProvider:Google:ClientSecret": "Klienthemlighet", + "ExternalProvider:Microsoft": "Microsoft", + "ExternalProvider:Microsoft:ClientId": "Klient-ID", + "ExternalProvider:Microsoft:ClientSecret": "Klienthemlighet", + "ExternalProvider:Twitter": "Twitter (X)", + "ExternalProvider:Twitter:ConsumerKey": "Konsumentnyckel", + "ExternalProvider:Twitter:ConsumerSecret": "Konsumenthemlighet", + "NewsletterHeader": "Prenumerera på nyhetsbrevet!", + "NewsletterInfo": "Få information om de senaste händelserna.", + "NewsletterPreference_Default": "Standardnyhetsbrev", + "NewsletterPrivacyAcceptMessage": "Jag accepterar Sekretesspolicy.", + "Language": "Språk", + "Search": "Söka", + "LoadMore": "Ladda mer", + "Settings": "Inställningar", + "Theme": "Tema", + "DeviceTheme": "Enhetstema", + "Dark": "Mörk", + "Light": "Ljus", + "Unspecified": "System", + "SeeAllUsers": "Se Alla användare", + "TakePhoto": "Ta foto", + "ChoosePhoto": "Välj Foto", + "Menu:Home": "Hem", + "LongWelcomeMessage": "Välkommen till ansökan. ", + "Welcome": "Välkomna" + } + } \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/tr.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/tr.json new file mode 100644 index 0000000..fc1011c --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/tr.json @@ -0,0 +1,42 @@ +{ + "culture": "tr", + "texts": { + "AppName": "BookStore", + "Menu:Home": "Ana sayfa", + "Menu:ContactUs": "Bize Ulaşın", + "Menu:ArticleSample": "Yazı Örneği", + "Home": "Ana sayfa", + "Welcome": "Hoşgeldiniz", + "LongWelcomeMessage": "Uygulamaya hoşgeldiniz. Bu, ABP framework'ü üzerine bina edilmiş bir başlangıç projesidir. Daha fazla bilgi için ziyaret edebilirsiniz", + "Date": "Tarih", + "Permission:Dashboard": "Genel görünüm", + "Menu:Dashboard": "Genel görünüm", + "Menu:HomePage": "ana sayfa", + "Dashboard": "Genel görünüm", + "ExternalProvider:Google": "Google", + "ExternalProvider:Google:ClientId": "Client ID", + "ExternalProvider:Google:ClientSecret": "Client Secret", + "ExternalProvider:Microsoft": "Microsoft", + "ExternalProvider:Microsoft:ClientId": "Client ID", + "ExternalProvider:Microsoft:ClientSecret": "Client Secret", + "ExternalProvider:Twitter": "Twitter", + "ExternalProvider:Twitter:ConsumerKey": "Consumer Key", + "ExternalProvider:Twitter:ConsumerSecret": "Consumer Secret", + "NewsletterHeader": "Bültene abone olun!", + "NewsletterInfo": "Son gelişmeler hakkında bilgi alın.", + "NewsletterPreference_Default": "Varsayılan Bülten", + "NewsletterPrivacyAcceptMessage": "Gizlilik Politikası'nı kabul ediyorum.", + "Language": "Dil", + "Search": "Ara", + "LoadMore": "Daha fazla yükle", + "Settings": "Ayarlar", + "Theme": "Tema", + "DeviceTheme": "Cihaz Teması", + "Dark": "Koyu", + "Light": "Açık", + "Unspecified": "Sistem", + "SeeAllUsers": "Tüm Kullanıcıları Gör", + "TakePhoto": "Fotoğraf Çek", + "ChoosePhoto": "Fotoğraf Seç" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/zh-Hans.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/zh-Hans.json new file mode 100644 index 0000000..fcdc1ee --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/zh-Hans.json @@ -0,0 +1,42 @@ +{ + "culture": "zh-Hans", + "texts": { + "AppName": "BookStore", + "Menu:Home": "首页", + "Menu:ContactUs": "联系我们", + "Menu:ArticleSample": "文章示例", + "Home": "首页", + "Welcome": "欢迎", + "LongWelcomeMessage": "欢迎使用本应用程序。这是一个基于 ABP 框架的启动项目。欲了解更多信息,请访问", + "Date": "日期", + "Permission:Dashboard": "仪表板", + "Menu:Dashboard": "仪表板", + "Menu:HomePage": "主页", + "Dashboard": "仪表板", + "ExternalProvider:Google": "Google", + "ExternalProvider:Google:ClientId": "Client Id", + "ExternalProvider:Google:ClientSecret": "Client Secret", + "ExternalProvider:Microsoft": "Microsoft", + "ExternalProvider:Microsoft:ClientId": "Client Id", + "ExternalProvider:Microsoft:ClientSecret": "Client Secret", + "ExternalProvider:Twitter": "Twitter", + "ExternalProvider:Twitter:ConsumerKey": "Consumer Key", + "ExternalProvider:Twitter:ConsumerSecret": "Consumer Secret", + "NewsletterHeader": "订阅时事通讯!", + "NewsletterInfo": "了解最新动态。", + "NewsletterPreference_Default": "默认通讯", + "NewsletterPrivacyAcceptMessage": "我接受隐私政策。", + "Language": "语言", + "Search": "搜索", + "LoadMore": "加载更多", + "Settings": "设置", + "Theme": "主题", + "DeviceTheme": "设备主题", + "Dark": "Dark", + "Light": "Light", + "Unspecified": "System", + "SeeAllUsers": "查看所有用户", + "TakePhoto": "拍摄照片", + "ChoosePhoto": "选择照片" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/zh-Hant.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/zh-Hant.json new file mode 100644 index 0000000..a1818f0 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStore/zh-Hant.json @@ -0,0 +1,9 @@ +{ + "Culture": "zh-Hant", + "Texts": { + "AppName": "BookStore", + "Menu:Home": "Home", + "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information visit", + "Welcome": "Welcome" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStoreResource.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStoreResource.cs new file mode 100644 index 0000000..18e16ba --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/Localization/BookStoreResource.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Localization; + +namespace BookStore.Localization; + +[LocalizationResourceName("BookStore")] +public class BookStoreResource +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/MultiTenancy/MultiTenancyConsts.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/MultiTenancy/MultiTenancyConsts.cs new file mode 100644 index 0000000..468f26a --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain.Shared/MultiTenancy/MultiTenancyConsts.cs @@ -0,0 +1,10 @@ +namespace BookStore.MultiTenancy; + +public static class MultiTenancyConsts +{ + /* Enable/disable multi-tenancy easily in a single point. + * If you will never need to multi-tenancy, you can remove + * related modules and code parts, including this file. + */ + public const bool IsEnabled = true; +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStore.Domain.abppkg b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStore.Domain.abppkg new file mode 100644 index 0000000..1d574ef --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStore.Domain.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.domain" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStore.Domain.abppkg.analyze.json b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStore.Domain.abppkg.analyze.json new file mode 100644 index 0000000..444cfad --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStore.Domain.abppkg.analyze.json @@ -0,0 +1,138 @@ +{ + "name": "BookStore.Domain", + "hash": "", + "contents": [ + { + "namespace": "BookStore", + "dependsOnModules": [ + { + "declaringAssemblyName": "BookStore.Domain.Shared", + "namespace": "BookStore", + "name": "BookStoreDomainSharedModule" + }, + { + "declaringAssemblyName": "Volo.Abp.AuditLogging.Domain", + "namespace": "Volo.Abp.AuditLogging", + "name": "AbpAuditLoggingDomainModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Caching", + "namespace": "Volo.Abp.Caching", + "name": "AbpCachingModule" + }, + { + "declaringAssemblyName": "Volo.Abp.BackgroundJobs.Domain", + "namespace": "Volo.Abp.BackgroundJobs", + "name": "AbpBackgroundJobsDomainModule" + }, + { + "declaringAssemblyName": "Volo.Abp.FeatureManagement.Domain", + "namespace": "Volo.Abp.FeatureManagement", + "name": "AbpFeatureManagementDomainModule" + }, + { + "declaringAssemblyName": "Volo.Abp.PermissionManagement.Domain.Identity", + "namespace": "Volo.Abp.PermissionManagement.Identity", + "name": "AbpPermissionManagementDomainIdentityModule" + }, + { + "declaringAssemblyName": "Volo.Abp.PermissionManagement.Domain.OpenIddict", + "namespace": "Volo.Abp.PermissionManagement.OpenIddict", + "name": "AbpPermissionManagementDomainOpenIddictModule" + }, + { + "declaringAssemblyName": "Volo.Abp.SettingManagement.Domain", + "namespace": "Volo.Abp.SettingManagement", + "name": "AbpSettingManagementDomainModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Emailing", + "namespace": "Volo.Abp.Emailing", + "name": "AbpEmailingModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Identity.Pro.Domain", + "namespace": "Volo.Abp.Identity", + "name": "AbpIdentityProDomainModule" + }, + { + "declaringAssemblyName": "Volo.Abp.OpenIddict.Pro.Domain", + "namespace": "Volo.Abp.OpenIddict", + "name": "AbpOpenIddictProDomainModule" + }, + { + "declaringAssemblyName": "Volo.Abp.TextTemplateManagement.Domain", + "namespace": "Volo.Abp.TextTemplateManagement", + "name": "TextTemplateManagementDomainModule" + }, + { + "declaringAssemblyName": "Volo.Abp.LanguageManagement.Domain", + "namespace": "Volo.Abp.LanguageManagement", + "name": "LanguageManagementDomainModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Commercial.SuiteTemplates", + "namespace": "Volo.Abp.Commercial.SuiteTemplates", + "name": "VoloAbpCommercialSuiteTemplatesModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Gdpr.Domain", + "namespace": "Volo.Abp.Gdpr", + "name": "AbpGdprDomainModule" + }, + { + "declaringAssemblyName": "Volo.Abp.BlobStoring.Database.Domain", + "namespace": "Volo.Abp.BlobStoring.Database", + "name": "BlobStoringDatabaseDomainModule" + } + ], + "implementingInterfaces": [ + { + "name": "IAbpModule", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IAbpModule" + }, + { + "name": "IOnPreApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPreApplicationInitialization" + }, + { + "name": "IOnApplicationInitialization", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationInitialization" + }, + { + "name": "IOnPostApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPostApplicationInitialization" + }, + { + "name": "IOnApplicationShutdown", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationShutdown" + }, + { + "name": "IPreConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPreConfigureServices" + }, + { + "name": "IPostConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPostConfigureServices" + } + ], + "contentType": "abpModule", + "name": "BookStoreDomainModule", + "summary": null + } + ] +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStore.Domain.csproj b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStore.Domain.csproj new file mode 100644 index 0000000..cb8accc --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStore.Domain.csproj @@ -0,0 +1,33 @@ + + + + + + net9.0 + enable + BookStore + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStoreConsts.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStoreConsts.cs new file mode 100644 index 0000000..74b09a8 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStoreConsts.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Identity; + +namespace BookStore; + +public static class BookStoreConsts +{ + public const string DbTablePrefix = "App"; + public const string? DbSchema = null; + public const string AdminEmailDefaultValue = IdentityDataSeedContributor.AdminEmailDefaultValue; + public const string AdminPasswordDefaultValue = IdentityDataSeedContributor.AdminPasswordDefaultValue; +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStoreDomainModule.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStoreDomainModule.cs new file mode 100644 index 0000000..a477c50 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/BookStoreDomainModule.cs @@ -0,0 +1,52 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using BookStore.Localization; +using BookStore.MultiTenancy; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy; +using Volo.Abp.PermissionManagement.Identity; +using Volo.Abp.SettingManagement; +using Volo.Abp.BlobStoring.Database; +using Volo.Abp.Caching; +using Volo.Abp.OpenIddict; +using Volo.Abp.PermissionManagement.OpenIddict; +using Volo.Abp.AuditLogging; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.Emailing; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Identity; +using Volo.Abp.TenantManagement; + +namespace BookStore; + +[DependsOn( + typeof(BookStoreDomainSharedModule), + typeof(AbpAuditLoggingDomainModule), + typeof(AbpCachingModule), + typeof(AbpBackgroundJobsDomainModule), + typeof(AbpFeatureManagementDomainModule), + typeof(AbpPermissionManagementDomainIdentityModule), + typeof(AbpPermissionManagementDomainOpenIddictModule), + typeof(AbpSettingManagementDomainModule), + typeof(AbpEmailingModule), + typeof(AbpIdentityDomainModule), + typeof(AbpOpenIddictDomainModule), + typeof(AbpTenantManagementDomainModule), + typeof(BlobStoringDatabaseDomainModule) + )] +public class BookStoreDomainModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.IsEnabled = MultiTenancyConsts.IsEnabled; + }); + + +#if DEBUG + context.Services.Replace(ServiceDescriptor.Singleton()); +#endif + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Data/BookStoreDbMigrationService.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Data/BookStoreDbMigrationService.cs new file mode 100644 index 0000000..ff74805 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Data/BookStoreDbMigrationService.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Identity; +using Volo.Abp.MultiTenancy; +using BookStore.MultiTenancy; +using Volo.Abp.TenantManagement; + +namespace BookStore.Data; + +public class BookStoreDbMigrationService : ITransientDependency +{ + public ILogger Logger { get; set; } + + private readonly IDataSeeder _dataSeeder; + private readonly IEnumerable _dbSchemaMigrators; + private readonly ITenantRepository _tenantRepository; + private readonly ICurrentTenant _currentTenant; + + public BookStoreDbMigrationService( + IDataSeeder dataSeeder, + ITenantRepository tenantRepository, + ICurrentTenant currentTenant, + IEnumerable dbSchemaMigrators) + { + _dataSeeder = dataSeeder; + _tenantRepository = tenantRepository; + _currentTenant = currentTenant; + _dbSchemaMigrators = dbSchemaMigrators; + + Logger = NullLogger.Instance; + } + + public async Task MigrateAsync() + { + + Logger.LogInformation("Started database migrations..."); + + await MigrateDatabaseSchemaAsync(); + await SeedDataAsync(); + + Logger.LogInformation($"Successfully completed host database migrations."); + + if (MultiTenancyConsts.IsEnabled) + { + + var tenants = await _tenantRepository.GetListAsync(includeDetails: true); + + var migratedDatabaseSchemas = new HashSet(); + foreach (var tenant in tenants) + { + using (_currentTenant.Change(tenant.Id)) + { + if (tenant.ConnectionStrings.Any()) + { + var tenantConnectionStrings = tenant.ConnectionStrings + .Select(x => x.Value) + .ToList(); + + if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings)) + { + await MigrateDatabaseSchemaAsync(tenant); + + migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings); + } + } + + await SeedDataAsync(tenant); + } + + Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations."); + } + + Logger.LogInformation("Successfully completed all database migrations."); + } + Logger.LogInformation("You can safely end this process..."); + } + + private async Task MigrateDatabaseSchemaAsync(Tenant? tenant = null) + { + Logger.LogInformation( + $"Migrating schema for {(tenant == null ? "host" : tenant.Name + " tenant")} database..."); + + foreach (var migrator in _dbSchemaMigrators) + { + await migrator.MigrateAsync(); + } + } + + private async Task SeedDataAsync(Tenant? tenant = null) + { + Logger.LogInformation($"Executing {(tenant == null ? "host" : tenant.Name + " tenant")} database seed..."); + + await _dataSeeder.SeedAsync(new DataSeedContext(tenant?.Id) + .WithProperty(IdentityDataSeedContributor.AdminEmailPropertyName, + BookStoreConsts.AdminEmailDefaultValue) + .WithProperty(IdentityDataSeedContributor.AdminPasswordPropertyName, + BookStoreConsts.AdminPasswordDefaultValue) + ); + } + +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Data/IBookStoreDbSchemaMigrator.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Data/IBookStoreDbSchemaMigrator.cs new file mode 100644 index 0000000..372dbc5 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Data/IBookStoreDbSchemaMigrator.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace BookStore.Data; + +public interface IBookStoreDbSchemaMigrator +{ + Task MigrateAsync(); +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Data/NullBookStoreDbSchemaMigrator.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Data/NullBookStoreDbSchemaMigrator.cs new file mode 100644 index 0000000..cc531af --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Data/NullBookStoreDbSchemaMigrator.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace BookStore.Data; + +/* This is used if database provider does't define + * IBookStoreDbSchemaMigrator implementation. + */ +public class NullBookStoreDbSchemaMigrator : IBookStoreDbSchemaMigrator, ITransientDependency +{ + public Task MigrateAsync() + { + return Task.CompletedTask; + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Identity/ChangeIdentityPasswordPolicySettingDefinitionProvider.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Identity/ChangeIdentityPasswordPolicySettingDefinitionProvider.cs new file mode 100644 index 0000000..4f4443a --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Identity/ChangeIdentityPasswordPolicySettingDefinitionProvider.cs @@ -0,0 +1,34 @@ +using Volo.Abp.Identity.Settings; +using Volo.Abp.Settings; + +namespace BookStore.Identity; + +public class ChangeIdentityPasswordPolicySettingDefinitionProvider : SettingDefinitionProvider +{ + public override void Define(ISettingDefinitionContext context) + { + var requireNonAlphanumeric = context.GetOrNull(IdentitySettingNames.Password.RequireNonAlphanumeric); + if (requireNonAlphanumeric != null) + { + requireNonAlphanumeric.DefaultValue = false.ToString(); + } + + var requireLowercase = context.GetOrNull(IdentitySettingNames.Password.RequireLowercase); + if (requireLowercase != null) + { + requireLowercase.DefaultValue = false.ToString(); + } + + var requireUppercase = context.GetOrNull(IdentitySettingNames.Password.RequireUppercase); + if (requireUppercase != null) + { + requireUppercase.DefaultValue = false.ToString(); + } + + var requireDigit = context.GetOrNull(IdentitySettingNames.Password.RequireDigit); + if (requireDigit != null) + { + requireDigit.DefaultValue = false.ToString(); + } + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/OpenIddict/OpenIddictDataSeedContributor.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/OpenIddict/OpenIddictDataSeedContributor.cs new file mode 100644 index 0000000..fcd3e91 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/OpenIddict/OpenIddictDataSeedContributor.cs @@ -0,0 +1,390 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Localization; +using OpenIddict.Abstractions; +using Volo.Abp; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.OpenIddict.Applications; +using Volo.Abp.OpenIddict.Scopes; +using Volo.Abp.PermissionManagement; +using Volo.Abp.Uow; + +namespace BookStore.OpenIddict; + +/* Creates initial data that is needed to property run the application + * and make client-to-server communication possible. + */ +public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDependency +{ + private readonly IConfiguration _configuration; + private readonly IOpenIddictApplicationRepository _openIddictApplicationRepository; + private readonly IAbpApplicationManager _applicationManager; + private readonly IOpenIddictScopeRepository _openIddictScopeRepository; + private readonly IOpenIddictScopeManager _scopeManager; + private readonly IPermissionDataSeeder _permissionDataSeeder; + private readonly IStringLocalizer L; + + public OpenIddictDataSeedContributor( + IConfiguration configuration, + IOpenIddictApplicationRepository openIddictApplicationRepository, + IAbpApplicationManager applicationManager, + IOpenIddictScopeRepository openIddictScopeRepository, + IOpenIddictScopeManager scopeManager, + IPermissionDataSeeder permissionDataSeeder, + IStringLocalizer l) + { + _configuration = configuration; + _openIddictApplicationRepository = openIddictApplicationRepository; + _applicationManager = applicationManager; + _openIddictScopeRepository = openIddictScopeRepository; + _scopeManager = scopeManager; + _permissionDataSeeder = permissionDataSeeder; + L = l; + } + + [UnitOfWork] + public virtual async Task SeedAsync(DataSeedContext context) + { + await CreateScopesAsync(); + await CreateApplicationsAsync(); + } + + private async Task CreateScopesAsync() + { + if (await _openIddictScopeRepository.FindByNameAsync("BookStore") == null) + { + await _scopeManager.CreateAsync(new OpenIddictScopeDescriptor { + Name = "BookStore", DisplayName = "BookStore API", Resources = { "BookStore" } + }); + } + } + + private async Task CreateApplicationsAsync() + { + var commonScopes = new List { + OpenIddictConstants.Permissions.Scopes.Address, + OpenIddictConstants.Permissions.Scopes.Email, + OpenIddictConstants.Permissions.Scopes.Phone, + OpenIddictConstants.Permissions.Scopes.Profile, + OpenIddictConstants.Permissions.Scopes.Roles, + "BookStore" + }; + + var configurationSection = _configuration.GetSection("OpenIddict:Applications"); + + + //Console Test / Angular Client + var consoleAndAngularClientId = configurationSection["BookStore_App:ClientId"]; + if (!consoleAndAngularClientId.IsNullOrWhiteSpace()) + { + var consoleAndAngularClientRootUrl = configurationSection["BookStore_App:RootUrl"]?.TrimEnd('/'); + await CreateApplicationAsync( + applicationType: OpenIddictConstants.ApplicationTypes.Web, + name: consoleAndAngularClientId!, + type: OpenIddictConstants.ClientTypes.Public, + consentType: OpenIddictConstants.ConsentTypes.Implicit, + displayName: "Console Test / Angular Application", + secret: null, + grantTypes: new List { + OpenIddictConstants.GrantTypes.AuthorizationCode, + OpenIddictConstants.GrantTypes.Password, + OpenIddictConstants.GrantTypes.ClientCredentials, + OpenIddictConstants.GrantTypes.RefreshToken, + "LinkLogin", + "Impersonation" + }, + scopes: commonScopes, + redirectUris: new List { consoleAndAngularClientRootUrl }, + postLogoutRedirectUris: new List { consoleAndAngularClientRootUrl }, + clientUri: consoleAndAngularClientRootUrl, + logoUri: "/images/clients/angular.svg" + ); + } + + + + + // Blazor Client + var blazorClientId = configurationSection["BookStore_Blazor:ClientId"]; + if (!blazorClientId.IsNullOrWhiteSpace()) + { + var blazorRootUrl = configurationSection["BookStore_Blazor:RootUrl"]?.TrimEnd('/'); + + await CreateApplicationAsync( + applicationType: OpenIddictConstants.ApplicationTypes.Web, + name: blazorClientId!, + type: OpenIddictConstants.ClientTypes.Public, + consentType: OpenIddictConstants.ConsentTypes.Implicit, + displayName: "Blazor Application", + secret: null, + grantTypes: new List { + OpenIddictConstants.GrantTypes.AuthorizationCode, + OpenIddictConstants.GrantTypes.RefreshToken, + }, + scopes: commonScopes, + redirectUris: new List { $"{blazorRootUrl}/authentication/login-callback" }, + postLogoutRedirectUris: new List { $"{blazorRootUrl}/authentication/logout-callback" }, + clientUri: blazorRootUrl, + logoUri: "/images/clients/blazor.svg" + ); + } + + + + // Swagger Client + var swaggerClientId = configurationSection["BookStore_Swagger:ClientId"]; + if (!swaggerClientId.IsNullOrWhiteSpace()) + { + var swaggerRootUrl = configurationSection["BookStore_Swagger:RootUrl"]?.TrimEnd('/'); + + await CreateApplicationAsync( + applicationType: OpenIddictConstants.ApplicationTypes.Web, + name: swaggerClientId!, + type: OpenIddictConstants.ClientTypes.Public, + consentType: OpenIddictConstants.ConsentTypes.Implicit, + displayName: "Swagger Application", + secret: null, + grantTypes: new List { OpenIddictConstants.GrantTypes.AuthorizationCode, }, + scopes: commonScopes, + redirectUris: new List { $"{swaggerRootUrl}/swagger/oauth2-redirect.html" }, + clientUri: swaggerRootUrl.EnsureEndsWith('/') + "swagger", + logoUri: "/images/clients/swagger.svg" + ); + } + + + } + + private async Task CreateApplicationAsync( + [NotNull] string applicationType, + [NotNull] string name, + [NotNull] string type, + [NotNull] string consentType, + string displayName, + string? secret, + List grantTypes, + List scopes, + List? redirectUris = null, + List? postLogoutRedirectUris = null, + List? permissions = null, + string? clientUri = null, + string? logoUri = null) + { + if (!string.IsNullOrEmpty(secret) && string.Equals(type, OpenIddictConstants.ClientTypes.Public, + StringComparison.OrdinalIgnoreCase)) + { + throw new BusinessException(L["NoClientSecretCanBeSetForPublicApplications"]); + } + + if (string.IsNullOrEmpty(secret) && string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, + StringComparison.OrdinalIgnoreCase)) + { + throw new BusinessException(L["TheClientSecretIsRequiredForConfidentialApplications"]); + } + + var client = await _openIddictApplicationRepository.FindByClientIdAsync(name); + + var application = new AbpApplicationDescriptor { + ApplicationType = applicationType, + ClientId = name, + ClientType = type, + ClientSecret = secret, + ConsentType = consentType, + DisplayName = displayName, + ClientUri = clientUri, + LogoUri = logoUri, + }; + + Check.NotNullOrEmpty(grantTypes, nameof(grantTypes)); + Check.NotNullOrEmpty(scopes, nameof(scopes)); + + if (new[] { OpenIddictConstants.GrantTypes.AuthorizationCode, OpenIddictConstants.GrantTypes.Implicit }.All( + grantTypes.Contains)) + { + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeIdToken); + + if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) + { + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeIdTokenToken); + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeToken); + } + } + + if (!redirectUris.IsNullOrEmpty() || !postLogoutRedirectUris.IsNullOrEmpty()) + { + application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.EndSession); + } + + var buildInGrantTypes = new[] { + OpenIddictConstants.GrantTypes.Implicit, OpenIddictConstants.GrantTypes.Password, + OpenIddictConstants.GrantTypes.AuthorizationCode, OpenIddictConstants.GrantTypes.ClientCredentials, + OpenIddictConstants.GrantTypes.DeviceCode, OpenIddictConstants.GrantTypes.RefreshToken + }; + + foreach (var grantType in grantTypes) + { + if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode) + { + application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode); + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.Code); + } + + if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode || + grantType == OpenIddictConstants.GrantTypes.Implicit) + { + application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Authorization); + } + + if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode || + grantType == OpenIddictConstants.GrantTypes.ClientCredentials || + grantType == OpenIddictConstants.GrantTypes.Password || + grantType == OpenIddictConstants.GrantTypes.RefreshToken || + grantType == OpenIddictConstants.GrantTypes.DeviceCode) + { + application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Token); + application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Revocation); + application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Introspection); + } + + if (grantType == OpenIddictConstants.GrantTypes.ClientCredentials) + { + application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials); + } + + if (grantType == OpenIddictConstants.GrantTypes.Implicit) + { + application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Implicit); + } + + if (grantType == OpenIddictConstants.GrantTypes.Password) + { + application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Password); + } + + if (grantType == OpenIddictConstants.GrantTypes.RefreshToken) + { + application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.RefreshToken); + } + + if (grantType == OpenIddictConstants.GrantTypes.DeviceCode) + { + application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.DeviceCode); + application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.DeviceAuthorization); + } + + if (grantType == OpenIddictConstants.GrantTypes.Implicit) + { + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.IdToken); + if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) + { + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.IdTokenToken); + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.Token); + } + } + + if (!buildInGrantTypes.Contains(grantType)) + { + application.Permissions.Add(OpenIddictConstants.Permissions.Prefixes.GrantType + grantType); + } + } + + var buildInScopes = new[] { + OpenIddictConstants.Permissions.Scopes.Address, OpenIddictConstants.Permissions.Scopes.Email, + OpenIddictConstants.Permissions.Scopes.Phone, OpenIddictConstants.Permissions.Scopes.Profile, + OpenIddictConstants.Permissions.Scopes.Roles + }; + + foreach (var scope in scopes) + { + if (buildInScopes.Contains(scope)) + { + application.Permissions.Add(scope); + } + else + { + application.Permissions.Add(OpenIddictConstants.Permissions.Prefixes.Scope + scope); + } + } + + if (!redirectUris.IsNullOrEmpty()) + { + foreach (var redirectUri in redirectUris!.Where(redirectUri => !redirectUri.IsNullOrWhiteSpace())) + { + if (!Uri.TryCreate(redirectUri, UriKind.Absolute, out var uri) || !uri.IsWellFormedOriginalString()) + { + throw new BusinessException(L["InvalidRedirectUri", redirectUri]); + } + + if (application.RedirectUris.All(x => x != uri)) + { + application.RedirectUris.Add(uri); + } + } + + } + + if (!postLogoutRedirectUris.IsNullOrEmpty()) + { + foreach (var postLogoutRedirectUri in postLogoutRedirectUris!.Where(postLogoutRedirectUri => !postLogoutRedirectUri.IsNullOrWhiteSpace())) + { + if (!Uri.TryCreate(postLogoutRedirectUri, UriKind.Absolute, out var uri) || + !uri.IsWellFormedOriginalString()) + { + throw new BusinessException(L["InvalidPostLogoutRedirectUri", postLogoutRedirectUri]); + } + + if (application.PostLogoutRedirectUris.All(x => x != uri)) + { + application.PostLogoutRedirectUris.Add(uri); + } + } + } + + if (permissions != null) + { + await _permissionDataSeeder.SeedAsync( + ClientPermissionValueProvider.ProviderName, + name, + permissions, + null + ); + } + + if (client == null) + { + await _applicationManager.CreateAsync(application); + return; + } + + if (!HasSameRedirectUris(client, application)) + { + client.RedirectUris = JsonSerializer.Serialize(application.RedirectUris.Select(q => q.ToString().RemovePostFix("/"))); + client.PostLogoutRedirectUris = JsonSerializer.Serialize(application.PostLogoutRedirectUris.Select(q => q.ToString().RemovePostFix("/"))); + + await _applicationManager.UpdateAsync(client.ToModel()); + } + + if (!HasSameScopes(client, application)) + { + client.Permissions = JsonSerializer.Serialize(application.Permissions.Select(q => q.ToString())); + await _applicationManager.UpdateAsync(client.ToModel()); + } + } + + private bool HasSameRedirectUris(OpenIddictApplication existingClient, AbpApplicationDescriptor application) + { + return existingClient.RedirectUris == JsonSerializer.Serialize(application.RedirectUris.Select(q => q.ToString().RemovePostFix("/"))); + } + + private bool HasSameScopes(OpenIddictApplication existingClient, AbpApplicationDescriptor application) + { + return existingClient.Permissions == JsonSerializer.Serialize(application.Permissions.Select(q => q.ToString().TrimEnd('/'))); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Properties/AssemblyInfo.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4dbf4b3 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; +[assembly:InternalsVisibleToAttribute("BookStore.Domain.Tests")] +[assembly:InternalsVisibleToAttribute("BookStore.TestBase")] diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Settings/BookStoreSettingDefinitionProvider.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Settings/BookStoreSettingDefinitionProvider.cs new file mode 100644 index 0000000..ff44a4d --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Settings/BookStoreSettingDefinitionProvider.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Settings; + +namespace BookStore.Settings; + +public class BookStoreSettingDefinitionProvider : SettingDefinitionProvider +{ + public override void Define(ISettingDefinitionContext context) + { + //Define your own settings here. Example: + //context.Add(new SettingDefinition(BookStoreSettings.MySetting1)); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Settings/BookStoreSettings.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Settings/BookStoreSettings.cs new file mode 100644 index 0000000..45771fd --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.Domain/Settings/BookStoreSettings.cs @@ -0,0 +1,9 @@ +namespace BookStore.Settings; + +public static class BookStoreSettings +{ + private const string Prefix = "BookStore"; + + //Add your own setting names here. Example: + //public const string MySetting1 = Prefix + ".MySetting1"; +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Client/BookStore.HttpApi.Client.abppkg b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Client/BookStore.HttpApi.Client.abppkg new file mode 100644 index 0000000..7deef5e --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Client/BookStore.HttpApi.Client.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.http-api-client" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Client/BookStore.HttpApi.Client.abppkg.analyze.json b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Client/BookStore.HttpApi.Client.abppkg.analyze.json new file mode 100644 index 0000000..615eeda --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Client/BookStore.HttpApi.Client.abppkg.analyze.json @@ -0,0 +1,118 @@ +{ + "name": "BookStore.HttpApi.Client", + "hash": "", + "contents": [ + { + "namespace": "BookStore", + "dependsOnModules": [ + { + "declaringAssemblyName": "BookStore.Application.Contracts", + "namespace": "BookStore", + "name": "BookStoreApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.PermissionManagement.HttpApi.Client", + "namespace": "Volo.Abp.PermissionManagement", + "name": "AbpPermissionManagementHttpApiClientModule" + }, + { + "declaringAssemblyName": "Volo.Abp.FeatureManagement.HttpApi.Client", + "namespace": "Volo.Abp.FeatureManagement", + "name": "AbpFeatureManagementHttpApiClientModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Identity.Pro.HttpApi.Client", + "namespace": "Volo.Abp.Identity", + "name": "AbpIdentityHttpApiClientModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Account.Pro.Admin.HttpApi.Client", + "namespace": "Volo.Abp.Account", + "name": "AbpAccountAdminHttpApiClientModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Account.Pro.Public.HttpApi.Client", + "namespace": "Volo.Abp.Account", + "name": "AbpAccountPublicHttpApiClientModule" + }, + { + "declaringAssemblyName": "Volo.Abp.AuditLogging.HttpApi.Client", + "namespace": "Volo.Abp.AuditLogging", + "name": "AbpAuditLoggingHttpApiClientModule" + }, + { + "declaringAssemblyName": "Volo.Abp.OpenIddict.Pro.HttpApi.Client", + "namespace": "Volo.Abp.OpenIddict", + "name": "AbpOpenIddictProHttpApiClientModule" + }, + { + "declaringAssemblyName": "Volo.Abp.TextTemplateManagement.HttpApi.Client", + "namespace": "Volo.Abp.TextTemplateManagement", + "name": "TextTemplateManagementHttpApiClientModule" + }, + { + "declaringAssemblyName": "Volo.Abp.LanguageManagement.HttpApi.Client", + "namespace": "Volo.Abp.LanguageManagement", + "name": "LanguageManagementHttpApiClientModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Gdpr.HttpApi.Client", + "namespace": "Volo.Abp.Gdpr", + "name": "AbpGdprHttpApiClientModule" + }, + { + "declaringAssemblyName": "Volo.Abp.SettingManagement.HttpApi.Client", + "namespace": "Volo.Abp.SettingManagement", + "name": "AbpSettingManagementHttpApiClientModule" + } + ], + "implementingInterfaces": [ + { + "name": "IAbpModule", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IAbpModule" + }, + { + "name": "IOnPreApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPreApplicationInitialization" + }, + { + "name": "IOnApplicationInitialization", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationInitialization" + }, + { + "name": "IOnPostApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPostApplicationInitialization" + }, + { + "name": "IOnApplicationShutdown", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationShutdown" + }, + { + "name": "IPreConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPreConfigureServices" + }, + { + "name": "IPostConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPostConfigureServices" + } + ], + "contentType": "abpModule", + "name": "BookStoreHttpApiClientModule", + "summary": null + } + ] +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Client/BookStore.HttpApi.Client.csproj b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Client/BookStore.HttpApi.Client.csproj new file mode 100644 index 0000000..6ef895f --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Client/BookStore.HttpApi.Client.csproj @@ -0,0 +1,32 @@ + + + + + + net9.0 + enable + BookStore + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Client/BookStoreHttpApiClientModule.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Client/BookStoreHttpApiClientModule.cs new file mode 100644 index 0000000..7618aa9 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Client/BookStoreHttpApiClientModule.cs @@ -0,0 +1,38 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Account; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement; +using Volo.Abp.SettingManagement; +using Volo.Abp.VirtualFileSystem; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Identity; +using Volo.Abp.TenantManagement; + +namespace BookStore; + +[DependsOn( + typeof(BookStoreApplicationContractsModule), + typeof(AbpPermissionManagementHttpApiClientModule), + typeof(AbpFeatureManagementHttpApiClientModule), + typeof(AbpAccountHttpApiClientModule), + typeof(AbpIdentityHttpApiClientModule), + typeof(AbpTenantManagementHttpApiClientModule), + typeof(AbpSettingManagementHttpApiClientModule) +)] +public class BookStoreHttpApiClientModule : AbpModule +{ + public const string RemoteServiceName = "Default"; + + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddHttpClientProxies( + typeof(BookStoreApplicationContractsModule).Assembly, + RemoteServiceName + ); + + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/BookStore.HttpApi.Host.abppkg b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/BookStore.HttpApi.Host.abppkg new file mode 100644 index 0000000..d5b2efb --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/BookStore.HttpApi.Host.abppkg @@ -0,0 +1,3 @@ +{ + "role": "host.http-api" +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/BookStore.HttpApi.Host.csproj b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/BookStore.HttpApi.Host.csproj new file mode 100644 index 0000000..e543982 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/BookStore.HttpApi.Host.csproj @@ -0,0 +1,52 @@ + + + + + + net9.0 + enable + InProcess + BookStore + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/BookStoreBrandingProvider.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/BookStoreBrandingProvider.cs new file mode 100644 index 0000000..973090e --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/BookStoreBrandingProvider.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.Localization; +using BookStore.Localization; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Ui.Branding; + +namespace BookStore; + +[Dependency(ReplaceServices = true)] +public class BookStoreBrandingProvider : DefaultBrandingProvider +{ + private IStringLocalizer _localizer; + + public BookStoreBrandingProvider(IStringLocalizer localizer) + { + _localizer = localizer; + } + + public override string AppName => _localizer["AppName"]; +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/BookStoreHttpApiHostModule.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/BookStoreHttpApiHostModule.cs new file mode 100644 index 0000000..07c1b4c --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/BookStoreHttpApiHostModule.cs @@ -0,0 +1,271 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography.X509Certificates; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.HttpOverrides; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.AspNetCore.Extensions.DependencyInjection; +using OpenIddict.Validation.AspNetCore; +using OpenIddict.Server.AspNetCore; +using BookStore.MongoDB; +using BookStore.MultiTenancy; +using Microsoft.OpenApi.Models; +using Volo.Abp; +using Volo.Abp.Studio; +using Volo.Abp.Account; +using Volo.Abp.Account.Web; +using Volo.Abp.AspNetCore.MultiTenancy; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Autofac; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.UI.Navigation.Urls; +using Volo.Abp.VirtualFileSystem; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Bundling; +using Microsoft.AspNetCore.Hosting; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Identity; +using Volo.Abp.OpenIddict; +using Volo.Abp.Swashbuckle; +using Volo.Abp.Studio.Client.AspNetCore; +using Volo.Abp.Security.Claims; + +namespace BookStore; + +[DependsOn( + typeof(BookStoreHttpApiModule), + typeof(AbpStudioClientAspNetCoreModule), + typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule), + typeof(AbpAutofacModule), + typeof(AbpAspNetCoreMultiTenancyModule), + typeof(BookStoreApplicationModule), + typeof(BookStoreMongoDbModule), + typeof(AbpAccountWebOpenIddictModule), + typeof(AbpSwashbuckleModule), + typeof(AbpAspNetCoreSerilogModule) + )] +public class BookStoreHttpApiHostModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + var configuration = context.Services.GetConfiguration(); + + PreConfigure(builder => + { + builder.AddValidation(options => + { + options.AddAudiences("BookStore"); + options.UseLocalServer(); + options.UseAspNetCore(); + }); + }); + + if (!hostingEnvironment.IsDevelopment()) + { + PreConfigure(options => + { + options.AddDevelopmentEncryptionAndSigningCertificate = false; + }); + + PreConfigure(serverBuilder => + { + serverBuilder.AddProductionEncryptionAndSigningCertificate("openiddict.pfx", configuration["AuthServer:CertificatePassPhrase"]!); + serverBuilder.SetIssuer(new Uri(configuration["AuthServer:Authority"]!)); + }); + } + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + var hostingEnvironment = context.Services.GetHostingEnvironment(); + + if (!configuration.GetValue("App:DisablePII")) + { + Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true; + Microsoft.IdentityModel.Logging.IdentityModelEventSource.LogCompleteSecurityArtifact = true; + } + + if (!configuration.GetValue("AuthServer:RequireHttpsMetadata")) + { + Configure(options => + { + options.DisableTransportSecurityRequirement = true; + }); + + Configure(options => + { + options.ForwardedHeaders = ForwardedHeaders.XForwardedProto; + }); + } + + ConfigureAuthentication(context); + ConfigureUrls(configuration); + ConfigureBundles(); + ConfigureConventionalControllers(); + ConfigureSwagger(context, configuration); + ConfigureVirtualFileSystem(context); + ConfigureCors(context, configuration); + } + + private void ConfigureAuthentication(ServiceConfigurationContext context) + { + context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); + context.Services.Configure(options => + { + options.IsDynamicClaimsEnabled = true; + }); + } + + private void ConfigureUrls(IConfiguration configuration) + { + Configure(options => + { + options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; + options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"]?.Split(',') ?? Array.Empty()); + }); + } + + private void ConfigureBundles() + { + Configure(options => + { + options.StyleBundles.Configure( + LeptonXLiteThemeBundles.Styles.Global, + bundle => + { + bundle.AddFiles("/global-styles.css"); + } + ); + + options.ScriptBundles.Configure( + LeptonXLiteThemeBundles.Scripts.Global, + bundle => + { + bundle.AddFiles("/global-scripts.js"); + } + ); + }); + } + + + private void ConfigureVirtualFileSystem(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + + if (hostingEnvironment.IsDevelopment()) + { + Configure(options => + { + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}BookStore.Domain.Shared")); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}BookStore.Domain")); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}BookStore.Application.Contracts")); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}BookStore.Application")); + }); + } + } + + private void ConfigureConventionalControllers() + { + Configure(options => + { + options.ConventionalControllers.Create(typeof(BookStoreApplicationModule).Assembly); + }); + } + + private static void ConfigureSwagger(ServiceConfigurationContext context, IConfiguration configuration) + { + context.Services.AddAbpSwaggerGenWithOidc( + configuration["AuthServer:Authority"]!, + ["BookStore"], + [AbpSwaggerOidcFlows.AuthorizationCode], + null, + options => + { + options.SwaggerDoc("v1", new OpenApiInfo { Title = "BookStore API", Version = "v1" }); + options.DocInclusionPredicate((docName, description) => true); + options.CustomSchemaIds(type => type.FullName); + }); + } + + private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration) + { + context.Services.AddCors(options => + { + options.AddDefaultPolicy(builder => + { + builder + .WithOrigins( + configuration["App:CorsOrigins"]? + .Split(",", StringSplitOptions.RemoveEmptyEntries) + .Select(o => o.Trim().RemovePostFix("/")) + .ToArray() ?? Array.Empty() + ) + .WithAbpExposedHeaders() + .SetIsOriginAllowedToAllowWildcardSubdomains() + .AllowAnyHeader() + .AllowAnyMethod() + .AllowCredentials(); + }); + }); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + var env = context.GetEnvironment(); + + app.UseForwardedHeaders(); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseAbpRequestLocalization(); + + if (!env.IsDevelopment()) + { + app.UseErrorPage(); + } + + app.UseRouting(); + app.MapAbpStaticAssets(); + app.UseAbpStudioLink(); + app.UseAbpSecurityHeaders(); + app.UseCors(); + app.UseAuthentication(); + app.UseAbpOpenIddictValidation(); + + if (MultiTenancyConsts.IsEnabled) + { + app.UseMultiTenancy(); + } + + app.UseUnitOfWork(); + app.UseDynamicClaims(); + app.UseAuthorization(); + + app.UseSwagger(); + app.UseAbpSwaggerUI(options => + { + options.SwaggerEndpoint("/swagger/v1/swagger.json", "BookStore API"); + + var configuration = context.ServiceProvider.GetRequiredService(); + options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); + }); + app.UseAuditing(); + app.UseAbpSerilogEnrichers(); + app.UseConfiguredEndpoints(); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Dockerfile b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Dockerfile new file mode 100644 index 0000000..3e41823 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Dockerfile @@ -0,0 +1,5 @@ +FROM mcr.microsoft.com/dotnet/aspnet:9.0 +COPY bin/Release/net9.0/publish/ app/ +WORKDIR /app +ENV ASPNETCORE_URLS=http://+:80 +ENTRYPOINT ["dotnet", "BookStore.HttpApi.Host.dll"] \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Dockerfile.local b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Dockerfile.local new file mode 100644 index 0000000..1d2cd70 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Dockerfile.local @@ -0,0 +1,18 @@ +FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base +USER $APP_UID +EXPOSE 8080 +EXPOSE 8081 + +COPY bin/Release/net9.0/publish/ app/ +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build +WORKDIR /src +RUN dotnet dev-certs https -v -ep openiddict.pfx -p 2dae3a4f-9e73-4cb7-b7b9-7ec95c44e1a3 +RUN chmod 644 openiddict.pfx + +FROM base AS final +WORKDIR /app +COPY --from=build /src . + +ENTRYPOINT ["dotnet", "BookStore.HttpApi.Host.dll"] \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Pages/Index.cshtml b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Pages/Index.cshtml new file mode 100644 index 0000000..88cc019 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Pages/Index.cshtml @@ -0,0 +1,127 @@ +@page +@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Http.Extensions +@using BookStore.Localization +@using BookStore.Pages +@using Volo.Abp.Account.Localization +@using Volo.Abp.Users +@using Volo.Abp.AspNetCore.Mvc.UI.Theming +@using Volo.Abp.Ui.Branding +@model IndexModel +@inject IHtmlLocalizer L +@inject IHtmlLocalizer AccountLocalizer +@inject ICurrentUser CurrentUser +@inject IBrandingProvider BrandingProvider +@inject ITheme Theme +@{ + Layout = Theme.GetEmptyLayout(); +} + + + + + + + + + @if (!BrandingProvider.LogoUrl.IsNullOrEmpty()) + { + + } + else + { + @BrandingProvider.AppName + } + + + + + + + + + + + @if (CurrentUser.IsAuthenticated) + { + + + @AccountLocalizer["MyAccount"] + @L["Logout"] + + + + } + else + { + + @L["Login"] + + } + + + + + + @if (Model.CurrentLanguage != null) + { + + } + + @if (Model.Languages != null) + { + + @foreach (var language in Model.Languages) + { + var languageUrl = Url.Content($"~/Abp/Languages/Switch?culture={language.CultureName}&uiCulture={language.UiCultureName}&returnUrl={System.Net.WebUtility.UrlEncode(Request.GetEncodedPathAndQuery())}"); + @language.DisplayName + } + + } + + + + + + + + + @if (Model.Applications != null) + { + @foreach (var application in Model.Applications) + { + + + + + @if (!application.LogoUri.IsNullOrEmpty()) + { + var logoUri = application.LogoUri; + if(application.LogoUri.StartsWith('/')) + { + logoUri = @Url.Content(application.LogoUri.EnsureStartsWith('~')); + } + + + + + } + @application.DisplayName + @application.ClientUri + + + + + } + } + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Pages/Index.cshtml.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Pages/Index.cshtml.cs new file mode 100644 index 0000000..c3c1b1c --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Pages/Index.cshtml.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using System.Globalization; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.Localization; +using Volo.Abp.OpenIddict.Applications; + +namespace BookStore.Pages; + +public class IndexModel : AbpPageModel +{ + public List? Applications { get; protected set; } + + public IReadOnlyList? Languages { get; protected set; } + + public string? CurrentLanguage { get; protected set; } + + protected IOpenIddictApplicationRepository OpenIdApplicationRepository { get; } + + protected ILanguageProvider LanguageProvider { get; } + + public IndexModel(IOpenIddictApplicationRepository openIdApplicationmRepository, ILanguageProvider languageProvider) + { + OpenIdApplicationRepository = openIdApplicationmRepository; + LanguageProvider = languageProvider; + } + + public async Task OnGetAsync() + { + Applications = await OpenIdApplicationRepository.GetListAsync(); + + Languages = await LanguageProvider.GetLanguagesAsync(); + CurrentLanguage = CultureInfo.CurrentCulture.DisplayName; + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Pages/_ViewImports.cshtml b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Pages/_ViewImports.cshtml new file mode 100644 index 0000000..c1da1f5 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Pages/_ViewImports.cshtml @@ -0,0 +1,4 @@ +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Program.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Program.cs new file mode 100644 index 0000000..73b44b7 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Program.cs @@ -0,0 +1,63 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Serilog; +using Serilog.Events; + +namespace BookStore; + +public class Program +{ + public async static Task Main(string[] args) + { + Log.Logger = new LoggerConfiguration() + .WriteTo.Async(c => c.File("Logs/logs.txt")) + .WriteTo.Async(c => c.Console()) + .CreateBootstrapLogger(); + + try + { + Log.Information("Starting BookStore.HttpApi.Host."); + var builder = WebApplication.CreateBuilder(args); + builder.Host + .AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog((context, services, loggerConfiguration) => + { + loggerConfiguration + #if DEBUG + .MinimumLevel.Debug() + #else + .MinimumLevel.Information() + #endif + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) + .Enrich.FromLogContext() + .WriteTo.Async(c => c.File("Logs/logs.txt")) + .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.AbpStudio(services)); + }); + await builder.AddApplicationAsync(); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); + return 0; + } + catch (Exception ex) + { + if (ex is HostAbortedException) + { + throw; + } + + Log.Fatal(ex, "Host terminated unexpectedly!"); + return 1; + } + finally + { + Log.CloseAndFlush(); + } + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Properties/launchSettings.json b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Properties/launchSettings.json new file mode 100644 index 0000000..bebbb6b --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "https://localhost:44318", + "sslPort": 44318 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "BookStore.HttpApi.Host": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "https://localhost:44318", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/abp.resourcemapping.js b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/abp.resourcemapping.js new file mode 100644 index 0000000..4a2ad45 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/abp.resourcemapping.js @@ -0,0 +1,11 @@ +module.exports = { + aliases: { + + }, + clean: [ + + ], + mappings: { + + } +}; diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/appsettings.Development.json b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/appsettings.Development.json new file mode 100644 index 0000000..2c63c08 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/appsettings.Development.json @@ -0,0 +1,2 @@ +{ +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/appsettings.json b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/appsettings.json new file mode 100644 index 0000000..45afff3 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/appsettings.json @@ -0,0 +1,20 @@ +{ + "App": { + "SelfUrl": "https://localhost:44318", + "CorsOrigins": "https://*.BookStore.com,https://localhost:44376", + "RedirectAllowedUrls": "https://localhost:44376", + "DisablePII": false, + "HealthCheckUrl": "/health-status" + }, + "ConnectionStrings": { + "Default": "mongodb://localhost:27017/BookStore" + }, + "AuthServer": { + "Authority": "https://localhost:44318", + "RequireHttpsMetadata": true, + "SwaggerClientId": "BookStore_Swagger", + "CertificatePassPhrase": "2dae3a4f-9e73-4cb7-b7b9-7ec95c44e1a3" + }, + "StringEncryption": { + "DefaultPassPhrase": "gKUiwtJbKPwoWvKG" + }} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/package.json b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/package.json new file mode 100644 index 0000000..5caead1 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/package.json @@ -0,0 +1,8 @@ +{ + "version": "1.0.0", + "name": "my-app", + "private": true, + "dependencies": { + "@abp/aspnetcore.mvc.ui.theme.leptonxlite": "~4.2.0" + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/web.config b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/web.config new file mode 100644 index 0000000..2d34260 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/global-scripts.js b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/global-scripts.js new file mode 100644 index 0000000..e8136b0 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/global-scripts.js @@ -0,0 +1 @@ +/* Your Global Scripts */ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/global-styles.css b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/global-styles.css new file mode 100644 index 0000000..9525cfe --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/global-styles.css @@ -0,0 +1,7 @@ +:root { + --lpx-logo: url('/images/logo/leptonxlite/logo-light.png'); + --lpx-logo-icon: url('/images/logo/leptonxlite/logo-light-thumbnail.png'); +} +:root .abp-account-layout .lpx-brand-logo{ + --lpx-logo: url('/images/logo/leptonxlite/logo-dark.png'); +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/clients/angular.svg b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/clients/angular.svg new file mode 100644 index 0000000..468c4ba --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/clients/angular.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/clients/aspnetcore.svg b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/clients/aspnetcore.svg new file mode 100644 index 0000000..82a2ef8 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/clients/aspnetcore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/clients/blazor.svg b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/clients/blazor.svg new file mode 100644 index 0000000..2f5a30c --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/clients/blazor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/clients/swagger.svg b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/clients/swagger.svg new file mode 100644 index 0000000..908edf5 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/clients/swagger.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/logo/leptonxlite/logo-dark-thumbnail.png b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/logo/leptonxlite/logo-dark-thumbnail.png new file mode 100644 index 0000000..9734a07 Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/logo/leptonxlite/logo-dark-thumbnail.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/logo/leptonxlite/logo-dark.png b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/logo/leptonxlite/logo-dark.png new file mode 100644 index 0000000..a3bbe82 Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/logo/leptonxlite/logo-dark.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/logo/leptonxlite/logo-light-thumbnail.png b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/logo/leptonxlite/logo-light-thumbnail.png new file mode 100644 index 0000000..ca39184 Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/logo/leptonxlite/logo-light-thumbnail.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/logo/leptonxlite/logo-light.png b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/logo/leptonxlite/logo-light.png new file mode 100644 index 0000000..761fb44 Binary files /dev/null and b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/wwwroot/images/logo/leptonxlite/logo-light.png differ diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/yarn.lock b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/yarn.lock new file mode 100644 index 0000000..ab84339 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi.Host/yarn.lock @@ -0,0 +1,306 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@abp/aspnetcore.mvc.ui.theme.leptonxlite@~4.2.0": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.leptonxlite/-/aspnetcore.mvc.ui.theme.leptonxlite-4.2.1.tgz#3e3cc78b0d1d56113d459d61e01125bffada0c21" + integrity sha512-unZMV9HY13Kq00FZROVlo9po+foivENEoM7jUmZWlxOQjxBwa3/VJaxwQIXd9DZOqdpJpi5zUv/pSb6DqiZkfg== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~9.2.1" + +"@abp/aspnetcore.mvc.ui.theme.shared@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.2.1.tgz#35f6de6f106c80592ce70d36b6e8b20c64862803" + integrity sha512-kZz1tgUguGHxwG1MRkbkeXn9sIjbCOHJcBU+w+XuWwCqigM2yaE+KgnASDcjCrjQiPu6i73hf9OwtxXY1UbGMQ== + dependencies: + "@abp/aspnetcore.mvc.ui" "~9.2.1" + "@abp/bootstrap" "~9.2.1" + "@abp/bootstrap-datepicker" "~9.2.1" + "@abp/bootstrap-daterangepicker" "~9.2.1" + "@abp/datatables.net-bs5" "~9.2.1" + "@abp/font-awesome" "~9.2.1" + "@abp/jquery-form" "~9.2.1" + "@abp/jquery-validation-unobtrusive" "~9.2.1" + "@abp/lodash" "~9.2.1" + "@abp/luxon" "~9.2.1" + "@abp/malihu-custom-scrollbar-plugin" "~9.2.1" + "@abp/moment" "~9.2.1" + "@abp/select2" "~9.2.1" + "@abp/sweetalert2" "~9.2.1" + "@abp/timeago" "~9.2.1" + +"@abp/aspnetcore.mvc.ui@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.2.1.tgz#8b30f830d85f7e1f4a386b0ef8d0444e2550bc42" + integrity sha512-0C41JpevGynbyHGeKkqLUSVNK64QETsKVyVWY4fSZkChGHlD09Fn3qIlHJInpBqJ9qNYs5VQ7RRP02PSum9mAg== + dependencies: + ansi-colors "^4.1.3" + +"@abp/bootstrap-datepicker@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.2.1.tgz#373c8715d175ca23a8871bacdb5f017b070254aa" + integrity sha512-uaCpz5EDSZYDacjnYoqTiktTDFGnGJPEHYh5eG4BORlQta53Hvak7m2CkRVjdOaXtuPLi6EbWPSh2bHIfhKRyQ== + dependencies: + bootstrap-datepicker "^1.10.0" + +"@abp/bootstrap-daterangepicker@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.2.1.tgz#b49e17a4753b09d49bfad6774a7f185e7e5bf71c" + integrity sha512-kd6LEACfx7CBIQOAiE/RHFp/WnthE2iz/eivl3fwuz1VgAO0CBIQ7hYoX91GaAIQgt+OAcgGbOl2G6E284EM9Q== + dependencies: + bootstrap-daterangepicker "^3.1.0" + +"@abp/bootstrap@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.2.1.tgz#ddf624e95f1dab4a8fce8d20b6dccd2b3d3f1679" + integrity sha512-NghAVP7M/Y2y9GYDu7IWo8oW7EyJEO+1NnPqCudpjWX4C6B27d7ghJ7I0MfrHoRq9/hBJZ07AKf3KMAZQD99ng== + dependencies: + "@abp/core" "~9.2.1" + bootstrap "^5.3.3" + +"@abp/core@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.2.1.tgz#f7c635f1fe88fc3fbbc4accaa6aee2dc3b5631a7" + integrity sha512-onCzS2w+U+wBv5FRDCVE176AiyZDMm1D5GaqiEnpuAwsBncFpFyZedC95dtPmykagJbpOvHVSPOLyZ2jzGjcYg== + dependencies: + "@abp/utils" "~9.2.1" + +"@abp/datatables.net-bs5@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.2.1.tgz#ff69059e96d5341166fa8d08390e9bb352010e5d" + integrity sha512-NEkf8xWTIYFDs9lAAPs0hOL2UD+pnVwyix/9IAtip3BIkyPFpLCniNWbu1WhuNJpfmLHrWPSqIrouR80gGL7PQ== + dependencies: + "@abp/datatables.net" "~9.2.1" + datatables.net-bs5 "^2.1.8" + +"@abp/datatables.net@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.2.1.tgz#0a5ab74ca44cd785efb487f0447e8acdea9d7aa1" + integrity sha512-A9TSPRNUV0eeCPnpGV9Htu9ZylUf3e03smYcbEROQHe+htwhcEV5dz8SLAI90baPi2g7VnyPav/3efaqo+ETdg== + dependencies: + "@abp/jquery" "~9.2.1" + datatables.net "^2.1.8" + +"@abp/font-awesome@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.2.1.tgz#a387f1cf457bdb6e3cd30bd9f4c455a41f8ca0b1" + integrity sha512-RVo3422BItdAAmafSCH/mT1Ux8q6yUz7nswGep4beP1k1VfmFExj1mgVphIpAlH3DWyzfnwUOq7lLWf/Ul2dOA== + dependencies: + "@abp/core" "~9.2.1" + "@fortawesome/fontawesome-free" "^6.6.0" + +"@abp/jquery-form@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.2.1.tgz#727b391c36e8ff46b62cb01be14715a05fe74b4f" + integrity sha512-n6EpUNNRzilOzP5rYTWr9K2mPQbvBQAuxPiwUZpfwf+QpJrs+NppJMaC06HFbHcSkDDy/utd+P1/sqWaJjL/tw== + dependencies: + "@abp/jquery" "~9.2.1" + jquery-form "^4.3.0" + +"@abp/jquery-validation-unobtrusive@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.2.1.tgz#98215811818e618d96a1dcac6419962fd39c6fef" + integrity sha512-7no3KxRW3agw4EAM5iTvQjE4+m9JrjuMAV20gAU0uVPB2+sHlluEAks0IU9wz76T+Ac7osferUZz33LgdDvIaw== + dependencies: + "@abp/jquery-validation" "~9.2.1" + jquery-validation-unobtrusive "^4.0.0" + +"@abp/jquery-validation@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.2.1.tgz#559c581523e4e098f2bf67627dfe6c7ef0e1c3c1" + integrity sha512-AEGm3agbwr1f5kmXvpBeiDmsS22P88zVr8NJDICGsgBxZofKndXsDFciNZGu6lXF5qXp8AwGRi//QPaCeQsP8g== + dependencies: + "@abp/jquery" "~9.2.1" + jquery-validation "^1.21.0" + +"@abp/jquery@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.2.1.tgz#bbcc9eab9cef528a8163f5062665ffcf2b87c2f0" + integrity sha512-gdDIKMNEpeUdzUu5C/g6j568ytJ7ifaDxBr1NYf2kJ34p7y6rrBmyY+sL+xR3ZlcGgyPGXyFhTLRD7qTjXlkPg== + dependencies: + "@abp/core" "~9.2.1" + jquery "~3.7.1" + +"@abp/lodash@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.2.1.tgz#a80ab7a908a0332b721277b1193209187fab57d8" + integrity sha512-I2+XYqwMi3+FXCv4xp5hBoJmOszg2WR1gnGc+Qd0zwb2VAbG4MvKVFgM/GUAFD8EKlquGyPf3f+4l5FkaPFkrQ== + dependencies: + "@abp/core" "~9.2.1" + lodash "^4.17.21" + +"@abp/luxon@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.2.1.tgz#7e3d197425813cfc6932cd3f9f09f97ecd2f4fc7" + integrity sha512-2tyOZRmq9jQN0Uhg8WaHfEzL0Xeew04sbA8O9bqw28psRbXaWXEVdElRMBNt50sZkFPhHFoxxFN7PR8obs0Qug== + dependencies: + "@abp/core" "~9.2.1" + luxon "^3.5.0" + +"@abp/malihu-custom-scrollbar-plugin@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.2.1.tgz#b0fa249885d442ba84657c7705df73851cb56db1" + integrity sha512-fzgQZsbN0xLMxEWh7znKAI4j0CPb8ciT/3x+QguGZDJf7OFw0YnEWctfEYJnnGG28HpHs1mh64gjqoeceHy0HQ== + dependencies: + "@abp/core" "~9.2.1" + malihu-custom-scrollbar-plugin "^3.1.5" + +"@abp/moment@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.2.1.tgz#9982c65d63171962091b08fc4e0d1ea98cc1f0eb" + integrity sha512-V4KH1WmahP0BoaQGLEY4a0AQyfk1cLeNMk3qCPtuqIUbOFwimJY3oQgpelilEwjI3oD/upMzGphjLGrfQLRM2A== + dependencies: + moment "^2.30.1" + +"@abp/select2@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.2.1.tgz#5c3c6a4b0018b533491d6a46540069782559c57a" + integrity sha512-p743cnoohNLKX11ptnBcN5z9+ZyC11M9mwRR6SWbW5f1Eqvbkq03bf2mDFUfukCNis4RefeURZunPlsBOmRn/A== + dependencies: + "@abp/core" "~9.2.1" + select2 "^4.0.13" + +"@abp/sweetalert2@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.2.1.tgz#3db7e33855614460d2fdc5e3f8b65530902fcd9a" + integrity sha512-fJYLVxc5pAJoSLIcQYf5xRkPVnVQi/5+xwTgOePy3QeygOrAMpGS7vy+MIq7Mn+tBoEFlQ/Jn+NoB04AIYYPFw== + dependencies: + "@abp/core" "~9.2.1" + sweetalert2 "^11.14.1" + +"@abp/timeago@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.2.1.tgz#6904e2d7bda57b436e3385c5fd1899b9cd806dd8" + integrity sha512-fmsPuBouWR/BvhXN53yJpg1Se06uIL7ox8XOgx1MHCe+1vxbXnFCtM2VujfowWtOSTJOzbL1DHcDpFE7JlkOag== + dependencies: + "@abp/jquery" "~9.2.1" + timeago "^1.6.7" + +"@abp/utils@~9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.2.1.tgz#803fd48927ae332309f8a7005806c6aa6e499750" + integrity sha512-+j0SNB/K2j2xTTijy/qCL3ds2c/7OW4nrJ8Ccq17WtEqP+jk2TtJi0EnLqhNTDih0A++XV+pcftUC+cQ0h1cUw== + dependencies: + just-compare "^2.3.0" + +"@fortawesome/fontawesome-free@^6.6.0": + version "6.7.2" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz#8249de9b7e22fcb3ceb5e66090c30a1d5492b81a" + integrity sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA== + +ansi-colors@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +bootstrap-datepicker@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/bootstrap-datepicker/-/bootstrap-datepicker-1.10.0.tgz#61612bbe8bf0a69a5bce32bbcdda93ebb6ccf24a" + integrity sha512-lWxtSYddAQOpbAO8UhYhHLcK6425eWoSjb5JDvZU3ePHEPF6A3eUr51WKaFy4PccU19JRxUG6wEU3KdhtKfvpg== + dependencies: + jquery ">=3.4.0 <4.0.0" + +bootstrap-daterangepicker@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bootstrap-daterangepicker/-/bootstrap-daterangepicker-3.1.0.tgz#632e6fb2de4b6360c5c0a9d5f6adb9aace051fe8" + integrity sha512-oaQZx6ZBDo/dZNyXGVi2rx5GmFXThyQLAxdtIqjtLlYVaQUfQALl5JZMJJZzyDIX7blfy4ppZPAJ10g8Ma4d/g== + dependencies: + jquery ">=1.10" + moment "^2.9.0" + +bootstrap@^5.3.3: + version "5.3.7" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.7.tgz#8640065036124d961d885d80b5945745e1154d90" + integrity sha512-7KgiD8UHjfcPBHEpDNg+zGz8L3LqR3GVwqZiBRFX04a1BCArZOz1r2kjly2HQ0WokqTO0v1nF+QAt8dsW4lKlw== + +datatables.net-bs5@^2.1.8: + version "2.3.2" + resolved "https://registry.yarnpkg.com/datatables.net-bs5/-/datatables.net-bs5-2.3.2.tgz#cffb8007a9f752a997bc70c0dbe9f545edfd18eb" + integrity sha512-1rh0ZTLoiziIQ4oAtgr+IOYVgJfAIceDnbDe535u8kv191pBAdTrKF6ovQO98Xy9mDXLdLNB7QCrLiV/sgPoQw== + dependencies: + datatables.net "2.3.2" + jquery ">=1.7" + +datatables.net@2.3.2, datatables.net@^2.1.8: + version "2.3.2" + resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-2.3.2.tgz#6821f6288e6ad3cb6879c33e0e7e11d4091d330b" + integrity sha512-31TzwIQM0+pr2ZOEOEH6dsHd/WSAl5GDDGPezOHPI3mM2NK4lcDyOoG8xXeWmSbVfbi852LNK5C84fpp4Q+qxg== + dependencies: + jquery ">=1.7" + +jquery-form@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/jquery-form/-/jquery-form-4.3.0.tgz#7d3961c314a1f2d15298f4af1d3943f54f4149c6" + integrity sha512-q3uaVCEWdLOYUCI6dpNdwf/7cJFOsUgdpq6r0taxtGQ5NJSkOzofyWm4jpOuJ5YxdmL1FI5QR+q+HB63HHLGnQ== + dependencies: + jquery ">=1.7.2" + +jquery-mousewheel@>=3.0.6: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jquery-mousewheel/-/jquery-mousewheel-3.2.2.tgz#48c833f6260ee0c46d438a999e7d0060ec9eed0b" + integrity sha512-JP71xTAg08ZY3hcs9ZbYUZ5i+dkSsz4yRl/zpWkAmtzc+kMs5EfPkpkINSidiLYMaR0MTo3DfFGF9WIezMsFQQ== + dependencies: + jquery ">=1.2.6" + +jquery-validation-unobtrusive@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-4.0.0.tgz#dfcf25a558496a2c883db6021d10f5398d15f99d" + integrity sha512-1ervYFFv6LX/rp7ktuLnMakHNG0piNRDyROI8Ir3hL1vPIwylAehB1AY3BPrYJnzW3WmwWryZq+Bz4sazZK9iQ== + dependencies: + jquery "^3.6.0" + jquery-validation ">=1.19" + +jquery-validation@>=1.19, jquery-validation@^1.21.0: + version "1.21.0" + resolved "https://registry.yarnpkg.com/jquery-validation/-/jquery-validation-1.21.0.tgz#78fc05ab76020912a246af3661b3f54a438bca93" + integrity sha512-xNot0rlUIgu7duMcQ5qb6MGkGL/Z1PQaRJQoZAURW9+a/2PGOUxY36o/WyNeP2T9R6jvWB8Z9lUVvvQWI/Zs5w== + +jquery@>=1.10, jquery@>=1.2.6, "jquery@>=1.5.0 <4.0", jquery@>=1.7, jquery@>=1.7.2, "jquery@>=3.4.0 <4.0.0", jquery@^3.6.0, jquery@~3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de" + integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg== + +just-compare@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/just-compare/-/just-compare-2.3.0.tgz#a2adcc1d1940536263275f5a1ef1298bcacfeda7" + integrity sha512-6shoR7HDT+fzfL3gBahx1jZG3hWLrhPAf+l7nCwahDdT9XDtosB9kIF0ZrzUp5QY8dJWfQVr5rnsPqsbvflDzg== + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +luxon@^3.5.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.6.1.tgz#d283ffc4c0076cb0db7885ec6da1c49ba97e47b0" + integrity sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ== + +malihu-custom-scrollbar-plugin@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.5.tgz#310cecc5e59415a1c29e9dfb5d2b6e01d66a29ef" + integrity sha512-lwW3LgI+CNDMPnP4ED2la6oYxWMkCXlnhex+s2wuOLhFDFGnGmQuTQVdRK9bvDLpxs10sGlfErVufJy9ztfgJQ== + dependencies: + jquery-mousewheel ">=3.0.6" + +moment@^2.30.1, moment@^2.9.0: + version "2.30.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" + integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== + +select2@^4.0.13: + version "4.0.13" + resolved "https://registry.yarnpkg.com/select2/-/select2-4.0.13.tgz#0dbe377df3f96167c4c1626033e924372d8ef44d" + integrity sha512-1JeB87s6oN/TDxQQYCvS5EFoQyvV6eYMZZ0AeA4tdFDYWN3BAGZ8npr17UBFddU0lgAt3H0yjX3X6/ekOj1yjw== + +sweetalert2@^11.14.1: + version "11.22.2" + resolved "https://registry.yarnpkg.com/sweetalert2/-/sweetalert2-11.22.2.tgz#d4d82a2edd4e97024306fe37f1bc64fa576e9bc9" + integrity sha512-GFQGzw8ZXF23PO79WMAYXLl4zYmLiaKqYJwcp5eBF07wiI5BYPbZtKi2pcvVmfUQK+FqL1risJAMxugcPbGIyg== + +timeago@^1.6.7: + version "1.6.7" + resolved "https://registry.yarnpkg.com/timeago/-/timeago-1.6.7.tgz#afd467c29a911e697fc22a81888c7c3022783cb5" + integrity sha512-FikcjN98+ij0siKH4VO4dZ358PR3oDDq4Vdl1+sN9gWz1/+JXGr3uZbUShYH/hL7bMhcTpPbplJU5Tej4b4jbQ== + dependencies: + jquery ">=1.5.0 <4.0" diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/BookStore.HttpApi.abppkg b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/BookStore.HttpApi.abppkg new file mode 100644 index 0000000..515bfe6 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/BookStore.HttpApi.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.http-api" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/BookStore.HttpApi.abppkg.analyze.json b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/BookStore.HttpApi.abppkg.analyze.json new file mode 100644 index 0000000..1a43e53 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/BookStore.HttpApi.abppkg.analyze.json @@ -0,0 +1,118 @@ +{ + "name": "BookStore.HttpApi", + "hash": "", + "contents": [ + { + "namespace": "BookStore", + "dependsOnModules": [ + { + "declaringAssemblyName": "BookStore.Application.Contracts", + "namespace": "BookStore", + "name": "BookStoreApplicationContractsModule" + }, + { + "declaringAssemblyName": "Volo.Abp.PermissionManagement.HttpApi", + "namespace": "Volo.Abp.PermissionManagement.HttpApi", + "name": "AbpPermissionManagementHttpApiModule" + }, + { + "declaringAssemblyName": "Volo.Abp.SettingManagement.HttpApi", + "namespace": "Volo.Abp.SettingManagement", + "name": "AbpSettingManagementHttpApiModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Identity.Pro.HttpApi", + "namespace": "Volo.Abp.Identity", + "name": "AbpIdentityHttpApiModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Account.Pro.Admin.HttpApi", + "namespace": "Volo.Abp.Account", + "name": "AbpAccountAdminHttpApiModule" + }, + { + "declaringAssemblyName": "Volo.Abp.TextTemplateManagement.HttpApi", + "namespace": "Volo.Abp.TextTemplateManagement", + "name": "TextTemplateManagementHttpApiModule" + }, + { + "declaringAssemblyName": "Volo.Abp.AuditLogging.HttpApi", + "namespace": "Volo.Abp.AuditLogging", + "name": "AbpAuditLoggingHttpApiModule" + }, + { + "declaringAssemblyName": "Volo.Abp.OpenIddict.Pro.HttpApi", + "namespace": "Volo.Abp.OpenIddict", + "name": "AbpOpenIddictProHttpApiModule" + }, + { + "declaringAssemblyName": "Volo.Abp.LanguageManagement.HttpApi", + "namespace": "Volo.Abp.LanguageManagement", + "name": "LanguageManagementHttpApiModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Gdpr.HttpApi", + "namespace": "Volo.Abp.Gdpr", + "name": "AbpGdprHttpApiModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Account.Pro.Public.HttpApi", + "namespace": "Volo.Abp.Account", + "name": "AbpAccountPublicHttpApiModule" + }, + { + "declaringAssemblyName": "Volo.Abp.FeatureManagement.HttpApi", + "namespace": "Volo.Abp.FeatureManagement", + "name": "AbpFeatureManagementHttpApiModule" + } + ], + "implementingInterfaces": [ + { + "name": "IAbpModule", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IAbpModule" + }, + { + "name": "IOnPreApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPreApplicationInitialization" + }, + { + "name": "IOnApplicationInitialization", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationInitialization" + }, + { + "name": "IOnPostApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPostApplicationInitialization" + }, + { + "name": "IOnApplicationShutdown", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationShutdown" + }, + { + "name": "IPreConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPreConfigureServices" + }, + { + "name": "IPostConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPostConfigureServices" + } + ], + "contentType": "abpModule", + "name": "BookStoreHttpApiModule", + "summary": null + } + ] +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/BookStore.HttpApi.csproj b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/BookStore.HttpApi.csproj new file mode 100644 index 0000000..b818a47 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/BookStore.HttpApi.csproj @@ -0,0 +1,27 @@ + + + + + + net9.0 + enable + BookStore + + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/BookStoreHttpApiModule.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/BookStoreHttpApiModule.cs new file mode 100644 index 0000000..073a6d3 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/BookStoreHttpApiModule.cs @@ -0,0 +1,41 @@ +using Localization.Resources.AbpUi; +using BookStore.Localization; +using Volo.Abp.Account; +using Volo.Abp.SettingManagement; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Identity; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement.HttpApi; +using Volo.Abp.Localization; +using Volo.Abp.TenantManagement; + +namespace BookStore; + + [DependsOn( + typeof(BookStoreApplicationContractsModule), + typeof(AbpPermissionManagementHttpApiModule), + typeof(AbpSettingManagementHttpApiModule), + typeof(AbpAccountHttpApiModule), + typeof(AbpIdentityHttpApiModule), + typeof(AbpTenantManagementHttpApiModule), + typeof(AbpFeatureManagementHttpApiModule) + )] +public class BookStoreHttpApiModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + ConfigureLocalization(); + } + + private void ConfigureLocalization() + { + Configure(options => + { + options.Resources + .Get() + .AddBaseTypes( + typeof(AbpUiResource) + ); + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/Controllers/BookStoreController.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/Controllers/BookStoreController.cs new file mode 100644 index 0000000..88af0e3 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/Controllers/BookStoreController.cs @@ -0,0 +1,14 @@ +using BookStore.Localization; +using Volo.Abp.AspNetCore.Mvc; + +namespace BookStore.Controllers; + +/* Inherit your controllers from this class. + */ +public abstract class BookStoreController : AbpControllerBase +{ + protected BookStoreController() + { + LocalizationResource = typeof(BookStoreResource); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/Models/Test/TestModel.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/Models/Test/TestModel.cs new file mode 100644 index 0000000..e480a88 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.HttpApi/Models/Test/TestModel.cs @@ -0,0 +1,10 @@ +using System; + +namespace BookStore.Models.Test; + +public class TestModel +{ + public string? Name { get; set; } + + public DateTime BirthDate { get; set; } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/BookStore.MongoDB.abppkg b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/BookStore.MongoDB.abppkg new file mode 100644 index 0000000..8b23fd1 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/BookStore.MongoDB.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.mongodb" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/BookStore.MongoDB.abppkg.analyze.json b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/BookStore.MongoDB.abppkg.analyze.json new file mode 100644 index 0000000..172d865 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/BookStore.MongoDB.abppkg.analyze.json @@ -0,0 +1,145 @@ +{ + "name": "BookStore.MongoDB", + "hash": "", + "contents": [ + { + "namespace": "BookStore.MongoDB", + "dependsOnModules": [ + { + "declaringAssemblyName": "BookStore.Domain", + "namespace": "BookStore", + "name": "BookStoreDomainModule" + }, + { + "declaringAssemblyName": "Volo.Abp.PermissionManagement.MongoDB", + "namespace": "Volo.Abp.PermissionManagement.MongoDB", + "name": "AbpPermissionManagementMongoDbModule" + }, + { + "declaringAssemblyName": "Volo.Abp.SettingManagement.MongoDB", + "namespace": "Volo.Abp.SettingManagement.MongoDB", + "name": "AbpSettingManagementMongoDbModule" + }, + { + "declaringAssemblyName": "Volo.Abp.BackgroundJobs.MongoDB", + "namespace": "Volo.Abp.BackgroundJobs.MongoDB", + "name": "AbpBackgroundJobsMongoDbModule" + }, + { + "declaringAssemblyName": "Volo.Abp.AuditLogging.MongoDB", + "namespace": "Volo.Abp.AuditLogging.MongoDB", + "name": "AbpAuditLoggingMongoDbModule" + }, + { + "declaringAssemblyName": "Volo.Abp.FeatureManagement.MongoDB", + "namespace": "Volo.Abp.FeatureManagement.MongoDB", + "name": "AbpFeatureManagementMongoDbModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Identity.Pro.MongoDB", + "namespace": "Volo.Abp.Identity.MongoDB", + "name": "AbpIdentityProMongoDbModule" + }, + { + "declaringAssemblyName": "Volo.Abp.OpenIddict.Pro.MongoDb", + "namespace": "Volo.Abp.OpenIddict.MongoDB", + "name": "AbpOpenIddictProMongoDbModule" + }, + { + "declaringAssemblyName": "Volo.Abp.LanguageManagement.MongoDB", + "namespace": "Volo.Abp.LanguageManagement.MongoDB", + "name": "LanguageManagementMongoDbModule" + }, + { + "declaringAssemblyName": "Volo.Saas.MongoDB", + "namespace": "Volo.Saas.MongoDB", + "name": "SaasMongoDbModule" + }, + { + "declaringAssemblyName": "Volo.Abp.TextTemplateManagement.MongoDB", + "namespace": "Volo.Abp.TextTemplateManagement.MongoDB", + "name": "TextTemplateManagementMongoDbModule" + }, + { + "declaringAssemblyName": "Volo.Abp.Gdpr.MongoDB", + "namespace": "Volo.Abp.Gdpr", + "name": "AbpGdprMongoDbModule" + }, + { + "declaringAssemblyName": "Volo.Abp.BlobStoring.Database.MongoDB", + "namespace": "Volo.Abp.BlobStoring.Database.MongoDB", + "name": "BlobStoringDatabaseMongoDbModule" + } + ], + "implementingInterfaces": [ + { + "name": "IAbpModule", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IAbpModule" + }, + { + "name": "IOnPreApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPreApplicationInitialization" + }, + { + "name": "IOnApplicationInitialization", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationInitialization" + }, + { + "name": "IOnPostApplicationInitialization", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IOnPostApplicationInitialization" + }, + { + "name": "IOnApplicationShutdown", + "namespace": "Volo.Abp", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.IOnApplicationShutdown" + }, + { + "name": "IPreConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPreConfigureServices" + }, + { + "name": "IPostConfigureServices", + "namespace": "Volo.Abp.Modularity", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.Modularity.IPostConfigureServices" + } + ], + "contentType": "abpModule", + "name": "BookStoreMongoDbModule", + "summary": null + }, + { + "namespace": "BookStore.MongoDB", + "connectionStringName": "Default", + "databaseCollections": [], + "implementingInterfaces": [ + { + "name": "IAbpMongoDbContext", + "namespace": "Volo.Abp.MongoDB", + "declaringAssemblyName": "Volo.Abp.MongoDB", + "fullName": "Volo.Abp.MongoDB.IAbpMongoDbContext" + }, + { + "name": "ITransientDependency", + "namespace": "Volo.Abp.DependencyInjection", + "declaringAssemblyName": "Volo.Abp.Core", + "fullName": "Volo.Abp.DependencyInjection.ITransientDependency" + } + ], + "contentType": "mongoDbContext", + "name": "BookStoreMongoDbContext", + "summary": null + } + ] +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/BookStore.MongoDB.csproj b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/BookStore.MongoDB.csproj new file mode 100644 index 0000000..db150a5 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/BookStore.MongoDB.csproj @@ -0,0 +1,30 @@ + + + + + + net9.0 + enable + BookStore + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/MongoDb/BookStoreMongoDbContext.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/MongoDb/BookStoreMongoDbContext.cs new file mode 100644 index 0000000..f16a454 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/MongoDb/BookStoreMongoDbContext.cs @@ -0,0 +1,24 @@ +using Volo.Abp.Data; +using Volo.Abp.MongoDB; +using MongoDB.Driver; + +namespace BookStore.MongoDB; + +[ConnectionStringName("Default")] +public class BookStoreMongoDbContext : AbpMongoDbContext +{ + + /* Add mongo collections here. Example: + * public IMongoCollection Questions => Collection(); + */ + + protected override void CreateModel(IMongoModelBuilder modelBuilder) + { + base.CreateModel(modelBuilder); + + //builder.Entity(b => + //{ + // //... + //}); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/MongoDb/BookStoreMongoDbModule.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/MongoDb/BookStoreMongoDbModule.cs new file mode 100644 index 0000000..9574ea1 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/MongoDb/BookStoreMongoDbModule.cs @@ -0,0 +1,43 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AuditLogging.MongoDB; +using Volo.Abp.BackgroundJobs.MongoDB; +using Volo.Abp.FeatureManagement.MongoDB; +using Volo.Abp.Identity.MongoDB; +using Volo.Abp.OpenIddict.MongoDB; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement.MongoDB; +using Volo.Abp.SettingManagement.MongoDB; +using Volo.Abp.BlobStoring.Database.MongoDB; +using Volo.Abp.Uow; +using Volo.Abp.TenantManagement.MongoDB; + +namespace BookStore.MongoDB; + +[DependsOn( + typeof(BookStoreDomainModule), + typeof(AbpPermissionManagementMongoDbModule), + typeof(AbpSettingManagementMongoDbModule), + typeof(AbpBackgroundJobsMongoDbModule), + typeof(AbpAuditLoggingMongoDbModule), + typeof(AbpFeatureManagementMongoDbModule), + typeof(AbpIdentityMongoDbModule), + typeof(AbpOpenIddictMongoDbModule), + typeof(AbpTenantManagementMongoDbModule), + typeof(BlobStoringDatabaseMongoDbModule) +)] +public class BookStoreMongoDbModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddMongoDbContext(options => + { + options.AddDefaultRepositories(); + }); + + context.Services.AddAlwaysDisableUnitOfWorkTransaction(); + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/MongoDb/MongoDbBookStoreDbSchemaMigrator.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/MongoDb/MongoDbBookStoreDbSchemaMigrator.cs new file mode 100644 index 0000000..3ad09fd --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/MongoDb/MongoDbBookStoreDbSchemaMigrator.cs @@ -0,0 +1,52 @@ +using System; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using MongoDB.Driver; +using BookStore.Data; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MongoDB; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Reflection; + +namespace BookStore.MongoDB; + +public class MongoDbBookStoreDbSchemaMigrator : IBookStoreDbSchemaMigrator, ITransientDependency +{ + private readonly IServiceProvider _serviceProvider; + + public MongoDbBookStoreDbSchemaMigrator(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public async Task MigrateAsync() + { + var dbContexts = _serviceProvider.GetServices(); + var connectionStringResolver = _serviceProvider.GetRequiredService(); + + if (_serviceProvider.GetRequiredService().IsAvailable) + { + dbContexts = dbContexts.Where(x => !x.GetType().IsDefined(typeof(IgnoreMultiTenancyAttribute))); + } + + foreach (var dbContext in dbContexts) + { + var connectionString = + await connectionStringResolver.ResolveAsync( + ConnectionStringNameAttribute.GetConnStringName(dbContext.GetType())); + var mongoUrl = new MongoUrl(connectionString); + var databaseName = mongoUrl.DatabaseName; + var client = new MongoClient(mongoUrl); + + if (databaseName.IsNullOrWhiteSpace()) + { + databaseName = ConnectionStringNameAttribute.GetConnStringName(dbContext.GetType()); + } + + (dbContext as AbpMongoDbContext)?.InitializeCollections(client.GetDatabase(databaseName)); + } + } +} diff --git a/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/Properties/AssemblyInfo.cs b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..db15775 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/src/BookStore.MongoDB/Properties/AssemblyInfo.cs @@ -0,0 +1,2 @@ +using System.Runtime.CompilerServices; +[assembly:InternalsVisibleToAttribute("BookStore.MongoDB.Tests")] diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/BookStore.Application.Tests.abppkg b/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/BookStore.Application.Tests.abppkg new file mode 100644 index 0000000..a686451 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/BookStore.Application.Tests.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/BookStore.Application.Tests.csproj b/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/BookStore.Application.Tests.csproj new file mode 100644 index 0000000..1574640 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/BookStore.Application.Tests.csproj @@ -0,0 +1,20 @@ + + + + + + net9.0 + enable + BookStore + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/BookStoreApplicationTestBase.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/BookStoreApplicationTestBase.cs new file mode 100644 index 0000000..ede63f1 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/BookStoreApplicationTestBase.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Modularity; + +namespace BookStore; + +public abstract class BookStoreApplicationTestBase : BookStoreTestBase + where TStartupModule : IAbpModule +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/BookStoreApplicationTestModule.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/BookStoreApplicationTestModule.cs new file mode 100644 index 0000000..19f3c75 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/BookStoreApplicationTestModule.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Modularity; + +namespace BookStore; + +[DependsOn( + typeof(BookStoreApplicationModule), + typeof(BookStoreDomainTestModule) +)] +public class BookStoreApplicationTestModule : AbpModule +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/Samples/SampleAppServiceTests.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/Samples/SampleAppServiceTests.cs new file mode 100644 index 0000000..7e8575a --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.Application.Tests/Samples/SampleAppServiceTests.cs @@ -0,0 +1,34 @@ +using Shouldly; +using System.Threading.Tasks; +using Volo.Abp.Identity; +using Volo.Abp.Modularity; +using Xunit; + +namespace BookStore.Samples; + +/* This is just an example test class. + * Normally, you don't test code of the modules you are using + * (like IIdentityUserAppService here). + * Only test your own application services. + */ +public abstract class SampleAppServiceTests : BookStoreApplicationTestBase + where TStartupModule : IAbpModule +{ + private readonly IIdentityUserAppService _userAppService; + + protected SampleAppServiceTests() + { + _userAppService = GetRequiredService(); + } + + [Fact] + public async Task Initial_Data_Should_Contain_Admin_User() + { + //Act + var result = await _userAppService.GetListAsync(new GetIdentityUsersInput()); + + //Assert + result.TotalCount.ShouldBeGreaterThan(0); + result.Items.ShouldContain(u => u.UserName == "admin"); + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/BookStore.Domain.Tests.abppkg b/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/BookStore.Domain.Tests.abppkg new file mode 100644 index 0000000..a686451 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/BookStore.Domain.Tests.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/BookStore.Domain.Tests.csproj b/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/BookStore.Domain.Tests.csproj new file mode 100644 index 0000000..bad4361 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/BookStore.Domain.Tests.csproj @@ -0,0 +1,20 @@ + + + + + + net9.0 + enable + BookStore + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/BookStoreDomainTestBase.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/BookStoreDomainTestBase.cs new file mode 100644 index 0000000..0e04bff --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/BookStoreDomainTestBase.cs @@ -0,0 +1,10 @@ +using Volo.Abp.Modularity; + +namespace BookStore; + +/* Inherit from this class for your domain layer tests. */ +public abstract class BookStoreDomainTestBase : BookStoreTestBase + where TStartupModule : IAbpModule +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/BookStoreDomainTestModule.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/BookStoreDomainTestModule.cs new file mode 100644 index 0000000..fbfad50 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/BookStoreDomainTestModule.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Modularity; + +namespace BookStore; + +[DependsOn( + typeof(BookStoreDomainModule), + typeof(BookStoreTestBaseModule) +)] +public class BookStoreDomainTestModule : AbpModule +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/Samples/SampleDomainTests.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/Samples/SampleDomainTests.cs new file mode 100644 index 0000000..d41088e --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.Domain.Tests/Samples/SampleDomainTests.cs @@ -0,0 +1,46 @@ +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Identity; +using Volo.Abp.Modularity; +using Xunit; + +namespace BookStore.Samples; + +/* This is just an example test class. + * Normally, you don't test code of the modules you are using + * (like IdentityUserManager here). + * Only test your own domain services. + */ +public abstract class SampleDomainTests : BookStoreDomainTestBase + where TStartupModule : IAbpModule +{ + private readonly IIdentityUserRepository _identityUserRepository; + private readonly IdentityUserManager _identityUserManager; + + protected SampleDomainTests() + { + _identityUserRepository = GetRequiredService(); + _identityUserManager = GetRequiredService(); + } + + [Fact] + public async Task Should_Set_Email_Of_A_User() + { + IdentityUser adminUser; + + /* Need to manually start Unit Of Work because + * FirstOrDefaultAsync should be executed while db connection / context is available. + */ + await WithUnitOfWorkAsync(async () => + { + adminUser = await _identityUserRepository + .FindByNormalizedUserNameAsync("ADMIN"); + + await _identityUserManager.SetEmailAsync(adminUser, "newemail@abp.io"); + await _identityUserRepository.UpdateAsync(adminUser); + }); + + adminUser = await _identityUserRepository.FindByNormalizedUserNameAsync("ADMIN"); + adminUser.Email.ShouldBe("newemail@abp.io"); + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/BookStore.HttpApi.Client.ConsoleTestApp.abppkg b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/BookStore.HttpApi.Client.ConsoleTestApp.abppkg new file mode 100644 index 0000000..a686451 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/BookStore.HttpApi.Client.ConsoleTestApp.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/BookStore.HttpApi.Client.ConsoleTestApp.csproj b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/BookStore.HttpApi.Client.ConsoleTestApp.csproj new file mode 100644 index 0000000..3ea40fd --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/BookStore.HttpApi.Client.ConsoleTestApp.csproj @@ -0,0 +1,36 @@ + + + + Exe + net9.0 + enable + + + + + + PreserveNewest + Always + + + + PreserveNewest + Always + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/BookStoreConsoleApiClientModule.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/BookStoreConsoleApiClientModule.cs new file mode 100644 index 0000000..455fab5 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/BookStoreConsoleApiClientModule.cs @@ -0,0 +1,30 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Polly; +using Volo.Abp.Autofac; +using Volo.Abp.Http.Client; +using Volo.Abp.Http.Client.IdentityModel; +using Volo.Abp.Modularity; + +namespace BookStore.HttpApi.Client.ConsoleTestApp; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(BookStoreHttpApiClientModule), + typeof(AbpHttpClientIdentityModelModule) + )] +public class BookStoreConsoleApiClientModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(options => + { + options.ProxyClientBuildActions.Add((remoteServiceName, clientBuilder) => + { + clientBuilder.AddTransientHttpErrorPolicy( + policyBuilder => policyBuilder.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i))) + ); + }); + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/ClientDemoService.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/ClientDemoService.cs new file mode 100644 index 0000000..2feb61d --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/ClientDemoService.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Identity; +using Volo.Abp.Account; + +namespace BookStore.HttpApi.Client.ConsoleTestApp; + +public class ClientDemoService : ITransientDependency +{ + private readonly IProfileAppService _profileAppService; + private readonly IIdentityUserAppService _identityUserAppService; + + public ClientDemoService( + IProfileAppService profileAppService, + IIdentityUserAppService identityUserAppService) + { + _profileAppService = profileAppService; + _identityUserAppService = identityUserAppService; + } + + public async Task RunAsync() + { + var profileDto = await _profileAppService.GetAsync(); + Console.WriteLine($"UserName : {profileDto.UserName}"); + Console.WriteLine($"Email : {profileDto.Email}"); + Console.WriteLine($"Name : {profileDto.Name}"); + Console.WriteLine($"Surname : {profileDto.Surname}"); + Console.WriteLine(); + + var resultDto = await _identityUserAppService.GetListAsync(new GetIdentityUsersInput()); + Console.WriteLine($"Total users: {resultDto.TotalCount}"); + foreach (var identityUserDto in resultDto.Items) + { + Console.WriteLine($"- [{identityUserDto.Id}] {identityUserDto.Name}"); + } + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/Program.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/Program.cs new file mode 100644 index 0000000..cb2b8ea --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/Program.cs @@ -0,0 +1,33 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; + +namespace BookStore.HttpApi.Client.ConsoleTestApp; + +class Program +{ + static async Task Main(string[] args) + { + using (var application = await AbpApplicationFactory.CreateAsync(options => + { + var builder = new ConfigurationBuilder(); + builder.AddJsonFile("appsettings.json", false); + builder.AddJsonFile("appsettings.secrets.json", true); + options.Services.ReplaceConfiguration(builder.Build()); + options.UseAutofac(); + })) + { + await application.InitializeAsync(); + + var demo = application.ServiceProvider.GetRequiredService(); + await demo.RunAsync(); + + Console.WriteLine("Press ENTER to stop application..."); + Console.ReadLine(); + + await application.ShutdownAsync(); + } + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/appsettings.json b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/appsettings.json new file mode 100644 index 0000000..84c7232 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/appsettings.json @@ -0,0 +1,17 @@ +{ + "RemoteServices": { + "Default": { + "BaseUrl": "https://localhost:44318/" + } + }, + "IdentityClients": { + "Default": { + "GrantType": "password", + "ClientId": "BookStore_App", + "UserName": "admin", + "UserPassword": "1q2w3E*", + "Authority": "https://localhost:44318/", + "Scope": "BookStore" + } + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/appsettings.secrets.json b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/appsettings.secrets.json new file mode 100644 index 0000000..2c63c08 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.HttpApi.Client.ConsoleTestApp/appsettings.secrets.json @@ -0,0 +1,2 @@ +{ +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/BookStore.MongoDB.Tests.abppkg b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/BookStore.MongoDB.Tests.abppkg new file mode 100644 index 0000000..a686451 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/BookStore.MongoDB.Tests.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/BookStore.MongoDB.Tests.csproj b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/BookStore.MongoDB.Tests.csproj new file mode 100644 index 0000000..6389c17 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/BookStore.MongoDB.Tests.csproj @@ -0,0 +1,24 @@ + + + + + + net9.0 + enable + BookStore + + + + + + + + + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/Applications/MongoDBSampleAppServiceTests.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/Applications/MongoDBSampleAppServiceTests.cs new file mode 100644 index 0000000..b061d26 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/Applications/MongoDBSampleAppServiceTests.cs @@ -0,0 +1,11 @@ +using BookStore.MongoDB; +using BookStore.Samples; +using Xunit; + +namespace BookStore.MongoDb.Applications; + +[Collection(BookStoreTestConsts.CollectionDefinitionName)] +public class MongoDBSampleAppServiceTests : SampleAppServiceTests +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoCollection.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoCollection.cs new file mode 100644 index 0000000..33d7d33 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoCollection.cs @@ -0,0 +1,9 @@ +using Xunit; + +namespace BookStore.MongoDB; + +[CollectionDefinition(BookStoreTestConsts.CollectionDefinitionName)] +public class BookStoreMongoCollection : BookStoreMongoDbCollectionFixtureBase +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbCollectionFixtureBase.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbCollectionFixtureBase.cs new file mode 100644 index 0000000..3f4aa52 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbCollectionFixtureBase.cs @@ -0,0 +1,9 @@ +using BookStore.MongoDB; +using Xunit; + +namespace BookStore.MongoDB; + +public class BookStoreMongoDbCollectionFixtureBase : ICollectionFixture +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbFixture.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbFixture.cs new file mode 100644 index 0000000..a6ec125 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbFixture.cs @@ -0,0 +1,34 @@ +using System; +using MongoSandbox; + +namespace BookStore.MongoDB; + +public class BookStoreMongoDbFixture : IDisposable +{ + public readonly static IMongoRunner MongoDbRunner; + + static BookStoreMongoDbFixture() + { + MongoDbRunner = MongoRunner.Run(new MongoRunnerOptions + { + UseSingleNodeReplicaSet = true + }); + } + + public static string GetRandomConnectionString() + { + return GetConnectionString("Db_" + Guid.NewGuid().ToString("N")); + } + + public static string GetConnectionString(string databaseName) + { + var stringArray = MongoDbRunner.ConnectionString.Split('?'); + var connectionString = stringArray[0].EnsureEndsWith('/') + databaseName + "/?" + stringArray[1]; + return connectionString; + } + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbTestBase.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbTestBase.cs new file mode 100644 index 0000000..91a2c98 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbTestBase.cs @@ -0,0 +1,6 @@ +namespace BookStore.MongoDB; + +public abstract class BookStoreMongoDbTestBase : BookStoreTestBase +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbTestModule.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbTestModule.cs new file mode 100644 index 0000000..4300ace --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbTestModule.cs @@ -0,0 +1,21 @@ +using System; +using Volo.Abp.Data; +using Volo.Abp.Modularity; +using Volo.Abp.Uow; + +namespace BookStore.MongoDB; + +[DependsOn( + typeof(BookStoreApplicationTestModule), + typeof(BookStoreMongoDbModule) +)] +public class BookStoreMongoDbTestModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.ConnectionStrings.Default = BookStoreMongoDbFixture.GetRandomConnectionString(); + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/Domains/MongoDBSampleDomainTests.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/Domains/MongoDBSampleDomainTests.cs new file mode 100644 index 0000000..1467c28 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/Domains/MongoDBSampleDomainTests.cs @@ -0,0 +1,10 @@ +using BookStore.Samples; +using Xunit; + +namespace BookStore.MongoDB.Domains; + +[Collection(BookStoreTestConsts.CollectionDefinitionName)] +public class MongoDBSampleDomainTests : SampleDomainTests +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs new file mode 100644 index 0000000..e9e001b --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs @@ -0,0 +1,40 @@ +using System; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Identity; +using Xunit; + +namespace BookStore.MongoDB.Samples; + +/* This is just an example test class. + * Normally, you don't test ABP framework code + * Only test your custom repository methods. + */ +[Collection(BookStoreTestConsts.CollectionDefinitionName)] +public class SampleRepositoryTests : BookStoreMongoDbTestBase +{ + private readonly IRepository _appUserRepository; + + public SampleRepositoryTests() + { + _appUserRepository = GetRequiredService>(); + } + + [Fact] + public async Task Should_Query_AppUser() + { + /* Need to manually start Unit Of Work because + * FirstOrDefaultAsync should be executed while db connection / context is available. + */ + await WithUnitOfWorkAsync(async () => + { + //Act + var adminUser = await _appUserRepository + .FirstOrDefaultAsync(u => u.UserName == "admin"); + + //Assert + adminUser.ShouldNotBeNull(); + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStore.TestBase.abppkg b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStore.TestBase.abppkg new file mode 100644 index 0000000..a686451 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStore.TestBase.abppkg @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStore.TestBase.csproj b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStore.TestBase.csproj new file mode 100644 index 0000000..0d5a663 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStore.TestBase.csproj @@ -0,0 +1,45 @@ + + + + + + net9.0 + enable + BookStore + + + + + + PreserveNewest + true + PreserveNewest + + + + PreserveNewest + Always + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStoreTestBase.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStoreTestBase.cs new file mode 100644 index 0000000..c38e9e2 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStoreTestBase.cs @@ -0,0 +1,67 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Modularity; +using Volo.Abp.Uow; +using Volo.Abp.Testing; + +namespace BookStore; + +public abstract class BookStoreTestBase : AbpIntegratedTest + where TStartupModule : IAbpModule +{ + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + + protected override void BeforeAddApplication(IServiceCollection services) + { + var builder = new ConfigurationBuilder(); + builder.AddJsonFile("appsettings.json", false); + builder.AddJsonFile("appsettings.secrets.json", true); + services.ReplaceConfiguration(builder.Build()); + } + + protected virtual Task WithUnitOfWorkAsync(Func func) + { + return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); + } + + protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func action) + { + using (var scope = ServiceProvider.CreateScope()) + { + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using (var uow = uowManager.Begin(options)) + { + await action(); + + await uow.CompleteAsync(); + } + } + } + + protected virtual Task WithUnitOfWorkAsync(Func> func) + { + return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); + } + + protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func> func) + { + using (var scope = ServiceProvider.CreateScope()) + { + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using (var uow = uowManager.Begin(options)) + { + var result = await func(); + await uow.CompleteAsync(); + return result; + } + } + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStoreTestBaseModule.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStoreTestBaseModule.cs new file mode 100644 index 0000000..c330b40 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStoreTestBaseModule.cs @@ -0,0 +1,47 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Authorization; +using Volo.Abp.Autofac; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.Data; +using Volo.Abp.Modularity; +using Volo.Abp.Threading; + +namespace BookStore; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(AbpTestBaseModule), + typeof(AbpAuthorizationModule), + typeof(AbpBackgroundJobsAbstractionsModule) +)] +public class BookStoreTestBaseModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.IsJobExecutionEnabled = false; + }); + + context.Services.AddAlwaysAllowAuthorization(); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + SeedTestData(context); + } + + private static void SeedTestData(ApplicationInitializationContext context) + { + AsyncHelper.RunSync(async () => + { + using (var scope = context.ServiceProvider.CreateScope()) + { + await scope.ServiceProvider + .GetRequiredService() + .SeedAsync(); + } + }); + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStoreTestConsts.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStoreTestConsts.cs new file mode 100644 index 0000000..41232fe --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStoreTestConsts.cs @@ -0,0 +1,6 @@ +namespace BookStore; + +public static class BookStoreTestConsts +{ + public const string CollectionDefinitionName = "BookStore collection"; +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStoreTestDataBuilder.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStoreTestDataBuilder.cs new file mode 100644 index 0000000..e7f0cc4 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/BookStoreTestDataBuilder.cs @@ -0,0 +1,26 @@ +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace BookStore; + +public class BookStoreTestDataSeedContributor : IDataSeedContributor, ITransientDependency +{ + private readonly ICurrentTenant _currentTenant; + + public BookStoreTestDataSeedContributor(ICurrentTenant currentTenant) + { + _currentTenant = currentTenant; + } + + public Task SeedAsync(DataSeedContext context) + { + /* Seed additional test data... */ + + using (_currentTenant.Change(context?.TenantId)) + { + return Task.CompletedTask; + } + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/Security/FakeCurrentPrincipalAccessor.cs b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/Security/FakeCurrentPrincipalAccessor.cs new file mode 100644 index 0000000..8c40ef9 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/Security/FakeCurrentPrincipalAccessor.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Security.Claims; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Security.Claims; + +namespace BookStore.Security; + +[Dependency(ReplaceServices = true)] +public class FakeCurrentPrincipalAccessor : ThreadCurrentPrincipalAccessor +{ + protected override ClaimsPrincipal GetClaimsPrincipal() + { + return GetPrincipal(); + } + + private ClaimsPrincipal GetPrincipal() + { + return new ClaimsPrincipal(new ClaimsIdentity(new List + { + new Claim(AbpClaimTypes.UserId, "2e701e62-0953-4dd3-910b-dc6cc93ccb0d"), + new Claim(AbpClaimTypes.UserName, "admin"), + new Claim(AbpClaimTypes.Email, "admin@abp.io") + })); + } +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/appsettings.json b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/appsettings.json new file mode 100644 index 0000000..0db3279 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/appsettings.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/appsettings.secrets.json b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/appsettings.secrets.json new file mode 100644 index 0000000..7a73a41 --- /dev/null +++ b/samples/WebAppBlazorWebAssembly/test/BookStore.TestBase/appsettings.secrets.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file