Merge pull request #147 from aspnetboilerplate/update-multiple-db-context-ef-core-to-abp-9.3
Updated MultipleDbContextEfCoreDemo project to ABP 9.3
This commit is contained in:
Коммит
e53d60895d
|
@ -1,63 +1,2 @@
|
|||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
**/wwwroot/lib/** linguist-vendored
|
||||
**/wwwroot/css/** linguist-vendored
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# Logs
|
||||
Logs/
|
||||
|
||||
# Generated files
|
||||
project.lock.json
|
||||
.vs/
|
||||
|
||||
# mstest test results
|
||||
TestResults
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# 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
|
||||
*.Publish.xml
|
||||
|
||||
# NuGet Packages Directory
|
||||
packages
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
[Bb]in
|
||||
[Oo]bj
|
||||
sql
|
||||
TestResults
|
||||
[Tt]est[Rr]esult*
|
||||
*.Cache
|
||||
ClientBin
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*.dbmdl
|
||||
Generated_Code #added for RIA/Silverlight projects
|
||||
|
||||
# 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
|
||||
src/.vs/config/applicationhost.config
|
||||
|
||||
|
||||
/src/MultipleDbContextEfCoreDemo.Web/wwwroot/lib/
|
||||
/src/MultipleDbContextEfCoreDemo.Web/App_Data/Logs/
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2016 ASP.NET Boilerplate
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -10,8 +10,9 @@ A sample project to show multiple Entity Framework Core DbContexts working toget
|
|||
### Run Migrations
|
||||
|
||||
* Open Package Manager Console, select MultipleDbContextEfCoreDemo.EntityFrameworkCore as default project.
|
||||
* Run command to create first db: **Update-Database -Context MultipleDbContextEfCoreDemoDbContext**
|
||||
* Run command to create second db: **Update-Database -Context MultipleDbContextEfCoreDemoSecondDbContext**
|
||||
* Run command to create first db migration file: **add-migration Added_Person_Entity -Context MultipleDbContextEfCoreDemoDbContext**
|
||||
* Run command to create second db migration file: **add-migration Added_Course_Entity -Contex MultipleDbContextEfCoreDemoSecondDbContext**
|
||||
* Run the ***.Migrator project** to apply the changes to the database.
|
||||
|
||||
### Run Application
|
||||
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 100 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 34 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 70 KiB |
|
@ -0,0 +1,25 @@
|
|||
**/.classpath
|
||||
**/.dockerignore
|
||||
**/.env
|
||||
**/.git
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/azds.yaml
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
|
@ -0,0 +1,63 @@
|
|||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
|
@ -0,0 +1,256 @@
|
|||
## 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
|
||||
|
||||
src/MultipleDbContextEfCoreDemo.Web.Mvc/secrets.json
|
||||
src/MultipleDbContextEfCoreDemo.Web.Host/secrets.json
|
||||
src/MultipleDbContextEfCoreDemo.Migrator/secrets.json
|
|
@ -1,23 +1,29 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26228.9
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30709.64
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{F10AA149-2626-486E-85BB-9CD5365F3016}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipleDbContextEfCoreDemo.Web", "src\MultipleDbContextEfCoreDemo.Web\MultipleDbContextEfCoreDemo.Web.csproj", "{A2213374-BB48-48FD-BBD4-81E6A961D866}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipleDbContextEfCoreDemo.Core", "src\MultipleDbContextEfCoreDemo.Core\MultipleDbContextEfCoreDemo.Core.csproj", "{0FA75A5B-AB83-4FD0-B545-279774C01E87}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipleDbContextEfCoreDemo.Application", "src\MultipleDbContextEfCoreDemo.Application\MultipleDbContextEfCoreDemo.Application.csproj", "{3870C648-4AEA-4B85-BA3F-F2F63B96136A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipleDbContextEfCoreDemo.EntityFrameworkCore", "src\MultipleDbContextEfCoreDemo.EntityFrameworkCore\MultipleDbContextEfCoreDemo.EntityFrameworkCore.csproj", "{DC780BC4-4EAC-4C63-9052-6F3169A59FA4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipleDbContextEfCoreDemo.Tests", "test\MultipleDbContextEfCoreDemo.Tests\MultipleDbContextEfCoreDemo.Tests.csproj", "{0D4C5D00-C144-4213-A007-4B8944113AB1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipleDbContextEfCoreDemo.Web.Tests", "test\MultipleDbContextEfCoreDemo.Web.Tests\MultipleDbContextEfCoreDemo.Web.Tests.csproj", "{5D441612-29CA-4DAD-9945-B9DE11CE026C}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipleDbContextEfCoreDemo.Migrator", "src\MultipleDbContextEfCoreDemo.Migrator\MultipleDbContextEfCoreDemo.Migrator.csproj", "{880B3591-E057-46FE-B525-10BD83828B93}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipleDbContextEfCoreDemo.Web.Host", "src\MultipleDbContextEfCoreDemo.Web.Host\MultipleDbContextEfCoreDemo.Web.Host.csproj", "{38E184BD-E874-4633-A947-AED4FDB73F40}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipleDbContextEfCoreDemo.Web.Core", "src\MultipleDbContextEfCoreDemo.Web.Core\MultipleDbContextEfCoreDemo.Web.Core.csproj", "{22CFE0D2-8DCA-42D7-AD7D-784C3862493F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipleDbContextEfCoreDemo.Web.Mvc", "src\MultipleDbContextEfCoreDemo.Web.Mvc\MultipleDbContextEfCoreDemo.Web.Mvc.csproj", "{A2213374-BB48-48FD-BBD4-81E6A961D866}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipleDbContextEfCoreDemo.EntityFrameworkCore", "src\MultipleDbContextEfCoreDemo.EntityFrameworkCore\MultipleDbContextEfCoreDemo.EntityFrameworkCore.csproj", "{E0580562-F8F2-4EBB-B07A-ABFC6F2C314F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipleDbContextEfCoreDemo.Web.Tests", "test\MultipleDbContextEfCoreDemo.Web.Tests\MultipleDbContextEfCoreDemo.Web.Tests.csproj", "{CA86CF6F-5D9E-4DAC-9CCB-0F87B519E087}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -25,10 +31,6 @@ Global
|
|||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A2213374-BB48-48FD-BBD4-81E6A961D866}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A2213374-BB48-48FD-BBD4-81E6A961D866}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A2213374-BB48-48FD-BBD4-81E6A961D866}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A2213374-BB48-48FD-BBD4-81E6A961D866}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0FA75A5B-AB83-4FD0-B545-279774C01E87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0FA75A5B-AB83-4FD0-B545-279774C01E87}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0FA75A5B-AB83-4FD0-B545-279774C01E87}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -37,28 +39,50 @@ Global
|
|||
{3870C648-4AEA-4B85-BA3F-F2F63B96136A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3870C648-4AEA-4B85-BA3F-F2F63B96136A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3870C648-4AEA-4B85-BA3F-F2F63B96136A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DC780BC4-4EAC-4C63-9052-6F3169A59FA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DC780BC4-4EAC-4C63-9052-6F3169A59FA4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DC780BC4-4EAC-4C63-9052-6F3169A59FA4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DC780BC4-4EAC-4C63-9052-6F3169A59FA4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0D4C5D00-C144-4213-A007-4B8944113AB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0D4C5D00-C144-4213-A007-4B8944113AB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0D4C5D00-C144-4213-A007-4B8944113AB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0D4C5D00-C144-4213-A007-4B8944113AB1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5D441612-29CA-4DAD-9945-B9DE11CE026C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5D441612-29CA-4DAD-9945-B9DE11CE026C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5D441612-29CA-4DAD-9945-B9DE11CE026C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5D441612-29CA-4DAD-9945-B9DE11CE026C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{880B3591-E057-46FE-B525-10BD83828B93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{880B3591-E057-46FE-B525-10BD83828B93}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{880B3591-E057-46FE-B525-10BD83828B93}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{880B3591-E057-46FE-B525-10BD83828B93}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{38E184BD-E874-4633-A947-AED4FDB73F40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{38E184BD-E874-4633-A947-AED4FDB73F40}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{38E184BD-E874-4633-A947-AED4FDB73F40}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{38E184BD-E874-4633-A947-AED4FDB73F40}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{22CFE0D2-8DCA-42D7-AD7D-784C3862493F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{22CFE0D2-8DCA-42D7-AD7D-784C3862493F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{22CFE0D2-8DCA-42D7-AD7D-784C3862493F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{22CFE0D2-8DCA-42D7-AD7D-784C3862493F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A2213374-BB48-48FD-BBD4-81E6A961D866}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A2213374-BB48-48FD-BBD4-81E6A961D866}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A2213374-BB48-48FD-BBD4-81E6A961D866}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A2213374-BB48-48FD-BBD4-81E6A961D866}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E0580562-F8F2-4EBB-B07A-ABFC6F2C314F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E0580562-F8F2-4EBB-B07A-ABFC6F2C314F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E0580562-F8F2-4EBB-B07A-ABFC6F2C314F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E0580562-F8F2-4EBB-B07A-ABFC6F2C314F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CA86CF6F-5D9E-4DAC-9CCB-0F87B519E087}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CA86CF6F-5D9E-4DAC-9CCB-0F87B519E087}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CA86CF6F-5D9E-4DAC-9CCB-0F87B519E087}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CA86CF6F-5D9E-4DAC-9CCB-0F87B519E087}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{A2213374-BB48-48FD-BBD4-81E6A961D866} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
|
||||
{0FA75A5B-AB83-4FD0-B545-279774C01E87} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
|
||||
{3870C648-4AEA-4B85-BA3F-F2F63B96136A} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
|
||||
{DC780BC4-4EAC-4C63-9052-6F3169A59FA4} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
|
||||
{0D4C5D00-C144-4213-A007-4B8944113AB1} = {F10AA149-2626-486E-85BB-9CD5365F3016}
|
||||
{5D441612-29CA-4DAD-9945-B9DE11CE026C} = {F10AA149-2626-486E-85BB-9CD5365F3016}
|
||||
{880B3591-E057-46FE-B525-10BD83828B93} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
|
||||
{38E184BD-E874-4633-A947-AED4FDB73F40} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
|
||||
{22CFE0D2-8DCA-42D7-AD7D-784C3862493F} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
|
||||
{A2213374-BB48-48FD-BBD4-81E6A961D866} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
|
||||
{E0580562-F8F2-4EBB-B07A-ABFC6F2C314F} = {AFAA0841-BD93-466F-B8F4-FB4EEC86F1FC}
|
||||
{CA86CF6F-5D9E-4DAC-9CCB-0F87B519E087} = {F10AA149-2626-486E-85BB-9CD5365F3016}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {9A55C749-0BFF-4EFD-8499-12A2CB3B5B07}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||
<add key="ABP Nightly Source" value="https://www.myget.org/F/abp-nightly/api/v3/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|
|
@ -0,0 +1,20 @@
|
|||
echo " Welcome to docker build"
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
$ABP_MVC="abp/mvc"
|
||||
$ABP_MVC_DOCKERFILE_PATH="src/MultipleDbContextEfCoreDemo.Web.Mvc/Dockerfile"
|
||||
$ABP_NG="abp/ng"
|
||||
|
||||
cd ..
|
||||
echo " Building docker image $ABP_MVC..."
|
||||
docker build -t $ABP_MVC -f $ABP_MVC_DOCKERFILE_PATH .
|
||||
echo " Done. -- Building docker image $ABP_MVC..."
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
# echo " Pushing docker image $ABP_MVC..."
|
||||
# docker push $ABP_MVC
|
||||
# echo " Done. -- Pushing docker image $ABP_MVC..."
|
||||
# echo ""
|
||||
# echo ""
|
|
@ -0,0 +1,34 @@
|
|||
#!/bin/bash
|
||||
echo " Welcome to docker build"
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
ABP_HOST="abp/host"
|
||||
ABP_NG="abp/ng"
|
||||
|
||||
cd ..
|
||||
echo " Building docker image $ABP_HOST..."
|
||||
docker build -t $ABP_HOST .
|
||||
echo " Done. -- Building docker image $ABP_HOST..."
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
# echo " Pushing docker image $ABP_HOST..."
|
||||
# docker push $ABP_HOST
|
||||
# echo " Done. -- Pushing docker image $ABP_HOST..."
|
||||
# echo ""
|
||||
# echo ""
|
||||
|
||||
cd ..
|
||||
cd angular/
|
||||
echo " Building docker image $ABP_NG..."
|
||||
docker build -t $ABP_NG -f Dockerfile .
|
||||
echo " Done. -- Building docker image $ABP_NG..."
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
# echo " Pushing docker image $ABP_NG..."
|
||||
# docker push $ABP_NG
|
||||
# echo " Done. -- Pushing docker image $ABP_NG..."
|
||||
# echo ""
|
||||
# echo ""
|
|
@ -0,0 +1,16 @@
|
|||
version: '3'
|
||||
|
||||
services:
|
||||
|
||||
abp_host:
|
||||
image: abp/mvc
|
||||
environment:
|
||||
ASPNETCORE_ENVIRONMENT: "Staging"
|
||||
ConnectionStrings__Default: "Server=10.0.75.1; Database=MultipleDbContextEfCoreDemoDb; User=sa; Password=123qwe;TrustServerCertificate=True;"
|
||||
TZ: "America/Toronto"
|
||||
Kestrel__Endpoints__Http__Url: "http://+:80"
|
||||
ports:
|
||||
- "44312:80"
|
||||
volumes:
|
||||
- "./Mvc-Logs:/app/App_Data/Logs"
|
||||
restart: always
|
|
@ -0,0 +1 @@
|
|||
docker-compose down -v --rmi local
|
|
@ -0,0 +1 @@
|
|||
docker-compose up -d
|
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using Abp;
|
||||
using Abp.Authorization;
|
||||
using Abp.Dependency;
|
||||
using Abp.UI;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization
|
||||
{
|
||||
public class AbpLoginResultTypeHelper : AbpServiceBase, ITransientDependency
|
||||
{
|
||||
public AbpLoginResultTypeHelper()
|
||||
{
|
||||
LocalizationSourceName = MultipleDbContextEfCoreDemoConsts.LocalizationSourceName;
|
||||
}
|
||||
|
||||
public Exception CreateExceptionForFailedLoginAttempt(AbpLoginResultType result, string usernameOrEmailAddress, string tenancyName)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case AbpLoginResultType.Success:
|
||||
return new Exception("Don't call this method with a success result!");
|
||||
case AbpLoginResultType.InvalidUserNameOrEmailAddress:
|
||||
case AbpLoginResultType.InvalidPassword:
|
||||
return new UserFriendlyException(L("LoginFailed"), L("InvalidUserNameOrPassword"));
|
||||
case AbpLoginResultType.InvalidTenancyName:
|
||||
return new UserFriendlyException(L("LoginFailed"), L("ThereIsNoTenantDefinedWithName{0}", tenancyName));
|
||||
case AbpLoginResultType.TenantIsNotActive:
|
||||
return new UserFriendlyException(L("LoginFailed"), L("TenantIsNotActive", tenancyName));
|
||||
case AbpLoginResultType.UserIsNotActive:
|
||||
return new UserFriendlyException(L("LoginFailed"), L("UserIsNotActiveAndCanNotLogin", usernameOrEmailAddress));
|
||||
case AbpLoginResultType.UserEmailIsNotConfirmed:
|
||||
return new UserFriendlyException(L("LoginFailed"), L("UserEmailIsNotConfirmedAndCanNotLogin"));
|
||||
case AbpLoginResultType.LockedOut:
|
||||
return new UserFriendlyException(L("LoginFailed"), L("UserLockedOutMessage"));
|
||||
default: // Can not fall to default actually. But other result types can be added in the future and we may forget to handle it
|
||||
Logger.Warn("Unhandled login fail reason: " + result);
|
||||
return new UserFriendlyException(L("LoginFailed"));
|
||||
}
|
||||
}
|
||||
|
||||
public string CreateLocalizedMessageForFailedLoginAttempt(AbpLoginResultType result, string usernameOrEmailAddress, string tenancyName)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case AbpLoginResultType.Success:
|
||||
throw new Exception("Don't call this method with a success result!");
|
||||
case AbpLoginResultType.InvalidUserNameOrEmailAddress:
|
||||
case AbpLoginResultType.InvalidPassword:
|
||||
return L("InvalidUserNameOrPassword");
|
||||
case AbpLoginResultType.InvalidTenancyName:
|
||||
return L("ThereIsNoTenantDefinedWithName{0}", tenancyName);
|
||||
case AbpLoginResultType.TenantIsNotActive:
|
||||
return L("TenantIsNotActive", tenancyName);
|
||||
case AbpLoginResultType.UserIsNotActive:
|
||||
return L("UserIsNotActiveAndCanNotLogin", usernameOrEmailAddress);
|
||||
case AbpLoginResultType.UserEmailIsNotConfirmed:
|
||||
return L("UserEmailIsNotConfirmedAndCanNotLogin");
|
||||
default: // Can not fall to default actually. But other result types can be added in the future and we may forget to handle it
|
||||
Logger.Warn("Unhandled login fail reason: " + result);
|
||||
return L("LoginFailed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
using System.Threading.Tasks;
|
||||
using Abp.Configuration;
|
||||
using Abp.Zero.Configuration;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Accounts.Dto;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Accounts
|
||||
{
|
||||
public class AccountAppService : MultipleDbContextEfCoreDemoAppServiceBase, IAccountAppService
|
||||
{
|
||||
// from: http://regexlib.com/REDetails.aspx?regexp_id=1923
|
||||
public const string PasswordRegex = "(?=^.{8,}$)(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\\s)[0-9a-zA-Z!@#$%^&*()]*$";
|
||||
|
||||
private readonly UserRegistrationManager _userRegistrationManager;
|
||||
|
||||
public AccountAppService(
|
||||
UserRegistrationManager userRegistrationManager)
|
||||
{
|
||||
_userRegistrationManager = userRegistrationManager;
|
||||
}
|
||||
|
||||
public async Task<IsTenantAvailableOutput> IsTenantAvailable(IsTenantAvailableInput input)
|
||||
{
|
||||
var tenant = await TenantManager.FindByTenancyNameAsync(input.TenancyName);
|
||||
if (tenant == null)
|
||||
{
|
||||
return new IsTenantAvailableOutput(TenantAvailabilityState.NotFound);
|
||||
}
|
||||
|
||||
if (!tenant.IsActive)
|
||||
{
|
||||
return new IsTenantAvailableOutput(TenantAvailabilityState.InActive);
|
||||
}
|
||||
|
||||
return new IsTenantAvailableOutput(TenantAvailabilityState.Available, tenant.Id);
|
||||
}
|
||||
|
||||
public async Task<RegisterOutput> Register(RegisterInput input)
|
||||
{
|
||||
var user = await _userRegistrationManager.RegisterAsync(
|
||||
input.Name,
|
||||
input.Surname,
|
||||
input.EmailAddress,
|
||||
input.UserName,
|
||||
input.Password,
|
||||
true // Assumed email address is always confirmed. Change this if you want to implement email confirmation.
|
||||
);
|
||||
|
||||
var isEmailConfirmationRequiredForLogin = await SettingManager.GetSettingValueAsync<bool>(AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin);
|
||||
|
||||
return new RegisterOutput
|
||||
{
|
||||
CanLogin = user.IsActive && (user.IsEmailConfirmed || !isEmailConfirmationRequiredForLogin)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Abp.MultiTenancy;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Accounts.Dto
|
||||
{
|
||||
public class IsTenantAvailableInput
|
||||
{
|
||||
[Required]
|
||||
[StringLength(AbpTenantBase.MaxTenancyNameLength)]
|
||||
public string TenancyName { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
namespace MultipleDbContextEfCoreDemo.Authorization.Accounts.Dto
|
||||
{
|
||||
public class IsTenantAvailableOutput
|
||||
{
|
||||
public TenantAvailabilityState State { get; set; }
|
||||
|
||||
public int? TenantId { get; set; }
|
||||
|
||||
public IsTenantAvailableOutput()
|
||||
{
|
||||
}
|
||||
|
||||
public IsTenantAvailableOutput(TenantAvailabilityState state, int? tenantId = null)
|
||||
{
|
||||
State = state;
|
||||
TenantId = tenantId;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Abp.Auditing;
|
||||
using Abp.Authorization.Users;
|
||||
using Abp.Extensions;
|
||||
using MultipleDbContextEfCoreDemo.Validation;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Accounts.Dto
|
||||
{
|
||||
public class RegisterInput : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
[StringLength(AbpUserBase.MaxNameLength)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpUserBase.MaxSurnameLength)]
|
||||
public string Surname { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpUserBase.MaxUserNameLength)]
|
||||
public string UserName { get; set; }
|
||||
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
[StringLength(AbpUserBase.MaxEmailAddressLength)]
|
||||
public string EmailAddress { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpUserBase.MaxPlainPasswordLength)]
|
||||
[DisableAuditing]
|
||||
public string Password { get; set; }
|
||||
|
||||
[DisableAuditing]
|
||||
public string CaptchaResponse { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (!UserName.IsNullOrEmpty())
|
||||
{
|
||||
if (!UserName.Equals(EmailAddress) && ValidationHelper.IsEmail(UserName))
|
||||
{
|
||||
yield return new ValidationResult("Username cannot be an email address unless it's the same as your email address!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace MultipleDbContextEfCoreDemo.Authorization.Accounts.Dto
|
||||
{
|
||||
public class RegisterOutput
|
||||
{
|
||||
public bool CanLogin { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace MultipleDbContextEfCoreDemo.Authorization.Accounts.Dto
|
||||
{
|
||||
public enum TenantAvailabilityState
|
||||
{
|
||||
Available = 1,
|
||||
InActive,
|
||||
NotFound
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System.Threading.Tasks;
|
||||
using Abp.Application.Services;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Accounts.Dto;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Accounts
|
||||
{
|
||||
public interface IAccountAppService : IApplicationService
|
||||
{
|
||||
Task<IsTenantAvailableOutput> IsTenantAvailable(IsTenantAvailableInput input);
|
||||
|
||||
Task<RegisterOutput> Register(RegisterInput input);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System.Threading.Tasks;
|
||||
using Abp.Authorization;
|
||||
using Abp.Runtime.Session;
|
||||
using MultipleDbContextEfCoreDemo.Configuration.Dto;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Configuration
|
||||
{
|
||||
[AbpAuthorize]
|
||||
public class ConfigurationAppService : MultipleDbContextEfCoreDemoAppServiceBase, IConfigurationAppService
|
||||
{
|
||||
public async Task ChangeUiTheme(ChangeUiThemeInput input)
|
||||
{
|
||||
await SettingManager.ChangeSettingForUserAsync(AbpSession.ToUserIdentifier(), AppSettingNames.UiTheme, input.Theme);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Configuration.Dto
|
||||
{
|
||||
public class ChangeUiThemeInput
|
||||
{
|
||||
[Required]
|
||||
[StringLength(32)]
|
||||
public string Theme { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using System.Threading.Tasks;
|
||||
using MultipleDbContextEfCoreDemo.Configuration.Dto;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Configuration
|
||||
{
|
||||
public interface IConfigurationAppService
|
||||
{
|
||||
Task ChangeUiTheme(ChangeUiThemeInput input);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
namespace MultipleDbContextEfCoreDemo.Configuration.Ui
|
||||
{
|
||||
public class UiThemeInfo
|
||||
{
|
||||
public string Name { get; }
|
||||
public string CssClass { get; }
|
||||
|
||||
public UiThemeInfo(string name, string cssClass)
|
||||
{
|
||||
Name = name;
|
||||
CssClass = cssClass;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Configuration.Ui
|
||||
{
|
||||
public static class UiThemes
|
||||
{
|
||||
public static List<UiThemeInfo> All { get; }
|
||||
|
||||
static UiThemes()
|
||||
{
|
||||
All = new List<UiThemeInfo>
|
||||
{
|
||||
new UiThemeInfo("Red", "red"),
|
||||
new UiThemeInfo("Pink", "pink"),
|
||||
new UiThemeInfo("Purple", "purple"),
|
||||
new UiThemeInfo("Deep Purple", "deep-purple"),
|
||||
new UiThemeInfo("Indigo", "indigo"),
|
||||
new UiThemeInfo("Blue", "blue"),
|
||||
new UiThemeInfo("Light Blue", "light-blue"),
|
||||
new UiThemeInfo("Cyan", "cyan"),
|
||||
new UiThemeInfo("Teal", "teal"),
|
||||
new UiThemeInfo("Green", "green"),
|
||||
new UiThemeInfo("Light Green", "light-green"),
|
||||
new UiThemeInfo("Lime", "lime"),
|
||||
new UiThemeInfo("Yellow", "yellow"),
|
||||
new UiThemeInfo("Amber", "amber"),
|
||||
new UiThemeInfo("Orange", "orange"),
|
||||
new UiThemeInfo("Deep Orange", "deep-orange"),
|
||||
new UiThemeInfo("Brown", "brown"),
|
||||
new UiThemeInfo("Grey", "grey"),
|
||||
new UiThemeInfo("Blue Grey", "blue-grey"),
|
||||
new UiThemeInfo("Black", "black")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Abp.Authorization.Users;
|
||||
using Abp.AutoMapper;
|
||||
using Abp.MultiTenancy;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.MultiTenancy.Dto
|
||||
{
|
||||
[AutoMapTo(typeof(Tenant))]
|
||||
public class CreateTenantDto
|
||||
{
|
||||
[Required]
|
||||
[StringLength(AbpTenantBase.MaxTenancyNameLength)]
|
||||
[RegularExpression(AbpTenantBase.TenancyNameRegex)]
|
||||
public string TenancyName { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpTenantBase.MaxNameLength)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpUserBase.MaxEmailAddressLength)]
|
||||
public string AdminEmailAddress { get; set; }
|
||||
|
||||
[StringLength(AbpTenantBase.MaxConnectionStringLength)]
|
||||
public string ConnectionString { get; set; }
|
||||
|
||||
public bool IsActive {get; set;}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using Abp.Application.Services.Dto;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.MultiTenancy.Dto
|
||||
{
|
||||
public class PagedTenantResultRequestDto : PagedResultRequestDto
|
||||
{
|
||||
public string Keyword { get; set; }
|
||||
public bool? IsActive { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Abp.Application.Services.Dto;
|
||||
using Abp.AutoMapper;
|
||||
using Abp.MultiTenancy;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.MultiTenancy.Dto
|
||||
{
|
||||
[AutoMapFrom(typeof(Tenant))]
|
||||
public class TenantDto : EntityDto
|
||||
{
|
||||
[Required]
|
||||
[StringLength(AbpTenantBase.MaxTenancyNameLength)]
|
||||
[RegularExpression(AbpTenantBase.TenancyNameRegex)]
|
||||
public string TenancyName { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpTenantBase.MaxNameLength)]
|
||||
public string Name { get; set; }
|
||||
|
||||
public bool IsActive {get; set;}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using Abp.Application.Services;
|
||||
using MultipleDbContextEfCoreDemo.MultiTenancy.Dto;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.MultiTenancy
|
||||
{
|
||||
public interface ITenantAppService : IAsyncCrudAppService<TenantDto, int, PagedTenantResultRequestDto, CreateTenantDto, TenantDto>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Abp.Application.Services;
|
||||
using Abp.Application.Services.Dto;
|
||||
using Abp.Authorization;
|
||||
using Abp.Domain.Repositories;
|
||||
using Abp.Extensions;
|
||||
using Abp.IdentityFramework;
|
||||
using Abp.Linq.Extensions;
|
||||
using Abp.MultiTenancy;
|
||||
using Abp.Runtime.Security;
|
||||
using MultipleDbContextEfCoreDemo.Authorization;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
using MultipleDbContextEfCoreDemo.Editions;
|
||||
using MultipleDbContextEfCoreDemo.MultiTenancy.Dto;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.MultiTenancy
|
||||
{
|
||||
[AbpAuthorize(PermissionNames.Pages_Tenants)]
|
||||
public class TenantAppService : AsyncCrudAppService<Tenant, TenantDto, int, PagedTenantResultRequestDto, CreateTenantDto, TenantDto>, ITenantAppService
|
||||
{
|
||||
private readonly TenantManager _tenantManager;
|
||||
private readonly EditionManager _editionManager;
|
||||
private readonly UserManager _userManager;
|
||||
private readonly RoleManager _roleManager;
|
||||
private readonly IAbpZeroDbMigrator _abpZeroDbMigrator;
|
||||
|
||||
public TenantAppService(
|
||||
IRepository<Tenant, int> repository,
|
||||
TenantManager tenantManager,
|
||||
EditionManager editionManager,
|
||||
UserManager userManager,
|
||||
RoleManager roleManager,
|
||||
IAbpZeroDbMigrator abpZeroDbMigrator)
|
||||
: base(repository)
|
||||
{
|
||||
_tenantManager = tenantManager;
|
||||
_editionManager = editionManager;
|
||||
_userManager = userManager;
|
||||
_roleManager = roleManager;
|
||||
_abpZeroDbMigrator = abpZeroDbMigrator;
|
||||
}
|
||||
|
||||
public override async Task<TenantDto> CreateAsync(CreateTenantDto input)
|
||||
{
|
||||
CheckCreatePermission();
|
||||
|
||||
// Create tenant
|
||||
var tenant = ObjectMapper.Map<Tenant>(input);
|
||||
tenant.ConnectionString = input.ConnectionString.IsNullOrEmpty()
|
||||
? null
|
||||
: SimpleStringCipher.Instance.Encrypt(input.ConnectionString);
|
||||
|
||||
var defaultEdition = await _editionManager.FindByNameAsync(EditionManager.DefaultEditionName);
|
||||
if (defaultEdition != null)
|
||||
{
|
||||
tenant.EditionId = defaultEdition.Id;
|
||||
}
|
||||
|
||||
await _tenantManager.CreateAsync(tenant);
|
||||
await CurrentUnitOfWork.SaveChangesAsync(); // To get new tenant's id.
|
||||
|
||||
// Create tenant database
|
||||
_abpZeroDbMigrator.CreateOrMigrateForTenant(tenant);
|
||||
|
||||
// We are working entities of new tenant, so changing tenant filter
|
||||
using (CurrentUnitOfWork.SetTenantId(tenant.Id))
|
||||
{
|
||||
// Create static roles for new tenant
|
||||
CheckErrors(await _roleManager.CreateStaticRoles(tenant.Id));
|
||||
|
||||
await CurrentUnitOfWork.SaveChangesAsync(); // To get static role ids
|
||||
|
||||
// Grant all permissions to admin role
|
||||
var adminRole = _roleManager.Roles.Single(r => r.Name == StaticRoleNames.Tenants.Admin);
|
||||
await _roleManager.GrantAllPermissionsAsync(adminRole);
|
||||
|
||||
// Create admin user for the tenant
|
||||
var adminUser = User.CreateTenantAdminUser(tenant.Id, input.AdminEmailAddress);
|
||||
await _userManager.InitializeOptionsAsync(tenant.Id);
|
||||
CheckErrors(await _userManager.CreateAsync(adminUser, User.DefaultPassword));
|
||||
await CurrentUnitOfWork.SaveChangesAsync(); // To get admin user's id
|
||||
|
||||
// Assign admin user to role!
|
||||
CheckErrors(await _userManager.AddToRoleAsync(adminUser, adminRole.Name));
|
||||
await CurrentUnitOfWork.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return MapToEntityDto(tenant);
|
||||
}
|
||||
|
||||
protected override IQueryable<Tenant> CreateFilteredQuery(PagedTenantResultRequestDto input)
|
||||
{
|
||||
return Repository.GetAll()
|
||||
.WhereIf(!input.Keyword.IsNullOrWhiteSpace(), x => x.TenancyName.Contains(input.Keyword) || x.Name.Contains(input.Keyword))
|
||||
.WhereIf(input.IsActive.HasValue, x => x.IsActive == input.IsActive);
|
||||
}
|
||||
|
||||
protected override void MapToEntity(TenantDto updateInput, Tenant entity)
|
||||
{
|
||||
// Manually mapped since TenantDto contains non-editable properties too.
|
||||
entity.Name = updateInput.Name;
|
||||
entity.TenancyName = updateInput.TenancyName;
|
||||
entity.IsActive = updateInput.IsActive;
|
||||
}
|
||||
|
||||
public override async Task DeleteAsync(EntityDto<int> input)
|
||||
{
|
||||
CheckDeletePermission();
|
||||
|
||||
var tenant = await _tenantManager.GetByIdAsync(input.Id);
|
||||
await _tenantManager.DeleteAsync(tenant);
|
||||
}
|
||||
|
||||
private void CheckErrors(IdentityResult identityResult)
|
||||
{
|
||||
identityResult.CheckErrors(LocalizationManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Version>1.0.0.0</Version>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<VersionPrefix>1.0.0.0</VersionPrefix>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
|
||||
<AssemblyName>MultipleDbContextEfCoreDemo.Application</AssemblyName>
|
||||
<PackageId>MultipleDbContextEfCoreDemo.Application</PackageId>
|
||||
|
@ -9,12 +9,9 @@
|
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||
<RootNamespace>MultipleDbContextEfCoreDemo</RootNamespace>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MultipleDbContextEfCoreDemo.Core\MultipleDbContextEfCoreDemo.Core.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Abp.EntityFrameworkCore" Version="3.4.0" />
|
||||
<PackageReference Include="Abp.AutoMapper" Version="3.4.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Abp.Application.Services;
|
||||
using Abp.IdentityFramework;
|
||||
using Abp.Runtime.Session;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
using MultipleDbContextEfCoreDemo.MultiTenancy;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// Derive your application services from this class.
|
||||
/// </summary>
|
||||
public abstract class MultipleDbContextEfCoreDemoAppServiceBase : ApplicationService
|
||||
{
|
||||
public TenantManager TenantManager { get; set; }
|
||||
|
||||
public UserManager UserManager { get; set; }
|
||||
|
||||
protected MultipleDbContextEfCoreDemoAppServiceBase()
|
||||
{
|
||||
LocalizationSourceName = MultipleDbContextEfCoreDemoConsts.LocalizationSourceName;
|
||||
}
|
||||
|
||||
protected virtual async Task<User> GetCurrentUserAsync()
|
||||
{
|
||||
var user = await UserManager.FindByIdAsync(AbpSession.GetUserId().ToString());
|
||||
if (user == null)
|
||||
{
|
||||
throw new Exception("There is no current user!");
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
protected virtual Task<Tenant> GetCurrentTenantAsync()
|
||||
{
|
||||
return TenantManager.GetByIdAsync(AbpSession.GetTenantId());
|
||||
}
|
||||
|
||||
protected virtual void CheckErrors(IdentityResult identityResult)
|
||||
{
|
||||
identityResult.CheckErrors(LocalizationManager);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using Abp.AutoMapper;
|
||||
using Abp.Modules;
|
||||
using Abp.Reflection.Extensions;
|
||||
using MultipleDbContextEfCoreDemo.Authorization;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo
|
||||
{
|
||||
[DependsOn(
|
||||
typeof(MultipleDbContextEfCoreDemoCoreModule),
|
||||
typeof(AbpAutoMapperModule))]
|
||||
public class MultipleDbContextEfCoreDemoApplicationModule : AbpModule
|
||||
{
|
||||
public override void PreInitialize()
|
||||
{
|
||||
Configuration.Authorization.Providers.Add<MultipleDbContextEfCoreDemoAuthorizationProvider>();
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
var thisAssembly = typeof(MultipleDbContextEfCoreDemoApplicationModule).GetAssembly();
|
||||
|
||||
IocManager.RegisterAssemblyByConvention(thisAssembly);
|
||||
|
||||
Configuration.Modules.AbpAutoMapper().Configurators.Add(
|
||||
// Scan the assembly for classes which inherit from AutoMapper.Profile
|
||||
cfg => cfg.AddMaps(thisAssembly)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,311 @@
|
|||
using System;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Net.MimeTypes
|
||||
{
|
||||
/* Copied from:
|
||||
* http://stackoverflow.com/questions/10362140/asp-mvc-are-there-any-constants-for-the-default-content-types */
|
||||
|
||||
/// <summary>
|
||||
/// Common mime types.
|
||||
/// </summary>
|
||||
public static class MimeTypeNames
|
||||
{
|
||||
///<summary>Used to denote the encoding necessary for files containing JavaScript source code. The alternative MIME type for this file type is text/javascript.</summary>
|
||||
public const string ApplicationXJavascript = "application/x-javascript";
|
||||
|
||||
///<summary>24bit Linear PCM audio at 8-48kHz, 1-N channels; Defined in RFC 3190</summary>
|
||||
public const string AudioL24 = "audio/L24";
|
||||
|
||||
///<summary>Adobe Flash files for example with the extension .swf</summary>
|
||||
public const string ApplicationXShockwaveFlash = "application/x-shockwave-flash";
|
||||
|
||||
///<summary>Arbitrary binary data.[5] Generally speaking this type identifies files that are not associated with a specific application. Contrary to past assumptions by software packages such as Apache this is not a type that should be applied to unknown files. In such a case, a server or application should not indicate a content type, as it may be incorrect, but rather, should omit the type in order to allow the recipient to guess the type.[6]</summary>
|
||||
public const string ApplicationOctetStream = "application/octet-stream";
|
||||
|
||||
///<summary>Atom feeds</summary>
|
||||
public const string ApplicationAtomXml = "application/atom+xml";
|
||||
|
||||
///<summary>Cascading Style Sheets; Defined in RFC 2318</summary>
|
||||
public const string TextCss = "text/css";
|
||||
|
||||
///<summary>commands; subtype resident in Gecko browsers like Firefox 3.5</summary>
|
||||
public const string TextCmd = "text/cmd";
|
||||
|
||||
///<summary>Comma-separated values; Defined in RFC 4180</summary>
|
||||
public const string TextCsv = "text/csv";
|
||||
|
||||
///<summary>deb (file format), a software package format used by the Debian project</summary>
|
||||
public const string ApplicationXDeb = "application/x-deb";
|
||||
|
||||
///<summary>Defined in RFC 1847</summary>
|
||||
public const string MultipartEncrypted = "multipart/encrypted";
|
||||
|
||||
///<summary>Defined in RFC 1847</summary>
|
||||
public const string MultipartSigned = "multipart/signed";
|
||||
|
||||
///<summary>Defined in RFC 2616</summary>
|
||||
public const string MessageHttp = "message/http";
|
||||
|
||||
///<summary>Defined in RFC 4735</summary>
|
||||
public const string ModelExample = "model/example";
|
||||
|
||||
///<summary>device-independent document in DVI format</summary>
|
||||
public const string ApplicationXDvi = "application/x-dvi";
|
||||
|
||||
///<summary>DTD files; Defined by RFC 3023</summary>
|
||||
public const string ApplicationXmlDtd = "application/xml-dtd";
|
||||
|
||||
///<summary>ECMAScript/JavaScript; Defined in RFC 4329 (equivalent to application/ecmascript but with looser processing rules) It is not accepted in IE 8 or earlier - text/javascript is accepted but it is defined as obsolete in RFC 4329. The "type" attribute of the <script> tag in HTML5 is optional and in practice omitting the media type of JavaScript programs is the most interoperable solution since all browsers have always assumed the correct default even before HTML5.</summary>
|
||||
public const string ApplicationJavascript = "application/javascript";
|
||||
|
||||
///<summary>ECMAScript/JavaScript; Defined in RFC 4329 (equivalent to application/javascript but with stricter processing rules)</summary>
|
||||
public const string ApplicationEcmascript = "application/ecmascript";
|
||||
|
||||
///<summary>EDI EDIFACT data; Defined in RFC 1767</summary>
|
||||
public const string ApplicationEdifact = "application/EDIFACT";
|
||||
|
||||
///<summary>EDI X12 data; Defined in RFC 1767</summary>
|
||||
public const string ApplicationEdiX12 = "application/EDI-X12";
|
||||
|
||||
///<summary>Email; Defined in RFC 2045 and RFC 2046</summary>
|
||||
public const string MessagePartial = "message/partial";
|
||||
|
||||
///<summary>Email; EML files, MIME files, MHT files, MHTML files; Defined in RFC 2045 and RFC 2046</summary>
|
||||
public const string MessageRfc822 = "message/rfc822";
|
||||
|
||||
///<summary>Extensible Markup Language; Defined in RFC 3023</summary>
|
||||
public const string TextXml = "text/xml";
|
||||
|
||||
///<summary>Flash video (FLV files)</summary>
|
||||
public const string VideoXFlv = "video/x-flv";
|
||||
|
||||
///<summary>GIF image; Defined in RFC 2045 and RFC 2046</summary>
|
||||
public const string ImageGif = "image/gif";
|
||||
|
||||
///<summary>GoogleWebToolkit data</summary>
|
||||
public const string TextXGwtRpc = "text/x-gwt-rpc";
|
||||
|
||||
///<summary>Gzip</summary>
|
||||
public const string ApplicationXGzip = "application/x-gzip";
|
||||
|
||||
///<summary>HTML; Defined in RFC 2854</summary>
|
||||
public const string TextHtml = "text/html";
|
||||
|
||||
///<summary>ICO image; Registered[9]</summary>
|
||||
public const string ImageVndMicrosoftIcon = "image/vnd.microsoft.icon";
|
||||
|
||||
///<summary>IGS files, IGES files; Defined in RFC 2077</summary>
|
||||
public const string ModelIges = "model/iges";
|
||||
|
||||
///<summary>IMDN Instant Message Disposition Notification; Defined in RFC 5438</summary>
|
||||
public const string MessageImdnXml = "message/imdn+xml";
|
||||
|
||||
///<summary>JavaScript Object Notation JSON; Defined in RFC 4627</summary>
|
||||
public const string ApplicationJson = "application/json";
|
||||
|
||||
///<summary>JavaScript Object Notation (JSON) Patch; Defined in RFC 6902</summary>
|
||||
public const string ApplicationJsonPatch = "application/json-patch+json";
|
||||
|
||||
///<summary>JavaScript - Defined in and obsoleted by RFC 4329 in order to discourage its usage in favor of application/javascript. However,text/javascript is allowed in HTML 4 and 5 and, unlike application/javascript, has cross-browser support. The "type" attribute of the <script> tag in HTML5 is optional and there is no need to use it at all since all browsers have always assumed the correct default (even in HTML 4 where it was required by the specification).</summary>
|
||||
[Obsolete]
|
||||
public const string TextJavascript = "text/javascript";
|
||||
|
||||
///<summary>JPEG JFIF image; Associated with Internet Explorer; Listed in ms775147(v=vs.85) - Progressive JPEG, initiated before global browser support for progressive JPEGs (Microsoft and Firefox).</summary>
|
||||
public const string ImagePjpeg = "image/pjpeg";
|
||||
|
||||
///<summary>JPEG JFIF image; Defined in RFC 2045 and RFC 2046</summary>
|
||||
public const string ImageJpeg = "image/jpeg";
|
||||
|
||||
///<summary>jQuery template data</summary>
|
||||
public const string TextXJqueryTmpl = "text/x-jquery-tmpl";
|
||||
|
||||
///<summary>KML files (e.g. for Google Earth)</summary>
|
||||
public const string ApplicationVndGoogleEarthKmlXml = "application/vnd.google-earth.kml+xml";
|
||||
|
||||
///<summary>LaTeX files</summary>
|
||||
public const string ApplicationXLatex = "application/x-latex";
|
||||
|
||||
///<summary>Matroska open media format</summary>
|
||||
public const string VideoXMatroska = "video/x-matroska";
|
||||
|
||||
///<summary>Microsoft Excel 2007 files</summary>
|
||||
public const string ApplicationVndOpenxmlformatsOfficedocumentSpreadsheetmlSheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
|
||||
///<summary>Microsoft Excel files</summary>
|
||||
public const string ApplicationVndMsExcel = "application/vnd.ms-excel";
|
||||
|
||||
///<summary>Microsoft Powerpoint 2007 files</summary>
|
||||
public const string ApplicationVndOpenxmlformatsOfficedocumentPresentationmlPresentation = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
||||
|
||||
///<summary>Microsoft Powerpoint files</summary>
|
||||
public const string ApplicationVndMsPowerpoint = "application/vnd.ms-powerpoint";
|
||||
|
||||
///<summary>Microsoft Word 2007 files</summary>
|
||||
public const string ApplicationVndOpenxmlformatsOfficedocumentWordprocessingmlDocument = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
|
||||
|
||||
///<summary>Microsoft Word files[15]</summary>
|
||||
public const string ApplicationMsword = "application/msword";
|
||||
|
||||
///<summary>MIME Email; Defined in RFC 2045 and RFC 2046</summary>
|
||||
public const string MultipartAlternative = "multipart/alternative";
|
||||
|
||||
///<summary>MIME Email; Defined in RFC 2045 and RFC 2046</summary>
|
||||
public const string MultipartMixed = "multipart/mixed";
|
||||
|
||||
///<summary>MIME Email; Defined in RFC 2387 and used by MHTML (HTML mail)</summary>
|
||||
public const string MultipartRelated = "multipart/related";
|
||||
|
||||
///<summary>MIME Webform; Defined in RFC 2388</summary>
|
||||
public const string MultipartFormData = "multipart/form-data";
|
||||
|
||||
///<summary>Mozilla XUL files</summary>
|
||||
public const string ApplicationVndMozillaXulXml = "application/vnd.mozilla.xul+xml";
|
||||
|
||||
///<summary>MP3 or other MPEG audio; Defined in RFC 3003</summary>
|
||||
public const string AudioMpeg = "audio/mpeg";
|
||||
|
||||
///<summary>MP4 audio</summary>
|
||||
public const string AudioMp4 = "audio/mp4";
|
||||
|
||||
///<summary>MP4 video; Defined in RFC 4337</summary>
|
||||
public const string VideoMp4 = "video/mp4";
|
||||
|
||||
///<summary>MPEG-1 video with multiplexed audio; Defined in RFC 2045 and RFC 2046</summary>
|
||||
public const string VideoMpeg = "video/mpeg";
|
||||
|
||||
///<summary>MSH files, MESH files; Defined in RFC 2077, SILO files</summary>
|
||||
public const string ModelMesh = "model/mesh";
|
||||
|
||||
///<summary>mulaw audio at 8 kHz, 1 channel; Defined in RFC 2046</summary>
|
||||
public const string AudioBasic = "audio/basic";
|
||||
|
||||
///<summary>Ogg Theora or other video (with audio); Defined in RFC 5334</summary>
|
||||
public const string VideoOgg = "video/ogg";
|
||||
|
||||
///<summary>Ogg Vorbis, Speex, Flac and other audio; Defined in RFC 5334</summary>
|
||||
public const string AudioOgg = "audio/ogg";
|
||||
|
||||
///<summary>Ogg, a multimedia bitstream container format; Defined in RFC 5334</summary>
|
||||
public const string ApplicationOgg = "application/ogg";
|
||||
|
||||
///<summary>OP</summary>
|
||||
public const string ApplicationXopXml = "application/xop+xml";
|
||||
|
||||
///<summary>OpenDocument Graphics; Registered[14]</summary>
|
||||
public const string ApplicationVndOasisOpendocumentGraphics = "application/vnd.oasis.opendocument.graphics";
|
||||
|
||||
///<summary>OpenDocument Presentation; Registered[13]</summary>
|
||||
public const string ApplicationVndOasisOpendocumentPresentation = "application/vnd.oasis.opendocument.presentation";
|
||||
|
||||
///<summary>OpenDocument Spreadsheet; Registered[12]</summary>
|
||||
public const string ApplicationVndOasisOpendocumentSpreadsheet = "application/vnd.oasis.opendocument.spreadsheet";
|
||||
|
||||
///<summary>OpenDocument Text; Registered[11]</summary>
|
||||
public const string ApplicationVndOasisOpendocumentText = "application/vnd.oasis.opendocument.text";
|
||||
|
||||
///<summary>p12 files</summary>
|
||||
public const string ApplicationXPkcs12 = "application/x-pkcs12";
|
||||
|
||||
///<summary>p7b and spc files</summary>
|
||||
public const string ApplicationXPkcs7Certificates = "application/x-pkcs7-certificates";
|
||||
|
||||
///<summary>p7c files</summary>
|
||||
public const string ApplicationXPkcs7Mime = "application/x-pkcs7-mime";
|
||||
|
||||
///<summary>p7r files</summary>
|
||||
public const string ApplicationXPkcs7Certreqresp = "application/x-pkcs7-certreqresp";
|
||||
|
||||
///<summary>p7s files</summary>
|
||||
public const string ApplicationXPkcs7Signature = "application/x-pkcs7-signature";
|
||||
|
||||
///<summary>Portable Document Format, PDF has been in use for document exchange on the Internet since 1993; Defined in RFC 3778</summary>
|
||||
public const string ApplicationPdf = "application/pdf";
|
||||
|
||||
///<summary>Portable Network Graphics; Registered,[8] Defined in RFC 2083</summary>
|
||||
public const string ImagePng = "image/png";
|
||||
|
||||
///<summary>PostScript; Defined in RFC 2046</summary>
|
||||
public const string ApplicationPostscript = "application/postscript";
|
||||
|
||||
///<summary>QuickTime video; Registered[10]</summary>
|
||||
public const string VideoQuicktime = "video/quicktime";
|
||||
|
||||
///<summary>RAR archive files</summary>
|
||||
public const string ApplicationXRarCompressed = "application/x-rar-compressed";
|
||||
|
||||
///<summary>RealAudio; Documented in RealPlayer Customer Support Answer 2559</summary>
|
||||
public const string AudioVndRnRealaudio = "audio/vnd.rn-realaudio";
|
||||
|
||||
///<summary>Resource Description Framework; Defined by RFC 3870</summary>
|
||||
public const string ApplicationRdfXml = "application/rdf+xml";
|
||||
|
||||
///<summary>RSS feeds</summary>
|
||||
public const string ApplicationRssXml = "application/rss+xml";
|
||||
|
||||
///<summary>SOAP; Defined by RFC 3902</summary>
|
||||
public const string ApplicationSoapXml = "application/soap+xml";
|
||||
|
||||
///<summary>StuffIt archive files</summary>
|
||||
public const string ApplicationXStuffit = "application/x-stuffit";
|
||||
|
||||
///<summary>SVG vector image; Defined in SVG Tiny 1.2 Specification Appendix M</summary>
|
||||
public const string ImageSvgXml = "image/svg+xml";
|
||||
|
||||
///<summary>Tag Image File Format (only for Baseline TIFF); Defined in RFC 3302</summary>
|
||||
public const string ImageTiff = "image/tiff";
|
||||
|
||||
///<summary>Tarball files</summary>
|
||||
public const string ApplicationXTar = "application/x-tar";
|
||||
|
||||
///<summary>Textual data; Defined in RFC 2046 and RFC 3676</summary>
|
||||
public const string TextPlain = "text/plain";
|
||||
|
||||
///<summary>TrueType Font No registered MIME type, but this is the most commonly used</summary>
|
||||
public const string ApplicationXFontTtf = "application/x-font-ttf";
|
||||
|
||||
///<summary>vCard (contact information); Defined in RFC 6350</summary>
|
||||
public const string TextVcard = "text/vcard";
|
||||
|
||||
///<summary>Vorbis encoded audio; Defined in RFC 5215</summary>
|
||||
public const string AudioVorbis = "audio/vorbis";
|
||||
|
||||
///<summary>WAV audio; Defined in RFC 2361</summary>
|
||||
public const string AudioVndWave = "audio/vnd.wave";
|
||||
|
||||
///<summary>Web Open Font Format; (candidate recommendation; use application/x-font-woff until standard is official)</summary>
|
||||
public const string ApplicationFontWoff = "application/font-woff";
|
||||
|
||||
///<summary>WebM Matroska-based open media format</summary>
|
||||
public const string VideoWebm = "video/webm";
|
||||
|
||||
///<summary>WebM open media format</summary>
|
||||
public const string AudioWebm = "audio/webm";
|
||||
|
||||
///<summary>Windows Media Audio Redirector; Documented in Microsoft help page</summary>
|
||||
public const string AudioXMsWax = "audio/x-ms-wax";
|
||||
|
||||
///<summary>Windows Media Audio; Documented in Microsoft KB 288102</summary>
|
||||
public const string AudioXMsWma = "audio/x-ms-wma";
|
||||
|
||||
///<summary>Windows Media Video; Documented in Microsoft KB 288102</summary>
|
||||
public const string VideoXMsWmv = "video/x-ms-wmv";
|
||||
|
||||
///<summary>WRL files, VRML files; Defined in RFC 2077</summary>
|
||||
public const string ModelVrml = "model/vrml";
|
||||
|
||||
///<summary>X3D ISO standard for representing 3D computer graphics, X3D XML files</summary>
|
||||
public const string ModelX3DXml = "model/x3d+xml";
|
||||
|
||||
///<summary>X3D ISO standard for representing 3D computer graphics, X3DB binary files</summary>
|
||||
public const string ModelX3DBinary = "model/x3d+binary";
|
||||
|
||||
///<summary>X3D ISO standard for representing 3D computer graphics, X3DV VRML files</summary>
|
||||
public const string ModelX3DVrml = "model/x3d+vrml";
|
||||
|
||||
///<summary>XHTML; Defined by RFC 3236</summary>
|
||||
public const string ApplicationXhtmlXml = "application/xhtml+xml";
|
||||
|
||||
///<summary>ZIP archive files; Registered[7]</summary>
|
||||
public const string ApplicationZip = "application/zip";
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
|
@ -0,0 +1,30 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Abp.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Roles.Dto
|
||||
{
|
||||
public class CreateRoleDto
|
||||
{
|
||||
[Required]
|
||||
[StringLength(AbpRoleBase.MaxNameLength)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpRoleBase.MaxDisplayNameLength)]
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public string NormalizedName { get; set; }
|
||||
|
||||
[StringLength(Role.MaxDescriptionLength)]
|
||||
public string Description { get; set; }
|
||||
|
||||
public List<string> GrantedPermissions { get; set; }
|
||||
|
||||
public CreateRoleDto()
|
||||
{
|
||||
GrantedPermissions = new List<string>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace MultipleDbContextEfCoreDemo.Roles.Dto
|
||||
{
|
||||
public class FlatPermissionDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Roles.Dto
|
||||
{
|
||||
public class GetRoleForEditOutput
|
||||
{
|
||||
public RoleEditDto Role { get; set; }
|
||||
|
||||
public List<FlatPermissionDto> Permissions { get; set; }
|
||||
|
||||
public List<string> GrantedPermissionNames { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace MultipleDbContextEfCoreDemo.Roles.Dto
|
||||
{
|
||||
public class GetRolesInput
|
||||
{
|
||||
public string Permission { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using Abp.Application.Services.Dto;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Roles.Dto
|
||||
{
|
||||
public class PagedRoleResultRequestDto : PagedResultRequestDto
|
||||
{
|
||||
public string Keyword { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
using Abp.Application.Services.Dto;
|
||||
using Abp.AutoMapper;
|
||||
using Abp.Authorization;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Roles.Dto
|
||||
{
|
||||
[AutoMapFrom(typeof(Permission))]
|
||||
public class PermissionDto : EntityDto<long>
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Abp.Application.Services.Dto;
|
||||
using Abp.Authorization.Roles;
|
||||
using Abp.AutoMapper;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Roles.Dto
|
||||
{
|
||||
public class RoleDto : EntityDto<int>
|
||||
{
|
||||
[Required]
|
||||
[StringLength(AbpRoleBase.MaxNameLength)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpRoleBase.MaxDisplayNameLength)]
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public string NormalizedName { get; set; }
|
||||
|
||||
[StringLength(Role.MaxDescriptionLength)]
|
||||
public string Description { get; set; }
|
||||
|
||||
public List<string> GrantedPermissions { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Abp.Application.Services.Dto;
|
||||
using Abp.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Roles.Dto
|
||||
{
|
||||
public class RoleEditDto: EntityDto<int>
|
||||
{
|
||||
[Required]
|
||||
[StringLength(AbpRoleBase.MaxNameLength)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpRoleBase.MaxDisplayNameLength)]
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
[StringLength(Role.MaxDescriptionLength)]
|
||||
public string Description { get; set; }
|
||||
|
||||
public bool IsStatic { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using Abp.Application.Services.Dto;
|
||||
using Abp.Domain.Entities.Auditing;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Roles.Dto
|
||||
{
|
||||
public class RoleListDto : EntityDto, IHasCreationTime
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public bool IsStatic { get; set; }
|
||||
|
||||
public bool IsDefault { get; set; }
|
||||
|
||||
public DateTime CreationTime { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using System.Linq;
|
||||
using AutoMapper;
|
||||
using Abp.Authorization;
|
||||
using Abp.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Roles.Dto
|
||||
{
|
||||
public class RoleMapProfile : Profile
|
||||
{
|
||||
public RoleMapProfile()
|
||||
{
|
||||
// Role and permission
|
||||
CreateMap<Permission, string>().ConvertUsing(r => r.Name);
|
||||
CreateMap<RolePermissionSetting, string>().ConvertUsing(r => r.Name);
|
||||
|
||||
CreateMap<CreateRoleDto, Role>();
|
||||
|
||||
CreateMap<RoleDto, Role>();
|
||||
|
||||
CreateMap<Role, RoleDto>().ForMember(x => x.GrantedPermissions,
|
||||
opt => opt.MapFrom(x => x.Permissions.Where(p => p.IsGranted)));
|
||||
|
||||
CreateMap<Role, RoleListDto>();
|
||||
CreateMap<Role, RoleEditDto>();
|
||||
CreateMap<Permission, FlatPermissionDto>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System.Threading.Tasks;
|
||||
using Abp.Application.Services;
|
||||
using Abp.Application.Services.Dto;
|
||||
using MultipleDbContextEfCoreDemo.Roles.Dto;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Roles
|
||||
{
|
||||
public interface IRoleAppService : IAsyncCrudAppService<RoleDto, int, PagedRoleResultRequestDto, CreateRoleDto, RoleDto>
|
||||
{
|
||||
Task<ListResultDto<PermissionDto>> GetAllPermissions();
|
||||
|
||||
Task<GetRoleForEditOutput> GetRoleForEdit(EntityDto input);
|
||||
|
||||
Task<ListResultDto<RoleListDto>> GetRolesAsync(GetRolesInput input);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Abp.Application.Services;
|
||||
using Abp.Application.Services.Dto;
|
||||
using Abp.Authorization;
|
||||
using Abp.Domain.Repositories;
|
||||
using Abp.Extensions;
|
||||
using Abp.IdentityFramework;
|
||||
using Abp.Linq.Extensions;
|
||||
using MultipleDbContextEfCoreDemo.Authorization;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
using MultipleDbContextEfCoreDemo.Roles.Dto;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Roles
|
||||
{
|
||||
[AbpAuthorize(PermissionNames.Pages_Roles)]
|
||||
public class RoleAppService : AsyncCrudAppService<Role, RoleDto, int, PagedRoleResultRequestDto, CreateRoleDto, RoleDto>, IRoleAppService
|
||||
{
|
||||
private readonly RoleManager _roleManager;
|
||||
private readonly UserManager _userManager;
|
||||
|
||||
public RoleAppService(IRepository<Role> repository, RoleManager roleManager, UserManager userManager)
|
||||
: base(repository)
|
||||
{
|
||||
_roleManager = roleManager;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
public override async Task<RoleDto> CreateAsync(CreateRoleDto input)
|
||||
{
|
||||
CheckCreatePermission();
|
||||
|
||||
var role = ObjectMapper.Map<Role>(input);
|
||||
role.SetNormalizedName();
|
||||
|
||||
CheckErrors(await _roleManager.CreateAsync(role));
|
||||
|
||||
var grantedPermissions = PermissionManager
|
||||
.GetAllPermissions()
|
||||
.Where(p => input.GrantedPermissions.Contains(p.Name))
|
||||
.ToList();
|
||||
|
||||
await _roleManager.SetGrantedPermissionsAsync(role, grantedPermissions);
|
||||
|
||||
return MapToEntityDto(role);
|
||||
}
|
||||
|
||||
public async Task<ListResultDto<RoleListDto>> GetRolesAsync(GetRolesInput input)
|
||||
{
|
||||
var roles = await _roleManager
|
||||
.Roles
|
||||
.WhereIf(
|
||||
!input.Permission.IsNullOrWhiteSpace(),
|
||||
r => r.Permissions.Any(rp => rp.Name == input.Permission && rp.IsGranted)
|
||||
)
|
||||
.ToListAsync();
|
||||
|
||||
return new ListResultDto<RoleListDto>(ObjectMapper.Map<List<RoleListDto>>(roles));
|
||||
}
|
||||
|
||||
public override async Task<RoleDto> UpdateAsync(RoleDto input)
|
||||
{
|
||||
CheckUpdatePermission();
|
||||
|
||||
var role = await _roleManager.GetRoleByIdAsync(input.Id);
|
||||
|
||||
ObjectMapper.Map(input, role);
|
||||
|
||||
CheckErrors(await _roleManager.UpdateAsync(role));
|
||||
|
||||
var grantedPermissions = PermissionManager
|
||||
.GetAllPermissions()
|
||||
.Where(p => input.GrantedPermissions.Contains(p.Name))
|
||||
.ToList();
|
||||
|
||||
await _roleManager.SetGrantedPermissionsAsync(role, grantedPermissions);
|
||||
|
||||
return MapToEntityDto(role);
|
||||
}
|
||||
|
||||
public override async Task DeleteAsync(EntityDto<int> input)
|
||||
{
|
||||
CheckDeletePermission();
|
||||
|
||||
var role = await _roleManager.FindByIdAsync(input.Id.ToString());
|
||||
var users = await _userManager.GetUsersInRoleAsync(role.NormalizedName);
|
||||
|
||||
foreach (var user in users)
|
||||
{
|
||||
CheckErrors(await _userManager.RemoveFromRoleAsync(user, role.NormalizedName));
|
||||
}
|
||||
|
||||
CheckErrors(await _roleManager.DeleteAsync(role));
|
||||
}
|
||||
|
||||
public Task<ListResultDto<PermissionDto>> GetAllPermissions()
|
||||
{
|
||||
var permissions = PermissionManager.GetAllPermissions();
|
||||
|
||||
return Task.FromResult(new ListResultDto<PermissionDto>(
|
||||
ObjectMapper.Map<List<PermissionDto>>(permissions).OrderBy(p => p.DisplayName).ToList()
|
||||
));
|
||||
}
|
||||
|
||||
protected override IQueryable<Role> CreateFilteredQuery(PagedRoleResultRequestDto input)
|
||||
{
|
||||
return Repository.GetAllIncluding(x => x.Permissions)
|
||||
.WhereIf(!input.Keyword.IsNullOrWhiteSpace(), x => x.Name.Contains(input.Keyword)
|
||||
|| x.DisplayName.Contains(input.Keyword)
|
||||
|| x.Description.Contains(input.Keyword));
|
||||
}
|
||||
|
||||
protected override async Task<Role> GetEntityByIdAsync(int id)
|
||||
{
|
||||
return await Repository.GetAllIncluding(x => x.Permissions).FirstOrDefaultAsync(x => x.Id == id);
|
||||
}
|
||||
|
||||
protected override IQueryable<Role> ApplySorting(IQueryable<Role> query, PagedRoleResultRequestDto input)
|
||||
{
|
||||
return query.OrderBy(r => r.DisplayName);
|
||||
}
|
||||
|
||||
protected virtual void CheckErrors(IdentityResult identityResult)
|
||||
{
|
||||
identityResult.CheckErrors(LocalizationManager);
|
||||
}
|
||||
|
||||
public async Task<GetRoleForEditOutput> GetRoleForEdit(EntityDto input)
|
||||
{
|
||||
var permissions = PermissionManager.GetAllPermissions();
|
||||
var role = await _roleManager.GetRoleByIdAsync(input.Id);
|
||||
var grantedPermissions = (await _roleManager.GetGrantedPermissionsAsync(role)).ToArray();
|
||||
var roleEditDto = ObjectMapper.Map<RoleEditDto>(role);
|
||||
|
||||
return new GetRoleForEditOutput
|
||||
{
|
||||
Role = roleEditDto,
|
||||
Permissions = ObjectMapper.Map<List<FlatPermissionDto>>(permissions).OrderBy(p => p.DisplayName).ToList(),
|
||||
GrantedPermissionNames = grantedPermissions.Select(p => p.Name).ToList()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Sessions.Dto
|
||||
{
|
||||
public class ApplicationInfoDto
|
||||
{
|
||||
public string Version { get; set; }
|
||||
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
|
||||
public Dictionary<string, bool> Features { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace MultipleDbContextEfCoreDemo.Sessions.Dto
|
||||
{
|
||||
public class GetCurrentLoginInformationsOutput
|
||||
{
|
||||
public ApplicationInfoDto Application { get; set; }
|
||||
|
||||
public UserLoginInfoDto User { get; set; }
|
||||
|
||||
public TenantLoginInfoDto Tenant { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using Abp.Application.Services.Dto;
|
||||
using Abp.AutoMapper;
|
||||
using MultipleDbContextEfCoreDemo.MultiTenancy;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Sessions.Dto
|
||||
{
|
||||
[AutoMapFrom(typeof(Tenant))]
|
||||
public class TenantLoginInfoDto : EntityDto
|
||||
{
|
||||
public string TenancyName { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using Abp.Application.Services.Dto;
|
||||
using Abp.AutoMapper;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Sessions.Dto
|
||||
{
|
||||
[AutoMapFrom(typeof(User))]
|
||||
public class UserLoginInfoDto : EntityDto<long>
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Surname { get; set; }
|
||||
|
||||
public string UserName { get; set; }
|
||||
|
||||
public string EmailAddress { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System.Threading.Tasks;
|
||||
using Abp.Application.Services;
|
||||
using MultipleDbContextEfCoreDemo.Sessions.Dto;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Sessions
|
||||
{
|
||||
public interface ISessionAppService : IApplicationService
|
||||
{
|
||||
Task<GetCurrentLoginInformationsOutput> GetCurrentLoginInformations();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Abp.Auditing;
|
||||
using MultipleDbContextEfCoreDemo.Sessions.Dto;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Sessions
|
||||
{
|
||||
public class SessionAppService : MultipleDbContextEfCoreDemoAppServiceBase, ISessionAppService
|
||||
{
|
||||
[DisableAuditing]
|
||||
public async Task<GetCurrentLoginInformationsOutput> GetCurrentLoginInformations()
|
||||
{
|
||||
var output = new GetCurrentLoginInformationsOutput
|
||||
{
|
||||
Application = new ApplicationInfoDto
|
||||
{
|
||||
Version = AppVersionHelper.Version,
|
||||
ReleaseDate = AppVersionHelper.ReleaseDate,
|
||||
Features = new Dictionary<string, bool>()
|
||||
}
|
||||
};
|
||||
|
||||
if (AbpSession.TenantId.HasValue)
|
||||
{
|
||||
output.Tenant = ObjectMapper.Map<TenantLoginInfoDto>(await GetCurrentTenantAsync());
|
||||
}
|
||||
|
||||
if (AbpSession.UserId.HasValue)
|
||||
{
|
||||
output.User = ObjectMapper.Map<UserLoginInfoDto>(await GetCurrentUserAsync());
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Users.Dto
|
||||
{
|
||||
public class ChangePasswordDto
|
||||
{
|
||||
[Required]
|
||||
public string CurrentPassword { get; set; }
|
||||
|
||||
[Required]
|
||||
public string NewPassword { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Users.Dto
|
||||
{
|
||||
public class ChangeUserLanguageDto
|
||||
{
|
||||
[Required]
|
||||
public string LanguageName { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Abp.Auditing;
|
||||
using Abp.Authorization.Users;
|
||||
using Abp.AutoMapper;
|
||||
using Abp.Runtime.Validation;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Users.Dto
|
||||
{
|
||||
[AutoMapTo(typeof(User))]
|
||||
public class CreateUserDto : IShouldNormalize
|
||||
{
|
||||
[Required]
|
||||
[StringLength(AbpUserBase.MaxUserNameLength)]
|
||||
public string UserName { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpUserBase.MaxNameLength)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpUserBase.MaxSurnameLength)]
|
||||
public string Surname { get; set; }
|
||||
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
[StringLength(AbpUserBase.MaxEmailAddressLength)]
|
||||
public string EmailAddress { get; set; }
|
||||
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
public string[] RoleNames { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpUserBase.MaxPlainPasswordLength)]
|
||||
[DisableAuditing]
|
||||
public string Password { get; set; }
|
||||
|
||||
public void Normalize()
|
||||
{
|
||||
if (RoleNames == null)
|
||||
{
|
||||
RoleNames = new string[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using Abp.Application.Services.Dto;
|
||||
using System;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Users.Dto
|
||||
{
|
||||
//custom PagedResultRequestDto
|
||||
public class PagedUserResultRequestDto : PagedResultRequestDto
|
||||
{
|
||||
public string Keyword { get; set; }
|
||||
public bool? IsActive { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Users.Dto
|
||||
{
|
||||
public class ResetPasswordDto
|
||||
{
|
||||
[Required]
|
||||
public string AdminPassword { get; set; }
|
||||
|
||||
[Required]
|
||||
public long UserId { get; set; }
|
||||
|
||||
[Required]
|
||||
public string NewPassword { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Abp.Application.Services.Dto;
|
||||
using Abp.Authorization.Users;
|
||||
using Abp.AutoMapper;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Users.Dto
|
||||
{
|
||||
[AutoMapFrom(typeof(User))]
|
||||
public class UserDto : EntityDto<long>
|
||||
{
|
||||
[Required]
|
||||
[StringLength(AbpUserBase.MaxUserNameLength)]
|
||||
public string UserName { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpUserBase.MaxNameLength)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(AbpUserBase.MaxSurnameLength)]
|
||||
public string Surname { get; set; }
|
||||
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
[StringLength(AbpUserBase.MaxEmailAddressLength)]
|
||||
public string EmailAddress { get; set; }
|
||||
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
public string FullName { get; set; }
|
||||
|
||||
public DateTime? LastLoginTime { get; set; }
|
||||
|
||||
public DateTime CreationTime { get; set; }
|
||||
|
||||
public string[] RoleNames { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using AutoMapper;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Users.Dto
|
||||
{
|
||||
public class UserMapProfile : Profile
|
||||
{
|
||||
public UserMapProfile()
|
||||
{
|
||||
CreateMap<UserDto, User>();
|
||||
CreateMap<UserDto, User>()
|
||||
.ForMember(x => x.Roles, opt => opt.Ignore())
|
||||
.ForMember(x => x.CreationTime, opt => opt.Ignore());
|
||||
|
||||
CreateMap<CreateUserDto, User>();
|
||||
CreateMap<CreateUserDto, User>().ForMember(x => x.Roles, opt => opt.Ignore());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using System.Threading.Tasks;
|
||||
using Abp.Application.Services;
|
||||
using Abp.Application.Services.Dto;
|
||||
using MultipleDbContextEfCoreDemo.Roles.Dto;
|
||||
using MultipleDbContextEfCoreDemo.Users.Dto;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Users
|
||||
{
|
||||
public interface IUserAppService : IAsyncCrudAppService<UserDto, long, PagedUserResultRequestDto, CreateUserDto, UserDto>
|
||||
{
|
||||
Task DeActivate(EntityDto<long> user);
|
||||
Task Activate(EntityDto<long> user);
|
||||
Task<ListResultDto<RoleDto>> GetRoles();
|
||||
Task ChangeLanguage(ChangeUserLanguageDto input);
|
||||
|
||||
Task<bool> ChangePassword(ChangePasswordDto input);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,251 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Abp.Application.Services;
|
||||
using Abp.Application.Services.Dto;
|
||||
using Abp.Authorization;
|
||||
using Abp.Domain.Entities;
|
||||
using Abp.Domain.Repositories;
|
||||
using Abp.Extensions;
|
||||
using Abp.IdentityFramework;
|
||||
using Abp.Linq.Extensions;
|
||||
using Abp.Localization;
|
||||
using Abp.Runtime.Session;
|
||||
using Abp.UI;
|
||||
using MultipleDbContextEfCoreDemo.Authorization;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Accounts;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
using MultipleDbContextEfCoreDemo.Roles.Dto;
|
||||
using MultipleDbContextEfCoreDemo.Users.Dto;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Users
|
||||
{
|
||||
[AbpAuthorize(PermissionNames.Pages_Users)]
|
||||
public class UserAppService : AsyncCrudAppService<User, UserDto, long, PagedUserResultRequestDto, CreateUserDto, UserDto>, IUserAppService
|
||||
{
|
||||
private readonly UserManager _userManager;
|
||||
private readonly RoleManager _roleManager;
|
||||
private readonly IRepository<Role> _roleRepository;
|
||||
private readonly IPasswordHasher<User> _passwordHasher;
|
||||
private readonly IAbpSession _abpSession;
|
||||
private readonly LogInManager _logInManager;
|
||||
|
||||
public UserAppService(
|
||||
IRepository<User, long> repository,
|
||||
UserManager userManager,
|
||||
RoleManager roleManager,
|
||||
IRepository<Role> roleRepository,
|
||||
IPasswordHasher<User> passwordHasher,
|
||||
IAbpSession abpSession,
|
||||
LogInManager logInManager)
|
||||
: base(repository)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_roleManager = roleManager;
|
||||
_roleRepository = roleRepository;
|
||||
_passwordHasher = passwordHasher;
|
||||
_abpSession = abpSession;
|
||||
_logInManager = logInManager;
|
||||
}
|
||||
|
||||
public override async Task<UserDto> CreateAsync(CreateUserDto input)
|
||||
{
|
||||
CheckCreatePermission();
|
||||
|
||||
var user = ObjectMapper.Map<User>(input);
|
||||
|
||||
user.TenantId = AbpSession.TenantId;
|
||||
user.IsEmailConfirmed = true;
|
||||
|
||||
await _userManager.InitializeOptionsAsync(AbpSession.TenantId);
|
||||
|
||||
CheckErrors(await _userManager.CreateAsync(user, input.Password));
|
||||
|
||||
if (input.RoleNames != null)
|
||||
{
|
||||
CheckErrors(await _userManager.SetRolesAsync(user, input.RoleNames));
|
||||
}
|
||||
|
||||
CurrentUnitOfWork.SaveChanges();
|
||||
|
||||
return MapToEntityDto(user);
|
||||
}
|
||||
|
||||
public override async Task<UserDto> UpdateAsync(UserDto input)
|
||||
{
|
||||
CheckUpdatePermission();
|
||||
|
||||
var user = await _userManager.GetUserByIdAsync(input.Id);
|
||||
|
||||
MapToEntity(input, user);
|
||||
|
||||
CheckErrors(await _userManager.UpdateAsync(user));
|
||||
|
||||
if (input.RoleNames != null)
|
||||
{
|
||||
CheckErrors(await _userManager.SetRolesAsync(user, input.RoleNames));
|
||||
}
|
||||
|
||||
return await GetAsync(input);
|
||||
}
|
||||
|
||||
public override async Task DeleteAsync(EntityDto<long> input)
|
||||
{
|
||||
var user = await _userManager.GetUserByIdAsync(input.Id);
|
||||
await _userManager.DeleteAsync(user);
|
||||
}
|
||||
|
||||
[AbpAuthorize(PermissionNames.Pages_Users_Activation)]
|
||||
public async Task Activate(EntityDto<long> user)
|
||||
{
|
||||
await Repository.UpdateAsync(user.Id, async (entity) =>
|
||||
{
|
||||
entity.IsActive = true;
|
||||
});
|
||||
}
|
||||
|
||||
[AbpAuthorize(PermissionNames.Pages_Users_Activation)]
|
||||
public async Task DeActivate(EntityDto<long> user)
|
||||
{
|
||||
await Repository.UpdateAsync(user.Id, async (entity) =>
|
||||
{
|
||||
entity.IsActive = false;
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<ListResultDto<RoleDto>> GetRoles()
|
||||
{
|
||||
var roles = await _roleRepository.GetAllListAsync();
|
||||
return new ListResultDto<RoleDto>(ObjectMapper.Map<List<RoleDto>>(roles));
|
||||
}
|
||||
|
||||
public async Task ChangeLanguage(ChangeUserLanguageDto input)
|
||||
{
|
||||
await SettingManager.ChangeSettingForUserAsync(
|
||||
AbpSession.ToUserIdentifier(),
|
||||
LocalizationSettingNames.DefaultLanguage,
|
||||
input.LanguageName
|
||||
);
|
||||
}
|
||||
|
||||
protected override User MapToEntity(CreateUserDto createInput)
|
||||
{
|
||||
var user = ObjectMapper.Map<User>(createInput);
|
||||
user.SetNormalizedNames();
|
||||
return user;
|
||||
}
|
||||
|
||||
protected override void MapToEntity(UserDto input, User user)
|
||||
{
|
||||
ObjectMapper.Map(input, user);
|
||||
user.SetNormalizedNames();
|
||||
}
|
||||
|
||||
protected override UserDto MapToEntityDto(User user)
|
||||
{
|
||||
var roleIds = user.Roles.Select(x => x.RoleId).ToArray();
|
||||
|
||||
var roles = _roleManager.Roles.Where(r => roleIds.Contains(r.Id)).Select(r => r.NormalizedName);
|
||||
|
||||
var userDto = base.MapToEntityDto(user);
|
||||
userDto.RoleNames = roles.ToArray();
|
||||
|
||||
return userDto;
|
||||
}
|
||||
|
||||
protected override IQueryable<User> CreateFilteredQuery(PagedUserResultRequestDto input)
|
||||
{
|
||||
return Repository.GetAllIncluding(x => x.Roles)
|
||||
.WhereIf(!input.Keyword.IsNullOrWhiteSpace(), x => x.UserName.Contains(input.Keyword) || x.Name.Contains(input.Keyword) || x.EmailAddress.Contains(input.Keyword))
|
||||
.WhereIf(input.IsActive.HasValue, x => x.IsActive == input.IsActive);
|
||||
}
|
||||
|
||||
protected override async Task<User> GetEntityByIdAsync(long id)
|
||||
{
|
||||
var user = await Repository.GetAllIncluding(x => x.Roles).FirstOrDefaultAsync(x => x.Id == id);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new EntityNotFoundException(typeof(User), id);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
protected override IQueryable<User> ApplySorting(IQueryable<User> query, PagedUserResultRequestDto input)
|
||||
{
|
||||
return query.OrderBy(r => r.UserName);
|
||||
}
|
||||
|
||||
protected virtual void CheckErrors(IdentityResult identityResult)
|
||||
{
|
||||
identityResult.CheckErrors(LocalizationManager);
|
||||
}
|
||||
|
||||
public async Task<bool> ChangePassword(ChangePasswordDto input)
|
||||
{
|
||||
await _userManager.InitializeOptionsAsync(AbpSession.TenantId);
|
||||
|
||||
var user = await _userManager.FindByIdAsync(AbpSession.GetUserId().ToString());
|
||||
if (user == null)
|
||||
{
|
||||
throw new Exception("There is no current user!");
|
||||
}
|
||||
|
||||
if (await _userManager.CheckPasswordAsync(user, input.CurrentPassword))
|
||||
{
|
||||
CheckErrors(await _userManager.ChangePasswordAsync(user, input.NewPassword));
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckErrors(IdentityResult.Failed(new IdentityError
|
||||
{
|
||||
Description = "Incorrect password."
|
||||
}));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> ResetPassword(ResetPasswordDto input)
|
||||
{
|
||||
if (_abpSession.UserId == null)
|
||||
{
|
||||
throw new UserFriendlyException("Please log in before attempting to reset password.");
|
||||
}
|
||||
|
||||
var currentUser = await _userManager.GetUserByIdAsync(_abpSession.GetUserId());
|
||||
var loginAsync = await _logInManager.LoginAsync(currentUser.UserName, input.AdminPassword, shouldLockout: false);
|
||||
if (loginAsync.Result != AbpLoginResultType.Success)
|
||||
{
|
||||
throw new UserFriendlyException("Your 'Admin Password' did not match the one on record. Please try again.");
|
||||
}
|
||||
|
||||
if (currentUser.IsDeleted || !currentUser.IsActive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var roles = await _userManager.GetRolesAsync(currentUser);
|
||||
if (!roles.Contains(StaticRoleNames.Tenants.Admin))
|
||||
{
|
||||
throw new UserFriendlyException("Only administrators may reset passwords.");
|
||||
}
|
||||
|
||||
var user = await _userManager.GetUserByIdAsync(input.UserId);
|
||||
if (user != null)
|
||||
{
|
||||
user.Password = _passwordHasher.HashPassword(user, input.NewPassword);
|
||||
await CurrentUnitOfWork.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Abp.Reflection.Extensions;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// Central point for application version.
|
||||
/// </summary>
|
||||
public class AppVersionHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets current version of the application.
|
||||
/// It's also shown in the web page.
|
||||
/// </summary>
|
||||
public const string Version = "9.3.0";
|
||||
|
||||
/// <summary>
|
||||
/// Gets release (last build) date of the application.
|
||||
/// It's shown in the web page.
|
||||
/// </summary>
|
||||
public static DateTime ReleaseDate => LzyReleaseDate.Value;
|
||||
|
||||
private static readonly Lazy<DateTime> LzyReleaseDate = new Lazy<DateTime>(() => new FileInfo(typeof(AppVersionHelper).GetAssembly().Location).LastWriteTime);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Abp.Authorization;
|
||||
using Abp.Authorization.Users;
|
||||
using Abp.Configuration;
|
||||
using Abp.Configuration.Startup;
|
||||
using Abp.Dependency;
|
||||
using Abp.Domain.Repositories;
|
||||
using Abp.Domain.Uow;
|
||||
using Abp.Zero.Configuration;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
using MultipleDbContextEfCoreDemo.MultiTenancy;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization
|
||||
{
|
||||
public class LogInManager : AbpLogInManager<Tenant, Role, User>
|
||||
{
|
||||
public LogInManager(
|
||||
UserManager userManager,
|
||||
IMultiTenancyConfig multiTenancyConfig,
|
||||
IRepository<Tenant> tenantRepository,
|
||||
IUnitOfWorkManager unitOfWorkManager,
|
||||
ISettingManager settingManager,
|
||||
IRepository<UserLoginAttempt, long> userLoginAttemptRepository,
|
||||
IUserManagementConfig userManagementConfig,
|
||||
IIocResolver iocResolver,
|
||||
IPasswordHasher<User> passwordHasher,
|
||||
RoleManager roleManager,
|
||||
UserClaimsPrincipalFactory claimsPrincipalFactory)
|
||||
: base(
|
||||
userManager,
|
||||
multiTenancyConfig,
|
||||
tenantRepository,
|
||||
unitOfWorkManager,
|
||||
settingManager,
|
||||
userLoginAttemptRepository,
|
||||
userManagementConfig,
|
||||
iocResolver,
|
||||
passwordHasher,
|
||||
roleManager,
|
||||
claimsPrincipalFactory)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
using Abp.Authorization;
|
||||
using Abp.Localization;
|
||||
using Abp.MultiTenancy;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization
|
||||
{
|
||||
public class MultipleDbContextEfCoreDemoAuthorizationProvider : AuthorizationProvider
|
||||
{
|
||||
public override void SetPermissions(IPermissionDefinitionContext context)
|
||||
{
|
||||
context.CreatePermission(PermissionNames.Pages_Users, L("Users"));
|
||||
context.CreatePermission(PermissionNames.Pages_Users_Activation, L("UsersActivation"));
|
||||
context.CreatePermission(PermissionNames.Pages_Roles, L("Roles"));
|
||||
context.CreatePermission(PermissionNames.Pages_Tenants, L("Tenants"), multiTenancySides: MultiTenancySides.Host);
|
||||
}
|
||||
|
||||
private static ILocalizableString L(string name)
|
||||
{
|
||||
return new LocalizableString(name, MultipleDbContextEfCoreDemoConsts.LocalizationSourceName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using Abp.Authorization;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization
|
||||
{
|
||||
public class PermissionChecker : PermissionChecker<Role, User>
|
||||
{
|
||||
public PermissionChecker(UserManager userManager)
|
||||
: base(userManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace MultipleDbContextEfCoreDemo.Authorization
|
||||
{
|
||||
public static class PermissionNames
|
||||
{
|
||||
public const string Pages_Tenants = "Pages.Tenants";
|
||||
|
||||
public const string Pages_Users = "Pages.Users";
|
||||
public const string Pages_Users_Activation = "Pages.Users.Activation";
|
||||
|
||||
public const string Pages_Roles = "Pages.Roles";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using Abp.MultiTenancy;
|
||||
using Abp.Zero.Configuration;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Roles
|
||||
{
|
||||
public static class AppRoleConfig
|
||||
{
|
||||
public static void Configure(IRoleManagementConfig roleManagementConfig)
|
||||
{
|
||||
// Static host roles
|
||||
|
||||
roleManagementConfig.StaticRoles.Add(
|
||||
new StaticRoleDefinition(
|
||||
StaticRoleNames.Host.Admin,
|
||||
MultiTenancySides.Host
|
||||
)
|
||||
);
|
||||
|
||||
// Static tenant roles
|
||||
|
||||
roleManagementConfig.StaticRoles.Add(
|
||||
new StaticRoleDefinition(
|
||||
StaticRoleNames.Tenants.Admin,
|
||||
MultiTenancySides.Tenant
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Abp.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Roles
|
||||
{
|
||||
public class Role : AbpRole<User>
|
||||
{
|
||||
public const int MaxDescriptionLength = 5000;
|
||||
|
||||
public Role()
|
||||
{
|
||||
}
|
||||
|
||||
public Role(int? tenantId, string displayName)
|
||||
: base(tenantId, displayName)
|
||||
{
|
||||
}
|
||||
|
||||
public Role(int? tenantId, string name, string displayName)
|
||||
: base(tenantId, name, displayName)
|
||||
{
|
||||
}
|
||||
|
||||
[StringLength(MaxDescriptionLength)]
|
||||
public string Description {get; set;}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Abp.Authorization;
|
||||
using Abp.Authorization.Roles;
|
||||
using Abp.Domain.Repositories;
|
||||
using Abp.Domain.Uow;
|
||||
using Abp.Organizations;
|
||||
using Abp.Runtime.Caching;
|
||||
using Abp.Zero.Configuration;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Roles
|
||||
{
|
||||
public class RoleManager : AbpRoleManager<Role, User>
|
||||
{
|
||||
public RoleManager(
|
||||
RoleStore store,
|
||||
IEnumerable<IRoleValidator<Role>> roleValidators,
|
||||
ILookupNormalizer keyNormalizer,
|
||||
IdentityErrorDescriber errors,
|
||||
ILogger<AbpRoleManager<Role, User>> logger,
|
||||
IPermissionManager permissionManager,
|
||||
ICacheManager cacheManager,
|
||||
IUnitOfWorkManager unitOfWorkManager,
|
||||
IRoleManagementConfig roleManagementConfig,
|
||||
IRepository<OrganizationUnit, long> organizationUnitRepository,
|
||||
IRepository<OrganizationUnitRole, long> organizationUnitRoleRepository)
|
||||
: base(
|
||||
store,
|
||||
roleValidators,
|
||||
keyNormalizer,
|
||||
errors, logger,
|
||||
permissionManager,
|
||||
cacheManager,
|
||||
unitOfWorkManager,
|
||||
roleManagementConfig,
|
||||
organizationUnitRepository,
|
||||
organizationUnitRoleRepository)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using Abp.Authorization.Roles;
|
||||
using Abp.Domain.Repositories;
|
||||
using Abp.Domain.Uow;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Roles
|
||||
{
|
||||
public class RoleStore : AbpRoleStore<Role, User>
|
||||
{
|
||||
public RoleStore(
|
||||
IUnitOfWorkManager unitOfWorkManager,
|
||||
IRepository<Role> roleRepository,
|
||||
IRepository<RolePermissionSetting, long> rolePermissionSettingRepository)
|
||||
: base(
|
||||
unitOfWorkManager,
|
||||
roleRepository,
|
||||
rolePermissionSettingRepository)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
namespace MultipleDbContextEfCoreDemo.Authorization.Roles
|
||||
{
|
||||
public static class StaticRoleNames
|
||||
{
|
||||
public static class Host
|
||||
{
|
||||
public const string Admin = "Admin";
|
||||
}
|
||||
|
||||
public static class Tenants
|
||||
{
|
||||
public const string Admin = "Admin";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Abp.Authorization.Users;
|
||||
using Abp.Extensions;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Users
|
||||
{
|
||||
public class User : AbpUser<User>
|
||||
{
|
||||
public const string DefaultPassword = "123qwe";
|
||||
|
||||
public static string CreateRandomPassword()
|
||||
{
|
||||
return Guid.NewGuid().ToString("N").Truncate(16);
|
||||
}
|
||||
|
||||
public static User CreateTenantAdminUser(int tenantId, string emailAddress)
|
||||
{
|
||||
var user = new User
|
||||
{
|
||||
TenantId = tenantId,
|
||||
UserName = AdminUserName,
|
||||
Name = AdminUserName,
|
||||
Surname = AdminUserName,
|
||||
EmailAddress = emailAddress,
|
||||
Roles = new List<UserRole>()
|
||||
};
|
||||
|
||||
user.SetNormalizedNames();
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Abp.Authorization;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
using Abp.Domain.Uow;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Users
|
||||
{
|
||||
public class UserClaimsPrincipalFactory : AbpUserClaimsPrincipalFactory<User, Role>
|
||||
{
|
||||
public UserClaimsPrincipalFactory(
|
||||
UserManager userManager,
|
||||
RoleManager roleManager,
|
||||
IOptions<IdentityOptions> optionsAccessor,
|
||||
IUnitOfWorkManager unitOfWorkManager)
|
||||
: base(
|
||||
userManager,
|
||||
roleManager,
|
||||
optionsAccessor,
|
||||
unitOfWorkManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Abp.Authorization;
|
||||
using Abp.Authorization.Users;
|
||||
using Abp.Configuration;
|
||||
using Abp.Domain.Repositories;
|
||||
using Abp.Domain.Uow;
|
||||
using Abp.Organizations;
|
||||
using Abp.Runtime.Caching;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
using Abp.Authorization.Roles;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Users
|
||||
{
|
||||
public class UserManager : AbpUserManager<Role, User>
|
||||
{
|
||||
public UserManager(
|
||||
RoleManager roleManager,
|
||||
UserStore store,
|
||||
IOptions<IdentityOptions> optionsAccessor,
|
||||
IPasswordHasher<User> passwordHasher,
|
||||
IEnumerable<IUserValidator<User>> userValidators,
|
||||
IEnumerable<IPasswordValidator<User>> passwordValidators,
|
||||
ILookupNormalizer keyNormalizer,
|
||||
IdentityErrorDescriber errors,
|
||||
IServiceProvider services,
|
||||
ILogger<UserManager<User>> logger,
|
||||
IPermissionManager permissionManager,
|
||||
IUnitOfWorkManager unitOfWorkManager,
|
||||
ICacheManager cacheManager,
|
||||
IRepository<OrganizationUnit, long> organizationUnitRepository,
|
||||
IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository,
|
||||
IOrganizationUnitSettings organizationUnitSettings,
|
||||
ISettingManager settingManager,
|
||||
IRepository<UserLogin, long> userLoginRepository)
|
||||
: base(
|
||||
roleManager,
|
||||
store,
|
||||
optionsAccessor,
|
||||
passwordHasher,
|
||||
userValidators,
|
||||
passwordValidators,
|
||||
keyNormalizer,
|
||||
errors,
|
||||
services,
|
||||
logger,
|
||||
permissionManager,
|
||||
unitOfWorkManager,
|
||||
cacheManager,
|
||||
organizationUnitRepository,
|
||||
userOrganizationUnitRepository,
|
||||
organizationUnitSettings,
|
||||
settingManager,
|
||||
userLoginRepository)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Abp.Authorization.Users;
|
||||
using Abp.Domain.Services;
|
||||
using Abp.IdentityFramework;
|
||||
using Abp.Runtime.Session;
|
||||
using Abp.UI;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.MultiTenancy;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Users
|
||||
{
|
||||
public class UserRegistrationManager : DomainService
|
||||
{
|
||||
public IAbpSession AbpSession { get; set; }
|
||||
|
||||
private readonly TenantManager _tenantManager;
|
||||
private readonly UserManager _userManager;
|
||||
private readonly RoleManager _roleManager;
|
||||
private readonly IPasswordHasher<User> _passwordHasher;
|
||||
|
||||
public UserRegistrationManager(
|
||||
TenantManager tenantManager,
|
||||
UserManager userManager,
|
||||
RoleManager roleManager,
|
||||
IPasswordHasher<User> passwordHasher)
|
||||
{
|
||||
_tenantManager = tenantManager;
|
||||
_userManager = userManager;
|
||||
_roleManager = roleManager;
|
||||
_passwordHasher = passwordHasher;
|
||||
|
||||
AbpSession = NullAbpSession.Instance;
|
||||
}
|
||||
|
||||
public async Task<User> RegisterAsync(string name, string surname, string emailAddress, string userName, string plainPassword, bool isEmailConfirmed)
|
||||
{
|
||||
CheckForTenant();
|
||||
|
||||
var tenant = await GetActiveTenantAsync();
|
||||
|
||||
var user = new User
|
||||
{
|
||||
TenantId = tenant.Id,
|
||||
Name = name,
|
||||
Surname = surname,
|
||||
EmailAddress = emailAddress,
|
||||
IsActive = true,
|
||||
UserName = userName,
|
||||
IsEmailConfirmed = isEmailConfirmed,
|
||||
Roles = new List<UserRole>()
|
||||
};
|
||||
|
||||
user.SetNormalizedNames();
|
||||
|
||||
foreach (var defaultRole in await _roleManager.Roles.Where(r => r.IsDefault).ToListAsync())
|
||||
{
|
||||
user.Roles.Add(new UserRole(tenant.Id, user.Id, defaultRole.Id));
|
||||
}
|
||||
|
||||
await _userManager.InitializeOptionsAsync(tenant.Id);
|
||||
|
||||
CheckErrors(await _userManager.CreateAsync(user, plainPassword));
|
||||
await CurrentUnitOfWork.SaveChangesAsync();
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
private void CheckForTenant()
|
||||
{
|
||||
if (!AbpSession.TenantId.HasValue)
|
||||
{
|
||||
throw new InvalidOperationException("Can not register host users!");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<Tenant> GetActiveTenantAsync()
|
||||
{
|
||||
if (!AbpSession.TenantId.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return await GetActiveTenantAsync(AbpSession.TenantId.Value);
|
||||
}
|
||||
|
||||
private async Task<Tenant> GetActiveTenantAsync(int tenantId)
|
||||
{
|
||||
var tenant = await _tenantManager.FindByIdAsync(tenantId);
|
||||
if (tenant == null)
|
||||
{
|
||||
throw new UserFriendlyException(L("UnknownTenantId{0}", tenantId));
|
||||
}
|
||||
|
||||
if (!tenant.IsActive)
|
||||
{
|
||||
throw new UserFriendlyException(L("TenantIdIsNotActive{0}", tenantId));
|
||||
}
|
||||
|
||||
return tenant;
|
||||
}
|
||||
|
||||
protected virtual void CheckErrors(IdentityResult identityResult)
|
||||
{
|
||||
identityResult.CheckErrors(LocalizationManager);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
using Abp.Authorization.Users;
|
||||
using Abp.Domain.Repositories;
|
||||
using Abp.Domain.Uow;
|
||||
using Abp.Linq;
|
||||
using Abp.Organizations;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Authorization.Users
|
||||
{
|
||||
public class UserStore : AbpUserStore<Role, User>
|
||||
{
|
||||
public UserStore(
|
||||
IUnitOfWorkManager unitOfWorkManager,
|
||||
IRepository<User, long> userRepository,
|
||||
IRepository<Role> roleRepository,
|
||||
IRepository<UserRole, long> userRoleRepository,
|
||||
IRepository<UserLogin, long> userLoginRepository,
|
||||
IRepository<UserClaim, long> userClaimRepository,
|
||||
IRepository<UserPermissionSetting, long> userPermissionSettingRepository,
|
||||
IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository,
|
||||
IRepository<OrganizationUnitRole, long> organizationUnitRoleRepository,
|
||||
IRepository<UserToken, long> userTokenRepository
|
||||
)
|
||||
: base(unitOfWorkManager,
|
||||
userRepository,
|
||||
roleRepository,
|
||||
userRoleRepository,
|
||||
userLoginRepository,
|
||||
userClaimRepository,
|
||||
userPermissionSettingRepository,
|
||||
userOrganizationUnitRepository,
|
||||
organizationUnitRoleRepository,
|
||||
userTokenRepository
|
||||
)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,28 +1,29 @@
|
|||
using System.Collections.Concurrent;
|
||||
using Abp.Extensions;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Abp.Extensions;
|
||||
using Abp.Reflection.Extensions;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Configuration
|
||||
{
|
||||
public static class AppConfigurations
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, IConfigurationRoot> ConfigurationCache;
|
||||
private static readonly ConcurrentDictionary<string, IConfigurationRoot> _configurationCache;
|
||||
|
||||
static AppConfigurations()
|
||||
{
|
||||
ConfigurationCache = new ConcurrentDictionary<string, IConfigurationRoot>();
|
||||
_configurationCache = new ConcurrentDictionary<string, IConfigurationRoot>();
|
||||
}
|
||||
|
||||
public static IConfigurationRoot Get(string path, string environmentName = null)
|
||||
public static IConfigurationRoot Get(string path, string environmentName = null, bool addUserSecrets = false)
|
||||
{
|
||||
var cacheKey = path + "#" + environmentName;
|
||||
return ConfigurationCache.GetOrAdd(
|
||||
var cacheKey = path + "#" + environmentName + "#" + addUserSecrets;
|
||||
return _configurationCache.GetOrAdd(
|
||||
cacheKey,
|
||||
_ => BuildConfiguration(path, environmentName)
|
||||
_ => BuildConfiguration(path, environmentName, addUserSecrets)
|
||||
);
|
||||
}
|
||||
|
||||
private static IConfigurationRoot BuildConfiguration(string path, string environmentName = null)
|
||||
private static IConfigurationRoot BuildConfiguration(string path, string environmentName = null, bool addUserSecrets = false)
|
||||
{
|
||||
var builder = new ConfigurationBuilder()
|
||||
.SetBasePath(path)
|
||||
|
@ -32,9 +33,14 @@ namespace MultipleDbContextEfCoreDemo.Configuration
|
|||
{
|
||||
builder = builder.AddJsonFile($"appsettings.{environmentName}.json", optional: true);
|
||||
}
|
||||
|
||||
|
||||
builder = builder.AddEnvironmentVariables();
|
||||
|
||||
if (addUserSecrets)
|
||||
{
|
||||
builder.AddUserSecrets(typeof(AppConfigurations).GetAssembly(), optional: true);
|
||||
}
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace MultipleDbContextEfCoreDemo.Configuration
|
||||
{
|
||||
public static class AppSettingNames
|
||||
{
|
||||
public const string UiTheme = "App.UiTheme";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System.Collections.Generic;
|
||||
using Abp.Configuration;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Configuration
|
||||
{
|
||||
public class AppSettingProvider : SettingProvider
|
||||
{
|
||||
public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new SettingDefinition(AppSettingNames.UiTheme, "red", scopes: SettingScopes.Application | SettingScopes.Tenant | SettingScopes.User, clientVisibilityProvider: new VisibleSettingClientVisibilityProvider())
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using Abp.Domain.Entities;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Courses
|
||||
{
|
||||
//In second database
|
||||
[Table("Courses")]
|
||||
public class Course: Entity
|
||||
{
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace MultipleDbContextEfCoreDemo.Debugging
|
||||
{
|
||||
public static class DebugHelper
|
||||
{
|
||||
public static bool IsDebug
|
||||
{
|
||||
get
|
||||
{
|
||||
#pragma warning disable
|
||||
#if DEBUG
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
#pragma warning restore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using Abp.Application.Editions;
|
||||
using Abp.Application.Features;
|
||||
using Abp.Domain.Repositories;
|
||||
using Abp.Domain.Uow;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Editions
|
||||
{
|
||||
public class EditionManager : AbpEditionManager
|
||||
{
|
||||
public const string DefaultEditionName = "Standard";
|
||||
|
||||
public EditionManager(
|
||||
IRepository<Edition> editionRepository,
|
||||
IAbpZeroFeatureValueStore featureValueStore,
|
||||
IUnitOfWorkManager unitOfWorkManager)
|
||||
: base(editionRepository, featureValueStore, unitOfWorkManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using Abp.Application.Features;
|
||||
using Abp.Domain.Repositories;
|
||||
using Abp.Domain.Uow;
|
||||
using Abp.MultiTenancy;
|
||||
using Abp.Runtime.Caching;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
using MultipleDbContextEfCoreDemo.MultiTenancy;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Features
|
||||
{
|
||||
public class FeatureValueStore : AbpFeatureValueStore<Tenant, User>
|
||||
{
|
||||
public FeatureValueStore(
|
||||
ICacheManager cacheManager,
|
||||
IRepository<TenantFeatureSetting, long> tenantFeatureRepository,
|
||||
IRepository<Tenant> tenantRepository,
|
||||
IRepository<EditionFeatureSetting, long> editionFeatureRepository,
|
||||
IFeatureManager featureManager,
|
||||
IUnitOfWorkManager unitOfWorkManager)
|
||||
: base(
|
||||
cacheManager,
|
||||
tenantFeatureRepository,
|
||||
tenantRepository,
|
||||
editionFeatureRepository,
|
||||
featureManager,
|
||||
unitOfWorkManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MultipleDbContextEfCoreDemo.Authorization;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
using MultipleDbContextEfCoreDemo.Editions;
|
||||
using MultipleDbContextEfCoreDemo.MultiTenancy;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Identity
|
||||
{
|
||||
public static class IdentityRegistrar
|
||||
{
|
||||
public static IdentityBuilder Register(IServiceCollection services)
|
||||
{
|
||||
services.AddLogging();
|
||||
|
||||
return services.AddAbpIdentity<Tenant, User, Role>()
|
||||
.AddAbpTenantManager<TenantManager>()
|
||||
.AddAbpUserManager<UserManager>()
|
||||
.AddAbpRoleManager<RoleManager>()
|
||||
.AddAbpEditionManager<EditionManager>()
|
||||
.AddAbpUserStore<UserStore>()
|
||||
.AddAbpRoleStore<RoleStore>()
|
||||
.AddAbpLogInManager<LogInManager>()
|
||||
.AddAbpSignInManager<SignInManager>()
|
||||
.AddAbpSecurityStampValidator<SecurityStampValidator>()
|
||||
.AddAbpUserClaimsPrincipalFactory<UserClaimsPrincipalFactory>()
|
||||
.AddPermissionChecker<PermissionChecker>()
|
||||
.AddDefaultTokenProviders();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Abp.Authorization;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
using MultipleDbContextEfCoreDemo.MultiTenancy;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Abp.Domain.Uow;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Identity
|
||||
{
|
||||
public class SecurityStampValidator : AbpSecurityStampValidator<Tenant, Role, User>
|
||||
{
|
||||
public SecurityStampValidator(
|
||||
IOptions<SecurityStampValidatorOptions> options,
|
||||
SignInManager signInManager,
|
||||
ILoggerFactory loggerFactory,
|
||||
IUnitOfWorkManager unitOfWorkManager)
|
||||
: base(options, signInManager, loggerFactory, unitOfWorkManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Abp.Authorization;
|
||||
using Abp.Authorization.Users;
|
||||
using Abp.Configuration;
|
||||
using Abp.Domain.Uow;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Roles;
|
||||
using MultipleDbContextEfCoreDemo.Authorization.Users;
|
||||
using MultipleDbContextEfCoreDemo.MultiTenancy;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Identity
|
||||
{
|
||||
public class SignInManager : AbpSignInManager<Tenant, Role, User>
|
||||
{
|
||||
public SignInManager(
|
||||
UserManager userManager,
|
||||
IHttpContextAccessor contextAccessor,
|
||||
UserClaimsPrincipalFactory claimsFactory,
|
||||
IOptions<IdentityOptions> optionsAccessor,
|
||||
ILogger<SignInManager<User>> logger,
|
||||
IUnitOfWorkManager unitOfWorkManager,
|
||||
ISettingManager settingManager,
|
||||
IAuthenticationSchemeProvider schemes,
|
||||
IUserConfirmation<User> userConfirmation)
|
||||
: base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, unitOfWorkManager, settingManager, schemes, userConfirmation)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
using System.Reflection;
|
||||
using Abp.Configuration.Startup;
|
||||
using Abp.Localization;
|
||||
using Abp.Configuration.Startup;
|
||||
using Abp.Localization.Dictionaries;
|
||||
using Abp.Localization.Dictionaries.Json;
|
||||
using Abp.Localization.Dictionaries.Xml;
|
||||
using Abp.Reflection.Extensions;
|
||||
|
||||
namespace MultipleDbContextEfCoreDemo.Localization
|
||||
|
@ -11,12 +9,9 @@ namespace MultipleDbContextEfCoreDemo.Localization
|
|||
{
|
||||
public static void Configure(ILocalizationConfiguration localizationConfiguration)
|
||||
{
|
||||
localizationConfiguration.Languages.Add(new LanguageInfo("en", "English", "famfamfam-flags england", isDefault: true));
|
||||
localizationConfiguration.Languages.Add(new LanguageInfo("tr", "Türkçe", "famfamfam-flags tr"));
|
||||
|
||||
localizationConfiguration.Sources.Add(
|
||||
new DictionaryBasedLocalizationSource(MultipleDbContextEfCoreDemoConsts.LocalizationSourceName,
|
||||
new JsonEmbeddedFileLocalizationDictionaryProvider(
|
||||
new XmlEmbeddedFileLocalizationDictionaryProvider(
|
||||
typeof(MultipleDbContextEfCoreDemoLocalizationConfigurer).GetAssembly(),
|
||||
"MultipleDbContextEfCoreDemo.Localization.SourceFiles"
|
||||
)
|
||||
|
@ -24,4 +19,4 @@ namespace MultipleDbContextEfCoreDemo.Localization
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<localizationDictionary culture="es">
|
||||
<texts>
|
||||
<text name="HomePage" value="Página de inicio" />
|
||||
<text name="About" value="Acerca de" />
|
||||
<text name="WelcomeMessage" value="Bienvenido a WMS!" />
|
||||
<text name="FormIsNotValidMessage" value="Formulario no es válido. Por favor, compruebe y corrija los errores." />
|
||||
<text name="TenantNameCanNotBeEmpty" value="Nombre de la empresa no puede estar vacío" />
|
||||
<text name="InvalidUserNameOrPassword" value="Usuario o contraseña invalido" />
|
||||
<text name="ThereIsNoTenantDefinedWithName{0}" value="No hay empresa definida con el nombre {0}" />
|
||||
<text name="TenantIsNotActive" value="La empresa {0} no está activa." />
|
||||
<text name="UserIsNotActiveAndCanNotLogin" value="El usuario {0} no está activo y no puede conectarse." />
|
||||
<text name="UserEmailIsNotConfirmedAndCanNotLogin">Su dirección de correo electrónico no está confirmada. No puede iniciar sesión.</text>
|
||||
<text name="UserLockedOutMessage">La cuenta de usuario ha sido bloqueada. Por favor, inténtelo de nuevo más tarde.</text>
|
||||
<text name="PleaseEnterLoginInformation" value="Por favor, introduzca la información de inicio de sesión" />
|
||||
<text name="TenancyName" value="Nombre de la empresa" />
|
||||
<text name="UserNameOrEmail" value="Nombre de usuario o correo electrónico" />
|
||||
<text name="Password" value="Contraseña" />
|
||||
<text name="ResetPassword" value="Restablecer la contraseña" />
|
||||
<text name="UpdatePassword" value="Actualiza contraseña" />
|
||||
<text name="RememberMe" value="Recuérdame" />
|
||||
<text name="LogIn" value="Iniciar sesión" />
|
||||
<text name="LoginFailed" value="¡Error de inicio de sesión!" />
|
||||
<text name="NameSurname" value="Nombre Apellido" />
|
||||
<text name="UserName" value="Nombre de usuario" />
|
||||
<text name="Name" value="Nombre" />
|
||||
<text name="Surname" value="Apellido" />
|
||||
<text name="EmailAddress" value="Dirección de correo electrónico" />
|
||||
<text name="Tenants" value="Empresas" />
|
||||
<text name="SavedSuccessfully" value="Guardado correctamente" />
|
||||
<text name="CreateNewTenant" value="Crear nueva empresa" />
|
||||
<text name="AdminEmailAddress" value="Dirección de correo electrónico del administrador" />
|
||||
<text name="AdminPassword" value="Clave de administrador" />
|
||||
<text name="Save" value="Guardar" />
|
||||
<text name="Cancel" value="Cancelar" />
|
||||
<text name="TenantName_Regex_Description" value="El nombre de la empresa debe ser de al menos 2 caracteres, empieza con una letra y continua con una letra, número, guión o un guión bajo." />
|
||||
<text name="DefaultPasswordIs" value="La contraseña por defecto es {0}" />
|
||||
<text name="CanBeEmptyToLoginAsHost" value="Puede estar vacía para iniciar la sesión como anfitrión." />
|
||||
<text name="Register" value="Registro" />
|
||||
<text name="OrLoginWith" value="o iniciar sesión con" />
|
||||
<text name="WaitingForActivationMessage" value="Su cuenta está en espera de ser activada por el administrador del sistema." />
|
||||
<text name="TenantSelection" value="Selección de Empresa" />
|
||||
<text name="TenantSelection_Detail" value="Por favor seleccione una de las siguientes empresas." />
|
||||
<text name="Logout" value="Cerrar sesión" />
|
||||
<text name="RegisterFormUserNameInvalidMessage">No ingrese una dirección de correo electrónico para el nombre de usuario.</text>
|
||||
<text name="DatabaseConnectionString" value="Cadena de conexión de base de datos" />
|
||||
<text name="Users" value="Usuarios" />
|
||||
<text name="IsActive" value="Está activo" />
|
||||
<text name="FullName" value="Nombre completo" />
|
||||
<text name="CreateNewUser" value="Crear nuevo usuario" />
|
||||
<text name="Yes" value="Si" />
|
||||
<text name="No" value="No" />
|
||||
<text name="Optional" value="Opcional" />
|
||||
<text name="LeaveEmptyToSwitchToHost">Dejar vacío para cambiar al anfitrion</text>
|
||||
<text name="CurrentTenant">Inquilino actual</text>
|
||||
<text name="NotSelected">No seleccionado</text>
|
||||
<text name="Change">Cambio</text>
|
||||
<text name="ChangeTenant">Cambiar inquilino</text>
|
||||
<text name="MultiLevelMenu">Menú multinivel</text>
|
||||
<text name="Back">Atras</text>
|
||||
<text name="SuccessfullyRegistered">Registrado exitosamente</text>
|
||||
<text name="WaitingForEmailActivation">Su dirección de correo electrónico debe estar activada</text>
|
||||
<text name="Roles">Roles</text>
|
||||
<text name="DisplayName">Nombre para mostrar</text>
|
||||
<text name="Edit">Editar</text>
|
||||
<text name="Delete">Eliminar</text>
|
||||
<text name="CreateNewRole">Crear nuevo rol</text>
|
||||
<text name="RoleName">Nombre de rol</text>
|
||||
<text name="Actions">Acciones</text>
|
||||
<text name="CouldNotCompleteLoginOperation">No se pudo completar la operación de inicio de sesión. Por favor, inténtelo de nuevo más tarde.</text>
|
||||
<text name="CouldNotValidateExternalUser">No se pudo validar el usuario externo</text>
|
||||
<text name="EditRole">Editar rol</text>
|
||||
<text name="EditTenant">Editar inquilino</text>
|
||||
<text name="EditUser">Editar usuario</text>
|
||||
<text name="TenantIdIsNotActive{0}">Identificación del inquilino {0} no está activo</text>
|
||||
<text name="UnknownTenantId{0}">TenantId {0} desconocido</text>
|
||||
<text name="ThisFieldIsRequired">este campo es requerido</text>
|
||||
<text name="PleaseWait">Por favor espera...</text>
|
||||
<text name="Administration">Administración</text>
|
||||
<text name="ClearAll">Borrar tdo</text>
|
||||
<text name="ClearOthers">Borrar otros</text>
|
||||
<text name="LabelOptions">Opciones de etiqueta</text>
|
||||
<text name="Permissions">Permisos</text>
|
||||
<text name="RoleDescription">Descripción del rol</text>
|
||||
<text name="Refresh">Actualizar</text>
|
||||
<text name="Create">Crear</text>
|
||||
<text name="UserDetails">Detalles de usuario</text>
|
||||
<text name="UserRoles">Roles del usuario</text>
|
||||
<text name="ConfirmPassword">Confirmar contraseña</text>
|
||||
<text name="Version">Versión</text>
|
||||
<text name="On">Activo</text>
|
||||
<text name="Off">Inactivo</text>
|
||||
<text name="AreYouSureWantToDelete">¿Estás seguro de que quieres eliminar {0}?</text>
|
||||
<text name="SuccessfullyDeleted">Eliminado con éxito</text>
|
||||
<text name="StartTyping">Empiece a escribir</text>
|
||||
<text name="Skins">Pieles</text>
|
||||
<text name="Settings">Configuracion</text>
|
||||
<text name="Filter">Filtrar</text>
|
||||
<text name="CurrentPassword">contraseña actual</text>
|
||||
<text name="NewPassword">Nueva contraseña</text>
|
||||
<text name="ConfirmNewPassword">Confirmar nueva contraseña</text>
|
||||
<text name="PasswordsDoNotMatch">Las contraseñas no coinciden</text>
|
||||
<text name="PasswordsMustBeAtLeast8CharactersContainLowercaseUppercaseNumber">Las contraseñas deben tener al menos 8 caracteres, contener minúsculas, mayúsculas y números.</text>
|
||||
<text name="UserDeleteWarningMessage">El usuario {0} será eliminado.</text>
|
||||
<text name="RoleDeleteWarningMessage">La función {0} se eliminará y se anulará la asignación de todos los usuarios asignados.</text>
|
||||
<text name="TenantDeleteWarningMessage">El inquilino {0} será eliminado.</text>
|
||||
<text name="SearchWithThreeDot">Buscar...</text>
|
||||
<text name="PleaseEnterAtLeastNCharacter">Ingrese al menos {0} caracteres.</text>
|
||||
<text name="PleaseEnterNoMoreThanNCharacter">Por favor ingrese no más de {0} caracteres.</text>
|
||||
<text name="InvalidEmailAddress">Dirección de correo electrónico inválida.</text>
|
||||
<text name="InvalidPattern">Inválido</text>
|
||||
<text name="PairsDoNotMatch">No coinciden</text>
|
||||
<text name="All">Todas</text>
|
||||
<text name="TotalRecordsCount">Total: {0}</text>
|
||||
<text name="Search">Buscar</text>
|
||||
<text name="Clear">Borrar</text>
|
||||
<text name="ResetPasswordStepOneInfo">1. Ingrese su contraseña de administrador</text>
|
||||
<text name="ResetPasswordStepTwoInfo">2. Copie esta contraseña aleatoria para poder enviársela al usuario</text>
|
||||
</texts>
|
||||
</localizationDictionary>
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<localizationDictionary culture="fa">
|
||||
<texts>
|
||||
<text name="HomePage" value="خانه" />
|
||||
<text name="About" value="درباره" />
|
||||
<text name="WelcomeMessage" value="به MultipleDbContextEfCoreDemo خوش آمدید!" />
|
||||
<text name="FormIsNotValidMessage" value="مقادیر فرم معتبر نمیباشند. لطفا مقادیر وارد شده را بررسی نمایید." />
|
||||
<text name="TenantNameCanNotBeEmpty" value="نام Tenant نمیتواند خالی باشد." />
|
||||
<text name="InvalidUserNameOrPassword" value="نام کاربری یا رمز عبور نامعتبر است." />
|
||||
<text name="ThereIsNoTenantDefinedWithName{0}" value="Tenant ای با نام {0} یافت نشد." />
|
||||
<text name="TenantIsNotActive" value="Tenant {0} فعال نیست." />
|
||||
<text name="UserIsNotActiveAndCanNotLogin" value="کاربر {0} فعال نیست و امکان ورود ندارد." />
|
||||
<text name="UserEmailIsNotConfirmedAndCanNotLogin">آدرس ایمیل شما تایید نشده است. امکان ورود ندارید.</text>
|
||||
<text name="UserLockedOutMessage">کاربر مورد نظر قفل نشده است. لطفا مجددا بررسی نمایید.</text>
|
||||
<text name="PleaseEnterLoginInformation" value="لطفا اطلاعات ورود را وارد نمایید" />
|
||||
<text name="TenancyName" value="نام Tenant" />
|
||||
<text name="UserNameOrEmail" value="نام کاربری یا ایمیل" />
|
||||
<text name="Password" value="رمز عبور" />
|
||||
<text name="ResetPassword" value="بازنشانی رمز عبور" />
|
||||
<text name="UpdatePassword" value="بروزرسانی رمز عبور" />
|
||||
<text name="RememberMe" value="مرا به خاطر بسپار" />
|
||||
<text name="LogIn" value="ورود" />
|
||||
<text name="LoginFailed" value="ورود ناموفق بود!" />
|
||||
<text name="NameSurname" value="نام و نام خانوادگی" />
|
||||
<text name="UserName" value="نام کاربری" />
|
||||
<text name="Name" value="نام" />
|
||||
<text name="Surname" value="نام خانوادگی" />
|
||||
<text name="EmailAddress" value="آدرس ایمیل" />
|
||||
<text name="Tenants" value="Tenants" />
|
||||
<text name="SavedSuccessfully" value="ذخیره با موفقیت انجام شد" />
|
||||
<text name="CreateNewTenant" value="Create new tenant" />
|
||||
<text name="AdminEmailAddress" value="آدرس ایمیل ادمین" />
|
||||
<text name="AdminPassword" value="رمز عبور ادمین" />
|
||||
<text name="Save" value="ذخیره" />
|
||||
<text name="Cancel" value="انصراف" />
|
||||
<text name="TenantName_Regex_Description" value="Tenant name must be at least 2 chars, starts with a letter and continue with letter, number, dash or underscore." />
|
||||
<text name="DefaultPasswordIs" value="رمز عبور پیشفرض {0} است." />
|
||||
<text name="CanBeEmptyToLoginAsHost" value="میتواند برای ورود به عنوان هاست خالی باشد." />
|
||||
<text name="Register" value="ثبت نام" />
|
||||
<text name="OrLoginWith" value="با لاگین کنید با " />
|
||||
<text name="WaitingForActivationMessage" value="حساب کاربری شما در انتظار تایید توسط ادمین سیستم است." />
|
||||
<text name="TenantSelection" value="انتخاب Tenant" />
|
||||
<text name="TenantSelection_Detail" value="لطفا یکی از Tenantهای زیر را انتخاب نمایید ." />
|
||||
<text name="Logout" value="خروج" />
|
||||
<text name="RegisterFormUserNameInvalidMessage">لطفا آدرس ایمیل برای نام کاربری وارد نکنید.</text>
|
||||
<text name="DatabaseConnectionString" value="آدرس اتصال پایگاه داده" />
|
||||
<text name="Users" value="کاربران" />
|
||||
<text name="IsActive" value="فعال" />
|
||||
<text name="FullName" value="نام کامل" />
|
||||
<text name="CreateNewUser" value="ثبت کاربر جدید" />
|
||||
<text name="Yes" value="بله" />
|
||||
<text name="No" value="خیر" />
|
||||
<text name="Optional" value="اختیاری" />
|
||||
<text name="LeaveEmptyToSwitchToHost">Leave empty to switch to the host</text>
|
||||
<text name="CurrentTenant">Current tenant</text>
|
||||
<text name="NotSelected">انتخاب نشده</text>
|
||||
<text name="Change">تغییر</text>
|
||||
<text name="ChangeTenant">Change tenant</text>
|
||||
<text name="MultiLevelMenu">منو چند سطحی</text>
|
||||
<text name="Back">بازگشت</text>
|
||||
<text name="SuccessfullyRegistered">ثبت نام با موفقیت انجام شد</text>
|
||||
<text name="WaitingForEmailActivation">آدرس ایمیل شما باید فعال شود.</text>
|
||||
<text name="Roles">نقشها</text>
|
||||
<text name="DisplayName">نام نمایشی</text>
|
||||
<text name="Edit">ویرایش</text>
|
||||
<text name="Delete">حذف</text>
|
||||
<text name="CreateNewRole">ثبت نقش جدید</text>
|
||||
<text name="RoleName">نام نقش</text>
|
||||
<text name="Actions">عملیات</text>
|
||||
<text name="CouldNotCompleteLoginOperation">ورود انجام نشد. لطفا مجددا اقدام نمایید.</text>
|
||||
<text name="CouldNotValidateExternalUser">امکان اعتبارسنجی کاربر بیرونی وجود نداشت.</text>
|
||||
<text name="EditRole">ویرایش نقش</text>
|
||||
<text name="EditTenant">ویرایش Tenant</text>
|
||||
<text name="EditUser">ویرایش کاربر</text>
|
||||
<text name="TenantIdIsNotActive{0}">TenantId {0} is not active</text>
|
||||
<text name="UnknownTenantId{0}">Unknown tenantId {0}</text>
|
||||
<text name="ThisFieldIsRequired">این فیلد اجباری است</text>
|
||||
<text name="PleaseWait">لطفا صبور باشید...</text>
|
||||
<text name="Administration">ادمین</text>
|
||||
<text name="ClearAll">حذف همه</text>
|
||||
<text name="ClearOthers">حذف بقیه</text>
|
||||
<text name="LabelOptions">Label options</text>
|
||||
<text name="Permissions">دسترسیها</text>
|
||||
<text name="RoleDescription">توضیحات نقش</text>
|
||||
<text name="Refresh">بازنشانی</text>
|
||||
<text name="Create">ایجاد</text>
|
||||
<text name="UserDetails">جزییات کاربر</text>
|
||||
<text name="UserRoles">نقشهای کاربر</text>
|
||||
<text name="ConfirmPassword">تایید رمز عبور</text>
|
||||
<text name="Version">نسخه</text>
|
||||
<text name="On">روشن</text>
|
||||
<text name="Off">خاموش</text>
|
||||
<text name="AreYouSureWantToDelete">آیا از حذف {0} اطمینان دارید؟</text>
|
||||
<text name="SuccessfullyDeleted">با موفقیت حذف شد</text>
|
||||
<text name="StartTyping">شروع به نوشتن کنید</text>
|
||||
<text name="Skins">Skins</text>
|
||||
<text name="Settings">تنظیمات</text>
|
||||
<text name="Filter">فیلتر</text>
|
||||
<text name="CurrentPassword">رمز عبور فعلی</text>
|
||||
<text name="NewPassword">رمز عبور جدید</text>
|
||||
<text name="ConfirmNewPassword">تایید رمز عبور جدید</text>
|
||||
<text name="PasswordsDoNotMatch">رمزهای وارد شده یکسان نیستند</text>
|
||||
<text name="PasswordsMustBeAtLeast8CharactersContainLowercaseUppercaseNumber">رمز عبور باید حداقل هشت کاراکتر داشته باشد، شامل حروف کوچک، بزرگ و اعداد باشد</text>
|
||||
<text name="UserDeleteWarningMessage">کاربر {0} حذف خواهد شد.</text>
|
||||
<text name="RoleDeleteWarningMessage">نقش {0} و دسترسیهای آن حذف خواهد شد.</text>
|
||||
<text name="TenantDeleteWarningMessage">Tenant {0} will be deleted.</text>
|
||||
<text name="SearchWithThreeDot">جستجو...</text>
|
||||
<text name="PleaseEnterAtLeastNCharacter">حداقل {0} کاراکتر وارد کنید.</text>
|
||||
<text name="PleaseEnterNoMoreThanNCharacter">لطفا بیشتر از {0} کاراکتر وارد نکنید.</text>
|
||||
<text name="InvalidEmailAddress">آدرس ایمیل نامعتبر</text>
|
||||
<text name="InvalidPattern">نامعتبر</text>
|
||||
<text name="PairsDoNotMatch">یکسان نیست</text>
|
||||
<text name="All">همه</text>
|
||||
<text name="TotalRecordsCount">مجموعا {0}</text>
|
||||
<text name="Search">جستجو</text>
|
||||
<text name="Clear">پاک کردن</text>
|
||||
<text name="ResetPasswordStepOneInfo">1. رمز عبور ادمین را وارد کنید</text>
|
||||
<text name="ResetPasswordStepTwoInfo">2. رمز تصادفی را کپی کنید تا آن را برای کاربر ارسال نمایید</text>
|
||||
<text name="UsersActivation">فعالسازی کاربران</text>
|
||||
</texts>
|
||||
</localizationDictionary>
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<localizationDictionary culture="fr">
|
||||
<texts>
|
||||
<text name="HomePage" value="Accueil" />
|
||||
<text name="About" value="A propos" />
|
||||
<text name="WelcomeMessage" value="Bienvenue sur MultipleDbContextEfCoreDemo !" />
|
||||
|
||||
<text name="FormIsNotValidMessage" value="Le formulaire n'est pas valide. Veuillez le corriger." />
|
||||
<text name="TenantNameCanNotBeEmpty" value="Le nom de client (tenant) doit être renseigné." />
|
||||
|
||||
<text name="InvalidUserNameOrPassword" value="Nom d'utilisateur ou mot de passe non valide." />
|
||||
<text name="ThereIsNoTenantDefinedWithName{0}" value="Il n'y a aucun nom de client (tenant) correspondant à {0}" />
|
||||
<text name="TenantIsNotActive" value="Le client (tenant) {0} n'est pas actif." />
|
||||
<text name="UserIsNotActiveAndCanNotLogin" value="L'utilisateur {0} n'est pas actif ou ne peut pas s'authentifier." />
|
||||
<text name="PleaseEnterLoginInformation" value="Veuillez entrer vos informations d'authentification" />
|
||||
<text name="TenancyName" value="Nom du client (tenant)" />
|
||||
<text name="UserNameOrEmail" value="Nom d'utilisateur ou email" />
|
||||
<text name="Password" value="Mot de passe" />
|
||||
<text name="RememberMe" value="Se rappeler de moi" />
|
||||
<text name="LogIn" value="Se connecter" />
|
||||
|
||||
<text name="LoginFailed" value="Echec d'authentification !" />
|
||||
|
||||
<text name="NameSurname" value="Nom de famille" />
|
||||
<text name="UserName" value="Nom d'utilisateur" />
|
||||
<text name="Name" value="Prénom" />
|
||||
<text name="Surname" value="Nom de famille" />
|
||||
<text name="EmailAddress" value="Adresse email" />
|
||||
|
||||
<text name="Tenants" value="Clients (tenants)" />
|
||||
<text name="SavedSuccessfully" value="Enregistrement réussi" />
|
||||
<text name="CreateNewTenant" value="Créer un nouveau client (tenant)" />
|
||||
<text name="AdminEmailAddress" value="Adresse email de l'administrateur" />
|
||||
<text name="Save" value="Valider" />
|
||||
<text name="Cancel" value="Annuler" />
|
||||
<text name="TenantName_Regex_Description" value="Le nom de client (tenant) doit comporter au moins 2 caractères et commencer par une lettre suivie d'autres lettres, chiffres ou tirets." />
|
||||
<text name="DefaultPasswordIs" value="Le mot de passe par défaut est {0}" />
|
||||
<text name="CanBeEmptyToLoginAsHost" value="Peut être laissé vide pour s'authentifier en tant qu'hébergeur (host)." />
|
||||
<text name="Register" value="S'enregistrer" />
|
||||
<text name="OrLoginWith" value="Ou s'authentifier avec" />
|
||||
<text name="WaitingForActivationMessage" value="Votre compte est en attente d'activation par l'administrateur du système." />
|
||||
<text name="TenantSelection" value="Sélection du client (tenant)" />
|
||||
<text name="TenantSelection_Detail" value="Veuillez choisir l'un de ces clients (tenants) suivants." />
|
||||
<text name="Logout" value="Déconnexion" />
|
||||
<text name="SearchWithThreeDot">Rechercher...</text>
|
||||
</texts>
|
||||
</localizationDictionary>
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<localizationDictionary culture="it">
|
||||
<texts>
|
||||
<text name="HomePage" value="Home page" />
|
||||
<text name="About" value="Chi siamo" />
|
||||
<text name="WelcomeMessage" value="Benvenuti su My New House!" />
|
||||
|
||||
<text name="FormIsNotValidMessage" value="I dati non sono corretti. Verifica gli errori." />
|
||||
<text name="TenantNameCanNotBeEmpty" value="Il Dominio non può essere vuoto" />
|
||||
|
||||
<text name="InvalidUserNameOrPassword" value="Username o password errati" />
|
||||
<text name="ThereIsNoTenantDefinedWithName{0}" value="Il dominio {0} non esiste" />
|
||||
<text name="TenantIsNotActive" value="Il dominio {0} non è attivo." />
|
||||
<text name="UserIsNotActiveAndCanNotLogin" value="L'utente {0} non è attivo e non può fare login." />
|
||||
<text name="UserEmailIsNotConfirmedAndCanNotLogin">Indirizzo email non registrato. Login non ammesso.</text>
|
||||
<text name="UserLockedOutMessage">L'account è momentaneamente bloccato. Riprovare più tardi.</text>
|
||||
<text name="PleaseEnterLoginInformation" value="Inserisci le informazioni di login" />
|
||||
<text name="TenancyName" value="Dominio" />
|
||||
<text name="UserNameOrEmail" value="Use name o email" />
|
||||
<text name="Password" value="Password" />
|
||||
<text name="RememberMe" value="Ricordati di me" />
|
||||
<text name="LogIn" value="Log in" />
|
||||
|
||||
<text name="LoginFailed" value="Login errato!" />
|
||||
|
||||
<text name="NameSurname" value="Nome e Cognome" />
|
||||
<text name="UserName" value="Username" />
|
||||
<text name="Name" value="Nome" />
|
||||
<text name="Surname" value="Cognome" />
|
||||
<text name="EmailAddress" value="Email" />
|
||||
|
||||
<text name="Tenants" value="Dominio" />
|
||||
<text name="SavedSuccessfully" value="Salvato" />
|
||||
<text name="CreateNewTenant" value="Crea un nuovo dominio" />
|
||||
<text name="AdminEmailAddress" value="Indirizzo email Amministratore" />
|
||||
<text name="Save" value="Salva" />
|
||||
<text name="Cancel" value="Annulla" />
|
||||
<text name="TenantName_Regex_Description" value="Il dominio deve essere di almeno 2 caratteri, iniziare con una lettera e continuare con lettere, numeri o trattini." />
|
||||
<text name="DefaultPasswordIs" value="La password di default è {0}" />
|
||||
<text name="CanBeEmptyToLoginAsHost" value="Può essere vuoto per entrare come ospite." />
|
||||
<text name="Register" value="Registrati" />
|
||||
<text name="OrLoginWith" value="O entra con" />
|
||||
<text name="WaitingForActivationMessage" value="Il tuo account è in attesa di approvazione." />
|
||||
<text name="TenantSelection" value="Selezione dominio" />
|
||||
<text name="TenantSelection_Detail" value="Seleziona uno dei seguenti domini." />
|
||||
<text name="Logout" value="Logout" />
|
||||
|
||||
<text name="DatabaseConnectionString" value="String connession Database" />
|
||||
<text name="Users" value="Utenti" />
|
||||
<text name="IsActive" value="Attivo" />
|
||||
<text name="FullName" value="Nome completo" />
|
||||
<text name="CreateNewUser" value="Nuovo utente" />
|
||||
<text name="Yes" value="Sì" />
|
||||
<text name="No" value="No" />
|
||||
<text name="Optional" value="Opzionale" />
|
||||
<text name="SearchWithThreeDot">Cerca...</text>
|
||||
</texts>
|
||||
</localizationDictionary>
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<localizationDictionary culture="ja">
|
||||
<texts>
|
||||
<text name="HomePage" value="ホームページ" />
|
||||
<text name="About" value="我々について" />
|
||||
<text name="WelcomeMessage" value="ようこそ MultipleDbContextEfCoreDemo へ!" />
|
||||
|
||||
<text name="FormIsNotValidMessage" value="フォームは無効です。エラーを修正してください。" />
|
||||
<text name="TenantNameCanNotBeEmpty" value="テナント名を空にすることはできません" />
|
||||
|
||||
<text name="InvalidUserNameOrPassword" value="無効なユーザー名またはパスワードです" />
|
||||
<text name="ThereIsNoTenantDefinedWithName{0}" value="テナント名前 {0} の定義がありません。" />
|
||||
<text name="TenantIsNotActive" value="テナント {0} はアクティブではありません。 " />
|
||||
<text name="UserIsNotActiveAndCanNotLogin" value="ユーザー {0} がアクティブでなくログインできません。" />
|
||||
<text name="PleaseEnterLoginInformation" value="ログイン情報を入力してください" />
|
||||
<text name="TenancyName" value="テナント名" />
|
||||
<text name="UserNameOrEmail" value="ユーザ名 または E-mail" />
|
||||
<text name="Password" value="パスワード" />
|
||||
<text name="RememberMe" value="ログイン情報を記憶する" />
|
||||
<text name="LogIn" value="ログイン" />
|
||||
|
||||
<text name="LoginFailed" value="ログイン失敗!" />
|
||||
|
||||
<text name="NameSurname" value="名 姓" />
|
||||
<text name="UserName" value="ユーザ名" />
|
||||
<text name="Name" value="名前" />
|
||||
<text name="Surname" value="姓" />
|
||||
<text name="EmailAddress" value="E-mailアドレス" />
|
||||
|
||||
<text name="Tenants" value="テナント" />
|
||||
<text name="SavedSuccessfully" value="保存成功" />
|
||||
<text name="CreateNewTenant" value="新規テナント作成" />
|
||||
<text name="AdminEmailAddress" value="管理者 E-mailアドレス" />
|
||||
<text name="Save" value="保存" />
|
||||
<text name="Cancel" value="キャンセル" />
|
||||
<text name="TenantName_Regex_Description" value="テナント名は少なくとも 2 文字、英字で始まり、文字、数字、ダッシュまたはアンダー スコアである必要があります。" />
|
||||
<text name="DefaultPasswordIs" value="デフォルトパスワードは {0} です" />
|
||||
<text name="CanBeEmptyToLoginAsHost" value="ホストでのログインは空とすることができます。" />
|
||||
<text name="Register" value="登録" />
|
||||
<text name="OrLoginWith" value="または次でログイン" />
|
||||
<text name="WaitingForActivationMessage" value="あなたのアカウントがシステム管理者によってアクティブにされるまで待機しています。" />
|
||||
<text name="TenantSelection" value="テナント選択" />
|
||||
<text name="TenantSelection_Detail" value="次のテナントの 1 つを選択してください。" />
|
||||
<text name="Logout" value="ログアウト" />
|
||||
|
||||
<text name="RegisterFormUserNameInvalidMessage">ユーザのメールアドレスを入力しないでください。</text>
|
||||
|
||||
<text name="DatabaseConnectionString" value="データベース接続文字列" />
|
||||
<text name="Users" value="ユーザ" />
|
||||
<text name="IsActive" value="アクティブ" />
|
||||
<text name="FullName" value="フルネーム" />
|
||||
<text name="CreateNewUser" value="新規ユーザ作成" />
|
||||
<text name="Yes" value="はい" />
|
||||
<text name="No" value="いいえ" />
|
||||
<text name="Optional" value="オプション" />
|
||||
</texts>
|
||||
</localizationDictionary>
|
|
@ -0,0 +1,131 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<localizationDictionary culture="lt">
|
||||
<texts>
|
||||
<text name="HomePage" value="Pagrindinis" />
|
||||
<text name="About" value="Apie" />
|
||||
<text name="WelcomeMessage" value="Sveiki atvykė į MultipleDbContextEfCoreDemo!" />
|
||||
|
||||
<text name="FormIsNotValidMessage" value="Forma blogai užpildyta. Peržiūrėkite ir pataisykite klaidas." />
|
||||
<text name="TenantNameCanNotBeEmpty" value="Savininko pavadinimas negali būti tuščias" />
|
||||
|
||||
<text name="InvalidUserNameOrPassword" value="Blogas vartotojo vardas ar slaptažodis" />
|
||||
<text name="ThereIsNoTenantDefinedWithName{0}" value="Nėra tokio savininko su pavadinimu {0}" />
|
||||
<text name="TenantIsNotActive" value="Savininkas {0} nėra aktyvus." />
|
||||
<text name="UserIsNotActiveAndCanNotLogin" value="Vartotojas {0} nėra aktyvus ir todėl negali prisijungti." />
|
||||
<text name="UserEmailIsNotConfirmedAndCanNotLogin">Jūsų el. pašto adresas nepatvirtintas. Jūs negalite prisijungti.</text>
|
||||
<text name="UserLockedOutMessage">Vartotojo paskyra buvo užblokuota. Pabandykite dar kartą vėliau.</text>
|
||||
<text name="PleaseEnterLoginInformation" value="Įveskite prisijungimo informaciją" />
|
||||
<text name="TenancyName" value="Savininko pavadinimas" />
|
||||
<text name="UserNameOrEmail" value="Vartotojo vardas ar slaptažodis" />
|
||||
<text name="Password" value="Slaptažodis" />
|
||||
<text name="RememberMe" value="Prisiminti mane" />
|
||||
<text name="LogIn" value="Prisijungti" />
|
||||
|
||||
<text name="LoginFailed" value="Prisijungimas nepavyko!" />
|
||||
|
||||
<text name="NameSurname" value="Vardas pavardė" />
|
||||
<text name="UserName" value="Vartotojo vardas" />
|
||||
<text name="Name" value="Vardas" />
|
||||
<text name="Surname" value="Pavardė" />
|
||||
<text name="EmailAddress" value="El. pašto adresas" />
|
||||
|
||||
<text name="Tenants" value="Savininkai" />
|
||||
<text name="SavedSuccessfully" value="Išsaugota sėkmingai" />
|
||||
<text name="CreateNewTenant" value="Sukurti naują savininką" />
|
||||
<text name="AdminEmailAddress" value="Administratoriaus el. pašto adresas" />
|
||||
<text name="Save" value="Išsaugoti" />
|
||||
<text name="Cancel" value="Atšaukti" />
|
||||
<text name="TenantName_Regex_Description" value="Savininko pavadinimas privalo būti bent 2 simboliai, prasidėti su raide, skaičiumi, brūkšneliu ar pabraukimu." />
|
||||
<text name="DefaultPasswordIs" value="Slaptažodis pagal nutylėjimą yra {0}" />
|
||||
<text name="CanBeEmptyToLoginAsHost" value="Gali būti tuščia prisijungimui šeimininku." />
|
||||
<text name="Register" value="Registruotis" />
|
||||
<text name="OrLoginWith" value="Arba prisijungti su" />
|
||||
<text name="WaitingForActivationMessage" value="Jūsų paskyra laukia, kol bus aktyvuota sistemos administratoriaus." />
|
||||
<text name="TenantSelection" value="Savininko Pasirinkimas" />
|
||||
<text name="TenantSelection_Detail" value="Pasirinkite vieną iš šių savininkų." />
|
||||
<text name="Logout" value="Atsijungti" />
|
||||
|
||||
<text name="RegisterFormUserNameInvalidMessage">Neveskite el. pašto adreso kaip vartotojo vardo.</text>
|
||||
|
||||
<text name="DatabaseConnectionString" value="Duomenų bazės prisijungimo eilutė" />
|
||||
<text name="Users" value="Vartotojai" />
|
||||
<text name="IsActive" value="Aktyvus" />
|
||||
<text name="FullName" value="Vardas pavardė" />
|
||||
<text name="CreateNewUser" value="Sukurti naują vartotoją" />
|
||||
<text name="Yes" value="Taip" />
|
||||
<text name="No" value="Ne" />
|
||||
<text name="Optional" value="Neprivaloma" />
|
||||
<text name="LeaveEmptyToSwitchToHost">Palikite tuščią, kad perjungtumėte į priimantįjį</text>
|
||||
|
||||
<text name="CurrentTenant">Dabartinis savininkas</text>
|
||||
<text name="NotSelected">Nepasirinkta</text>
|
||||
<text name="Change">Keisti</text>
|
||||
<text name="ChangeTenant">Keisti savininką</text>
|
||||
|
||||
<text name="MultiLevelMenu">Multi Level Menu</text>
|
||||
<text name="Back">Atgal</text>
|
||||
<text name="SuccessfullyRegistered">Sėkmingai užregistruota</text>
|
||||
<text name="WaitingForEmailActivation">Jūsų el. pašto adresas turi būti aktyvuotas.</text>
|
||||
<text name="Roles">Rolės</text>
|
||||
<text name="DisplayName">Rodomas vardas</text>
|
||||
|
||||
<text name="Edit">Keisti</text>
|
||||
<text name="Delete">Trinti</text>
|
||||
|
||||
<text name="CreateNewRole">Kurti naują rolę</text>
|
||||
<text name="RoleName">Rolės pavadinimas</text>
|
||||
<text name="Actions">Veiksmai</text>
|
||||
|
||||
<text name="CouldNotCompleteLoginOperation">Prisijungimo veiksmas nepavyko. Pabandykite vėliau.</text>
|
||||
|
||||
<text name="CouldNotValidateExternalUser">Nepavyko patikrinti išorinio vartotojo</text>
|
||||
<text name="EditRole">Keisti rolę</text>
|
||||
<text name="EditTenant">Keisti savininką</text>
|
||||
<text name="EditUser">Keisti vartotoją</text>
|
||||
<text name="TenantIdIsNotActive{0}">Savininkas su Id {0} yra neaktyvus</text>
|
||||
<text name="UnknownTenantId{0}">Nežinomas savininko Id {0}</text>
|
||||
|
||||
<text name="ThisFieldIsRequired">Šis laukas yra privalomas</text>
|
||||
<text name="PleaseWait">Prašome palaukti...</text>
|
||||
<text name="Administration">Administration</text>
|
||||
<text name="ClearAll">Išvalyti visus</text>
|
||||
<text name="ClearOthers">Išvalyti kitus</text>
|
||||
<text name="LabelOptions">Etiketės nustatymai</text>
|
||||
<text name="Permissions">Leidimai</text>
|
||||
<text name="RoleDescription">Rolės aprašymas</text>
|
||||
<text name="Refresh">Atnaujinti</text>
|
||||
<text name="Create">Sukurti</text>
|
||||
<text name="UserDetails">Vartotojo detalės</text>
|
||||
<text name="UserRoles">Vartotojo rolės</text>
|
||||
<text name="ConfirmPassword">Patvirtinti slaptažodį</text>
|
||||
<text name="Version">Versija</text>
|
||||
<text name="On">Įjungta</text>
|
||||
<text name="Off">Išjungta</text>
|
||||
<text name="AreYouSureWantToDelete">Ar tikrai norite pašalinti {0}?</text>
|
||||
<text name="StartTyping">Pradėkite rašyti</text>
|
||||
<text name="Skins">Apvalkalai</text>
|
||||
<text name="Settings">Nustatymai</text>
|
||||
<text name="Filter">Filtruoti</text>
|
||||
<text name="CurrentPassword">Dabartinis slaptažodis</text>
|
||||
<text name="NewPassword">Naujas slaptažodis</text>
|
||||
<text name="ConfirmNewPassword">Pakartoti naują slaptažodį</text>
|
||||
<text name="PasswordsDoNotMatch">Slaptažodžiai nesutampa</text>
|
||||
<text name="PasswordsMustBeAtLeast8CharactersContainLowercaseUppercaseNumber">Slaptažodžiai turi būti bent 8 simbolių, turėti mažųjų, didžiųjų raidžių ir skaičių</text>
|
||||
<text name="UserDeleteWarningMessage">Vartotojas {0} bus pašalintas.</text>
|
||||
<text name="RoleDeleteWarningMessage">Rolė {0} bus pašalinta ir atskirta nuo visų priskirtų vartotojų.</text>
|
||||
<text name="TenantDeleteWarningMessage">Savininkas {0} bus pašalintas.</text>
|
||||
<text name="SearchWithThreeDot">Ieškoti...</text>
|
||||
<text name="PleaseEnterAtLeastNCharacter">Įveskite bent {0} simbolius</text>
|
||||
<text name="PleaseEnterNoMoreThanNCharacter">Įveskite ne daugiau nei {0} simbolius</text>
|
||||
<text name="InvalidEmailAddress">Nevalidus el. pašto adresas</text>
|
||||
<text name="InvalidPattern">Nevalidus</text>
|
||||
<text name="PairsDoNotMatch">Nesutampa</text>
|
||||
<text name="All">Visi</text>
|
||||
<text name="TotalRecordsCount">Iš viso: {0}</text>
|
||||
<text name="Search">Ieškoti</text>
|
||||
<text name="Clear">Išvalyti</text>
|
||||
<text name="ResetPasswordStepOneInfo">1. Įveskite savo administratoriaus slaptažodį</text>
|
||||
<text name="ResetPasswordStepTwoInfo">2. Nusikopijuokite šį atsitiktinį slaptažodį, kad persiųstumėte vartotojui</text>
|
||||
<text name="UsersActivation">Vartotojų aktyvacija</text>
|
||||
</texts>
|
||||
</localizationDictionary>
|
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<localizationDictionary culture="nl">
|
||||
<texts>
|
||||
<text name="HomePage" value="Startpagina" />
|
||||
<text name="About" value="Over" />
|
||||
<text name="WelcomeMessage" value="Welkom bij MultipleDbContextEfCoreDemo!" />
|
||||
|
||||
<text name="FormIsNotValidMessage" value="Formulier is onjuist ingevuld. Controleer en herstel de fouten." />
|
||||
<text name="TenantNameCanNotBeEmpty" value="Naam van de huurder mag niet leeg zijn" />
|
||||
|
||||
<text name="InvalidUserNameOrPassword" value="Onjuiste gebruikersnaam en/of wachtwoord" />
|
||||
<text name="ThereIsNoTenantDefinedWithName{0}" value="Er is geen huurder met de naam {0}" />
|
||||
<text name="TenantIsNotActive" value="Huurder {0} is niet actief." />
|
||||
<text name="UserIsNotActiveAndCanNotLogin" value="Gebruiker {0} is niet actief en kan niet inloggen." />
|
||||
<text name="UserEmailIsNotConfirmedAndCanNotLogin">Uw email adres is nog niet bevestigd. U kan niet inloggen.</text>
|
||||
<text name="UserLockedOutMessage">De gebruikersaccount is geblokkeerd. Gelieve later opnieuw te proberen.</text>
|
||||
<text name="PleaseEnterLoginInformation" value="Vul gebruikersnaam en wachtwoord in" />
|
||||
<text name="TenancyName" value="Naam huurder" />
|
||||
<text name="UserNameOrEmail" value="Gebruikersnaam of e-mail" />
|
||||
<text name="Password" value="Wachtwoord" />
|
||||
<text name="RememberMe" value="Onthoud mij" />
|
||||
<text name="LogIn" value="Log in" />
|
||||
|
||||
<text name="LoginFailed" value="Inloggen mislukt!" />
|
||||
|
||||
<text name="NameSurname" value="Naam achternaam" />
|
||||
<text name="UserName" value="Gebruikersnaam" />
|
||||
<text name="Name" value="Naam" />
|
||||
<text name="Surname" value="Achternaam" />
|
||||
<text name="EmailAddress" value="E-mailadres" />
|
||||
|
||||
<text name="Tenants" value="Huurders" />
|
||||
<text name="SavedSuccessfully" value="Correct opgeslagen" />
|
||||
<text name="CreateNewTenant" value="Huurder aanmaken" />
|
||||
<text name="AdminEmailAddress" value="E-mailadres beheerder" />
|
||||
<text name="Save" value="Opslaan" />
|
||||
<text name="Cancel" value="Annuleer" />
|
||||
<text name="TenantName_Regex_Description" value="De naam van de huurder dient minimaal 2 tekens te hebben en moet beginnen met een letter en kan daarnaast nog letters, nummers en een (liggend) streepje bevatten." />
|
||||
<text name="DefaultPasswordIs" value="Standaard wachtwoord is {0}" />
|
||||
<text name="CanBeEmptyToLoginAsHost" value="Kan leeggelaten worden indien je als host in wilt loggen." />
|
||||
<text name="Register" value="Registreer" />
|
||||
<text name="OrLoginWith" value="Of log in met" />
|
||||
<text name="WaitingForActivationMessage" value="Je account dient nog te worden geactiveerd door de beheerder." />
|
||||
<text name="TenantSelection" value="Huurder selectie" />
|
||||
<text name="TenantSelection_Detail" value="Selecteer één van onderstaande huurders." />
|
||||
<text name="Logout" value="Uitloggen" />
|
||||
|
||||
<text name="RegisterFormUserNameInvalidMessage">Voer a.u.b. geen e-mailadres in als gebruikersnaam.</text>
|
||||
|
||||
<text name="DatabaseConnectionString" value="Database connectie string" />
|
||||
<text name="Users" value="Gebruikers" />
|
||||
<text name="IsActive" value="Is actief" />
|
||||
<text name="FullName" value="Volledige naam" />
|
||||
<text name="CreateNewUser" value="Gebruiker aanmaken" />
|
||||
<text name="Yes" value="Ja" />
|
||||
<text name="No" value="Nee" />
|
||||
<text name="Optional" value="Optioneel" />
|
||||
<text name="LeaveEmptyToSwitchToHost">Laat leeg om naar de host te gaan</text>
|
||||
|
||||
<text name="CurrentTenant">Huidige huurder</text>
|
||||
<text name="NotSelected">Niet geselecteerd</text>
|
||||
<text name="Change">Wijzig</text>
|
||||
<text name="ChangeTenant">Wijzig huurder</text>
|
||||
|
||||
<text name="MultiLevelMenu">Multi Level Menu</text>
|
||||
<text name="Back">Terug</text>
|
||||
<text name="SuccessfullyRegistered">Met success geregistreerd</text>
|
||||
<text name="WaitingForEmailActivation">Uw email adres moet geactiveerd worden</text>
|
||||
<text name="Roles">Rollen</text>
|
||||
<text name="DisplayName">Weergavenaam</text>
|
||||
|
||||
<text name="Edit">Bewerk</text>
|
||||
<text name="Delete">Verwijder</text>
|
||||
|
||||
<text name="CreateNewRole">Maak nieuwe rol</text>
|
||||
<text name="RoleName">Rol Naam</text>
|
||||
<text name="Actions">Acties</text>
|
||||
|
||||
<text name="CouldNotCompleteLoginOperation">De login operatie kon niet afgewerkt worden. Gelieve later opnieuw te proberen.</text>
|
||||
|
||||
<text name="CouldNotValidateExternalUser">De externe gebruiker kon niet gevalideerd worden</text>
|
||||
<text name="EditRole">Bewerk rol</text>
|
||||
<text name="EditTenant">Bewerk huurder</text>
|
||||
<text name="EditUser">Bewerk gebruiker</text>
|
||||
<text name="TenantIdIsNotActive{0}">HuurderId {0} is niet actief</text>
|
||||
<text name="UnknownTenantId{0}">Onbekend huurderId {0}</text>
|
||||
</texts>
|
||||
</localizationDictionary>
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче