@ -0,0 +1,50 @@ |
|||
param( |
|||
[string]$branch, |
|||
[string]$newVersion |
|||
) |
|||
|
|||
. ..\nupkg\common.ps1 |
|||
|
|||
if (!$branch) |
|||
{ |
|||
$branch = Read-Host "Enter the branch name" |
|||
} |
|||
|
|||
#----------- Read the current version from common.props ----------- |
|||
$commonPropsFilePath = resolve-path "../common.props" |
|||
$commonPropsXmlCurrent = [xml](Get-Content $commonPropsFilePath ) |
|||
$currentVersion = $commonPropsXmlCurrent.Project.PropertyGroup.Version.Trim() |
|||
|
|||
if (!$newVersion) |
|||
{ |
|||
$newVersion = Read-Host "Current version is '$currentVersion'. Enter the new version (empty for no change) " |
|||
if($newVersion -eq "") |
|||
{ |
|||
$newVersion = $currentVersion |
|||
} |
|||
} |
|||
|
|||
if ($newVersion -ne $currentVersion){ |
|||
# Update common.props for version attribute |
|||
$commonPropsXmlCurrent.Project.PropertyGroup.Version = $newVersion |
|||
$commonPropsXmlCurrent.Save( $commonPropsFilePath ) |
|||
#check if it's updated... |
|||
$commonPropsXmlNew = [xml](Get-Content $commonPropsFilePath ) |
|||
$newVersionAfterUpdate = $commonPropsXmlNew.Project.PropertyGroup.Version |
|||
echo "`n`nNew version updated as '$newVersionAfterUpdate' in $commonPropsFilePath`n" |
|||
} |
|||
|
|||
|
|||
################################################################ |
|||
Write-Info "Pulling ABP $branch branch from GitHub" |
|||
cd .. |
|||
git switch $branch |
|||
git pull origin |
|||
|
|||
################################################################ |
|||
Write-Info "Building ABP repository" |
|||
cd build |
|||
.\build-all-release.ps1 |
|||
|
|||
Write-Info "Completed: Building ABP repository" |
|||
cd ..\deploy #always return to the deploy directory |
|||
@ -0,0 +1,10 @@ |
|||
. ..\nupkg\common.ps1 |
|||
Write-Info "Creating NuGet packages" |
|||
|
|||
echo "`n-----=====[ CREATING NUGET PACKAGES ]=====-----`n" |
|||
cd ..\nupkg |
|||
powershell -File pack.ps1 |
|||
echo "`n-----=====[ CREATING NUGET PACKAGES COMPLETED ]=====-----`n" |
|||
|
|||
Write-Info "Completed: Creating NuGet packages" |
|||
cd ..\deploy #always return to the deploy directory |
|||
@ -0,0 +1,31 @@ |
|||
param( |
|||
[string]$nugetApiKey |
|||
) |
|||
|
|||
. ..\nupkg\common.ps1 |
|||
|
|||
if (!$nugetApiKey) |
|||
{ |
|||
#reading password from file content |
|||
$passwordFileName = "nuget-api-key.txt" |
|||
$pathExists = Test-Path -Path $passwordFileName -PathType Leaf |
|||
if ($pathExists) |
|||
{ |
|||
$nugetApiKey = Get-Content $passwordFileName |
|||
echo "Using NuGet API Key from $passwordFileName ..." |
|||
} |
|||
} |
|||
|
|||
if (!$nugetApiKey) |
|||
{ |
|||
$nugetApiKey = Read-Host "Enter the NuGet API KEY" |
|||
} |
|||
|
|||
Write-Info "Pushing packages to NuGet" |
|||
echo "`n-----=====[ PUSHING PACKAGES TO NUGET ]=====-----`n" |
|||
cd ..\nupkg |
|||
powershell -File push_packages.ps1 $nugetApiKey |
|||
echo "`n-----=====[ PUSHING PACKAGES TO NUGET COMPLETED ]=====-----`n" |
|||
Write-Info "Completed: Pushing packages to NuGet" |
|||
|
|||
cd ..\deploy #always return to the deploy directory |
|||
@ -0,0 +1,39 @@ |
|||
param( |
|||
[string]$npmAuthToken |
|||
) |
|||
|
|||
. ..\nupkg\common.ps1 |
|||
|
|||
if (!$npmAuthToken) |
|||
{ |
|||
#reading password from file content |
|||
$passwordFileName = "npm-auth-token.txt" |
|||
$pathExists = Test-Path -Path $passwordFileName -PathType Leaf |
|||
if ($pathExists) |
|||
{ |
|||
$npmAuthToken = Get-Content $passwordFileName |
|||
echo "Using NPM Auth Token from $passwordFileName ..." |
|||
} |
|||
} |
|||
|
|||
if (!$npmAuthToken) |
|||
{ |
|||
$npmAuthToken = Read-Host "Enter the NPM Auth Token" |
|||
} |
|||
|
|||
cd ..\npm |
|||
|
|||
#---------------------------------------------------------------------------- |
|||
|
|||
echo "`nSetting npmjs.org auth-token token`n" |
|||
npm set //registry.npmjs.org/:_authToken $npmAuthToken |
|||
|
|||
#---------------------------------------------------------------------------- |
|||
|
|||
Write-Info "Pushing MVC packages to NPM" |
|||
echo "`n-----=====[ PUSHING MVC PACKS TO NPM ]=====-----`n" |
|||
powershell -File publish-mvc.ps1 |
|||
echo "`n-----=====[ PUSHING MVC PACKS TO NPM COMPLETED ]=====-----`n" |
|||
Write-Info "Completed: Pushing MVC packages to NPM" |
|||
|
|||
cd ..\deploy #always return to the deploy directory |
|||
@ -0,0 +1,39 @@ |
|||
param( |
|||
[string]$npmAuthToken |
|||
) |
|||
|
|||
. ..\nupkg\common.ps1 |
|||
|
|||
if (!$npmAuthToken) |
|||
{ |
|||
#reading password from file content |
|||
$passwordFileName = "npm-auth-token.txt" |
|||
$pathExists = Test-Path -Path $passwordFileName -PathType Leaf |
|||
if ($pathExists) |
|||
{ |
|||
$npmAuthToken = Get-Content $passwordFileName |
|||
echo "Using NPM Auth Token from $passwordFileName ..." |
|||
} |
|||
} |
|||
|
|||
if (!$npmAuthToken) |
|||
{ |
|||
$npmAuthToken = Read-Host "Enter the NPM Auth Token" |
|||
} |
|||
|
|||
cd ..\npm |
|||
|
|||
#---------------------------------------------------------------------------- |
|||
|
|||
echo "`nSetting npmjs.org auth-token token`n" |
|||
npm set //registry.npmjs.org/:_authToken $npmAuthToken |
|||
|
|||
#---------------------------------------------------------------------------- |
|||
|
|||
Write-Info "Pushing MVC packages to NPM" |
|||
echo "`n-----=====[ PUSHING MVC PACKS TO NPM ]=====-----`n" |
|||
powershell -File publish-ng.ps1 |
|||
echo "`n-----=====[ PUSHING MVC PACKS TO NPM COMPLETED ]=====-----`n" |
|||
Write-Info "Completed: Pushing MVC packages to NPM" |
|||
|
|||
cd ..\deploy #always return to the deploy directory |
|||
@ -0,0 +1,14 @@ |
|||
. ..\nupkg\common.ps1 |
|||
|
|||
cd .. |
|||
|
|||
Write-Info "Committing changes to GitHub" |
|||
echo "`n-----=====[ COMMITTING CHANGES ]=====-----`n" |
|||
git add . |
|||
git commit -m Update_NPM_Package_Versions |
|||
git push |
|||
|
|||
echo "`n-----=====[ COMMITTING CHANGES COMPLETED ]=====-----`n" |
|||
Write-Info "Completed: Committing changes to GitHub" |
|||
|
|||
cd deploy #always return to the deploy directory |
|||
@ -0,0 +1,35 @@ |
|||
#THIS IS NOT BEING USED CURRENTLY. RELEASE GITHUB MANUALLY |
|||
|
|||
# Import the module dynamically from the PowerShell Gallery. Use CurrentUser scope to avoid having to run as admin. |
|||
Import-Module -Name new-github-release-function.psm1 |
|||
|
|||
# Specify the parameters required to create the release. Do it as a hash table for easier readability. |
|||
$newGitHubReleaseParameters = |
|||
@{ |
|||
GitHubUsername = 'abpframework' |
|||
GitHubRepositoryName = 'abp' |
|||
GitHubAccessToken = '*******************' |
|||
ReleaseName = "5.0.0-rc.2" |
|||
TagName = "5.0.0-rc.2" |
|||
ReleaseNotes = "N/A" |
|||
#AssetFilePaths = @('C:\MyProject\Installer.exe','C:\MyProject\Documentation.md') |
|||
IsPreRelease = $true |
|||
IsDraft = $true # Set to true when testing so we don't publish a real release (visible to everyone) by accident. |
|||
} |
|||
|
|||
# Try to create the Release on GitHub and save the results. |
|||
$result = New-GitHubRelease @newGitHubReleaseParameters |
|||
|
|||
# Provide some feedback to the user based on the results. |
|||
if ($result.Succeeded -eq $true) |
|||
{ |
|||
Write-Output "Release published successfully! View it at $($result.ReleaseUrl)" |
|||
} |
|||
elseif ($result.ReleaseCreationSucceeded -eq $false) |
|||
{ |
|||
Write-Error "The release was not created. Error message is: $($result.ErrorMessage)" |
|||
} |
|||
elseif ($result.AllAssetUploadsSucceeded -eq $false) |
|||
{ |
|||
Write-Error "The release was created, but not all of the assets were uploaded to it. View it at $($result.ReleaseUrl). Error message is: $($result.ErrorMessage)" |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
param( |
|||
[string]$password |
|||
) |
|||
|
|||
. ..\nupkg\common.ps1 |
|||
|
|||
if (!$password) |
|||
{ |
|||
#reading password from file content |
|||
$sshPasswordFileName = "ssh-password.txt" |
|||
$password = Get-Content $sshPasswordFileName |
|||
echo "Using SSH password from $sshPasswordFileName ..." |
|||
} |
|||
|
|||
if (!$password) |
|||
{ |
|||
$password = Read-Host "Enter the Natro jenkins user password" |
|||
} |
|||
|
|||
# Get the current version |
|||
[xml]$commonPropsXml = Get-Content "../common.props" |
|||
$version = $commonPropsXml.Project.PropertyGroup.Version |
|||
echo "`n---===[ Current version: $version ]===---" |
|||
|
|||
#--------------------------------------------------------------------- |
|||
Write-Info "Downloading release zip into Natro" |
|||
echo "`n---===[ Running SSH commands on NATRO ]===---" |
|||
echo "`nDownloading release file into Natro..." |
|||
|
|||
plink.exe -ssh jenkins@94.73.164.234 -pw $password -P 22 -batch "powershell -File c:\ci\scripts\download-latest-abp-release.ps1 ${version}" |
|||
|
|||
Write-Info "Completed: Downloading release zip into Natro completed" |
|||
#--------------------------------------------------------------------- |
|||
@ -0,0 +1,347 @@ |
|||
#Requires -Version 3.0 |
|||
|
|||
function New-GitHubRelease |
|||
{ |
|||
<# |
|||
.SYNOPSIS |
|||
Creates a new Release for the given GitHub repository. |
|||
|
|||
.DESCRIPTION |
|||
Uses the GitHub API to create a new Release for a given repository. |
|||
Allows you to specify all of the Release properties, such as the Tag, Name, Assets, and if it's a Draft or Prerelease or not. |
|||
|
|||
.PARAMETER GitHubUsername |
|||
The username that the GitHub repository exists under. |
|||
e.g. For the repository https://github.com/deadlydog/New-GitHubRelease, the username is 'deadlydog'. |
|||
|
|||
.PARAMETER GitHubRepositoryName |
|||
The name of the repository to create the Release for. |
|||
e.g. For the repository https://github.com/deadlydog/New-GitHubRelease, the repository name is 'New-GitHubRelease'. |
|||
|
|||
.PARAMETER GitHubAccessToken |
|||
The Access Token to use as credentials for GitHub. |
|||
Access tokens can be generated at https://github.com/settings/tokens. |
|||
The access token will need to have the repo/public_repo permission on it for it to be allowed to create a new Release. |
|||
|
|||
.PARAMETER TagName |
|||
The name of the tag to create at the Commitish. |
|||
|
|||
.PARAMETER ReleaseName |
|||
The name to use for the new release. |
|||
If blank, the TagName will be used. |
|||
|
|||
.PARAMETER ReleaseNotes |
|||
The text describing the contents of the release. |
|||
|
|||
.PARAMETER AssetFilePaths |
|||
The full paths of the files to include in the release. |
|||
|
|||
.PARAMETER Commitish |
|||
Specifies the commitish value that determines where the Git tag is created from. |
|||
Can be any branch or commit SHA. Unused if the Git tag already exists. |
|||
Default: the repository's default branch (usually master). |
|||
|
|||
.PARAMETER IsDraft |
|||
True to create a draft (unpublished) release, false to create a published one. |
|||
Default: false |
|||
|
|||
.PARAMETER IsPreRelease |
|||
True to identify the release as a prerelease. false to identify the release as a full release. |
|||
Default: false |
|||
|
|||
.OUTPUTS |
|||
A hash table with the following properties is returned: |
|||
|
|||
Succeeded = $true if the Release was created successfully and all assets were uploaded to it, $false if some part of the process failed. |
|||
ReleaseCreationSucceeded = $true if the Release was created successfully (does not include asset uploads), $false if the Release was not created. |
|||
AllAssetUploadsSucceeded = $true if all assets were uploaded to the Release successfully, $false if one of them failed, $null if there were no assets to upload. |
|||
ReleaseUrl = The URL of the new Release that was created. |
|||
ErrorMessage = A message describing what went wrong in the case that Succeeded is $false. |
|||
|
|||
.EXAMPLE |
|||
# Import the module dynamically from the PowerShell Gallery. Use CurrentUser scope to avoid having to run as admin. |
|||
Import-Module -Name New-GitHubRelease -Scope CurrentUser |
|||
|
|||
# Specify the parameters required to create the release. Do it as a hash table for easier readability. |
|||
$newGitHubReleaseParameters = |
|||
@{ |
|||
GitHubUsername = 'deadlydog' |
|||
GitHubRepositoryName = 'New-GitHubRelease' |
|||
GitHubAccessToken = 'SomeLongHexidecimalString' |
|||
ReleaseName = "New-GitHubRelease v1.0.0" |
|||
TagName = "v1.0.0" |
|||
ReleaseNotes = "This release contains the following changes: ..." |
|||
AssetFilePaths = @('C:\MyProject\Installer.exe','C:\MyProject\Documentation.md') |
|||
IsPreRelease = $false |
|||
IsDraft = $true # Set to true when testing so we don't publish a real release (visible to everyone) by accident. |
|||
} |
|||
|
|||
# Try to create the Release on GitHub and save the results. |
|||
$result = New-GitHubRelease @newGitHubReleaseParameters |
|||
|
|||
# Provide some feedback to the user based on the results. |
|||
if ($result.Succeeded -eq $true) |
|||
{ |
|||
Write-Output "Release published successfully! View it at $($result.ReleaseUrl)" |
|||
} |
|||
elseif ($result.ReleaseCreationSucceeded -eq $false) |
|||
{ |
|||
Write-Error "The release was not created. Error message is: $($result.ErrorMessage)" |
|||
} |
|||
elseif ($result.AllAssetUploadsSucceeded -eq $false) |
|||
{ |
|||
Write-Error "The release was created, but not all of the assets were uploaded to it. View it at $($result.ReleaseUrl). Error message is: $($result.ErrorMessage)" |
|||
} |
|||
|
|||
Attempt to create a new Release on GitHub, and provide feedback to the user indicating if it succeeded or not. |
|||
|
|||
.LINK |
|||
Project home: https://github.com/deadlydog/New-GitHubRelease |
|||
|
|||
.NOTES |
|||
Name: New-GitHubRelease |
|||
Author: Daniel Schroeder (originally based on the script at https://github.com/majkinetor/au/blob/master/scripts/Github-CreateRelease.ps1) |
|||
GitHub Release API Documentation: https://developer.github.com/v3/repos/releases/#create-a-release |
|||
Version: 1.0.2 |
|||
#> |
|||
[CmdletBinding()] |
|||
param |
|||
( |
|||
[Parameter(Mandatory=$true,HelpMessage="The username the repository is under (e.g. deadlydog).")] |
|||
[string] $GitHubUsername, |
|||
|
|||
[Parameter(Mandatory=$true,HelpMessage="The repository name to create the release in (e.g. Invoke-MsBuild).")] |
|||
[string] $GitHubRepositoryName, |
|||
|
|||
[Parameter(Mandatory=$true,HelpMessage="The Acess Token to use as credentials for GitHub.")] |
|||
[string] $GitHubAccessToken, |
|||
|
|||
[Parameter(Mandatory=$true,HelpMessage="The name of the tag to create at the the Commitish.")] |
|||
[string] $TagName, |
|||
|
|||
[Parameter(Mandatory=$false,HelpMessage="The name of the release. If blank, the TagName will be used.")] |
|||
[string] $ReleaseName, |
|||
|
|||
[Parameter(Mandatory=$false,HelpMessage="Text describing the contents of the tag.")] |
|||
[string] $ReleaseNotes, |
|||
|
|||
[Parameter(Mandatory=$false,HelpMessage="The full paths of the files to include in the release.")] |
|||
[string[]] $AssetFilePaths, |
|||
|
|||
[Parameter(Mandatory=$false, HelpMessage="Specifies the commitish value that determines where the Git tag is created from. Can be any branch or commit SHA. Unused if the Git tag already exists. Default: the repository's default branch (usually master).")] |
|||
[string] $Commitish, |
|||
|
|||
[Parameter(Mandatory=$false,HelpMessage="True to create a draft (unpublished) release, false to create a published one. Default: false")] |
|||
[bool] $IsDraft = $false, |
|||
|
|||
[Parameter(Mandatory=$false,HelpMessage="True to identify the release as a prerelease. false to identify the release as a full release. Default: false")] |
|||
[bool] $IsPreRelease = $false |
|||
) |
|||
|
|||
BEGIN |
|||
{ |
|||
# Turn on Strict Mode to help catch syntax-related errors. |
|||
# This must come after a script's/function's param section. |
|||
# Forces a function to be the first non-comment code to appear in a PowerShell Script/Module. |
|||
Set-StrictMode -Version Latest |
|||
|
|||
Set-SecurityProtocolForThread |
|||
|
|||
[string] $NewLine = [Environment]::NewLine |
|||
|
|||
if ([string]::IsNullOrEmpty($ReleaseName)) |
|||
{ |
|||
$ReleaseName = $TagName |
|||
} |
|||
|
|||
# Ensure that all of the given asset file paths to upload are valid. |
|||
Test-AllFilePathsAndThrowErrorIfOneIsNotValid $AssetFilePaths |
|||
} |
|||
|
|||
END { } |
|||
|
|||
PROCESS |
|||
{ |
|||
# Create the hash table to return, with default values. |
|||
$result = @{} |
|||
$result.Succeeded = $false |
|||
$result.ReleaseCreationSucceeded = $false |
|||
$result.AllAssetUploadsSucceeded = $false |
|||
$result.ReleaseUrl = $null |
|||
$result.ErrorMessage = $null |
|||
|
|||
[bool] $thereAreNoAssetsToIncludeInTheRelease = ($AssetFilePaths -eq $null) -or ($AssetFilePaths.Count -le 0) |
|||
if ($thereAreNoAssetsToIncludeInTheRelease) |
|||
{ |
|||
$result.AllAssetUploadsSucceeded = $null |
|||
} |
|||
|
|||
$authHeader = |
|||
@{ |
|||
Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($GitHubAccessToken + ":x-oauth-basic")) |
|||
} |
|||
|
|||
$releaseData = |
|||
@{ |
|||
tag_name = $TagName |
|||
target_commitish = $Commitish |
|||
name = $ReleaseName |
|||
body = $ReleaseNotes |
|||
draft = $IsDraft |
|||
prerelease = $IsPreRelease |
|||
} |
|||
|
|||
$createReleaseWebRequestParameters = |
|||
@{ |
|||
Uri = "https://api.github.com/repos/$GitHubUsername/$GitHubRepositoryName/releases" |
|||
Method = 'POST' |
|||
Headers = $authHeader |
|||
ContentType = 'application/json' |
|||
Body = (ConvertTo-Json $releaseData -Compress) |
|||
} |
|||
|
|||
try |
|||
{ |
|||
Write-Verbose "Sending web request to create the new Release..." |
|||
$createReleaseWebRequestResults = Invoke-RestMethodAndThrowDescriptiveErrorOnFailure $createReleaseWebRequestParameters |
|||
} |
|||
catch |
|||
{ |
|||
$result.ReleaseCreationSucceeded = $false |
|||
$result.ErrorMessage = $_.Exception.Message |
|||
return $result |
|||
} |
|||
|
|||
$result.ReleaseCreationSucceeded = $true |
|||
$result.ReleaseUrl = $createReleaseWebRequestResults.html_url |
|||
|
|||
if ($thereAreNoAssetsToIncludeInTheRelease) |
|||
{ |
|||
$result.Succeeded = $true |
|||
return $result |
|||
} |
|||
|
|||
# Upload Url has template parameters on the end (e.g. ".../assets{?name,label}"), so remove them. |
|||
[string] $urlToUploadFilesTo = $createReleaseWebRequestResults.upload_url -replace '{.+}' |
|||
|
|||
try |
|||
{ |
|||
Write-Verbose "Uploading asset files to the new release..." |
|||
Send-FilesToGitHubRelease -filePathsToUpload $AssetFilePaths -urlToUploadFilesTo $urlToUploadFilesTo -authHeader $authHeader |
|||
} |
|||
catch |
|||
{ |
|||
$result.AllAssetUploadsSucceeded = $false |
|||
$result.ErrorMessage = $_.Exception.Message |
|||
return $result |
|||
} |
|||
|
|||
$result.AllAssetUploadsSucceeded = $true |
|||
$result.Succeeded = $true |
|||
return $result |
|||
} |
|||
} |
|||
|
|||
function Send-FilesToGitHubRelease([string[]] $filePathsToUpload, [string] $urlToUploadFilesTo, $authHeader) |
|||
{ |
|||
[int] $numberOfFilesToUpload = $filePathsToUpload.Count |
|||
[int] $numberOfFilesUploaded = 0 |
|||
$filePathsToUpload | ForEach-Object ` |
|||
{ |
|||
$filePath = $_ |
|||
$fileName = Get-Item $filePath | Select-Object -ExpandProperty Name |
|||
|
|||
$uploadAssetWebRequestParameters = |
|||
@{ |
|||
# Append the name of the file to the upload url. |
|||
Uri = $urlToUploadFilesTo + "?name=$fileName" |
|||
Method = 'POST' |
|||
Headers = $authHeader |
|||
ContentType = 'application/zip' |
|||
InFile = $filePath |
|||
} |
|||
|
|||
$numberOfFilesUploaded = $numberOfFilesUploaded + 1 |
|||
Write-Verbose "Uploading asset $numberOfFilesUploaded of $numberOfFilesToUpload, '$filePath'." |
|||
Invoke-RestMethodAndThrowDescriptiveErrorOnFailure $uploadAssetWebRequestParameters > $null |
|||
} |
|||
} |
|||
|
|||
function Test-AllFilePathsAndThrowErrorIfOneIsNotValid([string[]] $filePaths) |
|||
{ |
|||
foreach ($filePath in $filePaths) |
|||
{ |
|||
[bool] $fileWasNotFoundAtPath = [string]::IsNullOrEmpty($filePath) -or !(Test-Path -Path $filePath -PathType Leaf) |
|||
if ($fileWasNotFoundAtPath) |
|||
{ |
|||
throw "There is no file at the specified path, '$filePath'." |
|||
} |
|||
} |
|||
} |
|||
|
|||
function Invoke-RestMethodAndThrowDescriptiveErrorOnFailure($requestParametersHashTable) |
|||
{ |
|||
$requestDetailsAsNicelyFormattedString = Convert-HashTableToNicelyFormattedString $requestParametersHashTable |
|||
Write-Verbose "Making web request with the following parameters:$NewLine$requestDetailsAsNicelyFormattedString" |
|||
|
|||
try |
|||
{ |
|||
$webRequestResult = Invoke-RestMethod @requestParametersHashTable |
|||
} |
|||
catch |
|||
{ |
|||
[Exception] $exception = $_.Exception |
|||
|
|||
[string] $errorMessage = Get-RestMethodExceptionDetailsOrNull -restMethodException $exception |
|||
if ([string]::IsNullOrWhiteSpace($errorMessage)) |
|||
{ |
|||
$errorMessage = $exception.ToString() |
|||
} |
|||
|
|||
throw "An unexpected error occurred while making web request:$NewLine$errorMessage" |
|||
} |
|||
|
|||
Write-Verbose "Web request returned the following result:$NewLine$webRequestResult" |
|||
return $webRequestResult |
|||
} |
|||
|
|||
function Get-RestMethodExceptionDetailsOrNull([Exception] $restMethodException) |
|||
{ |
|||
try |
|||
{ |
|||
$responseDetails = @{ |
|||
ResponseUri = $exception.Response.ResponseUri |
|||
StatusCode = $exception.Response.StatusCode |
|||
StatusDescription = $exception.Response.StatusDescription |
|||
ErrorMessage = $exception.Message |
|||
} |
|||
[string] $responseDetailsAsNicelyFormattedString = Convert-HashTableToNicelyFormattedString $responseDetails |
|||
|
|||
[string] $errorInfo = "Request Details:" + $NewLine + $requestDetailsAsNicelyFormattedString |
|||
$errorInfo += $NewLine |
|||
$errorInfo += "Response Details:" + $NewLine + $responseDetailsAsNicelyFormattedString |
|||
return $errorInfo |
|||
} |
|||
catch |
|||
{ |
|||
return $null |
|||
} |
|||
} |
|||
|
|||
function Convert-HashTableToNicelyFormattedString($hashTable) |
|||
{ |
|||
[string] $nicelyFormattedString = $hashTable.Keys | ForEach-Object ` |
|||
{ |
|||
$key = $_ |
|||
$value = $hashTable.$key |
|||
" $key = $value$NewLine" |
|||
} |
|||
return $nicelyFormattedString |
|||
} |
|||
|
|||
function Set-SecurityProtocolForThread |
|||
{ |
|||
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 -bor [System.Net.SecurityProtocolType]::Tls11 -bor [System.Net.SecurityProtocolType]::Tls |
|||
} |
|||
|
|||
Export-ModuleMember -Function New-GitHubRelease |
|||
@ -0,0 +1,31 @@ |
|||
# ABP Framework Release Steps |
|||
|
|||
## 1-) Set your secret keys |
|||
|
|||
The following files are ignored from GitHub, therefore you need to create these files in your local environment. |
|||
|
|||
* create `npm-auth-token.txt` file in this folder and write the npmjs.org auth token. it's a GUID type. |
|||
* create `nuget-api-key.txt` file this folder and write your nuget.org API key. |
|||
* create `ssh-password.txt` file and write `jenkins` user SSH password. |
|||
|
|||
## 2-) Run the commands |
|||
|
|||
The commands are the followings: |
|||
|
|||
- **1-fetch-and-build.ps1** |
|||
- You need to enter the branch name. eg: `rel-5.0` |
|||
- You need to enter the new version for this release. eg: `5.0.0-rc.2` |
|||
- **2-nuget-pack.ps1** |
|||
- **3-nuget-push.ps1** |
|||
- **4-npm-publish.ps1** |
|||
- **5-git-commit.ps1** |
|||
- **6-new-github-release.ps1** |
|||
- Note: The step 6 is not active. You need to manually make GitHub release from https://github.com/abpframework/abp/releases/new |
|||
* create tag. eg: `5.0.0-rc.1` |
|||
* create the release from the related branch eg: `rel-5.0` |
|||
* enter the release title. eg: `5.0.0-rc.1` |
|||
* auto generate release notes and delete merge lines |
|||
* check `This is a pre-release` if it's a RC version. |
|||
* click `Publish release` button. |
|||
- **7-download-release-zip.ps1** |
|||
|
|||
@ -0,0 +1,47 @@ |
|||
# ABP.IO Platform 5.0 Final Has Been Released! |
|||
|
|||
[ABP Framework](https://abp.io/) and [ABP Commercial](https://commercial.abp.io/) 5.0 versions have been released today. |
|||
|
|||
## What's new with 5.0? |
|||
|
|||
Since all the new features are already explained in details with the [5.0 RC.1 Announcement Post](https://blog.abp.io/abp/ABP-IO-Platform-5.0-RC-1-Has-Been-Released), I will not repeat all the details again. See the [RC Blog Post](https://blog.abp.io/abp/ABP-IO-Platform-5.0-RC-1-Has-Been-Released) for all the features and enhancements. |
|||
|
|||
## Getting started with 5.0 |
|||
|
|||
### Creating new solutions |
|||
|
|||
You can create a new solution with the ABP Framework version 5.0 by either using the `abp new` command or using the **direct download** tab on the [get started page](https://abp.io/get-started). |
|||
|
|||
Type the following command in a command-line terminal to install the ABP CLI version 5.0: |
|||
|
|||
````bash |
|||
dotnet tool install -g Volo.Abp.Cli --version 5.0.0 |
|||
```` |
|||
|
|||
To upgrade your existing ABP CLI installation: |
|||
|
|||
````bash |
|||
dotnet tool update -g Volo.Abp.Cli --version 5.0.0 |
|||
```` |
|||
|
|||
Then you can create a new solution using the `abp new` command: |
|||
|
|||
````bash |
|||
abp new Acme.BookStore |
|||
```` |
|||
|
|||
> See the [getting started document](https://docs.abp.io/en/abp/latest/Getting-Started) for details. |
|||
|
|||
### Upgrading existing solutions |
|||
|
|||
Check [the migration guide](https://docs.abp.io/en/abp/latest/Migration-Guides/Abp-5_0) for the applications with the version 4.x upgrading to the version 5.0. Also see [the upgrading guide](https://docs.abp.io/en/abp/latest/Upgrading) to understand how to update existing solutions. |
|||
|
|||
## ABP Community Talks 2021.12 |
|||
|
|||
 |
|||
|
|||
As the core ABP development team, we've decided to organize monthly live meetings with the ABP community. The first live meeting will be at **December 16, 2021, 17:00 (UTC)** on YouTube. ABP core team members will present some of the new features coming with ABP 5.0. |
|||
|
|||
**Join this event on the Kommunity platform: https://kommunity.com/volosoft/events/abp-community-talks-4afca9c9** |
|||
|
|||
See you in the event! |
|||
|
After Width: | Height: | Size: 907 KiB |
@ -0,0 +1,717 @@ |
|||
# Integrating DevExpress ASP.NET Core Reporting to ABP MVC Application |
|||
|
|||
In this step by step article, I will demonstrate how to integrate DevExpress Reporting [DocumentViewer](https://docs.devexpress.com/XtraReports/400248/web-reporting/asp-net-core-reporting/document-viewer-in-asp-net-core-applications) and [End-User Report Designer](https://docs.devexpress.com/XtraReports/400249/web-reporting/asp-net-core-reporting/end-user-report-designer-in-asp-net-core-applications) components to an existing ABP application. We will also create core bundling packages for styling, DevExpress javascript components and also DocumentViewer specific bundling packages. |
|||
|
|||
## Create the Project (Optional) |
|||
|
|||
ABP Framework offers startup templates to get to business faster. We can download a new startup template using [ABP CLI](https://docs.abp.io/en/abp/latest/CLI): |
|||
|
|||
````bash |
|||
abp new Acme.BookStore |
|||
```` |
|||
|
|||
After the download is finished, open the solution in Visual Studio (or your favorite IDE): |
|||
|
|||
 |
|||
|
|||
Run the `Acme.BookStore.DbMigrator` application to create the database and seed the initial data (which creates the admin user, admin role, related permissions, etc). Then we can run the `Acme.BookStore.Web` project to see our application working. |
|||
|
|||
> _Default admin username is **admin** and password is **1q2w3E\***_ |
|||
|
|||
## Installing Packages |
|||
|
|||
You can also follow [this documentation](https://js.devexpress.com/Documentation/17_1/Guide/ASP.NET_MVC_Controls/Prerequisites_and_Installation/) to install DevExpress packages into your computer. We will be installing both nuget references and npm references. |
|||
|
|||
> Don't forget to add _"DevExpress NuGet Feed"_ to your **Nuget Package Sources**. |
|||
|
|||
### Adding NuGet Packages |
|||
|
|||
- Add the `<PackageReference Include="DevExtreme.AspNet.Core" Version="21.2.3" />` NuGet package reference to the **Acme.BookStore.Application.Contracts.csproj**. Or run |
|||
|
|||
```csharp |
|||
Install-Package DevExtreme.AspNet.Core |
|||
``` |
|||
|
|||
command under **Acme.BookStore.Application.Contracts** project. |
|||
|
|||
- Add the `<PackageReference Include="DevExpress.AspNetCore.Reporting" Version="21.2.3" />` NuGet package reference to the **Acme.BookStore.Web.csproj**. Or run |
|||
|
|||
```csharp |
|||
Install-Package DevExpress.AspNetCore.Reporting |
|||
``` |
|||
|
|||
command under the **Acme.BookStore.Web** project. **Note:** You need a commercial license to use this package. |
|||
|
|||
### Adding NPM Packages |
|||
|
|||
Open your `Acme.BookStore.Web` project folder with a command line. Add **devextreme** and [other required third party NPM packages](https://docs.devexpress.com/XtraReports/401763/web-reporting/asp-net-core-reporting/end-user-report-designer-in-asp-net-applications/quick-start/add-an-end-user-report-designer-to-an-aspnet-core-application): |
|||
|
|||
- `npm install devexpress-reporting @devexpress/analytics-core devextreme` |
|||
- `npm install globalize jquery-ui-dist cldrjs` |
|||
|
|||
At the end, your `package.json` should look as shown below: |
|||
|
|||
```json |
|||
{ |
|||
"version": "1.0.0", |
|||
"name": "my-app", |
|||
"private": true, |
|||
"dependencies": { |
|||
"@abp/aspnetcore.mvc.ui.theme.basic": "^5.0.0-rc.1", |
|||
"@devexpress/analytics-core": "^21.2.3", |
|||
"cldrjs": "^0.5.5", |
|||
"devexpress-reporting": "^21.2.3", |
|||
"devextreme": "^21.2.3", |
|||
"globalize": "^1.7.0", |
|||
"jquery-ui-dist": "^1.12.1" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
### Adding Resource Mappings |
|||
|
|||
The `devextreme` and third party NPM packages will be saved under the `node_modules` folder. We need to move the needed files in our `wwwroot/libs` folder to use them in the web project. We can do it using the ABP [client side resource mapping](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Client-Side-Package-Management) system. |
|||
|
|||
Open the `abp.resourcemapping.js` file in your `Acme.BookStore.Web` project and add definitions inside the `mappings` object so the final `abp.resourcemapping.js` file can look as shown below: |
|||
|
|||
```javascript |
|||
module.exports = { |
|||
aliases: { |
|||
|
|||
}, |
|||
mappings: { |
|||
"@node_modules/devextreme/dist/**/*": "@libs/devextreme/", |
|||
"@node_modules/jquery-ui-dist/jquery-ui.min.js": "@libs/devextreme/js/", |
|||
"@node_modules/@devexpress/analytics-core/dist/**/*": "@libs/devexpress-analytics-core/", |
|||
"@node_modules/devexpress-reporting/dist/**/*": "@libs/devexpress-reporting/", |
|||
"@node_modules/knockout/build/output/knockout-latest.js":"@libs/devexpress-reporting/js/", |
|||
"@node_modules/cldrjs/dist/cldr.js":"@libs/devexpress-reporting/cldrjs/", |
|||
"@node_modules/cldrjs/dist/cldr/event.js":"@libs/devexpress-reporting/cldrjs/", |
|||
"@node_modules/cldrjs/dist/cldr/supplemental.js":"@libs/devexpress-reporting/cldrjs/", |
|||
"@node_modules/cldrjs/dist/cldr/unresolved.js":"@libs/devexpress-reporting/cldrjs/", |
|||
"@node_modules/globalize/dist/globalize.js":"@libs/devexpress-reporting/globalize/", |
|||
"@node_modules/globalize/dist/globalize/message.js":"@libs/devexpress-reporting/globalize/", |
|||
"@node_modules/globalize/dist/globalize/number.js":"@libs/devexpress-reporting/globalize/", |
|||
"@node_modules/globalize/dist/globalize/currency.js":"@libs/devexpress-reporting/globalize/", |
|||
"@node_modules/globalize/dist/globalize/date.js":"@libs/devexpress-reporting/globalize/", |
|||
"@node_modules/ace-builds/src-min-noconflict/ace.js":"@libs/devexpress-reporting/ace-builds/", |
|||
"@node_modules/ace-builds/src-min-noconflict/ext-language_tools.js":"@libs/devexpress-reporting/ace-builds/", |
|||
"@node_modules/ace-builds/src-min-noconflict/theme-dreamweaver.js":"@libs/devexpress-reporting/ace-builds/", |
|||
"@node_modules/ace-builds/src-min-noconflict/theme-ambiance.js":"@libs/devexpress-reporting/ace-builds/", |
|||
"@node_modules/ace-builds/src-min-noconflict/snippets/text.js":"@libs/devexpress-reporting/ace-builds/" |
|||
} |
|||
}; |
|||
``` |
|||
|
|||
Open your `Acme.BookStore.Web` project folder with a command line and run the `abp install-libs` command. This command will copy the needed library files into the `/wwwroot/libs/devextreme/` folder. |
|||
|
|||
````bash |
|||
abp install-libs |
|||
```` |
|||
|
|||
You can see `devextreme`, `devexpress-reporting` and `devexpress-analytics-core` folders inside the `wwwroot/libs`: |
|||
|
|||
 |
|||
|
|||
|
|||
|
|||
## Bundling |
|||
|
|||
We will create [bundle contributors](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Bundling-Minification) to add the devextreme css and javascript files for DevExpress [DocumentViewer](https://docs.devexpress.com/XtraReports/400248/web-reporting/asp-net-core-reporting/document-viewer-in-asp-net-core-applications) and [End-User Report Designer](https://docs.devexpress.com/XtraReports/400249/web-reporting/asp-net-core-reporting/end-user-report-designer-in-asp-net-core-applications) components. |
|||
|
|||
To utilize bundling better, we will create hierarchical contributors for both styles and scripts as seen below: |
|||
|
|||
 |
|||
|
|||
It is recommended to follow this hierarchy because some of the scripts and styles need to be added before one another. Once you grab the relations between the dependent scripts and styles, you are free to modify the `Bundling hierarchy` as you desire and re-use the contributors for other DevExpress components. |
|||
|
|||
We'll start with creating folders in the `Acme.BookStore.Web` project starting with a folder named **Bundling**. Create the following folders for future usage: |
|||
|
|||
- Create a `Common` folder under `Bundling` folder |
|||
- Create a `Reporting` folder under `Bundling` folder |
|||
- Create a `ThirdParty` folder under `Reporting ` folder |
|||
- Create a `DocumentViewer` folder under `Reporting ` folder |
|||
- Create a `DocumentDesigner` folder under `Reporting ` folder |
|||
|
|||
At the end, you should have a folder structure as shown below: |
|||
|
|||
 |
|||
|
|||
With this structured foldering, you can easily add other devexpress components in an isolated and maintained way. |
|||
|
|||
### Adding the Common Style Contributor |
|||
|
|||
Create a `DevExtremeCommonStyleContributor.cs` file under the `Bundling/Common` folder with the following content: |
|||
|
|||
```csharp |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace Acme.BookStore.Web.Bundling.Common; |
|||
|
|||
public class DevExtremeCommonStyleContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.AddIfNotContains("/libs/devextreme/css/dx.common.css"); |
|||
context.Files.AddIfNotContains("/libs/devextreme/css/dx.light.css"); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
> You can choose other themes than the light theme. Check the `/libs/devextreme/css/` folder and the DevExtreme documentation for other themes. |
|||
|
|||
Now we will add the common bundle to the global style bundles. Open your `Acme.BookStoreWebModule.cs` file in your `Acme.BookStore.Web` project and add the following code into the `ConfigureServices` method: |
|||
|
|||
```csharp |
|||
Configure<AbpBundlingOptions>(options => |
|||
{ |
|||
options |
|||
.StyleBundles |
|||
.Get(StandardBundles.Styles.Global) |
|||
.AddContributors(typeof(DevExtremeCommonStyleContributor)); |
|||
}); |
|||
``` |
|||
|
|||
### Adding the Document Viewer Style Contributor |
|||
|
|||
Create a `DevExpressDocumentViewerStyleContributor.cs` file under the `Bundling/Reporting/DocumentViewer` folder with the following content: |
|||
|
|||
```csharp |
|||
using System.Collections.Generic; |
|||
using Acme.BookStore.Web.Bundling.Common; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Acme.BookStore.Web.Bundling.Reporting.DocumentViewer; |
|||
|
|||
[DependsOn( |
|||
typeof(DevExtremeCommonStyleContributor) |
|||
)] |
|||
public class DevExpressDocumentViewerStyleContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/css/dx-reporting-skeleton-screen.css"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-analytics-core/css/dx-analytics.common.css"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-analytics-core/css/dx-analytics.light.css"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/css/dx-webdocumentviewer.css"); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
### Adding the Document Designer Style Contributor |
|||
|
|||
Create a `DevExtremeDocumentDesignerStyleContributor.cs` file under the `Bundling/Reporting/DocumentDesigner` folder with the following content: |
|||
|
|||
```csharp |
|||
using System.Collections.Generic; |
|||
using Acme.BookStore.Web.Bundling.Reporting.DocumentViewer; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Acme.BookStore.Web.Bundling.Reporting.DocumentDesigner; |
|||
|
|||
[DependsOn( |
|||
typeof(DevExtremeDocumentViewerStyleContributor) |
|||
)] |
|||
public class DevExtremeDocumentDesignerStyleContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.AddIfNotContains("/libs/devexpress-analytics-core/css/dx-querybuilder.css"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/css/dx-reportdesigner.css"); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
### Adding the Reporting Common Script Contributor |
|||
|
|||
Create a `DevExtremeReportingCommonScriptContributor.cs` file under the `Bundling/Common` folder with the following content: |
|||
|
|||
```csharp |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQuery; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Acme.BookStore.Web.Bundling.Common; |
|||
|
|||
[DependsOn( |
|||
typeof(JQueryScriptContributor) |
|||
)] |
|||
public class DevExtremeReportingCommonScriptContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.AddIfNotContains("/libs/devextreme/js/jquery-ui.min.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/js/knockout-latest.js"); |
|||
context.Files.AddIfNotContains("/libs/devextreme/js/dx.all.js"); // Has to be added after jquery and knockout |
|||
} |
|||
} |
|||
``` |
|||
|
|||
The `DevExtremeReportingCommonScriptContributor` depends on the `JQueryScriptContributor` which adds JQuery related files before the DevExpress packages (see the [bundling system](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Bundling-Minification) for details). |
|||
|
|||
> Since not all of the components of DevExtreme use scripts like `knockout.js` and `jquery-ui.js`, we used *ReportingCommon* naming. You can choose another name or a *Common* contributor by only adding `dx.all.js`. |
|||
|
|||
### Adding the Third Party Script Contributor |
|||
|
|||
Create a `DevExpressReportingThirdPartyScriptContributor.cs` file under the `Bundling/Reporting/ThirdParty` folder with the following content: |
|||
|
|||
```csharp |
|||
using System.Collections.Generic; |
|||
using Acme.BookStore.Web.Bundling.Common; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Acme.BookStore.Web.Bundling.Reporting.ThirdParty; |
|||
|
|||
[DependsOn( |
|||
typeof(DevExtremeReportingCommonScriptContributor) |
|||
)] |
|||
public class DevExpressReportingThirdPartyScriptContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
// cldrj related scripts |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/cldrjs/cldr.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/cldrjs/event.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/cldrjs/supplemental.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/cldrjs/unresolved.js"); |
|||
// globalize related scripts |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/globalize/globalize.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/globalize/currency.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/globalize/date.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/globalize/message.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/globalize/number.js"); |
|||
// ace-builds related scripts |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/ace-builds/ace.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/ace-builds/ext-language_tools.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/ace-builds/theme-ambiance.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/ace-builds/theme-dreamweaver.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/ace-builds/text.js"); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
The `DevExpressReportingThirdPartyScriptContributor` depends on the newly created `DevExtremeReportingCommonScriptContributor` which adds the specified scripts before third party scripts. |
|||
|
|||
### Adding the Document Viewer Script Contributor |
|||
|
|||
Create a `DevExpressDocumentViewerScriptContributor.cs` file under the `Bundling/Reporting/DocumentViewer` folder with the following content: |
|||
|
|||
```csharp |
|||
using System.Collections.Generic; |
|||
using Acme.BookStore.Web.Bundling.Reporting.ThirdParty; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Acme.BookStore.Web.Bundling.Reporting.DocumentViewer; |
|||
|
|||
[DependsOn(typeof(DevExpressReportingThirdPartyScriptContributor))] |
|||
public class DevExpressDocumentViewerScriptContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.AddIfNotContains("/libs/devexpress-analytics-core/js/dx-analytics-core.min.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/js/dx-webdocumentviewer.min.js"); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
Note that the `DevExpressDocumentViewerScriptContributor` depends on the newly created `DevExpressReportingThirdPartyScriptContributor`. |
|||
|
|||
### Adding the Document Designer Script Contributor |
|||
|
|||
```csharp |
|||
using System.Collections.Generic; |
|||
using Acme.BookStore.Web.Bundling.Reporting.DocumentViewer; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Acme.BookStore.Web.Bundling.Reporting.DocumentDesigner; |
|||
|
|||
[DependsOn( |
|||
typeof(DevExpressDocumentViewerScriptContributor) |
|||
)] |
|||
public class DevExpressDocumentDesignerScriptContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.AddIfNotContains("/libs/devexpress-analytics-core/js/dx-querybuilder.min.js"); |
|||
context.Files.AddIfNotContains("/libs/devexpress-reporting/js/dx-reportdesigner.min.js"); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
## End User Report Designer Integration |
|||
|
|||
> You are free to create your desired pages and rooting. This sample will be creating a **Designer** page to demonstrate the layout for the DevExpress reporting components individually. |
|||
|
|||
Create a `Reporting` folder under `Pages` in the `Acme.BookStore.Web` project . |
|||
|
|||
### Adding a Document Designer Page |
|||
|
|||
Create a `Designer.cshtml` Razor page under the `Pages/Reporting` folder and add the following: |
|||
|
|||
```csharp |
|||
@page |
|||
@using Acme.BookStore.Web.Bundling.Reporting.DocumentDesigner |
|||
@using DevExpress.AspNetCore |
|||
@model Acme.BookStore.Web.Pages.Reporting.Designer |
|||
|
|||
@{ |
|||
var designerRender = Html.DevExpress().ReportDesigner("reportDesigner") |
|||
.Height("1000px"); |
|||
@designerRender.RenderHtml() |
|||
} |
|||
|
|||
@section Scripts { |
|||
<abp-style type="typeof(DevExpressDocumentDesignerStyleContributor)"/> |
|||
|
|||
<abp-script type="typeof(DevExpressDocumentDesignerScriptContributor)"/> |
|||
@designerRender.RenderScripts() |
|||
} |
|||
``` |
|||
|
|||
### Adding Controllers |
|||
|
|||
Create a `Controllers` folder and add a `ReportingController.cs` file to contain customized controllers for reporting endpoints: |
|||
|
|||
```csharp |
|||
using DevExpress.AspNetCore.Reporting.QueryBuilder; |
|||
using DevExpress.AspNetCore.Reporting.QueryBuilder.Native.Services; |
|||
using DevExpress.AspNetCore.Reporting.ReportDesigner; |
|||
using DevExpress.AspNetCore.Reporting.ReportDesigner.Native.Services; |
|||
using DevExpress.AspNetCore.Reporting.WebDocumentViewer; |
|||
using DevExpress.AspNetCore.Reporting.WebDocumentViewer.Native.Services; |
|||
|
|||
namespace Acme.BookStore.Web.Controllers; |
|||
|
|||
public class CustomWebDocumentViewerController : WebDocumentViewerController |
|||
{ |
|||
public CustomWebDocumentViewerController(IWebDocumentViewerMvcControllerService controllerService) |
|||
: base(controllerService) |
|||
{ |
|||
} |
|||
} |
|||
|
|||
public class CustomReportDesignerController : ReportDesignerController |
|||
{ |
|||
public CustomReportDesignerController(IReportDesignerMvcControllerService controllerService) |
|||
: base(controllerService) |
|||
{ |
|||
} |
|||
} |
|||
|
|||
public class CustomQueryBuilderController : QueryBuilderController |
|||
{ |
|||
public CustomQueryBuilderController(IQueryBuilderMvcControllerService controllerService) |
|||
: base(controllerService) |
|||
{ |
|||
} |
|||
} |
|||
``` |
|||
|
|||
### Service Configuration and Midware Update |
|||
|
|||
Update the `ConfigureServices` method of the `BookStoreWebModule.cs` file in **Acme.BookStore.Web** project with the following: |
|||
|
|||
```csharp |
|||
context.Services.AddDevExpressControls(); |
|||
context.Services.AddTransient<CustomReportDesignerController>(); |
|||
context.Services.AddTransient<CustomQueryBuilderController>(); |
|||
context.Services.AddTransient<CustomWebDocumentViewerController>(); |
|||
// UnComment this line if you want to use report storage which is used for menus like "Save as" etc. |
|||
//context.Services.AddScoped<ReportStorageWebExtension, CustomReportStorageWebExtension>(); |
|||
``` |
|||
|
|||
Add `UseDevExpressControls` before `UseConfiguredEndpoints` in `OnApplicationInitialization` as the following: |
|||
|
|||
```csharp |
|||
... |
|||
app.UseDevExpressControls(); |
|||
|
|||
app.UseCorrelationId(); |
|||
... |
|||
``` |
|||
|
|||
### Adding Custom Report Storage (Optional) |
|||
|
|||
Create `CustomReportStorageWebExtension.cs` under the **Acme.BookStore.Web** project as below: |
|||
|
|||
```csharp |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using DevExpress.XtraReports.UI; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
|
|||
namespace Acme.BookStore.Web; |
|||
|
|||
public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extensions.ReportStorageWebExtension |
|||
{ |
|||
readonly string ReportDirectory; |
|||
const string FileExtension = ".repx"; |
|||
|
|||
public CustomReportStorageWebExtension(IWebHostEnvironment env) |
|||
{ |
|||
ReportDirectory = Path.Combine(env.ContentRootPath, "Reports"); |
|||
if (!Directory.Exists(ReportDirectory)) |
|||
{ |
|||
Directory.CreateDirectory(ReportDirectory); |
|||
} |
|||
} |
|||
|
|||
public override bool CanSetData(string url) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
public override bool IsValidUrl(string url) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
public override byte[] GetData(string url) |
|||
{ |
|||
try |
|||
{ |
|||
if (Directory.EnumerateFiles(ReportDirectory).Select(Path.GetFileNameWithoutExtension).Contains(url)) |
|||
{ |
|||
return File.ReadAllBytes(Path.Combine(ReportDirectory, url + FileExtension)); |
|||
} |
|||
|
|||
if (ReportsFactory.Reports.ContainsKey(url)) |
|||
{ |
|||
using (MemoryStream ms = new MemoryStream()) |
|||
{ |
|||
ReportsFactory.Reports[url]().SaveLayoutToXml(ms); |
|||
return ms.ToArray(); |
|||
} |
|||
} |
|||
|
|||
throw new DevExpress.XtraReports.Web.ClientControls.FaultException( |
|||
string.Format("Could not find report '{0}'.", url)); |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
throw new DevExpress.XtraReports.Web.ClientControls.FaultException( |
|||
string.Format("Could not find report '{0}'.", url)); |
|||
} |
|||
} |
|||
|
|||
public override Dictionary<string, string> GetUrls() |
|||
{ |
|||
return Directory.GetFiles(ReportDirectory, "*" + FileExtension) |
|||
.Select(Path.GetFileNameWithoutExtension) |
|||
.Concat(ReportsFactory.Reports.Select(x => x.Key)) |
|||
.ToDictionary<string, string>(x => x); |
|||
} |
|||
|
|||
public override void SetData(XtraReport report, string url) |
|||
{ |
|||
report.SaveLayoutToXml(Path.Combine(ReportDirectory, url + FileExtension)); |
|||
} |
|||
|
|||
public override string SetNewData(XtraReport report, string defaultUrl) |
|||
{ |
|||
SetData(report, defaultUrl); |
|||
return defaultUrl; |
|||
} |
|||
} |
|||
|
|||
public class ReportsFactory |
|||
{ |
|||
public static Dictionary<string, Func<XtraReport>> Reports { get; set; } |
|||
} |
|||
``` |
|||
|
|||
> You can check more about it at [DevExpress Report Storage documentation](https://docs.devexpress.com/XtraReports/400211/web-reporting/asp-net-core-reporting/end-user-report-designer-in-asp-net-applications/add-a-report-storage). |
|||
|
|||
### Adding a DataSource To Designer |
|||
|
|||
Update `Designer.cshtml.cs` under `Pages/Reporting` in the **Acme.BookStore.Web** project with the following: |
|||
|
|||
```csharp |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using DevExpress.DataAccess.ConnectionParameters; |
|||
using DevExpress.DataAccess.Json; |
|||
using DevExpress.DataAccess.Sql; |
|||
using DevExpress.XtraReports.UI; |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
|
|||
namespace Acme.BookStore.Web.Pages.Reporting; |
|||
|
|||
public class Designer : PageModel |
|||
{ |
|||
public ReportDesignerModel DesignerModel { get; set; } |
|||
|
|||
public void OnGet() |
|||
{ |
|||
// Create a SQL data source. |
|||
// MsSqlConnectionParameters parameters = new MsSqlConnectionParameters("localhost", |
|||
// "dbName", "userName", "password", MsSqlAuthorizationType.SqlServer); |
|||
// SqlDataSource dataSource = new SqlDataSource(parameters); |
|||
// SelectQuery query = SelectQueryFluentBuilder.AddTable("Products").SelectAllColumnsFromTable().Build("Products"); |
|||
// dataSource.Queries.Add(query); |
|||
// dataSource.RebuildResultSchema(); |
|||
|
|||
// Create a JSON data source. |
|||
JsonDataSource jsonDataSource = new JsonDataSource(); |
|||
jsonDataSource.JsonSource = new UriJsonSource(new Uri("https://raw.githubusercontent.com/DevExpress-Examples/DataSources/master/JSON/customers.json")); |
|||
jsonDataSource.Fill(); |
|||
|
|||
|
|||
DesignerModel = new ReportDesignerModel |
|||
{ |
|||
Report = new XtraReport(), |
|||
DataSources = new Dictionary<string, object>() |
|||
}; |
|||
// DesignerModel.DataSources.Add("BookStoreDb", dataSource); |
|||
DesignerModel.DataSources.Add("JsonDataSource", jsonDataSource); |
|||
} |
|||
|
|||
public class ReportDesignerModel |
|||
{ |
|||
public XtraReport Report { get; set; } |
|||
public Dictionary<string, object> DataSources { get; set; } |
|||
} |
|||
} |
|||
``` |
|||
|
|||
This will allow binding the `data-source` for your report designer. Also update `Designer.cshtml` to use these data sources: |
|||
|
|||
```csharp |
|||
@{ |
|||
var designerRender = Html.DevExpress().ReportDesigner("reportDesigner") |
|||
.Height("1000px") |
|||
.Bind(Model.DesignerModel.Report) |
|||
.DataSources(configureDS => |
|||
{ |
|||
foreach (var ds in Model.DesignerModel.DataSources) |
|||
{ |
|||
configureDS.Add(ds.Key, ds.Value); |
|||
} |
|||
}); |
|||
@designerRender.RenderHtml() |
|||
} |
|||
``` |
|||
|
|||
You can now see the **Add New DataSource** icon in the Field List: |
|||
 |
|||
|
|||
> You can check [DevExpress Reporting Use Data Sources and Connections documentations](https://docs.devexpress.com/XtraReports/401896/web-reporting/asp-net-core-reporting/end-user-report-designer-in-asp-net-applications/use-data-sources-and-connections) for more information. |
|||
|
|||
## Document Viewer Integration |
|||
|
|||
> You are free to create your desired pages and rooting. This sample will be creating a **Viewer** page to demonstrate the layout for the DevExpress reporting components individually. |
|||
|
|||
Since End User Report Designer already implements the required controllers for features, you should only add a new page for document viewing. |
|||
|
|||
### Adding a Document Viewer Page |
|||
|
|||
Create a `Viewer.cshtml` Razor page under the `Pages/Reporting` folder and add the following: |
|||
|
|||
```csharp |
|||
@page |
|||
@using Acme.BookStore.Web.Bundling.Reporting.DocumentViewer |
|||
@using DevExpress.AspNetCore |
|||
@model Acme.BookStore.Web.Pages.Reporting.Viewer |
|||
|
|||
@{ |
|||
var viewerRender = Html.DevExpress().WebDocumentViewer("DocumentViewer") |
|||
.Height("1000px") |
|||
.Bind("TestReport"); |
|||
@viewerRender.RenderHtml() |
|||
} |
|||
|
|||
@section Scripts { |
|||
<abp-style type="typeof(DevExpressDocumentViewerStyleContributor)"/> |
|||
|
|||
<abp-script type="typeof(DevExpressDocumentViewerScriptContributor)"/> |
|||
@viewerRender.RenderScripts() |
|||
} |
|||
``` |
|||
|
|||
> Note: `TestReport.repx` file must be found under `Reports` folder in **Acme.BookStore.Web** project. |
|||
|
|||
### Adding the Antiforgery Token or Passing Bearer Token |
|||
|
|||
While exporting data, you may come across **HTTP 400** error which logs as `[ERR] The required antiforgery request token was not provided in either form field "__RequestVerificationToken" or header value "RequestVerificationToken".` Or you may want to pass **Bearer Token**. |
|||
|
|||
To add these functionalities, update the `Viewer.cshtml` file under the `Pages/Reporting` folder in the **Acme.BookStore.Web** project as shown below: |
|||
|
|||
```csharp |
|||
@page |
|||
@using Acme.BookStore.Web.Bundling.Reporting.DocumentViewer |
|||
@using DevExpress.AspNetCore |
|||
@model Acme.BookStore.Web.Pages.Reporting.Viewer |
|||
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf |
|||
|
|||
@functions{ |
|||
public string GetAntiXsrfRequestToken() |
|||
{ |
|||
return Xsrf.GetAndStoreTokens(HttpContext).RequestToken; |
|||
} |
|||
} |
|||
|
|||
<script type="text/javascript"> |
|||
function SetupJwt(bearerToken, xsrf) { |
|||
DevExpress.Analytics.Utils.ajaxSetup.ajaxSettings = { |
|||
headers: { |
|||
//'Authorization': 'Bearer ' + bearerToken, |
|||
'RequestVerificationToken': xsrf |
|||
} |
|||
}; |
|||
} |
|||
|
|||
function AttachXSRFToken_OnExport(args, xsrf) { |
|||
args.FormData["__RequestVerificationToken"] = xsrf; |
|||
} |
|||
|
|||
function WebDocumentViewer_BeforeRender(s, e) { |
|||
SetupJwt('bearer token can be passed here', "@GetAntiXsrfRequestToken()"); |
|||
$(window).on('beforeunload', function(e) { |
|||
s.Close(); |
|||
}); |
|||
} |
|||
function OnViewerExport(_s, e) { |
|||
AttachXSRFToken_OnExport(e, "@GetAntiXsrfRequestToken()"); |
|||
} |
|||
</script> |
|||
|
|||
<input type="hidden" id="RequestVerificationToken" name="RequestVerificationToken" value="@GetAntiXsrfRequestToken()"> |
|||
|
|||
@{ |
|||
var viewerRender = Html.DevExpress().WebDocumentViewer("DocumentViewer") |
|||
.ClientSideEvents(x => |
|||
{ |
|||
x.BeforeRender("WebDocumentViewer_BeforeRender"); |
|||
x.OnExport("OnViewerExport"); |
|||
}) |
|||
.Height("1000px") |
|||
.Bind("CustomerReport"); |
|||
@viewerRender.RenderHtml() |
|||
} |
|||
|
|||
@section Scripts { |
|||
<abp-style type="typeof(DevExpressDocumentViewerStyleContributor)"/> |
|||
|
|||
<abp-script type="typeof(DevExpressDocumentViewerScriptContributor)"/> |
|||
@viewerRender.RenderScripts() |
|||
} |
|||
``` |
|||
|
|||
> You can also add similar configuration to Report Designer for exporting in Preview Mode. |
|||
|
|||
## Result |
|||
|
|||
 |
|||
|
|||
## Source Code |
|||
|
|||
- You can download the source code from [here](https://github.com/abpframework/abp-samples/tree/master/DevExtreme-Reports-Mvc). |
|||
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
@ -0,0 +1,321 @@ |
|||
# Integrating the Syncfusion MVC Components to the ABP MVC UI |
|||
|
|||
## Introduction |
|||
|
|||
In this article we will see how we can integrate the Syncfusion MVC Components into our ABP application. |
|||
|
|||
## Source Code |
|||
|
|||
You can find the source code of the application at https://github.com/EngincanV/ABP-Syncfusion-Components-Demo. |
|||
|
|||
## Prerequisites |
|||
|
|||
* [.NET 6](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) |
|||
|
|||
* In this article, we will create a new startup template in v5.0.0-rc.2 and if you follow this article from top to bottom and create a new startup template with me, you need to install the [.NET 6 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) before starting. |
|||
|
|||
**NOTE:** ABP v5.X stable version has been released. You can replace v5.0.0-rc.2 with the latest stable version in your steps. |
|||
|
|||
Also, you need to update your ABP CLI to the v5.0.0-rc.2, you can use the command below to update your CLI version: |
|||
|
|||
```bash |
|||
dotnet tool update Volo.Abp.Cli -g --version 5.0.0-rc.2 |
|||
``` |
|||
|
|||
or install it if you haven't installed it before: |
|||
|
|||
```bash |
|||
dotnet tool install Volo.Abp.Cli -g --version 5.0.0-rc.2 |
|||
``` |
|||
|
|||
## Creating the Solution |
|||
|
|||
In this article, we will create a new startup template with EF Core as a database provider and MVC for the UI framework. But if you already have a project with MVC UI, you don't need to create a new startup template, you can directly implement the following steps to your existing project. |
|||
|
|||
> If you already have a project with MVC/Razor Pages UI, you can skip this section. |
|||
|
|||
We can create a new startup template by using the [ABP CLI](https://docs.abp.io/en/abp/latest/CLI): |
|||
|
|||
```bash |
|||
abp new SyncfusionComponentsDemo -t app --preview |
|||
``` |
|||
|
|||
Our project boilerplate will be ready after the download is finished. Then, we can open the solution and start developing. |
|||
|
|||
## Starting the Development |
|||
|
|||
### Pre-requisite |
|||
|
|||
> If you've already had a license from Syncfusion, you can skip this section. |
|||
|
|||
* The first thing we need to do is create an account to be able to get a license from Syncfusion. |
|||
|
|||
* So, let's navigate to https://www.syncfusion.com/aspnet-core-ui-controls and click the "Download Free Trial" button. |
|||
|
|||
* Then fill the form and start your 30-day free trial. |
|||
|
|||
* After that, navigate to https://www.syncfusion.com/account/manage-trials/downloads to get our license key that will be used in our application. |
|||
|
|||
 |
|||
|
|||
Click the "Get License Key" link for "ASP.NET Core (Essential JS 2)". |
|||
|
|||
 |
|||
|
|||
Then a modal will be opened like in the above image, select a version and click the "Get License Key" button. |
|||
|
|||
 |
|||
|
|||
Lastly, copy the generated license key value. |
|||
|
|||
In order to use the relevant components, Syncfusion needs to check this license key to know that our license is valid. |
|||
|
|||
### Configurations |
|||
|
|||
After providing a license key from Syncfusion, we can start with the configuration that needs to be done in our application. |
|||
|
|||
#### 1-) Install the Syncfusion.EJ2.AspNet.Core package |
|||
|
|||
We need to install the `Syncfusion.EJ2.AspNet.Core` Nuget package to our Web project (*.Web). |
|||
|
|||
We can install it via **Visual Studio's Nuget Package Manager**: |
|||
|
|||
 |
|||
|
|||
or via dotnet cli: |
|||
|
|||
```bash |
|||
dotnet add package Syncfusion.EJ2.AspNet.Core --version 19.3.0.57 |
|||
``` |
|||
|
|||
> In this article, I've used the package in version 19.3.0.57. |
|||
|
|||
#### 2-) Register the License Key |
|||
|
|||
* After installing the package, we need to register our license key to be able to use the Syncfusion Components. |
|||
|
|||
* To register the license key, open your web module class and update the `ConfigureServices` method as follows: |
|||
|
|||
```csharp |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
//Register Syncfusion license |
|||
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(licenseKey: configuration["Syncfusion:LicenseKey"].ToString()); |
|||
|
|||
ConfigureUrls(configuration); |
|||
ConfigureBundles(); |
|||
ConfigureAuthentication(context, configuration); |
|||
ConfigureAutoMapper(); |
|||
ConfigureVirtualFileSystem(hostingEnvironment); |
|||
ConfigureLocalizationServices(); |
|||
ConfigureNavigationServices(); |
|||
ConfigureAutoApiControllers(); |
|||
ConfigureSwaggerServices(context.Services); |
|||
} |
|||
``` |
|||
|
|||
Instead of writing the license key directly in here we can define it in the **appsettings.json** file and use it here by using the Configuration system of .NET. |
|||
|
|||
|
|||
* Open your **appsettings.json** file and add a new section named "Syncfusion" as below: |
|||
|
|||
```json |
|||
{ |
|||
//... |
|||
|
|||
"Syncfusion": { |
|||
"LicenseKey": "<your-license-key>" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
> Replace the `<your-license-key> part with your license key that we've obtained in the previous section.` |
|||
|
|||
* To be able to use the Syncfusion Components we need to define them in our **_ViewImports.cshtml** file. By doing that we can use the Syncfusion components everywhere in our application. |
|||
|
|||
* Open your **/Pages/_ViewImports.cshtml** file and add a new tag helper: |
|||
|
|||
```cshtml |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling |
|||
@addTagHelper *, Syncfusion.EJ2 //use Syncfusion components |
|||
``` |
|||
|
|||
#### 3-) Adding Syncfusion styles and scripts to our application |
|||
|
|||
Firstly, let's install the `@syncfusion/ej2` package from **npm**. |
|||
|
|||
* Open your **package.json** file and add the `@syncfusion/ej2` package with version **19.3.57**: |
|||
|
|||
```json |
|||
{ |
|||
"version": "1.0.0", |
|||
"name": "my-app", |
|||
"private": true, |
|||
"dependencies": { |
|||
"@abp/aspnetcore.mvc.ui.theme.basic": "^5.0.0-rc.2", |
|||
"@syncfusion/ej2": "^19.3.57" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
* Then, open the **abp.resourcemapping.js** file and update the **mappings** section: |
|||
|
|||
```js |
|||
module.exports = { |
|||
aliases: { |
|||
|
|||
}, |
|||
mappings: { |
|||
"@node_modules/@syncfusion/ej2/dist/ej2.min.js": "@libs/syncfusion/", |
|||
"@node_modules/@syncfusion/ej2/material.css": "@libs/syncfusion/" |
|||
} |
|||
}; |
|||
``` |
|||
|
|||
> ABP copies related packages from **node_modules** folder to the **libs** folder by examining this file. You can read this [document](docs.abp.io/en/abp/latest/UI/AspNetCore/Client-Side-Package-Management#mapping-the-library-resources) for more info. |
|||
|
|||
* Then run the `abp install-libs` to install the dependencies and copy them into the libs folder by your mappings configuration. After running this command, in your **libs** folder it should be a folder named **syncfusion** folder. |
|||
|
|||
 |
|||
|
|||
The last thing we need to do is, add some style and script files provided by Syncfusion, between our head-body tags. |
|||
|
|||
* We can do this by creating two view components (one for Styles and the other for Scripts). Let's do that. |
|||
|
|||
First, create a folder structure as shown below under the **Components** folder. |
|||
|
|||
 |
|||
|
|||
Then open the related files and add the following codes to each of these files. |
|||
|
|||
* **Default.cshtml** (/Components/Syncfusion/Script/Default.cshtml) |
|||
|
|||
```cshtml |
|||
@addTagHelper *, Syncfusion.EJ2 //add this line |
|||
|
|||
<!-- Syncfusion Essential JS 2 Scripts --> |
|||
<script src="/libs/syncfusion/ej2.min.js"></script> |
|||
|
|||
<!-- Syncfusion Essential JS 2 ScriptManager --> |
|||
<ejs-scripts></ejs-scripts> |
|||
``` |
|||
|
|||
* **SyncfusionScriptComponent.cs** |
|||
|
|||
```csharp |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace SyncfusionComponentsDemo.Web.Components.Syncfusion.Script |
|||
{ |
|||
public class SyncfusionScriptComponent : AbpViewComponent |
|||
{ |
|||
public IViewComponentResult Invoke() |
|||
{ |
|||
return View("~/Components/Syncfusion/Script/Default.cshtml"); |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
* **Default.cshtml** (/Components/Syncfusion/Style/Default.cshtml) |
|||
|
|||
```cshtml |
|||
<!-- Syncfusion Essential JS 2 Styles --> |
|||
<link rel="stylesheet" href="/libs/syncfusion/material.css"> |
|||
``` |
|||
|
|||
* SyncfusionStyleComponent.cs |
|||
|
|||
```csharp |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace SyncfusionComponentsDemo.Web.Components.Syncfusion.Style |
|||
{ |
|||
public class SyncfusionStyleComponent : AbpViewComponent |
|||
{ |
|||
public IViewComponentResult Invoke() |
|||
{ |
|||
return View("~/Components/Syncfusion/Style/Default.cshtml"); |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
After creating these two components, we can use the [**Layout Hooks**](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Layout-Hooks) system of ABP to inject these two components between head and script tags. |
|||
|
|||
To do this, open your web module class and update the `ConfigureServices` method as below: |
|||
|
|||
|
|||
```csharp |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
//Register Syncfusion license |
|||
var licenseKey = configuration["Syncfusion:LicenseKey"].ToString(); |
|||
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(licenseKey: licenseKey); |
|||
|
|||
Configure<AbpLayoutHookOptions>(options => |
|||
{ |
|||
//Now, the SyncfusionStyleComponent code will be inserted in the head of the page as the last item. |
|||
options.Add(LayoutHooks.Head.Last, typeof(SyncfusionStyleComponent)); |
|||
|
|||
//the SyncfusionScriptComponent will be inserted in the body of the page as the last item. |
|||
options.Add(LayoutHooks.Body.Last, typeof(SyncfusionScriptComponent)); |
|||
}); |
|||
|
|||
ConfigureUrls(configuration); |
|||
ConfigureBundles(); |
|||
ConfigureAuthentication(context, configuration); |
|||
ConfigureAutoMapper(); |
|||
ConfigureVirtualFileSystem(hostingEnvironment); |
|||
ConfigureLocalizationServices(); |
|||
ConfigureNavigationServices(); |
|||
ConfigureAutoApiControllers(); |
|||
ConfigureSwaggerServices(context.Services); |
|||
} |
|||
``` |
|||
|
|||
After injecting the Syncfusion style and script into our application, our configurations have been completed. We can try with a simple component to see if it works as we expected. |
|||
|
|||
* Let's try with the [Calendar](https://www.syncfusion.com/aspnet-core-ui-controls/calendar) component. Open your **Index.cshtml** file and update with the below content: |
|||
|
|||
```cshtml |
|||
@page |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using SyncfusionComponentsDemo.Localization |
|||
@using Volo.Abp.Users |
|||
@model SyncfusionComponentsDemo.Web.Pages.IndexModel |
|||
|
|||
@section styles { |
|||
<abp-style src="/Pages/Index.css" /> |
|||
} |
|||
|
|||
@section scripts { |
|||
<abp-script src="/Pages/Index.js" /> |
|||
} |
|||
|
|||
<div class="container"> |
|||
<h2>Syncfusion - Calendar Component</h2> |
|||
<ejs-calendar id="calendar"></ejs-calendar> |
|||
</div> |
|||
``` |
|||
|
|||
* Then when we run the application, we need to see the relevant calendar component as below. |
|||
|
|||
 |
|||
|
|||
### Conclusion |
|||
|
|||
In this article, we've explained how to integrate the **Syncfusion Components** into our applications. After following this article, you can use the Syncfusion components in your application. |
|||
|
|||
Thanks for reading the article, I hope you've found it useful :) |
|||
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 53 KiB |
@ -0,0 +1,3 @@ |
|||
# eShopOnAbp |
|||
|
|||
This document is in progress. Please see the source code for now: https://github.com/abpframework/eShopOnAbp |
|||
@ -0,0 +1,71 @@ |
|||
# HTTP Error Reporter Service |
|||
|
|||
`HttpErrorReporterService` is a service which is exposed by `@abp/ng.core` package. HTTP errors can be reported by using this service. The service emits an event when an error is reported and keeps the errors as an array. The [`RestService`](./HTTP-Requests#restservice) uses the `HttpErrorReporterService` for reporting errors. |
|||
|
|||
See the example below to learn how to report an error: |
|||
|
|||
```ts |
|||
import { HttpErrorReporterService } from '@abp/ng.core'; |
|||
import { HttpClient } from '@angular/common/http'; |
|||
import { Injectable } from '@angular/core'; |
|||
import { of } from 'rxjs'; |
|||
import { catchError } from 'rxjs/operators'; |
|||
|
|||
@Injectable() |
|||
export class SomeService { |
|||
constructor(private http: HttpClient, private httpErrorReporter: HttpErrorReporterService) {} |
|||
|
|||
getData() { |
|||
return this.http.get('http://example.com/get-data').pipe( |
|||
catchError(err => { |
|||
this.httpErrorReporter.reportError(err); |
|||
return of(null); |
|||
}), |
|||
); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
See the following example to learn listening the reported errors: |
|||
|
|||
```ts |
|||
import { HttpErrorReporterService } from '@abp/ng.core'; |
|||
import { HttpErrorResponse } from '@angular/common/http'; |
|||
import { Injectable } from '@angular/core'; |
|||
|
|||
@Injectable() |
|||
export class MyErrorHandler { |
|||
constructor(private httpErrorReporter: HttpErrorReporterService) { |
|||
this.handleErrors(); |
|||
} |
|||
|
|||
handleErrors() { |
|||
this.httpErrorReporter.reporter$.subscribe((err: HttpErrorResponse) => { |
|||
// handle the errors here |
|||
}); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
|
|||
## API |
|||
|
|||
|
|||
### `reporter$: Observable<HttpErrorResponse>` |
|||
|
|||
`reporter$` is a getter, returns an observable. It emits an event when a new error is reported. The event value type is `HttpErrorResponse`. |
|||
|
|||
|
|||
### `errors$: Observable<HttpErrorResponse[]>` |
|||
|
|||
`errors$` is a getter, returns an observable. It emits an event when a new error is reported. The event value is all errors reported at runtime. |
|||
|
|||
### `errors: HttpErrorResponse` |
|||
|
|||
`errors` is a getter that returns all errors reported. |
|||
|
|||
|
|||
### `reportError(error: HttpErrorResponse): void` |
|||
|
|||
`reportError` is a method. The errors can be reported via this. |
|||
When an error is reported, the method triggers the `reports$` and `errors$` observables to emit an event. |
|||
|
After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 41 KiB |
@ -0,0 +1,73 @@ |
|||
# 入门教程 |
|||
|
|||
````json |
|||
//[doc-params] |
|||
{ |
|||
"UI": ["MVC", "Blazor", "BlazorServer", "NG"], |
|||
"DB": ["EF", "Mongo"], |
|||
"Tiered": ["Yes", "No"] |
|||
} |
|||
```` |
|||
|
|||
> 本文档假设你更喜欢使用 **{{ UI_Value }}** 作为 UI 框架, 使用 **{{ DB_Value }}** 作为数据库提供程序. 对于其他选项, 请更改本文档顶部的首选项. |
|||
|
|||
## 创建新项目 |
|||
|
|||
我们将使用 ABP CLI 创建一个新的 ABP 项目. |
|||
|
|||
> 或者, 你可以使用[ABP Framework 网站](https://abp.io/get-started)页面上的选项轻松的 **创建并下载** 项目. |
|||
|
|||
使用 ABP CLI 的 `new` 命令创建一个新项目: |
|||
|
|||
````shell |
|||
abp new Acme.BookStore{{if UI == "NG"}} -u angular{{else if UI == "Blazor"}} -u blazor{{else if UI == "BlazorServer"}} -u blazor-server{{end}}{{if DB == "Mongo"}} -d mongodb{{end}}{{if Tiered == "Yes"}}{{if UI == "MVC" || UI == "BlazorServer"}} --tiered{{else}} --separate-identity-server{{end}}{{end}} |
|||
```` |
|||
|
|||
*你可以使用不同级别的命名空间, 例如: BookStore、Acme.BookStore或 Acme.Retail.BookStore.* |
|||
|
|||
{{ if Tiered == "Yes" }} |
|||
|
|||
{{ if UI == "MVC" || UI == "BlazorServer" }} |
|||
|
|||
* `--tified` 参数用于创建认证服务器、 UI 和 API 实际分隔的 N-层解决方案. |
|||
|
|||
{{ else }} |
|||
|
|||
* `--separate-identity-server` 参数用于将Identity Server应用程序与API主机应用程序分隔开. 如果未指定, 则服务器上将只有一个端点. |
|||
|
|||
{{ end }} |
|||
|
|||
{{ end }} |
|||
|
|||
> [ABP CLI 文档](./CLI.md) 涵盖了所有可用的命令和选项. |
|||
|
|||
## 移动端开发 |
|||
|
|||
如果你想要在你的解决方案中包含 [React Native](https://reactnative.dev/) 项目, 将 `-m react-native` (or `--mobile react-native`) 参数添加到项目创建命令. 这是一个基础的 React Native 启动模板, 用于开发基于你的 ABP 后端的移动应用程序. |
|||
|
|||
请参阅 [React Native 入门](Getting-Started-React-Native.md) 文档, 了解如何配置和运行 React Native 应用程序. |
|||
|
|||
### 解决方案结构 |
|||
|
|||
该解决方案具有分层结构 (基于 [域驱动设计](Domain-Driven-Design.md)), 并包含单元 & 集成测试项目. 请参阅 [应用程序模板文档](Startup-Templates/Application.md) 以详细了解解决方案结构. |
|||
|
|||
{{ if DB == "Mongo" }} |
|||
|
|||
#### MongoDB 事务 |
|||
|
|||
[启动模板](Startup-templates/Index.md) 默认在`.MongoDB`项目中**禁用**事务. 如果你的MongoDB服务器支持事务, 你可以在*YourProjectMongoDbModule*类中的`ConfigureServices`方法开启它: |
|||
|
|||
```csharp |
|||
Configure<AbpUnitOfWorkDefaultOptions>(options => |
|||
{ |
|||
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Auto; |
|||
}); |
|||
``` |
|||
|
|||
> 或者你可以删除该代码, 因为 `Auto` 已经是默认行为. |
|||
|
|||
{{ end }} |
|||
|
|||
## 下一步 |
|||
|
|||
* [运行解决方案](Getting-Started-Running-Solution.md) |
|||
@ -0,0 +1,199 @@ |
|||
# 入门教程 |
|||
|
|||
````json |
|||
//[doc-params] |
|||
{ |
|||
"UI": ["MVC", "Blazor", "BlazorServer", "NG"], |
|||
"DB": ["EF", "Mongo"], |
|||
"Tiered": ["Yes", "No"] |
|||
} |
|||
```` |
|||
|
|||
> 本文档假设你更喜欢使用 **{{ UI_Value }}** 作为 UI 框架, 使用 **{{ DB_Value }}** 作为数据库提供程序. 对于其他选项, 请更改本文档顶部的首选项. |
|||
|
|||
## 创建数据库 |
|||
|
|||
### 连接字符串 |
|||
|
|||
检查在 {{if Tiered == "Yes"}}`.IdentityServer` 和`.HttpApi.Host` 项目{{else}}{{if UI=="MVC"}}`.Web` 项目{{else if UI=="BlazorServer"}}`.Blazor` 项目{{else}}`.HttpApi.Host` 项目{{end}}{{end}} 中 `appsettings.json` 文件里的**连接字符串**. |
|||
|
|||
{{ if DB == "EF" }} |
|||
|
|||
````json |
|||
"ConnectionStrings": { |
|||
"Default": "Server=(LocalDb)\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True" |
|||
} |
|||
```` |
|||
|
|||
> **关于连接字符串和数据库管理系统** |
|||
> |
|||
> 解决方案配置为默认使用 **Entity Framework Core** 与 **MS SQL Server**. 但是, 如果在执行ABP CLI 的`new`命令时使用了`-dbms`参数来选择其他DBMS (如`-dbms MySQL`), 那么连接字符串可能不同. |
|||
> |
|||
> EF Core 支持 [多种](https://docs.microsoft.com/en-us/ef/core/providers/) 据库提供程序, 因此你可以使用任何受支持的DBMS. 你可以需要时候参阅[Entity Framework 集成文档](Entity-Framework-Core.md) 来学习如何[切换到另一个DBMS](Entity-Framework-Core-Other-DBMS.md). |
|||
|
|||
### 数据库迁移 |
|||
|
|||
该解决方案使用[Entity Framework Core Code First 迁移](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli). 带有 `.DbMigrator` 的控制台程序用于 **应用迁移** 和 **初始化种子数据**. 它在**开发**和**生产**环境中都很有用. |
|||
|
|||
> `.dbMigator` 项目有自己的 `appsettings.json`. 因此, 如果你更改了之前的连接字符串, 那么也应该更改这个连接字符串. |
|||
|
|||
### 初次迁移 |
|||
|
|||
`.dbMigator` 应用程序在首次运行时自动**创建初始迁移**. |
|||
|
|||
**如果你使用的是 Visual Studio, 你可以跳到 *运行 dbMigrator* 部分.** 但是, 其他 IDE (例如 Rider) 在首次运行时可能会遇到问题, 因为它会添加初始迁移并编译项目. 在这种情况下, 请在 `.dbMigration` 项目的文件夹中打开命令行终端, 然后运行以下命令: |
|||
|
|||
````bash |
|||
dotnet run |
|||
```` |
|||
|
|||
下次, 你可以像往常一样在 IDE 中运行它. |
|||
|
|||
### 运行迁移 |
|||
|
|||
右键单击 `.dbMigration` 项目, 然后选择 **设置为启动项目** |
|||
|
|||
 |
|||
|
|||
按F5(或Ctrl + F5) 运行应用程序. 它将具有如下所示的输出: |
|||
|
|||
 |
|||
|
|||
> 初始的[种子数据](Data-Seeding.md)在数据库中创建了 `admin` 用户(密码为`1q2w3E*`) 用于登录应用程序. 所以, 对于新数据库至少使用 `.DbMigrator` 一次. |
|||
|
|||
{{ else if DB == "Mongo" }} |
|||
|
|||
````json |
|||
"ConnectionStrings": { |
|||
"Default": "mongodb://localhost:27017/BookStore" |
|||
} |
|||
```` |
|||
|
|||
该解决方案配置为在本地计算机中使用 **MongoDB**, 因此你需要启动并运行 MongoDB 服务器实例, 或者将连接字符串更改为另一台 MongoDB 服务器. |
|||
|
|||
### 种子初始数据 |
|||
|
|||
该解决方案带有 `.DbMigrator` 的控制台程序用于 **初始化种子数据**. 它在**开发**和**生产**环境中都很有用. |
|||
|
|||
> `.dbMigator` 项目有自己的 `appsettings.json`. 因此, 如果你更改了之前的连接字符串, 那么也应该更改这个连接字符串. |
|||
|
|||
右键单击 `.dbMigration` 项目, 然后选择 **设置为启动项目** |
|||
|
|||
 |
|||
|
|||
按F5(或Ctrl + F5) 运行应用程序. 它将具有如下所示的输出: |
|||
|
|||
 |
|||
|
|||
> 初始的[种子数据](Data-Seeding.md)在数据库中创建了 `admin` 用户(密码为`1q2w3E*`) 用于登录应用程序. 所以, 对于新数据库至少使用 `.DbMigrator` 一次. |
|||
|
|||
{{ end }} |
|||
|
|||
## 运行应用程序 |
|||
|
|||
{{ if UI == "MVC" || UI == "BlazorServer" }} |
|||
|
|||
{{ if Tiered == "Yes" }} |
|||
|
|||
> 分层解决方案使用 **Redis** 作为分布式缓存. 确保它已安装并在本地计算机上运行. 如果你使用的是远程 Redis 服务器, 请修改项目的 ` appsettings.json` 文件中的配置. |
|||
|
|||
1. 确保 `.IdentityServer` 项目是启动项目. 运行此应用程序, 它将在浏览器中打开 **登录** 页面. |
|||
|
|||
> 在 Visual Studio 中使用 Ctrl+F5(而不是F5) 在不进行调试的情况下运行应用程序. 如果你没有调试目的, 这会更快. |
|||
|
|||
你可以登录, 但不能在这里进入主应用程序. 这 **只是身份验证服务器**. |
|||
|
|||
2. 确保 `.httpapi.Host` 项目是启动项目, 然后运行应用将在浏览器中打开 **Swagger UI**. |
|||
|
|||
 |
|||
|
|||
这是 Web 应用程序使用的 HTTP API. |
|||
|
|||
3. 最后, 确保 {{if UI=="MVC"}}`.Web`{{else}}`.Blazor`{{end}} 项目是启动项目,然后运行应用程序,它将在浏览器中打开 **欢迎** 页面 |
|||
|
|||
 |
|||
|
|||
单击 **login** 按钮, 它将重定向到 *身份验证服务器* 以登录到应用程序: |
|||
|
|||
 |
|||
|
|||
{{ else # Tiered != "Yes" }} |
|||
|
|||
确保 {{if UI=="MVC"}}`.Web`{{else}}`.Blazor`{{end}} 项目是启动项目. 运行应用程序将会在浏览器中打开 **login** 页面: |
|||
|
|||
> 在 Visual Studio 中使用 Ctrl+F5(而不是F5) 在不进行调试的情况下运行应用程序. 如果你没有调试目的, 这会更快. |
|||
|
|||
 |
|||
|
|||
{{ end # Tiered }} |
|||
|
|||
{{ else # UI != MVC || BlazorServer }} |
|||
|
|||
### 运行 HTTP API 主机(服务器端) |
|||
|
|||
{{ if Tiered == "Yes" }} |
|||
|
|||
> 分层解决方案使用 Redis 作为分布式缓存. 确保它已安装并在本地计算机上运行. 如果你使用的是远程 Redis 服务器, 请修改项目的 `appsettings.json` 文件中的配置. |
|||
|
|||
确保 `.IdentityServer` 项目是启动项目. 运行此应用程序, 它将在浏览器中打开 **登录** 页面. |
|||
|
|||
> 在 Visual Studio 中使用 Ctrl+F5(而不是F5) 在不进行调试的情况下运行应用程序. 如果你没有调试目的, 这会更快. |
|||
|
|||
你可以登录, 但不能在这里进入主应用程序. 这 **只是身份验证服务器**. |
|||
|
|||
确保 `.HttpApi.Host` 项目是启动项目, 然后运行应用程序将打开 Swagger UI 的: |
|||
|
|||
{{ else # Tiered == "No" }} |
|||
|
|||
确保 `.HttpApi.Host` 项目是启动项目, 然后运行应用程序将打开 Swagger UI 的: |
|||
|
|||
> 在 Visual Studio 中使用 Ctrl+F5(而不是F5) 在不进行调试的情况下运行应用程序. 如果你没有调试目的, 这会更快. |
|||
|
|||
{{ end # Tiered }} |
|||
|
|||
 |
|||
|
|||
你可以在这里查看应用程序的API并测试它们. 获取Swagger UI的[更多信息](https://swagger.io/tools/swagger-ui/). |
|||
|
|||
{{ end # UI }} |
|||
|
|||
{{ if UI == "Blazor" }} |
|||
|
|||
### 运行 Blazor 应用程序 (客户端) |
|||
|
|||
确保 `.Blazor` 项目是启动项目并运行应用程序. |
|||
|
|||
> 在 Visual Studio 中使用 Ctrl+F5(而不是F5) 在不进行调试的情况下运行应用程序. 如果你没有调试目的, 这会更快. |
|||
|
|||
应用程序启动后, 单击页头上的 **Login** 链接, 你将重定向到身份验证服务器以输入用户名和密码: |
|||
|
|||
 |
|||
|
|||
{{ else if UI == "NG" }} |
|||
|
|||
### 运行 Angular 应用程序 (客户端) |
|||
|
|||
转到 `Angular` 文件夹, 打开命令行终端, 键入 `yarn` 命令(我们建议使用 [yarn](https://yarnpkg.com/) 软件包管理器, 而 `npm install` 也可以使用) |
|||
|
|||
```bash |
|||
yarn |
|||
``` |
|||
|
|||
当所有node模块加载完毕后, 执行 `yarn start` (或 `npm start`) 命令: |
|||
|
|||
```bash |
|||
yarn start |
|||
``` |
|||
|
|||
初次构建可能需要更长的时间. 完成后, 它会在默认浏览器中使用 [localhost:4200](http://localhost:4200/) 地址打开 Angular UI. |
|||
|
|||
 |
|||
|
|||
{{ end }} |
|||
|
|||
输入用户名 **admin** 和 密码 **1q2w3E*** 登录应用程序. 应用程序已启动并正在运行. 你可以根据此启动模板开始开发应用程序. |
|||
|
|||
## 另请参见 |
|||
|
|||
* [Web 应用程序开发教程](Tutorials/Part-1.md) |
|||
* [应用程序启动模板](Startup-Templates/Application.md) |
|||
@ -0,0 +1,53 @@ |
|||
# 入门教程 |
|||
|
|||
````json |
|||
//[doc-params] |
|||
{ |
|||
"UI": ["MVC", "Blazor", "BlazorServer", "NG"], |
|||
"DB": ["EF", "Mongo"], |
|||
"Tiered": ["Yes", "No"] |
|||
} |
|||
```` |
|||
|
|||
> 本文档假设你更喜欢使用 **{{ UI_Value }}** 作为 UI 框架, 使用 **{{ DB_Value }}** 作为数据库提供程序. 对于其他选项, 请更改本文档顶部的首选项. |
|||
|
|||
## 设置你的开发环境 |
|||
|
|||
第一件事! 在创建项目之前, 让我们先设置你的开发环境. |
|||
|
|||
### 先决条件 |
|||
|
|||
开发计算机上应安装以下工具: |
|||
|
|||
* 一个集成开发环境 (比如: [Visual Studio](https://visualstudio.microsoft.com/vs/)) 它需要支持 [.NET 6.0+](https://dotnet.microsoft.com/download/dotnet) 的开发. |
|||
{{ if UI != "Blazor" }} |
|||
* [Node v12 或 v14](https://nodejs.org/) |
|||
* [Yarn v1.20+ (不是v2)](https://classic.yarnpkg.com/en/docs/install) <sup id="a-yarn">[1](#f-yarn)</sup> 或 npm v6+ (已跟随Node一起安装) |
|||
{{ end }} |
|||
{{ if Tiered == "Yes" }} |
|||
* [Redis](https://redis.io/) (启动解决方案使用 Redis 作为 [分布式缓存](Caching.md)). |
|||
{{ end }} |
|||
|
|||
{{ if UI != "Blazor" }} |
|||
|
|||
<sup id="f-yarn"><b>1</b></sup> _Yarn v2 工作方式不同, 不被支持._ <sup>[↩](#a-yarn)</sup> |
|||
|
|||
{{ end }} |
|||
|
|||
### 安装 ABP CLI |
|||
|
|||
[ABP CLI](./CLI.md) 是一个命令行界面, 用于自动执行基于 ABP 的解决方案的一些常见任务. 首先, 你需要使用以下命令安装 ABP CLI: |
|||
|
|||
````shell |
|||
dotnet tool install -g Volo.Abp.Cli |
|||
```` |
|||
|
|||
如果已安装, 则可以使用以下命令对其进行更新: |
|||
|
|||
````shell |
|||
dotnet tool update -g Volo.Abp.Cli |
|||
```` |
|||
|
|||
## 下一步 |
|||
|
|||
* [创建新的解决方案](Getting-Started-Create-Solution.md) |
|||
@ -1,374 +1,20 @@ |
|||
## 入门 |
|||
# 入门教程 |
|||
|
|||
````json |
|||
//[doc-params] |
|||
{ |
|||
"UI": ["MVC","NG"], |
|||
"UI": ["MVC", "Blazor", "BlazorServer", "NG"], |
|||
"DB": ["EF", "Mongo"], |
|||
"Tiered": ["Yes", "No"] |
|||
} |
|||
```` |
|||
|
|||
本教程介绍了如何创建一个新的{{if UI == "MVC"}} ASP.NET Core MVC web {{else if UI == "NG"}} Angular {{end}}. 配置并运行它. |
|||
> 本文档假设你更喜欢使用 **{{ UI_Value }}** 作为 UI 框架, 使用 **{{ DB_Value }}** 作为数据库提供程序. 对于其他选项, 请更改本文档顶部的首选项. |
|||
|
|||
## 设置你的开发环境 |
|||
## 内容 |
|||
|
|||
创建第一个项目之前,需要正确的设置你的开发环境. |
|||
本教程介绍如何使用 ABP 框架 **创建和运行** 新的 Web 应用程序. 请按照以下步骤操作; |
|||
|
|||
### 预先要求 |
|||
|
|||
你需要安装以下工具: |
|||
|
|||
* [Visual Studio 2019 (v16.4+)](https://visualstudio.microsoft.com/vs/) for Windows / [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/).<sup id="a-editor">[1](#f-editor)</sup> |
|||
* [.NET Core 3.1+](https://www.microsoft.com/net/download/dotnet-core/) |
|||
|
|||
* [Node v12 或 v14](https://nodejs.org/en/) |
|||
* [Yarn v1.19+](https://classic.yarnpkg.com/) |
|||
* [Yarn v1.20+ (not v2)](https://classic.yarnpkg.com/en/docs/install) <sup id="a-yarn">[2](#f-yarn)</sup> 或 npm v6+ (与Node一起安装) |
|||
{{ if Tiered == "Yes" }} |
|||
|
|||
* [Redis](https://redis.io/): 入门解决方案将Redis用作[分布式缓存](Caching.md). 因此你需要安装并运行Redis. |
|||
|
|||
{{ end }} |
|||
|
|||
<sup id="f-editor"><b>1</b></sup> _只要支持.NET Core和ASP.NET Core,就可以使用其他编辑器代替Visual Studio._ <sup>[↩](#a-editor)</sup> |
|||
|
|||
<sup id="f-yarn"><b>2</b></sup> _Yarn v2 的工作方式不同,不受支持._ <sup>[↩](#a-yarn)</sup> |
|||
|
|||
### 安装ABP CLI |
|||
|
|||
[ABP CLI](./CLI.md)是一个命令行页面,用于自动执行一些基于ABP的应用程序的常见任务. |
|||
|
|||
> ABP CLI是ABP框架一个免费开源的工具. |
|||
|
|||
你需要使用以下命令安排ABP CLI: |
|||
|
|||
````shell |
|||
dotnet tool install -g Volo.Abp.Cli |
|||
```` |
|||
|
|||
如果你已经安装,你可以使用以下命令更新到最新版本: |
|||
|
|||
````shell |
|||
dotnet tool update -g Volo.Abp.Cli |
|||
```` |
|||
|
|||
## 创建新项目 |
|||
|
|||
> 本文假设你使用 **{{ UI_Value }}** 做为UI框架 **{{ DB_Value }}** 做为数据库提供程序,对于其它选项,你可以更改文档顶部的首选项. |
|||
|
|||
### 使用ABP CLI创建一个新项目 |
|||
|
|||
使用ABP CLI的 `new` 命令创建新项目: |
|||
|
|||
````shell |
|||
abp new Acme.BookStore{{if UI == "NG"}} -u angular {{end}}{{if DB == "Mongo"}} -d mongodb{{end}}{{if Tiered == "Yes" && UI != "NG"}} --tiered {{else if Tiered == "Yes" && UI == "NG"}}--separate-identity-server{{end}} --mobile react-native |
|||
```` |
|||
|
|||
* 此命令还会在解决方案文件夹内创建一个React Native移动应用程序. 如果你不想要它,可以安全地删除它或从`abp new`命令中删除`--mobile react-native`选项, 以使其完全不包含在解决方案中. |
|||
|
|||
{{ if UI == "NG" }} |
|||
|
|||
* `-u` 指定UI框架, 本例中是 `angular`. |
|||
|
|||
{{ if Tiered == "Yes" }} |
|||
|
|||
* `--separate-identity-server` 参数用于将Identity服务器应用程序与API主机应用程序分隔开. 如果未指定,则服务器上将只有一个端点. |
|||
|
|||
{{ end }} |
|||
|
|||
{{ end }} |
|||
|
|||
{{ if DB == "Mongo" }} |
|||
|
|||
* `-d` 指定数据库提供程序, 本例中是 `mongodb`. |
|||
|
|||
{{ end }} |
|||
|
|||
{{ if Tiered == "Yes" && UI != "NG" }} |
|||
|
|||
* `--tiered` 参数用于创建n层解决方案,其中身份验证服务器层,UI层和API层在物理上是分离的. |
|||
|
|||
{{ end }} |
|||
|
|||
> 你可以使用不同级别的命令空间; 例如. BookStore, Acme.BookStore or Acme.Retail.BookStore. |
|||
|
|||
#### ABP CLI 命令 & 选项 |
|||
|
|||
[ABP CLI文档](./CLI.md)涵盖了ABP CLI的所有可用命令和选项. 本文档使用[应用程序启动模板](Startup-Templates/Application.md)创建新的Web应用程序. 有关其他模板,请参见[ABP启动模板](Startup-Templates/Index.md)文档. |
|||
|
|||
> 或者,您可以从[ABP Framework网站](https://abp.io/get-started)中选择"直接下载"选项卡创建新的解决方案. |
|||
|
|||
## 解决方案结构 |
|||
|
|||
{{ if UI == "MVC" }} |
|||
|
|||
创建项目后你会有以下解决方案目录和文件: |
|||
|
|||
 |
|||
|
|||
在Visual Studio中打开 `.sln` 文件时,将看到以下解决方案结构: |
|||
|
|||
{{if DB == "Mongo"}} |
|||
|
|||
 |
|||
|
|||
{{else}} |
|||
|
|||
 |
|||
|
|||
{{end}} |
|||
|
|||
{{ else if UI == "NG" }} |
|||
|
|||
在创建的解决方案中有三个文件夹: |
|||
|
|||
 |
|||
|
|||
* `angular` 文件夹包含Angular UI应用程序. |
|||
* `aspnet-core` 文件夹包含后端应用程序. |
|||
* `react-native` 文件夹包含React Native UI 应用程序. |
|||
|
|||
打开 `aspnet-core` 文件夹下的 `.sln`(`Visual Studio`解决方案)文件: |
|||
|
|||
 |
|||
|
|||
{{ end }} |
|||
|
|||
> ###### 关于解决方案中的项目 |
|||
> |
|||
> 根据你的**UI**,**数据库**和其他选项,你的解决方案的结构可能略有不同. |
|||
|
|||
该解决方案具有分层结构(基于[Domain Driven Design](Domain-Driven-Design.md)), 并包含配置好的的单元&集成测试项目. |
|||
|
|||
{{ if DB == "EF" }} |
|||
|
|||
集成测试项目已配置为可与 **EF Core** & **SQLite 内存** database同时使用. |
|||
|
|||
{{ else if DB == "Mongo" }} |
|||
|
|||
集成测试项目已配置为每个测试创建的内存中的**MongoDB**数据库(使用的[Mongo2Go](https://github.com/Mongo2Go/Mongo2Go)库). |
|||
|
|||
{{ end }} |
|||
|
|||
> 请参阅[应用程序模板文档](Startup-Templates/Application.md)详细了解解决方案结构. |
|||
|
|||
{{ if DB == "Mongo" }} |
|||
|
|||
> [启动模板](Startup-templates/Index.md)默认在 `.MongoDB` 项目中**禁用**了工作单元事务. 如果你的MongoDB服务器支持事务,你可以手动启用工作单元的事务: |
|||
|
|||
```csharp |
|||
Configure<AbpUnitOfWorkDefaultOptions>(options => |
|||
{ |
|||
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Enabled; |
|||
}); |
|||
``` |
|||
|
|||
{{ end }} |
|||
|
|||
## 创建数据库 |
|||
|
|||
### 连接字符串 |
|||
|
|||
检查 {{if UI == "MVC"}}{{if Tiered == "Yes"}}`.IdentityServer` 和 `.HttpApi.Host` 项目{{else}}`.Web` 项目{{end}}{{else if UI == "NG" }}`.HttpApi.Host` 项目{{end}}下 `appsettings.json` 文件中的 **链接字符串**: |
|||
|
|||
{{ if DB == "EF" }} |
|||
|
|||
````json |
|||
"ConnectionStrings": { |
|||
"Default": "Server=localhost;Database=BookStore;Trusted_Connection=True" |
|||
} |
|||
```` |
|||
|
|||
该解决方案配置为**Entity Framework Core**与**MS SQL Server**一起使用. EF Core支持[各种](https://docs.microsoft.com/en-us/ef/core/providers/)数据库提供程序,因此你可以使用任何受支持的DBMS. 请参阅[Entity Framework集成文档](https://docs.abp.io/en/abp/latest/Entity-Framework-Core)了解如何切换到另一个DBMS. |
|||
|
|||
### 数据库连接字符串 |
|||
|
|||
查看`.Web`项目下`appsettings.json`文件中的 **连接字符串**: |
|||
|
|||
````json |
|||
{ |
|||
"ConnectionStrings": { |
|||
"Default": "Server=localhost;Database=BookStore;Trusted_Connection=True" |
|||
} |
|||
} |
|||
```` |
|||
|
|||
解决方案使用 **Entity Framework Core** 和 **MS SQL Server**. EF Core支持[各种](https://docs.microsoft.com/zh-cn/ef/core/providers/)数据库提供程序,因此你可以根据实际需要使用其他DBMS. 如果需要,请更改连接字符串. |
|||
|
|||
### 应用迁移 |
|||
|
|||
该解决方案使用[Entity Framework Core Code First 迁移](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli). 你需要应用迁移来创建数据库,有两种方法迁移数据库. |
|||
|
|||
#### 使用DbMigrator应用程序应用迁移 |
|||
|
|||
该解决方案包含一个控制台应用程序(在此示例中名为`Acme.BookStore.DbMigrator`),可以创建数据库,应用迁移和初始化数据. 它对开发和生产环境都很有用. |
|||
|
|||
> `.DbMigrator`项目有自己的`appsettings.json`. 因此,如果你更改了上面的连接字符串,则还应更改此字符串. |
|||
|
|||
右键单击`.DbMigrator`项目并选择 **设置为启动项目**: |
|||
|
|||
 |
|||
|
|||
按F5(或Ctrl + F5)运行应用程序. 它将具有如下所示的输出: |
|||
|
|||
 |
|||
|
|||
#### 使用EF Core Update-Database命令 |
|||
|
|||
Ef Core具有`Update-Database`命令, 可根据需要创建数据库并应用挂起的迁移. 右键单击`.Web`项目并选择**设置为启动项目**: |
|||
|
|||
{{ if UI == "MVC" }} |
|||
|
|||
右键单击{{if Tiered == "Yes"}}`.IdentityServer`{{else}}`.Web`{{end}}项目并选择**设置为启动项目**: |
|||
|
|||
{{ else if UI != "MVC" }} |
|||
|
|||
右键单击`.HttpApi.Host`项目并选择**设置为启动项目**: |
|||
|
|||
{{ end }} |
|||
|
|||
 |
|||
|
|||
打开**包管理器控制台(Package Manager Console)**, 选择`.EntityFrameworkCore.DbMigrations`项目作为**默认项目**并运行`Update-Database`命令: |
|||
|
|||
 |
|||
|
|||
这将基于配置的连接字符串创建新数据库. |
|||
|
|||
> **使用`.DbMigrator`工具是建议的方法**, 因为它能初始化初始数据能够正确运行Web应用程序. |
|||
> |
|||
> 如果你只是使用 `Update-Database` 命令,你会得到一个空数据库,所以你无法登录到应用程序因为数据库中没有初始管理用户. 不需要种子数据库时,可以在开发期间使用 `Update-Database` 命令. 但是使用 `.DbMigrator` 应用程序会更简单,你始终可以使用它来迁移模式并为数据库添加种子. |
|||
|
|||
{{ else if DB == "Mongo" }} |
|||
|
|||
````json |
|||
"ConnectionStrings": { |
|||
"Default": "mongodb://localhost:27017/BookStore" |
|||
} |
|||
```` |
|||
|
|||
该解决方案被配置为在你的本地计算机中使用 **MongoDB**,因此你需要启动并运行一个MongoDB服务器实例或者将连接字符串更改为另一个MongoDB服务器. |
|||
|
|||
### 初始化种子数据 |
|||
|
|||
该解决方案附带一个 `.DbMigrator` 控制台应用程序,该应用程序为初始数据提供了种子. 它对于开发以及生产环境都很有用. |
|||
|
|||
> `.DbMigrator` 项目有自己的 `appsettings.json`.如果你更改了其他项目的 `appsettings.json`,也应该更改这个. |
|||
|
|||
右键点击 `.DbMigrator` 并选择 **设置为启动项目**. |
|||
|
|||
 |
|||
|
|||
按F5(或Ctrl+F5)启动应用程序,你会看到以下输出: |
|||
|
|||
 |
|||
|
|||
> 数据库创建后会初始化[种子数据](Data-Seeding.md), 其中包含用于登录的 `admin` 用户. 所以你至少使用 `.DbMigrator` 一次. |
|||
|
|||
{{ end }} |
|||
|
|||
### 运行应用程序 |
|||
|
|||
{{ if UI == "MVC" }} |
|||
|
|||
{{ if Tiered == "Yes" }} |
|||
|
|||
确保 `.IdentityServer` 是启动项目,运行应用程序后会在你的浏览器打开一个 **login** 页面. |
|||
|
|||
> 在Visual Studio中使用Ctrl+F5(而不是F5)运行应用,如果你不用于调试,这会减少启动时间. |
|||
|
|||
你可以登录,但是不能在这里进入主应用程序,它仅是验证服务器. |
|||
|
|||
确保 `.HttpApi.Host` 是启动项目,运行应用程序后会在你的浏览器打开一个 **Swagger UI** 页面. |
|||
|
|||
 |
|||
|
|||
这里是Web应用程序使用的API应用程序. |
|||
|
|||
最后确保 `.Web` 是启动项目,运行应用程序后会在你的浏览器打开一个 **welcome** 页面. |
|||
|
|||
 |
|||
|
|||
点击 **login** 按钮重定向到 `Identity Server` 来登录应用程序. |
|||
|
|||
 |
|||
|
|||
{{ else }} |
|||
|
|||
最后确保 `.Web` 是启动项目,运行应用程序后会在你的浏览器打开一个 **login** 页面. |
|||
|
|||
> 在Visual Studio中使用Ctrl+F5(而不是F5)运行应用,如果你不用于调试,这会减少启动时间. |
|||
|
|||
 |
|||
|
|||
{{ end }} |
|||
|
|||
{{ else if UI != "MVC" }} |
|||
|
|||
#### 运行HTTP API Host (服务器端) |
|||
|
|||
{{ if Tiered == "Yes" }} |
|||
|
|||
确保 `.IdentityServer` 是启动项目,运行应用程序后会在你的浏览器打开一个 **login** 页面. |
|||
|
|||
> 在Visual Studio中使用Ctrl+F5(而不是F5)运行应用,如果你不用于调试,这会减少启动时间. |
|||
|
|||
你可以登录,但是不能在这里进入主应用程序,它仅是验证服务器. |
|||
|
|||
{{ end }} |
|||
|
|||
确保 `.HttpApi.Host` 是启动项目,运行应用程序后会在你的浏览器打开一个 **Swagger UI** 页面. |
|||
|
|||
{{ if Tiered == "No" }} |
|||
|
|||
> 在Visual Studio中使用Ctrl+F5(而不是F5)运行应用,如果你不用于调试,这会减少启动时间. |
|||
|
|||
{{ end }} |
|||
|
|||
 |
|||
|
|||
你可以看到应用程序的API并进行测试. 更多信息,请参阅[Swagger UI](https://swagger.io/tools/swagger-ui/). |
|||
|
|||
> ##### Swagger UI 授权 |
|||
> |
|||
> 大多数的HTTP API都需要身份验证和授权. 如果你要测试授权API, 请手动进入 `/Account/Login` 页面, 输入用户名: `admin` 和密码: `1q2w3E*` 登录到应用程序. 然后你可以访问授权API. |
|||
|
|||
{{ end }} |
|||
|
|||
{{ if UI == "NG" }} |
|||
#### 运行 Angular 应用程序 (客户端) |
|||
|
|||
在 `angular` 下打开命令行终端, 输入 `yarn` 命令(我们推荐使用[yarn](https://yarnpkg.com/)包管理, `npm install` 在大多数情况下也可以工作). |
|||
|
|||
```bash |
|||
yarn |
|||
``` |
|||
|
|||
等到所有node模块加载成功, 执行 `yarn start` (或 `npm start`) 命令: |
|||
|
|||
```bash |
|||
yarn start |
|||
``` |
|||
|
|||
等待 `Angular CLI` 使用 `BrowserSync` 启动 `Webpack` dev-server. |
|||
它会负责编译你的 `TypeScript`代码, 并自动重新加载浏览器. |
|||
完成后 `Angular Live Development Server` 会监听 localhost:4200. |
|||
打开你的浏览器并导航到[localhost:4200](http://localhost:4200/). |
|||
|
|||
 |
|||
|
|||
{{ end }} |
|||
|
|||
输入用户名 **admin**,密码 **1q2w3E*** 登录到应用程序,应用程序已经启动并执行,你可以基于此启动模板开始开发应用程序. |
|||
|
|||
#### 移动开发 |
|||
|
|||
当你创建一个新的应用程序时. 可以添加`-m react-native`选项以在解决方案中包含 `react-native`项目. 这是一个基础的[React Native](https://reactnative.dev/)启动模板,用于开发与基于ABP的后端集成的移动应用程序. |
|||
|
|||
|
|||
请参阅"[React Native入门](Getting-Started-React-Native.md)"文档了解如何配置和运行React Native应用程序. |
|||
|
|||
## 下一步是什么? |
|||
|
|||
[Web应用程序开发教程](Tutorials/Part-1.md) |
|||
1. [设置你的开发环境](Getting-Started-Setup-Environment.md) |
|||
2. [创建新的解决方案](Getting-Started-Create-Solution.md) |
|||
3. [运行解决方案](Getting-Started-Running-Solution.md) |
|||
@ -1 +1,173 @@ |
|||
TODO... |
|||
# 身份服务器模块 |
|||
|
|||
身份服务器模块提供了一个 [IdentityServer](https://github.com/IdentityServer/IdentityServer4) (IDS) 的完全集成,该框架提供高级身份验证功能,如单点登录和API访问控制.此模块将客户端,资源以及其他 IDS 相关的对象保存到数据库中. |
|||
|
|||
## 如何安装 |
|||
|
|||
当你使用 ABP 框架 [创建一个新的解决方案](https://abp.io/get-started) 时,此模块将被预安装(作为 NuGet/NPM 包).你可以继续用其作为包并轻松地获取更新,也可以将其源代码包含在解决方案中(请参阅 `get-source` [CLI](../CLI.md))以开发自定义模块. |
|||
|
|||
### 源代码 |
|||
|
|||
可以 [在此处](https://github.com/abpframework/abp/tree/dev/modules/identityserver) 访问源代码.源代码使用 [MIT](https://choosealicense.com/licenses/mit/) 许可,所以你可以免费使用和自定义它. |
|||
|
|||
## 用户界面 |
|||
|
|||
此模块使用了领域逻辑和数据库集成,但没有提供任何 UI.如果你需要动态添加客户端和资源, 管理 UI 是非常有用的.在这种情况下,你可以自己构建管理 UI,或者考虑购买为此模块提供了管理 UI 的 [ABP 商业版](https://commercial.abp.io/). |
|||
|
|||
## 与其他模块的关系 |
|||
|
|||
此模块基于 [身份模块](Identity.md) 并且[账户模块](Account.md) 有一个 [集成包](https://www.nuget.org/packages/Volo.Abp.Account.Web.IdentityServer). |
|||
|
|||
## 选项 |
|||
|
|||
### AbpIdentityServerBuilderOptions |
|||
|
|||
`AbpIdentityServerBuilderOptions` 在你的身份服务器 [模块](https://docs.abp.io/en/abp/latest/Module-Development-Basics) 中的 `PreConfigureServices` 方法中配置.例如: |
|||
|
|||
````csharp |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<AbpIdentityServerBuilderOptions>(builder => |
|||
{ |
|||
//Set options here... |
|||
}); |
|||
} |
|||
```` |
|||
|
|||
`AbpIdentityServerBuilderOptions` 属性: |
|||
|
|||
* `UpdateJwtSecurityTokenHandlerDefaultInboundClaimTypeMap` (默认值:true):更新 `JwtSecurityTokenHandler.DefaultInboundClaimTypeMap` 使其与身份服务器声明兼容. |
|||
* `UpdateAbpClaimTypes` (默认值:true):更新 `AbpClaimTypes` 与身份服务器声明兼容. |
|||
* `IntegrateToAspNetIdentity` (默认值:true):集成到 ASP.NET Identity. |
|||
* `AddDeveloperSigningCredential` (默认值:true):设置为 false 禁止调用 IIdentityServerBuilder 中的 `AddDeveloperSigningCredential()`. |
|||
|
|||
`IIdentityServerBuilder` 可以在你的身份服务器 [模块](https://docs.abp.io/en/abp/latest/Module-Development-Basics) 中的 `PreConfigureServices` 方法中配置.例如: |
|||
|
|||
````csharp |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<IIdentityServerBuilder>(builder => |
|||
{ |
|||
builder.AddSigningCredential(...); |
|||
}); |
|||
} |
|||
```` |
|||
|
|||
## 内部结构 |
|||
|
|||
### 领域层 |
|||
|
|||
#### 聚合 |
|||
|
|||
##### API 资源 |
|||
|
|||
需要 API 资源来允许客户端请求访问令牌. |
|||
|
|||
* `ApiResource` (聚合根):表示系统中的 API 资源. |
|||
* `ApiSecret` (集合):API 资源的密钥. |
|||
* `ApiScope` (集合):API 资源的作用域. |
|||
* `ApiResourceClaim` (集合):API 资源的声明. |
|||
|
|||
##### 客户端 |
|||
|
|||
客户端表示可以从你的身份服务器请求令牌的应用程序. |
|||
|
|||
* `Client` (聚合根):表示一个身份服务器的客户端应用程序. |
|||
* `ClientScope` (集合):客户端的作用域. |
|||
* `ClientSecret` (集合):客户端的密钥. |
|||
* `ClientGrantType` (集合):客户端的授权类型. |
|||
* `ClientCorsOrigin` (集合):客户端的 CORS 源. |
|||
* `ClientRedirectUri` (集合):客户端的重定向 URIs. |
|||
* `ClientPostLogoutRedirectUri` (集合):客户端的登出重定向 URIs. |
|||
* `ClientIdPRestriction` (集合):客户端的提供程序约束. |
|||
* `ClientClaim` (集合):客户端的声明. |
|||
* `ClientProperty` (集合):客户端的自定义属性. |
|||
|
|||
##### 持续化授权 |
|||
|
|||
持续化授权存储了授权码,刷新令牌和用户准许. |
|||
|
|||
* `PersistedGrant` (聚合根):表示为身份服务器持续化授权. |
|||
|
|||
##### 身份资源 |
|||
|
|||
身份资源是用户的用户 ID ,名称或邮件地址等数据. |
|||
|
|||
* `IdentityResource` (聚合根):表示与身份服务器的身份资源. |
|||
* `IdentityClaim` (集合):身份资源的声明. |
|||
|
|||
#### 仓储 |
|||
|
|||
为此模块定义了以下自定义仓储: |
|||
|
|||
* `IApiResourceRepository` |
|||
* `IClientRepository` |
|||
* `IPersistentGrantRepository` |
|||
* `IIdentityResourceRepository` |
|||
|
|||
#### 领域服务 |
|||
|
|||
此模块不包含任何领域服务,但重写了下面的服务; |
|||
|
|||
* `AbpProfileService` (当 `AbpIdentityServerBuilderOptions.IntegrateToAspNetIdentity` 为 true 时使用) |
|||
* `AbpClaimsService` |
|||
* `AbpCorsPolicyService` |
|||
|
|||
### 设置 |
|||
|
|||
此模块未定义任何设置. |
|||
|
|||
### 应用层 |
|||
|
|||
#### 应用服务 |
|||
|
|||
* `ApiResourceAppService` (实现 `IApiResourceAppService`):实现了 API 资源管理 UI 的用例. |
|||
* `IdentityServerClaimTypeAppService` (实现 `IIdentityServerClaimTypeAppService`):用于获取声明列表. |
|||
* `ApiResourceAppService` (实现 `IApiResourceAppService`):实现了 API 管理资源 UI 的用例. |
|||
* `IdentityResourceAppService` (实现 `IIdentityResourceAppService`):实现了身份资源管理 UI 的用例. |
|||
|
|||
### 数据库提供程序 |
|||
|
|||
#### 公共 |
|||
|
|||
##### 表/集合 前缀 & 架构 |
|||
|
|||
所有表/集合都使用 `IdentityServer` 作为默认前缀.如果你需要改变表的前缀或设置一个架构名称(如果你的数据库提供程序支持),请设置 `AbpIdentityServerDbProperties` 类的静态属性. |
|||
|
|||
##### 连接字符串 |
|||
|
|||
此模块使用 `AbpIdentityServer` 作为连接字符串的名称.如果你没有用这个名称定义连接字符串,它将回退到 `Default` 连接字符串. |
|||
|
|||
有关详细信息,请参阅 [连接字符串](https://docs.abp.io/en/abp/latest/Connection-Strings) 文档. |
|||
|
|||
#### EF Core |
|||
|
|||
##### 表 |
|||
|
|||
* **IdentityServerApiResources** |
|||
* IdentityServerApiSecrets |
|||
* IdentityServerApiScopes |
|||
* IdentityServerApiScopeClaims |
|||
* IdentityServerApiClaims |
|||
* **IdentityServerClients** |
|||
* IdentityServerClientScopes |
|||
* IdentityServerClientSecrets |
|||
* IdentityServerClientGrantTypes |
|||
* IdentityServerClientCorsOrigins |
|||
* IdentityServerClientRedirectUris |
|||
* IdentityServerClientPostLogoutRedirectUris |
|||
* IdentityServerClientIdPRestrictions |
|||
* IdentityServerClientClaims |
|||
* IdentityServerClientProperties |
|||
* **IdentityServerPersistedGrants** |
|||
* **IdentityServerIdentityResources** |
|||
* IdentityServerIdentityClaims |
|||
|
|||
#### MongoDB |
|||
|
|||
##### 集合 |
|||
|
|||
* **IdentityServerApiResources** |
|||
* **IdentityServerClients** |
|||
* **IdentityServerPersistedGrants** |
|||
* **IdentityServerIdentityResources** |
|||
|
|||
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 41 KiB |
@ -1,7 +1,12 @@ |
|||
// This file is part of AbpApplicationConfigurationClientProxy, you can customize it here
|
|||
// ReSharper disable once CheckNamespace
|
|||
|
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClientProxies; |
|||
|
|||
[RemoteService(false)] |
|||
[DisableConventionalRegistration] |
|||
public partial class AbpApplicationConfigurationClientProxy |
|||
{ |
|||
} |
|||
|
|||
@ -1,7 +1,14 @@ |
|||
// This file is part of AbpTenantClientProxy, you can customize it here
|
|||
// ReSharper disable once CheckNamespace
|
|||
|
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Pages.Abp.MultiTenancy.ClientProxies; |
|||
|
|||
[RemoteService(false)] |
|||
[DisableConventionalRegistration] |
|||
public partial class AbpTenantClientProxy |
|||
{ |
|||
} |
|||
|
|||
|
|||