├── .gitignore ├── .travis.yml ├── LICENSE ├── NuGet.config ├── README.md ├── appveyor.yml ├── build.cmd ├── build.ps1 ├── build.sh ├── dotNETCore-Extensions.sln └── src ├── Pomelo.Algorithm.Geography ├── Edge.cs ├── Line.cs ├── Point.cs ├── PointType.cs ├── PolyLine.cs ├── Polygon.cs ├── Pomelo.Algorithm.Geography.csproj └── Properties │ └── AssemblyInfo.cs ├── Pomelo.AntiXss ├── AntiXSS.cs ├── DefaultTagAuthorizationProvider.cs ├── DefaultWhiteListProvider.cs ├── ITagAuthorizationProvider.cs ├── IWhiteListProvider.cs ├── Pomelo.AntiXss.csproj ├── Properties │ └── AssemblyInfo.cs └── lib │ ├── AntiXSS.cs │ ├── CodeCharts.cs │ ├── CodeCharts │ ├── CodeChartHelper.cs │ ├── Lower.cs │ ├── LowerMiddle.cs │ ├── Middle.cs │ ├── Upper.cs │ └── UpperMiddle.cs │ ├── CssEncoder.cs │ ├── Encoder.cs │ ├── EncoderUtil.cs │ ├── GlobalSuppressions.cs │ ├── HtmlParameterEncoder.cs │ ├── Lazy.cs │ ├── LdapEncoder.cs │ ├── SafeList.cs │ ├── UnicodeCharacterEncoder.cs │ ├── UriUtil.cs │ ├── UrlEncoder.cs │ └── Utf16StringReader.cs ├── Pomelo.AspNetCore.AntiXSS ├── AntiXss.cs ├── EntityFramework │ ├── AntiXSSModelBuilderExtensions.cs │ ├── EntityFrameworkTagAuthorizationProvider.cs │ ├── EntityFrameworkWhiteListProvider.cs │ ├── IAntiXSSDbContext.cs │ ├── WhiteListAttribute.cs │ └── WhiteListTag.cs ├── FilterXSSAttribute.cs ├── Json │ ├── JsonTagAuthorizationProvider.cs │ └── JsonWhiteListProvider.cs ├── Pomelo.AspNetCore.AntiXSS.csproj └── Properties │ └── AssemblyInfo.cs ├── Pomelo.AspNetCore.Common ├── HttpContextAccessorExtensions.cs ├── Pomelo.AspNetCore.Common.csproj └── Properties │ └── AssemblyInfo.cs ├── Pomelo.AspNetCore.Extensions ├── Attributes │ ├── Claims.cs │ └── InjectAttribute.cs ├── BlobStorage │ ├── BlobStorageBuilder.cs │ ├── BlobStorageServiceCollectionExtensions.cs │ ├── EFBlobStorageProvider.cs │ ├── IBlobAccessAuthorizationProvider.cs │ ├── IBlobHander.cs │ ├── IBlobStorageBuilder.cs │ ├── IBlobStorageProvider.cs │ ├── IBlobUploadAuthorizationProvider.cs │ ├── Middlewares │ │ └── BlobStorage.cs │ ├── Models │ │ ├── Blob.cs │ │ ├── Blob`1.cs │ │ ├── IFileDbContext.cs │ │ └── ModelBuilderExtensions.cs │ ├── SignedUserDownloadAuthorizationProvider.cs │ └── SignedUserUploadAuthorizationProvider.cs ├── Controllers │ ├── AjaxPagedView.cs │ ├── AjaxPagedViewWithViewModel.cs │ ├── AutoAjaxExtensions.cs │ ├── BaseController.cs │ ├── BaseControllerWithEF.cs │ ├── BaseControllerWithIdentity.cs │ ├── IConvertible.cs │ ├── PagedJson.cs │ ├── PagedJsonWIthViewModel.cs │ ├── PagedView.cs │ ├── PagedViewWithViewModel.cs │ ├── Paging.cs │ ├── Prompt.cs │ ├── PromptMessage.cs │ ├── RenderSvg.cs │ └── RenderXls.cs ├── Others │ ├── AesCryptoExtensions.cs │ ├── ConfigurationExtensions.cs │ ├── FormFileExtensions.cs │ ├── HtmlContentExtensions.cs │ ├── Marked.cs │ └── SmtpEmailSenderExtensions.cs ├── Pomelo.AspNetCore.Extensions.csproj ├── Properties │ └── AssemblyInfo.cs ├── SmartCookies │ ├── SmartCookies.cs │ └── SmartCookiesExtensions.cs ├── SmartUser │ ├── SmartUser.cs │ ├── SmartUserClaimsExtensions.cs │ ├── SmartUserExtensions.cs │ └── UserManagerExtensions.cs └── Template │ ├── CookieRequestTemplateProvider.cs │ ├── IRequestTemplateProvider.cs │ ├── QueryStringRequestTemplateProvider.cs │ ├── Template.cs │ ├── TemplateCollection.cs │ ├── TemplateEngine.cs │ ├── TemplateExtension.cs │ ├── TemplateHtmlHelper.cs │ └── TemplateInfo.cs ├── Pomelo.AspNetCore.Localization ├── Attributes │ └── LocalizedAttribute.cs ├── BaiduTranslator.cs ├── DefaultCultureProvider.cs ├── DefaultStringReader.cs ├── DefaultTranslatorDisabler.cs ├── Extensions │ ├── HtmlHelperExtensions.cs │ └── ServiceCollectionExtensions.cs ├── Filters │ ├── DbContextModelBindingFilter.cs │ └── LocalizationFilter.cs ├── ICultureProvider.cs ├── ICultureSet.cs ├── ILocalizedStringStore.cs ├── IStringReader.cs ├── ITranslatedCaching.cs ├── ITranslator.cs ├── ITranslatorDisabler.cs ├── JsonLocalizedStringStore.cs ├── Listeners │ └── LocalizationEntityStateListener.cs ├── MemoryCultureSet.cs ├── MemoryTranslatedCaching.cs ├── Middlewares │ └── FrontendLocalizer.cs ├── NonTranslator.cs ├── Pomelo.AspNetCore.Localization.csproj └── Properties │ └── AssemblyInfo.cs ├── Pomelo.AspNetCore.ReverseProxy ├── FormFileExtensions.cs ├── Pomelo.AspNetCore.ReverseProxy.csproj ├── Properties │ └── AssemblyInfo.cs └── ReverseProxy.cs ├── Pomelo.AspNetCore.Statistics ├── Browser.cs ├── IGeolocationProvider.cs ├── IpInformation.cs ├── Middlewares │ └── StatisticsMiddleware.cs ├── OperateSystem.cs ├── Pomelo.AspNetCore.Statistics.csproj ├── PomeloGeolocationProvider.cs ├── Properties │ └── AssemblyInfo.cs ├── RequestLog.cs └── UserAgentHelper.cs ├── Pomelo.AspNetCore.TimedJob ├── DynamicTimedJob.cs ├── EntityFramework │ ├── EntityFrameworkDynamicTimedJobProvider.cs │ ├── EntityFrameworkDynamicTimedJobServiceBuilderExtensions.cs │ ├── ITimedJobContext.cs │ ├── TimedJob.cs │ └── TimedJobDbContextExtensions.cs ├── Extensions │ └── TimedJobExtensions.cs ├── IDynamicTimedJobProvider.cs ├── Job.cs ├── Jobs │ ├── DefaultAssemblyLocator.cs │ └── IAssemblyLocator.cs ├── Pomelo.AspNetCore.TimedJob.csproj ├── Properties │ └── AssemblyInfo.cs ├── Schema │ ├── InvokeAttribute.cs │ └── NonJobAttribute.cs └── TimedJobService.cs ├── Pomelo.Data.Excel ├── ExcelStream.cs ├── ExcelStreamBase.cs ├── ExcelStreamReader.cs ├── Infrastructure │ ├── ColNumber.cs │ ├── Header.cs │ ├── Row.cs │ ├── SharedStrings.cs │ ├── Sheet.cs │ ├── SheetHDR.cs │ ├── SheetReader.cs │ ├── SheetWithoutHDR.cs │ └── WorkBook.cs ├── Interface │ ├── IExceStreamlReader.cs │ └── IExcelStream.cs ├── NewExcel.cs ├── Pomelo.Data.Excel.csproj └── Properties │ └── AssemblyInfo.cs ├── Pomelo.Extensions.Caching ├── DistributedCacheExtensions.cs ├── Pomelo.Extensions.Caching.csproj └── Properties │ └── AssemblyInfo.cs ├── Pomelo.Extensions.Common ├── AesCrypto.cs ├── Base64StringFile.cs ├── DateTimeExtensions.cs ├── Download.cs ├── EnumerableExtensions.cs ├── GitClone.cs ├── Image.cs ├── ListExtensions.cs ├── MediaFile.cs ├── MediaHelper.cs ├── OSType.cs ├── Pomelo.Extensions.Common.csproj ├── Properties │ └── AssemblyInfo.cs ├── String.cs ├── Unzip.cs ├── Video.cs ├── VideoInfo.cs └── Zip.cs ├── Pomelo.Extensions.RuntimeEnvironment.Sources ├── Native │ ├── NativeMethods.Windows.cs │ └── PlatformApis.cs ├── Pomelo.Extensions.RuntimeEnvironment.Sources.csproj └── RuntimeEnvironment.cs ├── Pomelo.Extensions ├── Pomelo.Extensions.csproj └── Properties │ └── AssemblyInfo.cs ├── Pomelo.HtmlAgilityPack ├── EncodingFoundException.cs ├── HtmlAttribute.cs ├── HtmlAttributeCollection.cs ├── HtmlCmdLine.cs ├── HtmlCommentNode.cs ├── HtmlConsoleListener.cs ├── HtmlDocument.PathMethods.cs ├── HtmlDocument.Xpath.cs ├── HtmlDocument.cs ├── HtmlElementFlag.cs ├── HtmlEntity.cs ├── HtmlNameTable.cs ├── HtmlNode.Xpath.cs ├── HtmlNode.cs ├── HtmlNodeCollection.cs ├── HtmlNodeNavigator.cs ├── HtmlNodeType.cs ├── HtmlParseError.cs ├── HtmlParseErrorCode.cs ├── HtmlTextNode.cs ├── HtmlWeb.Xpath.cs ├── HtmlWeb.cs ├── HtmlWebException.cs ├── IOLibrary.cs ├── MixedCodeDocument.cs ├── MixedCodeDocumentCodeFragment.cs ├── MixedCodeDocumentFragment.cs ├── MixedCodeDocumentFragmentList.cs ├── MixedCodeDocumentFragmentType.cs ├── MixedCodeDocumentTextFragment.cs ├── NameValuePair.cs ├── NameValuePairList.cs ├── Pomelo.HtmlAgilityPack.csproj ├── Properties │ └── AssemblyInfo.cs ├── Trace.FullFramework.cs ├── Trace.cs ├── Utilities.cs └── crc32.cs ├── Pomelo.Marked ├── BlockRules.cs ├── InlineLexer.cs ├── InlineRules.cs ├── Lexer.cs ├── Marked.cs ├── Objects.cs ├── Options.cs ├── Parser.cs ├── Pomelo.Marked.csproj ├── Properties │ └── AssemblyInfo.cs ├── Renderer.cs ├── StringHelper.cs ├── Token.cs └── TokensResult.cs └── Pomelo.Net.Smtp ├── Attachment.cs ├── EmailSender.cs ├── HtmlHelper.cs ├── IEmailSender.cs ├── Pomelo.Net.Smtp.csproj ├── Properties └── AssemblyInfo.cs └── SmtpEmailSender.cs /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | sudo: required 3 | dist: trusty 4 | addons: 5 | apt: 6 | packages: 7 | - gettext 8 | - libcurl4-openssl-dev 9 | - libicu-dev 10 | - libssl-dev 11 | - libunwind8 12 | - zlib1g 13 | mono: 14 | - 4.0.5 15 | os: 16 | - linux 17 | - osx 18 | osx_image: xcode7.1 19 | branches: 20 | only: 21 | - master 22 | - release 23 | - dev 24 | - /^(.*\/)?ci-.*$/ 25 | script: 26 | - ./build.sh --quiet verify 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Pomelo Foundation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dotNETCore-Extensions -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | init: 2 | - git config --global core.autocrlf true 3 | branches: 4 | only: 5 | - master 6 | - release 7 | - dev 8 | - /^(.*\/)?ci-.*$/ 9 | build_script: 10 | - build.cmd --quiet verify 11 | clone_depth: 1 12 | test: off 13 | deploy: off -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*; exit $LASTEXITCODE" -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = "Stop" 2 | 3 | function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries) 4 | { 5 | while($true) 6 | { 7 | try 8 | { 9 | Invoke-WebRequest $url -OutFile $downloadLocation 10 | break 11 | } 12 | catch 13 | { 14 | $exceptionMessage = $_.Exception.Message 15 | Write-Host "Failed to download '$url': $exceptionMessage" 16 | if ($retries -gt 0) { 17 | $retries-- 18 | Write-Host "Waiting 10 seconds before retrying. Retries left: $retries" 19 | Start-Sleep -Seconds 10 20 | 21 | } 22 | else 23 | { 24 | $exception = $_.Exception 25 | throw $exception 26 | } 27 | } 28 | } 29 | } 30 | 31 | cd $PSScriptRoot 32 | 33 | $repoFolder = $PSScriptRoot 34 | $env:REPO_FOLDER = $repoFolder 35 | 36 | $koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0-preview2.zip" 37 | if ($env:KOREBUILD_ZIP) 38 | { 39 | $koreBuildZip=$env:KOREBUILD_ZIP 40 | } 41 | 42 | $buildFolder = ".build" 43 | $buildFile="$buildFolder\KoreBuild.ps1" 44 | 45 | if (!(Test-Path $buildFolder)) { 46 | Write-Host "Downloading KoreBuild from $koreBuildZip" 47 | 48 | $tempFolder=$env:TEMP + "\KoreBuild-" + [guid]::NewGuid() 49 | New-Item -Path "$tempFolder" -Type directory | Out-Null 50 | 51 | $localZipFile="$tempFolder\korebuild.zip" 52 | 53 | DownloadWithRetry -url $koreBuildZip -downloadLocation $localZipFile -retries 6 54 | 55 | Add-Type -AssemblyName System.IO.Compression.FileSystem 56 | [System.IO.Compression.ZipFile]::ExtractToDirectory($localZipFile, $tempFolder) 57 | 58 | New-Item -Path "$buildFolder" -Type directory | Out-Null 59 | copy-item "$tempFolder\**\build\*" $buildFolder -Recurse 60 | 61 | # Cleanup 62 | if (Test-Path $tempFolder) { 63 | Remove-Item -Recurse -Force $tempFolder 64 | } 65 | } 66 | 67 | &"$buildFile" @args -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | cd $repoFolder 4 | 5 | koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0-preview2.zip" 6 | if [ ! -z $KOREBUILD_ZIP ]; then 7 | koreBuildZip=$KOREBUILD_ZIP 8 | fi 9 | 10 | buildFolder=".build" 11 | buildFile="$buildFolder/KoreBuild.sh" 12 | 13 | if test ! -d $buildFolder; then 14 | echo "Downloading KoreBuild from $koreBuildZip" 15 | 16 | tempFolder="/tmp/KoreBuild-$(uuidgen)" 17 | mkdir $tempFolder 18 | 19 | localZipFile="$tempFolder/korebuild.zip" 20 | 21 | retries=6 22 | until (wget -O $localZipFile $koreBuildZip 2>/dev/null || curl -o $localZipFile --location $koreBuildZip 2>/dev/null) 23 | do 24 | echo "Failed to download '$koreBuildZip'" 25 | if [ "$retries" -le 0 ]; then 26 | exit 1 27 | fi 28 | retries=$((retries - 1)) 29 | echo "Waiting 10 seconds before retrying. Retries left: $retries" 30 | sleep 10s 31 | done 32 | 33 | unzip -q -d $tempFolder $localZipFile 34 | 35 | mkdir $buildFolder 36 | cp -r $tempFolder/**/build/** $buildFolder 37 | 38 | chmod +x $buildFile 39 | 40 | # Cleanup 41 | if test -d $tempFolder; then 42 | rm -rf $tempFolder 43 | fi 44 | fi 45 | 46 | $buildFile -r $repoFolder "$@" -------------------------------------------------------------------------------- /src/Pomelo.Algorithm.Geography/Edge.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace System 7 | { 8 | public class Edge 9 | { 10 | public double MinX { get; set; } 11 | public double MaxX { get; set; } 12 | public double MinY { get; set; } 13 | public double MaxY { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Pomelo.Algorithm.Geography/Line.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace System 7 | { 8 | public class Line 9 | { 10 | public Point Begin { get; set; } 11 | public Point End { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Pomelo.Algorithm.Geography/PointType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace System 7 | { 8 | public enum PointType 9 | { 10 | None, 11 | WGS, 12 | GCJ, 13 | Baidu 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Pomelo.Algorithm.Geography/PolyLine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace System 7 | { 8 | public class PolyLine : List 9 | { 10 | public PolyLine() 11 | { 12 | } 13 | 14 | public PolyLine(ICollection pts) 15 | { 16 | this.AddRange(pts); 17 | ConvertPoints(); 18 | } 19 | 20 | public double Circumference 21 | { 22 | get 23 | { 24 | ConvertPoints(); 25 | double c = 0; 26 | for (var i = 0; i < this.Count - 1; i++) 27 | c += this[i].GetDistance(this[i + 1]); 28 | return c; 29 | } 30 | } 31 | 32 | private void ConvertPoints() 33 | { 34 | if (this.Count > 0) 35 | { 36 | var first = this.First(); 37 | for (var i = 0; i < this.Count; i++) 38 | { 39 | if (this[i].Type != first.Type) 40 | { 41 | if (first.Type == PointType.None) 42 | throw new NotSupportedException($"不支持{this[i].Type}与{first.Type}混合构成折线"); 43 | else if (first.Type == PointType.WGS) 44 | this[i] = this[i].ToWgsPoint(); 45 | else if (first.Type == PointType.GCJ) 46 | this[i] = this[i].ToGcjPoint(); 47 | else 48 | this[i] = this[i].ToBaiduPoint(); 49 | } 50 | } 51 | } 52 | } 53 | 54 | public Point Begin { get { return this.First(); } } 55 | public Point End { get { return this.Last(); } } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Pomelo.Algorithm.Geography/Pomelo.Algorithm.Geography.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.Algorithm.Geography 7 | Pomelo.Algorithm.Geography 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Pomelo.Algorithm.Geography/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.Algorithm.Geography")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("cd0cc8e5-4e99-4187-9ed0-f29ffced89e1")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.AntiXss/DefaultTagAuthorizationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AntiXSS 7 | { 8 | public class DefaultTagAuthorizationProvider : ITagAuthorizationProvider 9 | { 10 | public bool IsAbleToUse(string tag, object UserId = null) 11 | { 12 | return true; 13 | } 14 | public bool IsAbleToUse(string tag, string attribute, object UserId = null) 15 | { 16 | return true; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Pomelo.AntiXss/ITagAuthorizationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AntiXSS 7 | { 8 | public interface ITagAuthorizationProvider 9 | { 10 | bool IsAbleToUse(string tag, object UserId = null); 11 | 12 | bool IsAbleToUse(string tag, string attribute, object UserId = null); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Pomelo.AntiXss/IWhiteListProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AntiXSS 7 | { 8 | public interface IWhiteListProvider 9 | { 10 | IDictionary WhiteList { get; } 11 | 12 | void Refresh(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Pomelo.AntiXss/Pomelo.AntiXss.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.AntiXss 7 | Pomelo.AntiXss 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Pomelo.AntiXss/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.AntiXSS")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("dc98679b-223f-4548-9432-873f4e83cc40")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.AntiXss/lib/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) 2008, 2009, 2010 All Rights Reserved, Microsoft Corporation 4 | // 5 | // This source is subject to the Microsoft Permissive License. 6 | // Please see the License.txt file for more information. 7 | // All other rights reserved. 8 | // 9 | // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 10 | // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 11 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 12 | // PARTICULAR PURPOSE. 13 | // 14 | // 15 | // Global FXCop supressions. 16 | // 17 | // -------------------------------------------------------------------------------------------------------------------- 18 | 19 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.AntiXSS/EntityFramework/AntiXSSModelBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace Pomelo.AspNetCore.AntiXSS.EntityFramework 8 | { 9 | public static class AntiXSSModelBuilderExtensions 10 | { 11 | public static ModelBuilder SetupAntiXSS(this ModelBuilder self) 12 | { 13 | return self.Entity(e => 14 | { 15 | e.HasKey(x => x.Id); 16 | }); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.AntiXSS/EntityFramework/EntityFrameworkWhiteListProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.EntityFrameworkCore; 6 | using Pomelo.AntiXSS; 7 | 8 | namespace Pomelo.AspNetCore.AntiXSS.EntityFramework 9 | { 10 | public class EntityFrameworkWhiteListProvider : IWhiteListProvider 11 | where TContext : IAntiXSSDbContext 12 | { 13 | private TContext DB { get; set; } 14 | 15 | private Dictionary whiteList { get; set; } 16 | 17 | public EntityFrameworkWhiteListProvider(TContext db) 18 | { 19 | DB = db; 20 | } 21 | 22 | public IDictionary WhiteList 23 | { 24 | get 25 | { 26 | if (whiteList == null) 27 | whiteList = DB.WhiteListTags 28 | .Include(x => x.Attributes) 29 | .ToList() 30 | .ToDictionary(x => x.Id, x => x.Attributes 31 | .ToList() 32 | .Select(y => y.Attribute) 33 | .ToArray()); 34 | return whiteList; 35 | } 36 | } 37 | 38 | public void Refresh() 39 | { 40 | whiteList = null; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.AntiXSS/EntityFramework/IAntiXSSDbContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace Pomelo.AspNetCore.AntiXSS.EntityFramework 8 | { 9 | public interface IAntiXSSDbContext 10 | { 11 | DbSet WhiteListTags { get; set; } 12 | DbSet WhiteListAttributes { get; set; } 13 | 14 | int SaveChanges(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.AntiXSS/EntityFramework/WhiteListAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | 8 | namespace Pomelo.AspNetCore.AntiXSS.EntityFramework 9 | { 10 | public class WhiteListAttribute 11 | { 12 | public Guid Id { get; set; } 13 | 14 | [MaxLength(64)] 15 | public string Attribute { get; set; } 16 | 17 | [MaxLength(128)] 18 | public string RoleRequired { get; set; } 19 | 20 | [MaxLength(64)] 21 | [ForeignKey("Tag")] 22 | public string TagId { get; set; } 23 | 24 | public virtual WhiteListTag Tag { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.AntiXSS/EntityFramework/WhiteListTag.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using Newtonsoft.Json; 6 | 7 | namespace Pomelo.AspNetCore.AntiXSS.EntityFramework 8 | { 9 | public class WhiteListTag 10 | { 11 | [MaxLength(64)] 12 | public string Id { get; set; } 13 | 14 | [MaxLength(128)] 15 | public string RoleRequired { get; set; } 16 | 17 | public virtual ICollection Attributes { get; set; } = new List(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.AntiXSS/FilterXSSAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.Extensions.Internal; 6 | using Microsoft.AspNetCore.Mvc.Filters; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using Pomelo.AntiXSS; 9 | 10 | namespace Microsoft.AspNetCore.Mvc 11 | { 12 | public class FilterXSSAttribute : ActionFilterAttribute 13 | { 14 | public FilterXSSAttribute() { } 15 | 16 | public override void OnActionExecuting(ActionExecutingContext context) 17 | { 18 | var qs = WebUtilities.QueryHelpers.ParseQuery(context.HttpContext.Request.QueryString.ToUriComponent()); 19 | var ret = new Http.QueryString(); 20 | var AntiXss = context.HttpContext.RequestServices.GetRequiredService(); 21 | foreach (var k in qs.Keys) 22 | { 23 | for (var i = 0; i < qs[k].Count(); i++) 24 | { 25 | try 26 | { 27 | ret.Add(k, AntiXss.Sanitize(qs[k][i])); 28 | } 29 | catch 30 | { 31 | ret.Add(k, qs[k][i]); 32 | } 33 | } 34 | } 35 | context.HttpContext.Request.QueryString = ret; 36 | base.OnActionExecuting(context); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.AntiXSS/Pomelo.AspNetCore.AntiXSS.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.AspNetCore.AntiXSS 7 | Pomelo.AspNetCore.AntiXSS 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.AntiXSS/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.AspNetCore.AntiXSS")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("d7dc4d44-d948-4466-8cc0-18cb2f8b1e37")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Common/HttpContextAccessorExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Microsoft.AspNetCore.Http; 3 | using Microsoft.AspNetCore.Mvc.Infrastructure; 4 | 5 | namespace Microsoft.Extensions.DependencyInjection 6 | { 7 | public static class HttpContextAccessorExtensions 8 | { 9 | public static IServiceCollection AddContextAccessor(this IServiceCollection self) 10 | { 11 | if (self.Count(x => x.ServiceType == typeof(IHttpContextAccessor)) == 0) 12 | self.AddSingleton(); 13 | 14 | if (self.Count(x => x.ServiceType == typeof(IActionContextAccessor)) == 0) 15 | self.AddSingleton(); 16 | 17 | return self; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Common/Pomelo.AspNetCore.Common.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.AspNetCore.Common 7 | Pomelo.AspNetCore.Common 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Common/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.AspNetCore.Common")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("cac5d089-c25c-4b70-b98d-623da7b48d7d")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Attributes/InjectAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.Mvc.ModelBinding; 3 | 4 | namespace Microsoft.AspNetCore.Mvc 5 | { 6 | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] 7 | public class InjectAttribute : Attribute, IBindingSourceMetadata 8 | { 9 | /// 10 | public BindingSource BindingSource => BindingSource.Services; 11 | } 12 | } -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/BlobStorageBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Microsoft.Extensions.DependencyInjection 7 | { 8 | public class BlobStorageBuilder : IBlobStorageBuilder 9 | { 10 | public IServiceCollection Services { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/BlobStorageServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Pomelo.AspNetCore.Extensions.BlobStorage; 6 | 7 | namespace Microsoft.Extensions.DependencyInjection 8 | { 9 | public static class BlobServiceCollectionExtensions 10 | { 11 | public static IBlobStorageBuilder AddBlobStorage(this IServiceCollection self) 12 | { 13 | self.AddContextAccessor(); 14 | var builder = new BlobStorageBuilder(); 15 | builder.Services = self.AddRouting(); 16 | return builder; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/IBlobAccessAuthorizationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.Extensions.BlobStorage 7 | { 8 | public interface IBlobAccessAuthorizationProvider 9 | where TKey : IEquatable 10 | { 11 | bool IsAbleToDownload(TKey BlobId); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/IBlobHander.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Pomelo.AspNetCore.Extensions.BlobStorage 4 | { 5 | public interface IBlobHandler 6 | where TKey : IEquatable 7 | where TModel : Models.Blob 8 | { 9 | TModel Handle(TModel obj, Base64StringFile file); 10 | } 11 | 12 | public interface IBlobHandler : IBlobHandler 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/IBlobStorageBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Microsoft.Extensions.DependencyInjection 7 | { 8 | public interface IBlobStorageBuilder 9 | { 10 | IServiceCollection Services { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/IBlobStorageProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Pomelo.AspNetCore.Extensions.BlobStorage 4 | { 5 | public interface IBlobStorageProvider 6 | where TKey : IEquatable 7 | where TModel : Models.Blob 8 | { 9 | TModel Get(TKey id); 10 | void Delete(TKey id); 11 | TKey Set(TModel blob); 12 | } 13 | 14 | public interface IBlobStorageProvider : IBlobStorageProvider 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/IBlobUploadAuthorizationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.Extensions.BlobStorage 7 | { 8 | public interface IBlobUploadAuthorizationProvider 9 | { 10 | bool IsAbleToUpload(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/Models/Blob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations; 3 | using Newtonsoft.Json; 4 | 5 | namespace Pomelo.AspNetCore.Extensions.BlobStorage.Models 6 | { 7 | public class Blob : Blob 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/Models/Blob`1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations; 3 | using Newtonsoft.Json; 4 | 5 | namespace Pomelo.AspNetCore.Extensions.BlobStorage.Models 6 | { 7 | public class Blob 8 | where TKey : IEquatable 9 | { 10 | public TKey Id { get; set; } 11 | 12 | [MaxLength(128)] 13 | public string FileName { get; set; } 14 | 15 | [MaxLength(128)] 16 | public string ContentType { get; set; } 17 | 18 | public long ContentLength { get; set; } 19 | 20 | public DateTime Time { get; set; } 21 | 22 | [JsonIgnore] 23 | public byte[] Bytes { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/Models/IFileDbContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Pomelo.AspNetCore.Extensions.BlobStorage.Models; 3 | 4 | namespace Microsoft.EntityFrameworkCore 5 | { 6 | public interface IBlobStorageDbContext 7 | where TKey: IEquatable 8 | where TModel : Blob 9 | { 10 | DbSet Blobs { get; set; } 11 | int SaveChanges(); 12 | } 13 | 14 | public interface IBlobStorageDbContext : IBlobStorageDbContext 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/Models/ModelBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace Pomelo.AspNetCore.Extensions.BlobStorage.Models 8 | { 9 | public static class ModelBuilderExtensions 10 | { 11 | public static ModelBuilder SetupBlobStorage(this ModelBuilder self) 12 | where TKey : IEquatable 13 | where TModel : Blob 14 | { 15 | return self.Entity(e => 16 | { 17 | e.HasIndex(x => x.Time); 18 | e.HasIndex(x => x.FileName); 19 | }); 20 | } 21 | 22 | public static ModelBuilder SetupBlobStorage(this ModelBuilder self) 23 | where TKey : IEquatable 24 | { 25 | return self.SetupBlobStorage, TKey>(); 26 | } 27 | 28 | public static ModelBuilder SetupBlobStorage(this ModelBuilder self) 29 | { 30 | return self.SetupBlobStorage(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/SignedUserDownloadAuthorizationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | using Pomelo.AspNetCore.Extensions.BlobStorage; 7 | 8 | namespace Pomelo.AspNetCore.Extensions.BlobStorage 9 | { 10 | public class SignedUserDownloadAuthorizationProvider : IBlobAccessAuthorizationProvider 11 | where TKey : IEquatable 12 | { 13 | protected HttpContext httpContext { get; set; } 14 | 15 | public SignedUserDownloadAuthorizationProvider(IHttpContextAccessor accessor) 16 | { 17 | httpContext = accessor.HttpContext; 18 | } 19 | 20 | public bool IsAbleToDownload(TKey BlobId) 21 | { 22 | return httpContext.User.Identities.Count() > 0; 23 | } 24 | } 25 | } 26 | 27 | namespace Microsoft.Extensions.DependencyInjection 28 | { 29 | public static class SignedUserAccessAuthorizationProviderServiceCollectionExtensions 30 | { 31 | public static IBlobStorageBuilder AddSignedUserDownloadAuthorization(this IBlobStorageBuilder self) 32 | where TKey : IEquatable 33 | { 34 | self.Services.AddSingleton, SignedUserDownloadAuthorizationProvider>(); 35 | return self; 36 | } 37 | 38 | public static IBlobStorageBuilder AddSignedUserDownloadAuthorization(this IBlobStorageBuilder self) 39 | { 40 | self.Services.AddSingleton, SignedUserDownloadAuthorizationProvider>(); 41 | return self; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/BlobStorage/SignedUserUploadAuthorizationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.AspNetCore.Http; 4 | using Pomelo.AspNetCore.Extensions.BlobStorage; 5 | 6 | namespace Pomelo.AspNetCore.Extensions.BlobStorage 7 | { 8 | public class SignedUserUploadAuthorizationProvider : IBlobUploadAuthorizationProvider 9 | { 10 | protected HttpContext httpContext { get; set; } 11 | 12 | public SignedUserUploadAuthorizationProvider (IHttpContextAccessor accessor) 13 | { 14 | httpContext = accessor.HttpContext; 15 | } 16 | 17 | public bool IsAbleToUpload() 18 | { 19 | return httpContext.User.Identities.Count() > 0; 20 | } 21 | } 22 | } 23 | 24 | namespace Microsoft.Extensions.DependencyInjection 25 | { 26 | public static class SignedUserUploadAuthorizationProviderServiceCollectionExtensions 27 | { 28 | public static IBlobStorageBuilder AddSignedUserUploadAuthorization(this IBlobStorageBuilder self) 29 | { 30 | self.Services.AddSingleton(); 31 | return self; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Controllers/BaseController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.AspNetCore.Mvc.Filters; 8 | using Microsoft.AspNetCore.Hosting; 9 | 10 | namespace Microsoft.AspNetCore.Mvc 11 | { 12 | public abstract partial class BaseController : Controller 13 | { 14 | public string AppRoot { get { return HttpContext.RequestServices?.GetService().ContentRootPath; } } 15 | 16 | public string WebRoot { get { return HttpContext.RequestServices?.GetService().WebRootPath; } } 17 | 18 | public IConfiguration Configuration { get { return HttpContext.RequestServices?.GetService(); } } 19 | 20 | public Http.SmartCookies Cookies { get { return HttpContext.RequestServices?.GetService(); } } 21 | 22 | public TemplateManager TemplateManager { get { return HttpContext.RequestServices?.GetService(); } } 23 | 24 | public Pomelo.AspNetCore.Extensions.Others.Marked Marked { get; set; } = new Pomelo.AspNetCore.Extensions.Others.Marked(); 25 | 26 | public Pomelo.AspNetCore.Localization.IStringReader SR { get { return HttpContext.RequestServices?.GetService(); } } 27 | 28 | public override void OnActionExecuting(ActionExecutingContext context) 29 | { 30 | Prepare(); 31 | base.OnActionExecuting(context); 32 | } 33 | 34 | public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) 35 | { 36 | Prepare(); 37 | return base.OnActionExecutionAsync(context, next); 38 | } 39 | 40 | public virtual void Prepare() 41 | { 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Controllers/BaseControllerWithEF.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Microsoft.AspNetCore.Mvc 7 | { 8 | public abstract class BaseController : BaseController 9 | { 10 | [Inject] 11 | public virtual TContext DB { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Controllers/BaseControllerWithIdentity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Identity; 6 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 7 | using Microsoft.Extensions.DependencyInjection; 8 | 9 | namespace Microsoft.AspNetCore.Mvc 10 | { 11 | public abstract class BaseController : BaseController 12 | where TKey : IEquatable 13 | where TUser : IdentityUser 14 | { 15 | public UserManager UserManager { get { return HttpContext.RequestServices?.GetService>(); } } 16 | 17 | public SignInManager SignInManager { get { return HttpContext.RequestServices?.GetService>(); } } 18 | 19 | public RoleManager RoleManager { get { return HttpContext.RequestServices?.GetService>(); } } 20 | 21 | public new SmartUser User { get { return HttpContext.RequestServices?.GetService>(); } } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Controllers/IConvertible.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace System 7 | { 8 | public interface IConvertible 9 | { 10 | T ToType(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Controllers/PagedJson.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Identity; 7 | using System.Security.Claims; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 10 | using Newtonsoft.Json; 11 | 12 | namespace Microsoft.AspNetCore.Mvc 13 | { 14 | public abstract partial class BaseController : Controller 15 | { 16 | [NonAction] 17 | protected IActionResult PagedJson( 18 | IEnumerable Source, 19 | int PageSize = 50, 20 | JsonSerializerSettings JsonSerializerSettings = null) 21 | { 22 | int? p; 23 | try 24 | { 25 | if (Request.Query["p"].Count > 0) 26 | { 27 | p = int.Parse(Request.Query["p"].ToString()); 28 | } 29 | else if (RouteData.Values["p"] != null) 30 | { 31 | p = int.Parse(RouteData.Values["p"].ToString()); 32 | } 33 | else 34 | { 35 | p = 1; 36 | } 37 | } 38 | catch 39 | { 40 | p = 1; 41 | } 42 | ViewData["PagingInfo"] = Paging.Divide(ref Source, PageSize, p.Value); 43 | if (JsonSerializerSettings == null) 44 | return Json(Source); 45 | else 46 | return Json(Source, JsonSerializerSettings); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Controllers/PagedJsonWIthViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Identity; 7 | using System.Security.Claims; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 10 | using Newtonsoft.Json; 11 | 12 | namespace Microsoft.AspNetCore.Mvc 13 | { 14 | public abstract partial class BaseController : Controller 15 | { 16 | [NonAction] 17 | protected IActionResult PagedJson( 18 | IEnumerable Source, 19 | int PageSize = 50, 20 | JsonSerializerSettings JsonSerializerSettings = null) 21 | where TView : class 22 | where TModel : IConvertible 23 | { 24 | int? p; 25 | try 26 | { 27 | if (Request.Query["p"].Count > 0) 28 | { 29 | p = int.Parse(Request.Query["p"].ToString()); 30 | } 31 | else if (RouteData.Values["p"] != null) 32 | { 33 | p = int.Parse(RouteData.Values["p"].ToString()); 34 | } 35 | else 36 | { 37 | p = 1; 38 | } 39 | } 40 | catch 41 | { 42 | p = 1; 43 | } 44 | ViewData["PagingInfo"] = Paging.Divide(ref Source, PageSize, p.Value); 45 | var ret = new List(); 46 | foreach (var item in Source) 47 | { 48 | var tmp = (item as IConvertible).ToType(); 49 | ret.Add(tmp); 50 | } 51 | if (JsonSerializerSettings == null) 52 | return Json(ret); 53 | else 54 | return Json(ret, JsonSerializerSettings); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Controllers/PagedView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Identity; 7 | using System.Security.Claims; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 10 | using Newtonsoft.Json; 11 | 12 | namespace Microsoft.AspNetCore.Mvc 13 | { 14 | public abstract partial class BaseController : Controller 15 | { 16 | [NonAction] 17 | protected IActionResult PagedView( 18 | IEnumerable Source, 19 | int PageSize = 50, 20 | string ViewPath = null) 21 | { 22 | int? p; 23 | try 24 | { 25 | if (Request.Query["p"].Count > 0) 26 | { 27 | p = int.Parse(Request.Query["p"].ToString()); 28 | } 29 | else if (RouteData.Values["p"] != null) 30 | { 31 | p = int.Parse(RouteData.Values["p"].ToString()); 32 | } 33 | else 34 | { 35 | p = 1; 36 | } 37 | } 38 | catch 39 | { 40 | p = 1; 41 | } 42 | ViewData["PagingInfo"] = Paging.Divide(ref Source, PageSize, p.Value); 43 | if (string.IsNullOrEmpty(ViewPath)) 44 | return View(Source); 45 | else 46 | return View(ViewPath, Source); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Controllers/PagedViewWithViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Identity; 7 | using System.Security.Claims; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 10 | using Newtonsoft.Json; 11 | 12 | namespace Microsoft.AspNetCore.Mvc 13 | { 14 | public abstract partial class BaseController : Controller 15 | { 16 | [NonAction] 17 | protected IActionResult PagedView( 18 | IEnumerable Source, 19 | int PageSize = 50, 20 | string ViewPath = null) 21 | where TView : class 22 | where TModel : IConvertible 23 | { 24 | int? p; 25 | try 26 | { 27 | if (Request.Query["p"].Count > 0) 28 | { 29 | p = int.Parse(Request.Query["p"].ToString()); 30 | } 31 | else if (RouteData.Values["p"] != null) 32 | { 33 | p = int.Parse(RouteData.Values["p"].ToString()); 34 | } 35 | else 36 | { 37 | p = 1; 38 | } 39 | } 40 | catch 41 | { 42 | p = 1; 43 | } 44 | ViewData["PagingInfo"] = Paging.Divide(ref Source, PageSize, p.Value); 45 | var ret = new List(); 46 | foreach (var item in Source) 47 | { 48 | var tmp = (item as IConvertible).ToType(); 49 | ret.Add(tmp); 50 | } 51 | if (string.IsNullOrEmpty(ViewPath)) 52 | return View(ret); 53 | else 54 | return View(ViewPath, ret); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Controllers/Prompt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.AspNetCore.Http; 5 | 6 | namespace Microsoft.AspNetCore.Mvc 7 | { 8 | public abstract partial class BaseController : Controller 9 | { 10 | [NonAction] 11 | [Obsolete] 12 | protected IActionResult Prompt(Prompt prompt) 13 | { 14 | Response.StatusCode = prompt.StatusCode; 15 | return View("Prompt", prompt); 16 | } 17 | 18 | [NonAction] 19 | protected IActionResult Prompt(Action setupPrompt) 20 | { 21 | var prompt = new Prompt(); 22 | setupPrompt(prompt); 23 | Response.StatusCode = prompt.StatusCode; 24 | return View("Prompt", prompt); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Controllers/PromptMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Microsoft.AspNetCore.Mvc 7 | { 8 | public class Prompt 9 | { 10 | public string Title { get; set; } 11 | public int StatusCode { get; set; } = 200; 12 | public string Details { get; set; } 13 | public string RedirectUrl { get; set; } 14 | public string RedirectText { get; set; } 15 | public string Requires { get; set; } 16 | public dynamic Hint { get; set; } 17 | public bool HideBack { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Controllers/RenderSvg.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Identity; 7 | using System.Security.Claims; 8 | using Microsoft.AspNetCore.Http; 9 | using Microsoft.Extensions.DependencyInjection; 10 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 11 | using Newtonsoft.Json; 12 | 13 | namespace Microsoft.AspNetCore.Mvc 14 | { 15 | public abstract partial class BaseController : Controller 16 | { 17 | [NonAction] 18 | protected IActionResult RenderSvg(string FileName = null, string ViewPath = null) 19 | { 20 | if (string.IsNullOrEmpty(FileName)) 21 | FileName = DateTime.Now.ToTimeStamp().ToString() + ".svg"; 22 | Response.Headers.Add("content-disposition", new string[] { "attachment;filename=\"" + FileName + "\"" }); 23 | Response.ContentType = "image/svg+xml"; 24 | if (ViewPath == null) 25 | return View(); 26 | else 27 | return View(ViewPath); 28 | } 29 | 30 | [NonAction] 31 | protected IActionResult RenderSvg(object Model = null, string FileName = null, string ViewPath = null) 32 | { 33 | if (string.IsNullOrEmpty(FileName)) 34 | FileName = DateTime.Now.ToTimeStamp().ToString() + ".svg"; 35 | Response.Headers.Add("content-disposition", new string[] { "attachment;filename=\"" + FileName + "\"" }); 36 | Response.ContentType = "image/svg+xml"; 37 | if (string.IsNullOrEmpty(ViewPath)) 38 | { 39 | if (Model == null) 40 | return View(); 41 | else 42 | return View(Model); 43 | } 44 | else 45 | { 46 | if (Model == null) 47 | return View(ViewPath); 48 | else 49 | return View(ViewPath, Model); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Controllers/RenderXls.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Identity; 7 | using System.Security.Claims; 8 | using Microsoft.AspNetCore.Http; 9 | using Microsoft.Extensions.DependencyInjection; 10 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 11 | using Newtonsoft.Json; 12 | 13 | namespace Microsoft.AspNetCore.Mvc 14 | { 15 | public abstract partial class BaseController : Controller 16 | { 17 | [NonAction] 18 | protected IActionResult RenderXls(object Model = null, string FileName = null, string ViewPath = null) 19 | { 20 | if (string.IsNullOrEmpty(FileName)) 21 | FileName = DateTime.Now.ToTimeStamp().ToString() + ".xls"; 22 | Response.Headers.Add("content-disposition", new string[] { "attachment;filename=\"" + FileName + "\"" }); 23 | Response.ContentType = "application/x-xls"; 24 | if (string.IsNullOrEmpty(ViewPath)) 25 | { 26 | if (Model == null) 27 | return View(); 28 | else 29 | return View(Model); 30 | } 31 | else 32 | { 33 | if (Model == null) 34 | return View(ViewPath); 35 | else 36 | return View(ViewPath, Model); 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Others/AesCryptoExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Microsoft.Extensions.DependencyInjection 7 | { 8 | public static class AesCryptoExtensions 9 | { 10 | public static IServiceCollection AddAesCrypto(this IServiceCollection self, string PrivateKey = null, string IV = null) 11 | { 12 | return self.AddSingleton(x => new AesCrypto(PrivateKey, IV)); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Others/ConfigurationExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.IO; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.Extensions.Configuration; 8 | 9 | namespace Microsoft.Extensions.DependencyInjection 10 | { 11 | public static class ConfigurationExtensions 12 | { 13 | public static IServiceCollection AddConfiguration(this IServiceCollection self, out IConfiguration config, string fileName = "config") 14 | { 15 | var services = self.BuildServiceProvider(); 16 | var env = services.GetRequiredService(); 17 | 18 | var builder = new ConfigurationBuilder() 19 | .SetBasePath(env.ContentRootPath) 20 | .AddJsonFile($"{fileName}.json") 21 | .AddJsonFile($"{fileName}.{env.EnvironmentName}.json", optional: true); 22 | var configuration = builder.Build(); 23 | self.AddSingleton(configuration); 24 | config = configuration; 25 | 26 | return self; 27 | } 28 | 29 | public static IServiceCollection AddConfiguration(this IServiceCollection self, string fileName = "config") 30 | { 31 | var services = self.BuildServiceProvider(); 32 | var env = services.GetRequiredService(); 33 | 34 | var builder = new ConfigurationBuilder() 35 | .SetBasePath(env.ContentRootPath) 36 | .AddJsonFile($"{fileName}.json") 37 | .AddJsonFile($"{fileName}.{env.EnvironmentName}.json", optional: true); 38 | var configuration = builder.Build(); 39 | self.AddSingleton(configuration); 40 | 41 | return self; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Others/FormFileExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.IO; 6 | using Microsoft.AspNetCore.Http; 7 | 8 | 9 | namespace Microsoft.AspNetCore.Http 10 | { 11 | public static class FormFileExtentions 12 | { 13 | public static byte[] ReadAllBytes(this IFormFile self) 14 | { 15 | using (var reader = new BinaryReader(self.OpenReadStream())) 16 | { 17 | return reader.ReadBytes(Convert.ToInt32(self.Length)); 18 | } 19 | } 20 | 21 | public static Task ReadAllBytesAsync(this IFormFile self) 22 | { 23 | return Task.Factory.StartNew(() => { 24 | using (var reader = new BinaryReader(self.OpenReadStream())) 25 | { 26 | return reader.ReadBytes(Convert.ToInt32(self.Length)); 27 | } 28 | }); 29 | } 30 | 31 | public static string GetFormFieldName(this IFormFile self) 32 | { 33 | try 34 | { 35 | var tmp = self.ContentDisposition.Split(';'); 36 | foreach (var str in tmp) 37 | { 38 | var tmp2 = str.Trim(' '); 39 | var tmp3 = tmp2.Split('='); 40 | if (tmp3.Count() == 2 && tmp3[0].ToLower() == "name") 41 | return tmp3[1].PopFrontMatch("\"").PopBackMatch("\""); 42 | } 43 | return null; 44 | } 45 | catch 46 | { 47 | return null; 48 | } 49 | } 50 | 51 | public static string GetFileName(this IFormFile self) 52 | { 53 | try 54 | { 55 | var tmp = self.ContentDisposition.Split(';'); 56 | foreach (var str in tmp) 57 | { 58 | var tmp2 = str.Trim(' '); 59 | var tmp3 = tmp2.Split('='); 60 | if (tmp3.Count() == 2 && tmp3[0].ToLower() == "filename") 61 | return tmp3[1].PopFrontMatch("\"").PopBackMatch("\""); 62 | } 63 | return null; 64 | } 65 | catch 66 | { 67 | return null; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Others/Marked.cs: -------------------------------------------------------------------------------- 1 | namespace Pomelo.AspNetCore.Extensions.Others 2 | { 3 | public class Marked 4 | { 5 | public static string Parse(string md) 6 | { 7 | return Pomelo.Marked.Instance.Parse(md); 8 | } 9 | } 10 | } 11 | 12 | namespace Microsoft.AspNetCore.Mvc.Rendering 13 | { 14 | using Microsoft.AspNetCore.Html; 15 | 16 | public static class MarkedExtensions 17 | { 18 | public static HtmlString Marked(this IHtmlHelper self, string Content) 19 | { 20 | return new HtmlString(Pomelo.Marked.Instance.Parse(Content)); 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Others/SmtpEmailSenderExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.StaticFiles; 2 | using Pomelo.Net.Smtp; 3 | 4 | namespace Microsoft.Extensions.DependencyInjection 5 | { 6 | public static class SmtpEmailSenderExtensions 7 | { 8 | public static IServiceCollection AddSmtpEmailSender(this IServiceCollection self, string server, int port, string senderName, string email, string username, string password, bool ssl = false) 9 | { 10 | return self.AddSingleton() 11 | .AddSingleton(x => new SmtpEmailSender(x.GetRequiredService() ,server, port, senderName, email, username, password, ssl)); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Pomelo.AspNetCore.Extensions.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | true 7 | Pomelo.AspNetCore.Extensions 8 | Pomelo.AspNetCore.Extensions 9 | https://avatars2.githubusercontent.com/u/19828814?v=3 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions 11 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 12 | git 13 | https://github.com/PomeloFoundation/dotNETCore-Extensions 14 | 2.0.0-preview2-25401-01 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.AspNetCore.Extensions")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("1f0dc9f2-f875-48ae-a261-1040dda742d3")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/SmartCookies/SmartCookiesExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | 7 | namespace Microsoft.Extensions.DependencyInjection 8 | { 9 | public static class CookiesExtensions 10 | { 11 | public static IServiceCollection AddSmartCookies(this IServiceCollection self) 12 | { 13 | return self.AddScoped(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/SmartUser/SmartUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Security.Claims; 6 | using Microsoft.AspNetCore.Identity; 7 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 8 | using Microsoft.AspNetCore.Http; 9 | using Microsoft.Extensions.DependencyInjection; 10 | 11 | namespace Microsoft.AspNetCore.Identity 12 | { 13 | public class SmartUser : ClaimsPrincipal 14 | where TKey : IEquatable 15 | where TUser : IdentityUser 16 | { 17 | public HttpContext HttpContext { get; } 18 | 19 | public UserManager Manager { get; } 20 | 21 | private TUser _current = null; 22 | 23 | public bool IsSignedIn() 24 | { 25 | return HttpContext.User.Identity.IsAuthenticated; 26 | } 27 | 28 | public new TUser Current 29 | { 30 | get 31 | { 32 | if (_current == null) 33 | { 34 | if (!HttpContext.User.Identity.IsAuthenticated) return null; 35 | var um = HttpContext.RequestServices.GetRequiredService>(); 36 | var Type = typeof(TUser); 37 | var tmp = um.GetUserId(HttpContext.User); 38 | TKey uid; 39 | if (typeof(TKey) == typeof(Guid)) 40 | { 41 | uid = (dynamic)Guid.Parse(tmp); 42 | } 43 | else 44 | { 45 | uid = (TKey)Convert.ChangeType(tmp, typeof(TKey)); 46 | } 47 | try 48 | { 49 | _current = um.Users.Where(x => x.Id.Equals(uid)).Single(); 50 | return _current; 51 | } 52 | catch 53 | { 54 | return null; 55 | } 56 | } 57 | else 58 | { 59 | return _current; 60 | } 61 | } 62 | } 63 | 64 | public SmartUser(IHttpContextAccessor accessor, UserManager userManager) 65 | { 66 | HttpContext = accessor.HttpContext; 67 | Manager = userManager; 68 | this.AddIdentity(new ClaimsIdentity(HttpContext.User.Identity)); 69 | this.AddIdentities(HttpContext.User.Identities); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/SmartUser/SmartUserClaimsExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 6 | using Microsoft.AspNetCore.Identity; 7 | 8 | namespace System.Security.Claims 9 | { 10 | public static class SmartUserClaimsExtensions 11 | { 12 | public static bool AnyRoles(this SmartUser self, string Roles) 13 | where TKey : IEquatable 14 | where TUser : IdentityUser 15 | { 16 | var roles = Roles.Split(','); 17 | for (var i = 0; i < roles.Count(); i++) 18 | roles[i] = roles[i].Trim(' '); 19 | foreach (var r in roles) 20 | if (self.IsInRole(r)) 21 | return true; 22 | return false; 23 | } 24 | 25 | public static bool AnyRolesOrClaims(this SmartUser self, string Roles, List Claims) 26 | where TKey : IEquatable 27 | where TUser : IdentityUser 28 | { 29 | var roles = Roles.Split(','); 30 | for (var i = 0; i < roles.Count(); i++) 31 | roles[i] = roles[i].Trim(' '); 32 | foreach (var r in roles) 33 | if (self.IsInRole(r)) 34 | return true; 35 | foreach(var c in Claims) 36 | { 37 | if (self.HasClaim(c.Type, c.Value)) 38 | return true; 39 | } 40 | return false; 41 | } 42 | 43 | public static bool AnyRolesOrClaims(this SmartUser self, string Roles, string Types, string Value) 44 | where TKey : IEquatable 45 | where TUser : IdentityUser 46 | { 47 | var tmp = Types.Split(','); 48 | var claims = new List(); 49 | foreach(var c in tmp) 50 | { 51 | claims.Add(new Claim(c.Trim(' '), Value)); 52 | } 53 | return self.AnyRolesOrClaims(Roles, claims); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/SmartUser/SmartUserExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Security.Claims; 6 | using Microsoft.AspNetCore.Http; 7 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 8 | using Microsoft.AspNetCore.Identity; 9 | 10 | namespace Microsoft.Extensions.DependencyInjection 11 | { 12 | public static class SmartUserExtensions 13 | { 14 | public static IServiceCollection AddSmartUser(this IServiceCollection self) 15 | where TUser : IdentityUser 16 | where TKey : IEquatable 17 | { 18 | return self.AddScoped>(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Template/CookieRequestTemplateProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.Extensions.DependencyInjection; 7 | 8 | namespace Microsoft.AspNetCore.Mvc 9 | { 10 | public class CookieRequestTemplateProvider : IRequestTemplateProvider 11 | { 12 | public HttpContext HttpContext { get; set; } 13 | 14 | public IServiceProvider Services { get; } 15 | 16 | public string CookieField { get; } 17 | 18 | public CookieRequestTemplateProvider(IServiceProvider provider, string cookieField = "ASPNET_TEMPLATE") 19 | { 20 | CookieField = cookieField; 21 | Services = provider; 22 | } 23 | 24 | public string DetermineRequestTemplate() 25 | { 26 | try 27 | { 28 | HttpContext = Services.GetRequiredService().HttpContext; 29 | return HttpContext.Request.Cookies[CookieField]?.ToString(); 30 | } 31 | catch 32 | { 33 | return null; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Template/IRequestTemplateProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Microsoft.AspNetCore.Mvc 7 | { 8 | public interface IRequestTemplateProvider 9 | { 10 | string DetermineRequestTemplate(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Template/QueryStringRequestTemplateProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.Extensions.DependencyInjection; 7 | 8 | namespace Microsoft.AspNetCore.Mvc 9 | { 10 | public class QueryStringRequestTemplateProvider : IRequestTemplateProvider 11 | { 12 | public HttpContext HttpContext { get; set; } 13 | 14 | public string QueryField { get; } 15 | 16 | public IServiceProvider Services { get; } 17 | 18 | public QueryStringRequestTemplateProvider(IServiceProvider provider, string queryField = "template") 19 | { 20 | QueryField = queryField; 21 | Services = provider; 22 | } 23 | 24 | public string DetermineRequestTemplate() 25 | { 26 | try 27 | { 28 | HttpContext = Services.GetRequiredService().HttpContext; 29 | return HttpContext.Request.Query[QueryField].ToString(); 30 | } 31 | catch 32 | { 33 | return null; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Template/Template.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.IO; 6 | using Microsoft.AspNetCore.Http; 7 | 8 | namespace Microsoft.AspNetCore.Mvc 9 | { 10 | public class TemplateManager 11 | { 12 | public TemplateCollection Collection { get; } 13 | 14 | public TemplateInfo Current 15 | { 16 | get 17 | { 18 | var ret = Collection.Templates.Where(x => x.Identifier == Provider.DetermineRequestTemplate()).FirstOrDefault(); 19 | if (ret ==null) 20 | ret = Collection.Templates.Where(x => x.IsDefault).FirstOrDefault(); 21 | if (ret == null) 22 | throw new FileNotFoundException(); 23 | return ret; 24 | } 25 | } 26 | 27 | public TemplateInfo Default 28 | { 29 | get 30 | { 31 | var ret = Collection.Templates.Where(x => x.IsDefault).FirstOrDefault(); 32 | if (ret == null) 33 | ret = Collection.Templates.FirstOrDefault(); 34 | if (ret == null) 35 | throw new FileNotFoundException(); 36 | return ret; 37 | } 38 | } 39 | 40 | public IRequestTemplateProvider Provider { get; private set; } 41 | 42 | public TemplateManager(IRequestTemplateProvider templateProvider, TemplateCollection collection) 43 | { 44 | Collection = collection; 45 | Provider = templateProvider; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Template/TemplateCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.IO; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Newtonsoft.Json; 7 | 8 | namespace Microsoft.AspNetCore.Mvc 9 | { 10 | public class TemplateCollection 11 | { 12 | public List Templates { get; private set; } 13 | 14 | public int Count { get { return Templates.Count; } } 15 | 16 | private IHostingEnvironment _env { get; set; } 17 | 18 | public TemplateInfo Find(string identifier) 19 | { 20 | var ret = Templates.Where(x => x.Identifier == identifier).FirstOrDefault(); 21 | if (ret == null) 22 | Templates.Where(x => x.IsDefault).FirstOrDefault(); 23 | if (ret == null) 24 | Templates.Where(x => x.IsDefault).First(); 25 | if (ret == null) 26 | ret = null; 27 | return ret; 28 | } 29 | 30 | public TemplateCollection(IHostingEnvironment env) 31 | { 32 | _env = env; 33 | Refresh(); 34 | } 35 | 36 | public void Refresh() 37 | { 38 | var tmp = new List(); 39 | var path = _env.ContentRootPath + "/Views/"; 40 | if (Directory.Exists(path)) 41 | { 42 | var directories = Directory.GetDirectories(path); 43 | foreach (var d in directories) 44 | { 45 | System.Diagnostics.Debug.WriteLine(d + "/template.json"); 46 | try 47 | { 48 | if (File.Exists(d + "/template.json")) 49 | { 50 | var jsonStr = File.ReadAllText(d + "/template.json"); 51 | var template = JsonConvert.DeserializeObject(jsonStr); 52 | var lst1 = d.LastIndexOf('/'); 53 | var lst2 = d.LastIndexOf('\\'); 54 | var lst = Math.Max(lst1, lst2); 55 | template.Identifier = d.Substring(lst + 1); 56 | tmp.Add(template); 57 | } 58 | } 59 | catch (Exception ex) 60 | { 61 | throw ex; 62 | } 63 | } 64 | } 65 | Templates = tmp; 66 | GC.Collect(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Template/TemplateExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.AspNetCore.Mvc.Razor; 8 | 9 | namespace Microsoft.Extensions.DependencyInjection 10 | { 11 | public static class TemplateExtension 12 | { 13 | public static IMvcBuilder AddMultiTemplateEngine(this IMvcBuilder self) 14 | { 15 | self.Services 16 | .AddContextAccessor() 17 | .AddSingleton() 18 | .AddSingleton() 19 | .AddScoped(); 20 | 21 | return self.AddViewOptions(x => 22 | { 23 | foreach (var v in x.ViewEngines) 24 | if (!(v is MultiTemplateEngine)) 25 | x.ViewEngines.Remove(v); 26 | }); 27 | } 28 | 29 | public static IMvcBuilder AddQueryStringTemplateProvider(this IMvcBuilder self, string QueryField = "template") 30 | { 31 | self.Services.AddScoped(x => new QueryStringRequestTemplateProvider(x, QueryField)); 32 | return self; 33 | } 34 | 35 | public static IMvcBuilder AddCookieTemplateProvider(this IMvcBuilder self, string CookieField = "ASPNET_TEMPLATE") 36 | { 37 | self.Services.AddScoped(x => new CookieRequestTemplateProvider(x, CookieField)); 38 | return self; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Template/TemplateHtmlHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.Extensions.DependencyInjection; 6 | 7 | namespace Microsoft.AspNetCore.Mvc.Rendering 8 | { 9 | public static class TemplateHtmlHelper 10 | { 11 | public static TemplateInfo GetTemplateInfo(this IHtmlHelper self) 12 | { 13 | var template = self.ViewContext.HttpContext.RequestServices.GetRequiredService(); 14 | return template.Current; 15 | } 16 | 17 | public static string GetTemplateIdentifier(this IHtmlHelper self) 18 | { 19 | var template = self.ViewContext.HttpContext.RequestServices.GetRequiredService(); 20 | return template.Current.Identifier; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Extensions/Template/TemplateInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Newtonsoft.Json; 6 | 7 | namespace Microsoft.AspNetCore.Mvc 8 | { 9 | public class TemplateInfo 10 | { 11 | [JsonIgnore] 12 | public string Identifier { get; set; } 13 | 14 | public bool IsDefault { get; set; } 15 | 16 | public string Author { get; set; } 17 | 18 | public string License { get; set; } 19 | 20 | public string Title { get; set; } 21 | 22 | public string Description { get; set; } 23 | 24 | public string Version { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/Attributes/LocalizedAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace System.ComponentModel.DataAnnotations 7 | { 8 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] 9 | public class LocalizedAttribute : Attribute 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/BaiduTranslator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using System.Text.Encodings.Web; 4 | using System.Net.Http; 5 | using Newtonsoft.Json; 6 | 7 | namespace Pomelo.AspNetCore.Localization 8 | { 9 | public class BaiduTranslator : ITranslator 10 | { 11 | private ITranslatorDisabler disabler { get; set; } 12 | 13 | public BaiduTranslator(ITranslatorDisabler disabler) 14 | { 15 | this.disabler = disabler; 16 | } 17 | 18 | public async Task TranslateAsync(string from, string to, string src) 19 | { 20 | try 21 | { 22 | if (disabler.IsDisabled()) 23 | return src; 24 | 25 | if (from.IndexOf('-') >= 0) 26 | from = from.Split('-')[0]; 27 | if (to.IndexOf('-') >= 0) 28 | to = to.Split('-')[0]; 29 | 30 | if (from == to) 31 | return src; 32 | 33 | using (var client = new HttpClient() { BaseAddress = new Uri("http://fanyi.baidu.com") }) 34 | { 35 | var result = await client.GetAsync($"/v2transapi?from={ from }&query={ UrlEncoder.Default.Encode(src) }&to={ to }"); 36 | var jsonStr = await result.Content.ReadAsStringAsync(); 37 | var json = JsonConvert.DeserializeObject(jsonStr); 38 | if (json.trans_result.data.Count == 0) 39 | return src; 40 | else 41 | return json.trans_result.data.First.dst; 42 | } 43 | } 44 | catch 45 | { 46 | return src; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/DefaultCultureProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.AspNetCore.Http; 4 | using Microsoft.AspNetCore.Mvc.Infrastructure; 5 | using Microsoft.Extensions.DependencyInjection; 6 | 7 | namespace Pomelo.AspNetCore.Localization 8 | { 9 | public class DefaultCultureProvider : ICultureProvider 10 | { 11 | private IServiceProvider services { get; set; } 12 | 13 | public DefaultCultureProvider(IServiceProvider services) 14 | { 15 | this.services = services; 16 | } 17 | 18 | private string _DetermineCulture() 19 | { 20 | var httpContextAccessor = services.GetRequiredService(); 21 | var actionContextAccessor = services.GetRequiredService(); 22 | 23 | try 24 | { 25 | if (httpContextAccessor.HttpContext.Request.Cookies.ContainsKey("ASPNET_LANG")) 26 | return httpContextAccessor.HttpContext.Request.Cookies["ASPNET_LANG"]; 27 | else if (actionContextAccessor.ActionContext.RouteData.Values.ContainsKey("culture")) 28 | return actionContextAccessor.ActionContext.RouteData.Values["culture"].ToString(); 29 | else if (httpContextAccessor.HttpContext.Request.Query.ContainsKey("lang")) 30 | return httpContextAccessor.HttpContext.Request.Query["lang"].ToString(); 31 | else 32 | { 33 | var raw = httpContextAccessor.HttpContext.Request.Headers["Accept-Language"].ToString().Split(';')[0].Split(',').Select(x => x.Trim()); 34 | return raw.FirstOrDefault(); 35 | } 36 | } 37 | catch 38 | { 39 | var raw = httpContextAccessor.HttpContext.Request.Headers["Accept-Language"].ToString().Split(';')[0].Split(',').Select(x => x.Trim()); 40 | return raw.FirstOrDefault(); 41 | } 42 | } 43 | 44 | public string DetermineCulture() 45 | { 46 | var culture = _DetermineCulture(); 47 | var cs = services.GetRequiredService(); 48 | return cs.SimplifyCulture(culture); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/DefaultStringReader.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Threading; 3 | using System.Globalization; 4 | 5 | namespace Pomelo.AspNetCore.Localization 6 | { 7 | public class DefaultStringReader : IStringReader 8 | { 9 | public ICultureProvider culture { get; set; } 10 | 11 | public ICultureSet set { get; set; } 12 | 13 | public ITranslator translator { get; set; } 14 | 15 | public ITranslatedCaching cache { get; set; } 16 | 17 | public DefaultStringReader(ICultureProvider culture, ICultureSet set, ITranslator translator, ITranslatedCaching cache) 18 | { 19 | this.culture = culture; 20 | this.set = set; 21 | this.translator = translator; 22 | this.cache = cache; 23 | } 24 | 25 | public string this[string src, params object[] args] 26 | { 27 | get 28 | { 29 | var culture = this.culture.DetermineCulture(); 30 | #if NETSTANDARD1_6 31 | CultureInfo.CurrentCulture = new CultureInfo(culture); 32 | #else 33 | Thread.CurrentThread.CurrentCulture = new CultureInfo(culture); 34 | #endif 35 | var s = set.GetLocalizedStrings(culture); 36 | if (s.ContainsKey(src) || translator is NonTranslator) 37 | return s.Localize(src, args); 38 | else 39 | { 40 | var key = set.DefaultCulture; 41 | var cachedString = cache.Get(set.Default.ContainsKey(key) ? set.Default[key] : src, culture); 42 | if (cachedString == null) 43 | { 44 | var translateTask = translator.TranslateAsync(key, culture, set.Default.ContainsKey(key) ? set.Default[key] : src); 45 | translateTask.Wait(); 46 | cache.Set(set.Default.ContainsKey(key) ? set.Default[key] : src, culture, translateTask.Result); 47 | return string.Format(translateTask.Result, args); 48 | } 49 | else 50 | { 51 | return string.Format(cachedString, args); 52 | } 53 | } 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/DefaultTranslatorDisabler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.Extensions.DependencyInjection; 7 | 8 | namespace Pomelo.AspNetCore.Localization 9 | { 10 | public class DefaultTranslatorDisabler : ITranslatorDisabler 11 | { 12 | public IServiceProvider services { get; set; } 13 | 14 | public DefaultTranslatorDisabler(IServiceProvider services) 15 | { 16 | this.services = services; 17 | } 18 | 19 | public bool IsDisabled() 20 | { 21 | var httpContext = services.GetRequiredService().HttpContext; 22 | if (httpContext.Request.Cookies.ContainsKey("ASPNET_TRANSLATOR") && Convert.ToBoolean(httpContext.Request.Cookies["ASPNET_TRANSLATOR"])) 23 | return true; 24 | return false; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/Extensions/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.Extensions.DependencyInjection.Extensions; 4 | using Microsoft.EntityFrameworkCore; 5 | using System.Collections.Generic; 6 | using JetBrains.Annotations; 7 | using Microsoft.EntityFrameworkCore.Infrastructure; 8 | using Microsoft.Extensions.Caching.Memory; 9 | using Microsoft.Extensions.Logging; 10 | using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; 11 | using Pomelo.AspNetCore.Localization; 12 | using Pomelo.AspNetCore.Localization.Filters; 13 | using Pomelo.AspNetCore.Localization.Listeners; 14 | 15 | namespace Microsoft.Extensions.DependencyInjection 16 | { 17 | public static class ServiceCollectionExtensions 18 | { 19 | public static IServiceCollection AddPomeloLocalization(this IServiceCollection self, Action InitCultureSource = null) 20 | { 21 | var set = new MemoryCultureSet(); 22 | InitCultureSource?.Invoke(set); 23 | self.AddMemoryCache(); 24 | self.AddContextAccessor(); 25 | self.AddSingleton(set); 26 | self.AddScoped(); 27 | self.AddScoped(); 28 | self.AddSingleton(); 29 | self.AddSingleton(); 30 | self.AddScoped(); 31 | self.AddScoped(); 32 | self.Configure(x => x.Filters.Add(typeof(DbContextModelBindingFilter))); 33 | return self; 34 | } 35 | 36 | public static IServiceCollection AddLocalizationViewDataFilter(this IServiceCollection self) 37 | { 38 | return self.Configure(x => x.Filters.Add(typeof(LocalizationFilter))); 39 | } 40 | 41 | public static IServiceCollection AddBaiduTranslator(this IServiceCollection self) 42 | { 43 | return self.AddSingleton(); 44 | } 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/Filters/DbContextModelBindingFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Reflection; 6 | using Microsoft.EntityFrameworkCore; 7 | using Microsoft.AspNetCore.Mvc.Filters; 8 | 9 | namespace Pomelo.AspNetCore.Localization.Filters 10 | { 11 | public class DbContextModelBindingFilter : IActionFilter 12 | { 13 | public void OnActionExecuted(ActionExecutedContext context) 14 | { 15 | } 16 | 17 | public void OnActionExecuting(ActionExecutingContext context) 18 | { 19 | var pending = context.ActionArguments.Where(x => x.Value is DbContext).Select(x => x.Value as DbContext); 20 | foreach(var x in pending) 21 | { 22 | var type = typeof(DbContext); 23 | var field = type.GetRuntimeFields().Single(y => y.Name == "_options"); 24 | var opt = new DbContextOptionsBuilder((DbContextOptions)field.GetValue(x)); 25 | opt.UseInternalServiceProvider(context.HttpContext.RequestServices); 26 | field.SetValue(x, opt.Options); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/ICultureProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | 3 | namespace Pomelo.AspNetCore.Localization 4 | { 5 | public interface ICultureProvider 6 | { 7 | string DetermineCulture(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/ICultureSet.cs: -------------------------------------------------------------------------------- 1 | namespace Pomelo.AspNetCore.Localization 2 | { 3 | public interface ICultureSet 4 | { 5 | ILocalizedStringStore Default { get; set; } 6 | 7 | string DefaultCulture { get; set; } 8 | 9 | ILocalizedStringStore GetLocalizedStrings(string Culture); 10 | 11 | void AddCulture(string[] Cultures, ILocalizedStringStore strings, bool IsDefault = false); 12 | 13 | string SimplifyCulture(string Culture); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/ILocalizedStringStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.Localization 7 | { 8 | public interface ILocalizedStringStore : IDictionary 9 | { 10 | string Localize(string src, params object[] args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/IStringReader.cs: -------------------------------------------------------------------------------- 1 | namespace Pomelo.AspNetCore.Localization 2 | { 3 | public interface IStringReader 4 | { 5 | string this[string src, params object[] args] { get; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/ITranslatedCaching.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.Localization 7 | { 8 | public interface ITranslatedCaching 9 | { 10 | void Set(string key, string culture, string dst); 11 | 12 | string Get(string key, string culture); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/ITranslator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.Localization 7 | { 8 | public interface ITranslator 9 | { 10 | Task TranslateAsync(string from, string to, string src); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/ITranslatorDisabler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.Localization 7 | { 8 | public interface ITranslatorDisabler 9 | { 10 | bool IsDisabled(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/JsonLocalizedStringStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using Newtonsoft.Json; 5 | 6 | namespace Pomelo.AspNetCore.Localization 7 | { 8 | public class JsonLocalizedStringStore : Dictionary, ILocalizedStringStore 9 | { 10 | [JsonIgnore] 11 | private string path { get; set; } 12 | 13 | [JsonIgnore] 14 | private DateTime time { get; set; } = DateTime.Now; 15 | 16 | public JsonLocalizedStringStore(string path) 17 | { 18 | this.path = path; 19 | Load(); 20 | } 21 | 22 | public string Localize(string src, params object[] args) 23 | { 24 | var fi = new FileInfo(path); 25 | if (fi.LastWriteTime > time) 26 | Load(); 27 | if (this.ContainsKey(src)) 28 | { 29 | if (args == null) 30 | return this[src]; 31 | else 32 | return string.Format(this[src], args); 33 | } 34 | else 35 | { 36 | if (args == null) 37 | return src; 38 | else 39 | return string.Format(src, args); 40 | } 41 | } 42 | 43 | private void Load() 44 | { 45 | var tmp = JsonConvert.DeserializeObject>(File.ReadAllText(path)); 46 | this.Clear(); 47 | foreach (var x in tmp) 48 | this.Add(x.Key, x.Value); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/MemoryCultureSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.Localization 7 | { 8 | public class MemoryCultureSet : ICultureSet 9 | { 10 | public ILocalizedStringStore Default { get; set; } 11 | 12 | public string DefaultCulture { get; set; } 13 | 14 | private IDictionary, ILocalizedStringStore> dic { get; set; } = new Dictionary, ILocalizedStringStore>(); 15 | 16 | public void AddCulture(string[] Cultures, ILocalizedStringStore Strings, bool IsDefault = false) 17 | { 18 | if (IsDefault || dic.Count == 0) 19 | { 20 | Default = Strings; 21 | DefaultCulture = Cultures.First(); 22 | } 23 | 24 | if (!dic.ContainsKey(Cultures.ToList())) 25 | { 26 | dic.Add(Cultures, Strings); 27 | } 28 | else 29 | { 30 | dic[Cultures] = Strings; 31 | } 32 | } 33 | 34 | public ILocalizedStringStore GetLocalizedStrings(string Culture) 35 | { 36 | if (dic.Where(x => x.Key.Contains(Culture)).Count() == 0) 37 | return Default; 38 | return dic.FirstOrDefault(x => x.Key.Contains(Culture)).Value; 39 | } 40 | 41 | public string SimplifyCulture(string Culture) 42 | { 43 | if (dic.Where(x => x.Key.Contains(Culture)).Count() == 0) 44 | return Culture; 45 | else 46 | return dic.Where(x => x.Key.Contains(Culture)).First().Key.First(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/MemoryTranslatedCaching.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Microsoft.Extensions.Caching.Memory; 3 | 4 | namespace Pomelo.AspNetCore.Localization 5 | { 6 | public class MemoryTranslatedCaching : ITranslatedCaching 7 | { 8 | private IMemoryCache Cache { get; set; } 9 | 10 | public MemoryTranslatedCaching(IMemoryCache Cache) 11 | { 12 | this.Cache = Cache; 13 | } 14 | 15 | public string Get(string key, string culture) 16 | { 17 | IDictionary value; 18 | var flag = Cache.TryGetValue(key, out value); 19 | if (!flag) return null; 20 | if (value.ContainsKey(culture)) 21 | return value[culture]; 22 | else 23 | return null; 24 | } 25 | 26 | public void Set(string key, string culture, string dst) 27 | { 28 | IDictionary value; 29 | var flag = Cache.TryGetValue(key, out value); 30 | if (!flag) 31 | { 32 | value = new Dictionary(); 33 | value.Add(culture, dst); 34 | Cache.Set(key, value); 35 | } 36 | else 37 | { 38 | if (value.ContainsKey(culture)) 39 | value[culture] = dst; 40 | else 41 | value.Add(culture, dst); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/Middlewares/FrontendLocalizer.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Microsoft.AspNetCore.Http; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Newtonsoft.Json; 5 | using Pomelo.AspNetCore.Localization; 6 | 7 | namespace Microsoft.AspNetCore.Builder 8 | { 9 | public static class FrontendLocalizer 10 | { 11 | public static IApplicationBuilder UseFrontendLocalizer(this IApplicationBuilder self, string scriptUrl = "/scripts/localizer.js") 12 | { 13 | return self.Map(scriptUrl, config => 14 | { 15 | config.Run(async context => 16 | { 17 | var cultureProvider = self.ApplicationServices.GetRequiredService(); 18 | var cultureSet = self.ApplicationServices.GetRequiredService(); 19 | var strings = cultureSet.GetLocalizedStrings(cultureProvider.DetermineCulture()); 20 | var json = JsonConvert.SerializeObject(strings); 21 | 22 | var js = new StringBuilder("var __dictionary = {};"); 23 | js.AppendLine("__dictionary = " + json + ";"); 24 | js.AppendLine(@" 25 | function __replaceAll(str0, str1, str2) 26 | { 27 | return str0.replace(new RegExp(str1, 'gm'), str2); 28 | } 29 | function SR() 30 | { 31 | var key = arguments[0]; 32 | if (arguments.length == 1) 33 | return __dictionary[key] || key; 34 | else 35 | { 36 | var ret = __dictionary[key] || key; 37 | for (var i = 1; i < arguments.length; i++) 38 | ret = __replaceAll(ret, '\\{' + parseInt(i - 1) + '\\}', arguments[i]); 39 | return ret; 40 | } 41 | }"); 42 | context.Response.Headers["Cache-Control"] = $"max-age={ 60 * 24 * 7 }"; 43 | await context.Response.WriteAsync(js.ToString()); 44 | return; 45 | }); 46 | }); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/NonTranslator.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace Pomelo.AspNetCore.Localization 4 | { 5 | public class NonTranslator : ITranslator 6 | { 7 | public Task TranslateAsync(string from, string to, string src) 8 | { 9 | return Task.FromResult(src); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/Pomelo.AspNetCore.Localization.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.AspNetCore.Localization 7 | Pomelo.AspNetCore.Localization 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Localization/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.AspNetCore.Localization")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("6ac39ffe-9302-4081-8484-da01197509d4")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.ReverseProxy/FormFileExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.IO; 6 | using Microsoft.AspNetCore.Http; 7 | 8 | 9 | namespace Pomelo.AspNetCore.ReverseProxy.Extensions 10 | { 11 | public static class FormFileExtentions 12 | { 13 | public static byte[] ReadAllBytes(this IFormFile self) 14 | { 15 | using (var reader = new BinaryReader(self.OpenReadStream())) 16 | { 17 | return reader.ReadBytes(Convert.ToInt32(self.Length)); 18 | } 19 | } 20 | 21 | public static Task ReadAllBytesAsync(this IFormFile self) 22 | { 23 | return Task.Factory.StartNew(() => { 24 | using (var reader = new BinaryReader(self.OpenReadStream())) 25 | { 26 | return reader.ReadBytes(Convert.ToInt32(self.Length)); 27 | } 28 | }); 29 | } 30 | 31 | public static string GetFormFieldName(this IFormFile self) 32 | { 33 | try 34 | { 35 | var tmp = self.ContentDisposition.Split(';'); 36 | foreach (var str in tmp) 37 | { 38 | var tmp2 = str.Trim(' '); 39 | var tmp3 = tmp2.Split('='); 40 | if (tmp3.Count() == 2 && tmp3[0].ToLower() == "name") 41 | return tmp3[1].PopFrontMatch("\"").PopBackMatch("\""); 42 | } 43 | return null; 44 | } 45 | catch 46 | { 47 | return null; 48 | } 49 | } 50 | 51 | public static string GetFileName(this IFormFile self) 52 | { 53 | try 54 | { 55 | var tmp = self.ContentDisposition.Split(';'); 56 | foreach (var str in tmp) 57 | { 58 | var tmp2 = str.Trim(' '); 59 | var tmp3 = tmp2.Split('='); 60 | if (tmp3.Count() == 2 && tmp3[0].ToLower() == "filename") 61 | return tmp3[1].PopFrontMatch("\"").PopBackMatch("\""); 62 | } 63 | return null; 64 | } 65 | catch 66 | { 67 | return null; 68 | } 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.ReverseProxy/Pomelo.AspNetCore.ReverseProxy.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.AspNetCore.ReverseProxy 7 | Pomelo.AspNetCore.ReverseProxy 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.ReverseProxy/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.AspNetCore.ReverseProxy")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("edddebb6-19d6-45f5-aa84-2f38096e9263")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Statistics/Browser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.Statistics 7 | { 8 | public class Browser 9 | { 10 | public string Name { get; set; } 11 | 12 | public string Version { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Statistics/IGeolocationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.Statistics 7 | { 8 | public interface IGeolocationProvider 9 | { 10 | Task GeolocateAsync(string ip); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Statistics/IpInformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.Statistics 7 | { 8 | public class IpInformation 9 | { 10 | public string Ip { get; set; } 11 | 12 | public string City { get; set; } 13 | 14 | public string Country { get; set; } 15 | 16 | public string ISP { get; set; } 17 | 18 | public double? Longitude { get; set; } 19 | 20 | public double? Latitude { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Statistics/Middlewares/StatisticsMiddleware.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.Extensions.DependencyInjection; 7 | 8 | namespace Pomelo.AspNetCore.Statistics.Middlewares 9 | { 10 | public class StatisticsMiddleware 11 | { 12 | private readonly RequestDelegate next; 13 | 14 | public StatisticsMiddleware(RequestDelegate next) 15 | { 16 | this.next = next; 17 | } 18 | 19 | public Task Invoke(HttpContext context) 20 | { 21 | Task.Factory.StartNew(async ()=> { 22 | 23 | // Get services 24 | var geo = context.RequestServices.GetRequiredService(); 25 | 26 | // Get significant arguments 27 | var url = context.Request.Scheme + "://" + context.Request.Host + "/" + context.Request.Path; 28 | var ip = context.Connection.RemoteIpAddress.ToString(); 29 | var geolocation = await geo.GeolocateAsync(ip); 30 | }); 31 | return Task.FromResult(0); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Statistics/OperateSystem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.Statistics 7 | { 8 | public class OperateSystem 9 | { 10 | public string Name { get; set; } 11 | 12 | public string Version { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Statistics/Pomelo.AspNetCore.Statistics.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.AspNetCore.Statistics 7 | Pomelo.AspNetCore.Statistics 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Statistics/PomeloGeolocationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Net.Http; 6 | using Newtonsoft.Json; 7 | 8 | namespace Pomelo.AspNetCore.Statistics 9 | { 10 | public class PomeloGeolocationProvider : IGeolocationProvider 11 | { 12 | public async Task GeolocateAsync(string ip) 13 | { 14 | var ret = new IpInformation(); 15 | ret.Ip = ip; 16 | 17 | // 1. Try get informations from http://geoip.nekudo.com/ 18 | using (var client = new HttpClient { BaseAddress = new Uri("http://geoip.nekudo.com/") }) 19 | { 20 | var result = await client.GetAsync($"/api/{ip}/en/json"); 21 | var jsonStr = await result.Content.ReadAsStringAsync(); 22 | var json = JsonConvert.DeserializeObject(jsonStr); 23 | ret.City = json.city; 24 | ret.Country = json.country.name; 25 | ret.Longitude = json.location.longitude; 26 | ret.Latitude = json.location.latitude; 27 | } 28 | 29 | // 2. Get ISP informations for China visitors from http://ip.taobao.com/ 30 | using (var client = new HttpClient { BaseAddress = new Uri("http://ip.taobao.com/") }) 31 | { 32 | var result = await client.GetAsync($"/service/getIpInfo.php?ip={ip}"); 33 | var jsonStr = await result.Content.ReadAsStringAsync(); 34 | var json = JsonConvert.DeserializeObject(jsonStr); 35 | ret.ISP = json.data.isp; 36 | } 37 | 38 | return ret; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Statistics/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.AspNetCore.Statistics")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("d843981d-1460-4af0-87e7-a12b94c43a76")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.Statistics/RequestLog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.Statistics 7 | { 8 | public class RequestLog 9 | { 10 | public string IP { get; set; } 11 | 12 | public string Zone { get; set; } 13 | 14 | public DateTime Time { get; set; } 15 | 16 | public string UserName { get; set; } 17 | 18 | public string OperateSystem { get; set; } 19 | 20 | public string UserAgent { get; set; } 21 | 22 | public string Referer { get; set; } 23 | 24 | public string Browser { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/DynamicTimedJob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace Pomelo.AspNetCore.TimedJob 5 | { 6 | public class DynamicTimedJob 7 | { 8 | [MaxLength(512)] 9 | public string Id { get; set; } 10 | 11 | public DateTime Begin { get; set; } 12 | 13 | public int Interval { get; set; } 14 | 15 | public bool IsEnabled { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/EntityFramework/EntityFrameworkDynamicTimedJobProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | 5 | namespace Pomelo.AspNetCore.TimedJob.EntityFramework 6 | { 7 | public class EntityFrameworkDynamicTimedJobProvider : IDynamicTimedJobProvider 8 | where TContext : ITimedJobContext 9 | { 10 | private TContext DB { get; set; } 11 | 12 | public EntityFrameworkDynamicTimedJobProvider(TContext db) 13 | { 14 | DB = db; 15 | } 16 | 17 | public IList GetJobs() 18 | { 19 | return DB.TimedJobs 20 | .Where(x => x.IsEnabled) 21 | .Select(x => new DynamicTimedJob 22 | { 23 | Id = x.Id, 24 | Begin = x.Begin, 25 | Interval = x.Interval, 26 | IsEnabled = x.IsEnabled 27 | }) 28 | .ToList(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/EntityFramework/EntityFrameworkDynamicTimedJobServiceBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using Pomelo.AspNetCore.TimedJob; 2 | using Pomelo.AspNetCore.TimedJob.EntityFramework; 3 | 4 | namespace Microsoft.Extensions.DependencyInjection 5 | { 6 | public static class EntityFrameworkDynamicTimedJobServiceBuilderExtensions 7 | { 8 | public static IServiceCollection AddEntityFrameworkDynamicTimedJob(this IServiceCollection self) 9 | where TContext : ITimedJobContext 10 | { 11 | return self.AddScoped>(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/EntityFramework/ITimedJobContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace Pomelo.AspNetCore.TimedJob.EntityFramework 4 | { 5 | public interface ITimedJobContext 6 | { 7 | DbSet TimedJobs { get; set; } 8 | 9 | int SaveChanges(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/EntityFramework/TimedJob.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations.Schema; 2 | 3 | namespace Pomelo.AspNetCore.TimedJob.EntityFramework 4 | { 5 | [Table("AspNetTimedJobs")] 6 | public class TimedJob : DynamicTimedJob 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/EntityFramework/TimedJobDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace Pomelo.AspNetCore.TimedJob.EntityFramework 4 | { 5 | public static class TimedJobDbContextExtensions 6 | { 7 | public static ModelBuilder SetupTimedJobs(this ModelBuilder self) 8 | { 9 | return self.Entity(e => 10 | { 11 | e.HasKey(x => x.Id); 12 | e.HasIndex(x => x.IsEnabled); 13 | }); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/Extensions/TimedJobExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Pomelo.AspNetCore.TimedJob; 6 | using Pomelo.AspNetCore.TimedJob.Jobs; 7 | using Microsoft.Extensions.DependencyInjection; 8 | 9 | namespace Microsoft.Extensions.DependencyInjection 10 | { 11 | public static class TimedJobExtensions 12 | { 13 | public static IServiceCollection AddTimedJob(this IServiceCollection self) 14 | { 15 | return self.AddSingleton() 16 | .AddSingleton(); 17 | } 18 | } 19 | } 20 | 21 | namespace Microsoft.AspNetCore.Builder 22 | { 23 | public static class TimedJobExtensions 24 | { 25 | public static IApplicationBuilder UseTimedJob(this IApplicationBuilder self) 26 | { 27 | self.ApplicationServices.GetRequiredService(); 28 | return self; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/IDynamicTimedJobProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.TimedJob 7 | { 8 | public interface IDynamicTimedJobProvider 9 | { 10 | IList GetJobs(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/Job.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Pomelo.AspNetCore.TimedJob 4 | { 5 | public class Job 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/Jobs/DefaultAssemblyLocator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.DependencyModel; 7 | 8 | namespace Pomelo.AspNetCore.TimedJob.Jobs 9 | { 10 | public class DefaultAssemblyLocator : IAssemblyLocator 11 | { 12 | private static readonly string AssemblyRoot = typeof(Job).GetTypeInfo().Assembly.GetName().Name; 13 | private readonly Assembly _entryAssembly; 14 | private readonly DependencyContext _dependencyContext; 15 | 16 | public DefaultAssemblyLocator(IHostingEnvironment environment) 17 | { 18 | _entryAssembly = Assembly.Load(new AssemblyName(environment.ApplicationName)); 19 | _dependencyContext = DependencyContext.Load(_entryAssembly); 20 | } 21 | 22 | public virtual IList GetAssemblies() 23 | { 24 | if (_dependencyContext == null) 25 | { 26 | // Use the entry assembly as the sole candidate. 27 | return new[] { _entryAssembly }; 28 | } 29 | 30 | return _dependencyContext 31 | .RuntimeLibraries 32 | .Where(IsCandidateLibrary) 33 | .SelectMany(l => l.GetDefaultAssemblyNames(_dependencyContext)) 34 | .Select(assembly => Assembly.Load(new AssemblyName(assembly.Name))) 35 | .ToArray(); 36 | } 37 | 38 | private bool IsCandidateLibrary(RuntimeLibrary library) 39 | { 40 | return library.Dependencies.Any(dependency => string.Equals(AssemblyRoot, dependency.Name, StringComparison.Ordinal)); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/Jobs/IAssemblyLocator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics.CodeAnalysis; 3 | using System.Reflection; 4 | 5 | namespace Pomelo.AspNetCore.TimedJob.Jobs 6 | { 7 | public interface IAssemblyLocator 8 | { 9 | [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Might be expensive.")] 10 | IList GetAssemblies(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/Pomelo.AspNetCore.TimedJob.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.AspNetCore.TimedJob 7 | Pomelo.AspNetCore.TimedJob 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.Threading.TimedJob")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("343bdeb6-9852-481f-9617-00293fccaf26")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/Schema/InvokeAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.TimedJob 7 | { 8 | public class InvokeAttribute : Attribute 9 | { 10 | public bool IsEnabled { get; set; } = true; 11 | 12 | public int Interval { get; set; } = 1000 * 60 * 60 * 24; // 24 hours 13 | 14 | public bool SkipWhileExecuting { get; set; } = false; 15 | 16 | public string Begin 17 | { 18 | get { return _begin.ToString(); } 19 | set { _begin = Convert.ToDateTime(value); } 20 | } 21 | 22 | public DateTime _begin { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Pomelo.AspNetCore.TimedJob/Schema/NonJobAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.AspNetCore.TimedJob 7 | { 8 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 9 | public class NonJobAttribute : Attribute 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Pomelo.Data.Excel/ExcelStreamReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.IO; 6 | using System.IO.Compression; 7 | using System.Xml; 8 | using Pomelo.Data.Excel.Infrastructure; 9 | 10 | namespace Pomelo.Data.Excel 11 | { 12 | public class ExcelStreamReader : ExcelStreamBase, IExcelStreamReader, IDisposable 13 | { 14 | public ExcelStreamReader() 15 | { 16 | 17 | } 18 | 19 | private SheetReader LoadSheetReader(string name, bool hdr) 20 | { 21 | var id = WorkBook 22 | .Where(x => x.Name == name) 23 | .Select(x => x.Id) 24 | .First(); 25 | return LoadSheetReader(id, hdr); 26 | } 27 | 28 | private SheetReader LoadSheetReader(ulong id, bool hdr) 29 | { 30 | var worksheet = WorkBook.First(x => x.Id == id); 31 | var e = ZipArchive.GetEntry($"xl/{worksheet.Target}"); 32 | 33 | var sheetStream = e.Open(); 34 | return new SheetReader(sheetStream, CachedSharedStrings, hdr); 35 | } 36 | 37 | public SheetReader LoadSheetReader(string name) 38 | { 39 | return LoadSheetReader(name, false); 40 | } 41 | 42 | public SheetReader LoadSheetReader(ulong id) 43 | { 44 | return LoadSheetReader(id, false); 45 | } 46 | 47 | public SheetReader LoadSheetReaderHDR(ulong id) 48 | { 49 | return LoadSheetReader(id, true); 50 | } 51 | 52 | public SheetReader LoadSheetReaderHDR(string name) 53 | { 54 | return LoadSheetReader(name, true); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Pomelo.Data.Excel/Infrastructure/Header.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.Data.Excel.Infrastructure 7 | { 8 | public class Header : List 9 | { 10 | public void Add(string item, string pos) 11 | { 12 | var numStr = ""; 13 | foreach (var x in pos) 14 | if ("QWERTYUIOPASDFGHJKLZXCVBNM".Contains(x)) 15 | numStr += x; 16 | var num = new ColNumber(numStr); 17 | var intvalue = Convert.ToInt64(ColNumber.FromNumberSystem26(num)) - 1; 18 | while (this.LongCount() != intvalue + 1) 19 | this.Add(null); 20 | this[(int)intvalue] = item; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Pomelo.Data.Excel/Infrastructure/Row.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.Data.Excel.Infrastructure 7 | { 8 | public class Row : Header 9 | { 10 | private readonly Header _header; 11 | 12 | public Row(Header header = null) 13 | { 14 | _header = header; 15 | } 16 | 17 | public string this[string index] 18 | { 19 | get 20 | { 21 | try 22 | { 23 | return this[_header.IndexOf(index)]; 24 | } 25 | catch 26 | { 27 | return null; 28 | } 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Pomelo.Data.Excel/Infrastructure/SheetWithoutHDR.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Xml; 6 | 7 | namespace Pomelo.Data.Excel.Infrastructure 8 | { 9 | public class SheetWithoutHDR : Sheet 10 | { 11 | public SheetWithoutHDR(ulong id, string xmlSource, ExcelStream excel, SharedStrings stringDictionary) 12 | : base(id, excel, stringDictionary) 13 | { 14 | var xd = new XmlDocument(); 15 | xd.LoadXml(xmlSource); 16 | var rows = xd.GetElementsByTagName("row"); 17 | // 遍历row标签 18 | foreach (XmlNode x in rows) 19 | { 20 | var cols = x.ChildNodes; 21 | var objs = new Row(); 22 | // 遍历c标签 23 | foreach (XmlNode y in cols) 24 | { 25 | string value = null; 26 | // 如果是字符串类型,则需要从字典中查询 27 | if (y.Attributes["t"]?.Value == "s") 28 | { 29 | var index = Convert.ToUInt64(y.FirstChild.InnerText); 30 | value = StringDictionary[index]; 31 | } 32 | else if (y.Attributes["t"]?.Value == "inlineStr") 33 | { 34 | value = y.FirstChild.FirstChild.InnerText; 35 | } 36 | // 否则其中的v标签值即为单元格内容 37 | else 38 | { 39 | value = y.InnerText; 40 | } 41 | 42 | objs.Add(value, y.Attributes["r"].Value); 43 | } 44 | 45 | // 去掉末尾的null 46 | while (objs.LastOrDefault() == null) 47 | objs.RemoveAt(objs.Count - 1); 48 | if (objs.Count > 0) 49 | this.Add(objs); 50 | } 51 | while (this.Count > 0 && this.Last().Count == 0) 52 | this.RemoveAt(this.Count - 1); 53 | GC.Collect(); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/Pomelo.Data.Excel/Infrastructure/WorkBook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.Data.Excel.Infrastructure 7 | { 8 | public class WorkBook 9 | { 10 | public ulong Id { get; set; } 11 | public string Name { get; set; } 12 | public string Target { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Pomelo.Data.Excel/Interface/IExceStreamlReader.cs: -------------------------------------------------------------------------------- 1 | using Pomelo.Data.Excel.Infrastructure; 2 | using System.IO; 3 | 4 | namespace Pomelo.Data.Excel 5 | { 6 | public interface IExcelStreamReader 7 | { 8 | ExcelStreamReader Load(Stream stream); 9 | 10 | ExcelStreamReader Load(string path); 11 | 12 | SheetReader LoadSheetReader(string name); 13 | 14 | SheetReader LoadSheetReader(ulong id); 15 | 16 | SheetReader LoadSheetReaderHDR(string name); 17 | 18 | SheetReader LoadSheetReaderHDR(ulong id); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Pomelo.Data.Excel/Interface/IExcelStream.cs: -------------------------------------------------------------------------------- 1 | using Pomelo.Data.Excel.Infrastructure; 2 | using System.IO; 3 | 4 | namespace Pomelo.Data.Excel 5 | { 6 | public interface IExcelStream 7 | { 8 | /// 9 | /// 创建ExcelStream 10 | /// 11 | /// 文件路径 12 | /// 13 | ExcelStream Create(string path); 14 | 15 | // 16 | /// 创建Sheet 17 | /// 18 | /// Sheet名称 19 | /// 20 | SheetWithoutHDR CreateSheet(string name); 21 | 22 | // 23 | /// 创建Sheet 24 | /// 25 | /// Sheet名称 26 | /// 27 | SheetHDR CreateSheetHDR(string name); 28 | 29 | /// 30 | /// 加载Excel,返回ExcelStream 31 | /// 32 | /// excel字节流 33 | /// 34 | ExcelStream Load(Stream stream); 35 | 36 | /// 37 | /// 加载Excel,返回ExcelStream 38 | /// 39 | /// excel文件路径 40 | /// 41 | ExcelStream Load(string path); 42 | 43 | /// 44 | /// 加载LoadSheet不包含列名 45 | /// 46 | /// Sheet名称 47 | /// 48 | SheetWithoutHDR LoadSheet(string name); 49 | 50 | /// 51 | /// 加载LoadSheet不包含列名 52 | /// 53 | /// Sheet名称对于的Id,从1开始 54 | /// 55 | SheetWithoutHDR LoadSheet(ulong id); 56 | 57 | /// 58 | /// 加载LoadSheet包含列名 59 | /// 60 | /// 61 | /// 62 | SheetHDR LoadSheetHDR(string name); 63 | 64 | /// 65 | /// 加载LoadSheet包含列名 66 | /// 67 | /// Sheet名称对应的Id,从1开始 68 | /// 69 | SheetHDR LoadSheetHDR(ulong Id); 70 | 71 | /// 72 | /// 删除Sheet 73 | /// 74 | /// Sheet名称 75 | void RemoveSheet(string name); 76 | 77 | /// 78 | /// 删除Sheet 79 | /// 80 | /// Sheet名称对应的Id 81 | void RemoveSheet(ulong Id); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Pomelo.Data.Excel/Pomelo.Data.Excel.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.Data.Excel 7 | Pomelo.Data.Excel 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/Pomelo.Data.Excel/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.Data.Excel")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("785a8fdc-9bf5-462d-8560-200cdb84397b")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Caching/Pomelo.Extensions.Caching.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.Extensions.Caching 7 | Pomelo.Extensions.Caching 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Caching/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.Extensions.Caching")] 11 | [assembly: AssemblyTrademark("")] 12 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Common/Base64StringFile.cs: -------------------------------------------------------------------------------- 1 | namespace System 2 | { 3 | public class Base64StringFile 4 | { 5 | public Base64StringFile() { } 6 | 7 | public Base64StringFile(byte[] Blob, string contentType) 8 | { 9 | ContentString = Convert.ToBase64String(Blob); 10 | ContentType = contentType; 11 | } 12 | 13 | public Base64StringFile(string base64String) 14 | { 15 | ContentString = base64String.Split(',')[1].Trim(); 16 | ContentType = base64String.Split(':')[1].Split(';')[0]; 17 | } 18 | 19 | public string ContentType { get; set; } 20 | 21 | private string ContentString { get; set; } 22 | 23 | private byte[] allBytes; 24 | 25 | public byte[] AllBytes 26 | { 27 | get 28 | { 29 | if (allBytes == null) 30 | { 31 | allBytes = Convert.FromBase64String(ContentString); 32 | } 33 | return allBytes; 34 | } 35 | } 36 | 37 | private string base64String; 38 | 39 | public string Base64String 40 | { 41 | get 42 | { 43 | if (base64String == null) 44 | { 45 | base64String = "data:" + ContentType + "; base64, " + ContentString; 46 | } 47 | return base64String; 48 | } 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Common/DateTimeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace System 7 | { 8 | public static class DateTimeExt 9 | { 10 | public static long ToTimeStamp(this System.DateTime self) 11 | { 12 | return DateTimeToStamp(self); 13 | } 14 | 15 | private static System.DateTime FromTimeStamp(this DateTime self, long timeStamp) 16 | { 17 | System.DateTime dtStart = new System.DateTime(1970, 1, 1); 18 | var tmp = timeStamp.ToString(); 19 | if (tmp.Length == 10) 20 | timeStamp *= 10000000; 21 | else 22 | timeStamp *= 10000; 23 | TimeSpan toNow = new TimeSpan(timeStamp); 24 | return dtStart.Add(toNow); 25 | } 26 | 27 | public static long DateTimeToStamp(System.DateTime time) 28 | { 29 | System.DateTime startTime = new System.DateTime(1970, 1, 1); 30 | return (long)(time - startTime).TotalMilliseconds; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Common/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace System.Linq 7 | { 8 | public static class EnumerableExtensions 9 | { 10 | public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) 11 | { 12 | HashSet hashSet = new HashSet(); 13 | foreach (TSource element in source) 14 | { 15 | if (hashSet.Add(keySelector(element))) { yield return element; } 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Common/GitClone.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Diagnostics; 6 | 7 | namespace Pomelo.Package 8 | { 9 | public class GitCloneResult 10 | { 11 | public bool IsSucceeded { get; set; } 12 | public string Output { get; set; } 13 | public string Error { get; set; } 14 | } 15 | 16 | public static class GitClone 17 | { 18 | public static GitCloneResult Clone(string uri, string dest, string branch = null, int timeLimit = 1000 * 60 * 20) 19 | { 20 | if (!System.IO.Directory.Exists(dest)) 21 | System.IO.Directory.CreateDirectory(dest); 22 | Process p = new Process(); 23 | 24 | var argument = $"clone {uri}"; 25 | if (!string.IsNullOrEmpty(branch)) 26 | argument = $"clone {uri} -b {branch}"; 27 | 28 | p.StartInfo = new ProcessStartInfo 29 | { 30 | RedirectStandardError = true, 31 | RedirectStandardOutput = true, 32 | UseShellExecute = false, 33 | CreateNoWindow = true, 34 | FileName = "git", 35 | Arguments = argument, 36 | WorkingDirectory = dest 37 | }; 38 | p.Start(); 39 | if (!p.WaitForExit(timeLimit)) 40 | p.Kill(); 41 | var ret = new GitCloneResult 42 | { 43 | IsSucceeded = true, 44 | Output = p.StandardOutput.ReadToEnd(), 45 | Error = p.StandardError.ReadToEnd() 46 | }; 47 | if (p.ExitCode != 0) 48 | ret.IsSucceeded = false; 49 | return ret; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Common/MediaFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace System 8 | { 9 | public abstract class MediaFile 10 | { 11 | public MediaFile() 12 | { 13 | ID = Guid.NewGuid(); 14 | } 15 | 16 | protected string _Source { get; set; } 17 | 18 | public bool IsTemp { get; set; } 19 | 20 | /// 21 | /// 文件路径 22 | /// 23 | public string Source { get { return _Source; } } 24 | 25 | public Guid ID { get; set; } 26 | public virtual byte[] AllBytes { get; set; } 27 | 28 | /// 29 | /// 另存为 30 | /// 31 | /// 32 | public void SaveAs(string Path) 33 | { 34 | System.IO.File.WriteAllBytes(Path, AllBytes); 35 | } 36 | 37 | public Task SaveAsAsync(string Path) 38 | { 39 | return Task.Factory.StartNew(() => SaveAs(Path)); 40 | } 41 | 42 | public void MoveTo(string Path) 43 | { 44 | System.IO.File.WriteAllBytes(Path, AllBytes); 45 | System.IO.File.Delete(_Source); 46 | _Source = Path; 47 | } 48 | 49 | public Task MoveToAsync(string Path) 50 | { 51 | return Task.Factory.StartNew(() => MoveTo(Path)); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Common/OSType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | #if !NET451 6 | using System.Runtime.InteropServices; 7 | #endif 8 | 9 | namespace System 10 | { 11 | public enum OSType 12 | { 13 | Windows, 14 | OSX, 15 | Linux 16 | } 17 | 18 | public static class Platform 19 | { 20 | public static OSType OS 21 | { 22 | get 23 | { 24 | #if !NET451 25 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) 26 | return OSType.Windows; 27 | else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) 28 | return OSType.OSX; 29 | else 30 | return OSType.Linux; 31 | #else 32 | if (Environment.OSVersion.Platform == PlatformID.Win32NT || Environment.OSVersion.Platform == PlatformID.Win32S || Environment.OSVersion.Platform == PlatformID.Win32Windows || Environment.OSVersion.Platform == PlatformID.WinCE) 33 | return OSType.Windows; 34 | else if (Environment.OSVersion.Platform == PlatformID.MacOSX) 35 | return OSType.OSX; 36 | else 37 | return OSType.Linux; 38 | #endif 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Common/Pomelo.Extensions.Common.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.Extensions.Common 7 | Pomelo.Extensions.Common 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Common/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.Extensions.Common")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("1911668d-54df-408c-862a-4929f3a42acc")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Common/String.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace System 7 | { 8 | public static class PomeloForStringExtensions 9 | { 10 | public static int[] IndexOfMany(this string self, string substr) 11 | { 12 | var ret = new List(); 13 | var ch1 = self.ToCharArray(); 14 | var ch2 = substr.ToCharArray(); 15 | for (var i = 0; i <= ch1.Length - ch2.Length; i++) 16 | { 17 | var flag = true; 18 | for (var j = 0; j < ch2.Length; i++) 19 | { 20 | if (ch1[i + j] != ch2[j]) 21 | { 22 | flag = false; 23 | break; 24 | } 25 | } 26 | if (flag) 27 | ret.Add(i); 28 | } 29 | return ret.ToArray(); 30 | } 31 | 32 | public static int CountSubString(this string self, string substr) 33 | { 34 | return self.IndexOfMany(substr).Count(); 35 | } 36 | 37 | 38 | public static string PopFrontMatch(this string self, string str) 39 | { 40 | if (str.Length > self.Length) 41 | return self; 42 | else if (self.IndexOf(str) == 0) 43 | return self.Substring(str.Length); 44 | else 45 | return self; 46 | } 47 | 48 | public static string PopBackMatch(this string self, string str) 49 | { 50 | if (str.Length > self.Length) 51 | return self; 52 | else if (self.LastIndexOf(str) == self.Length - str.Length) 53 | return self.Substring(0, self.Length - str.Length); 54 | else 55 | return self; 56 | } 57 | 58 | public static string PopFront(this string self, int count = 1) 59 | { 60 | if (count > self.Length || count < 0) 61 | throw new IndexOutOfRangeException(); 62 | return self.Substring(count); 63 | } 64 | 65 | public static string PopBack(this string self, int count = 1) 66 | { 67 | if (count > self.Length || count < 0) 68 | throw new IndexOutOfRangeException(); 69 | return self.Substring(0, self.Length - count); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Common/Unzip.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.IO.Compression; 4 | 5 | namespace Pomelo.Package 6 | { 7 | public class Unzip 8 | { 9 | public static void ExtractAll(string filePath, string dest, bool deleteAfterExtracted = true) 10 | { 11 | using (var fileStream = new FileStream(filePath, FileMode.Open)) 12 | using (var archive = new ZipArchive(fileStream)) 13 | { 14 | foreach (var x in archive.Entries) 15 | { 16 | if (!Directory.Exists(Path.GetDirectoryName(dest + x.FullName))) 17 | Directory.CreateDirectory(Path.GetDirectoryName(dest + x.FullName)); 18 | if (x.Length == 0 && string.IsNullOrEmpty(Path.GetExtension(x.FullName))) 19 | continue; 20 | using (var entryStream = x.Open()) 21 | using (var destStream = File.OpenWrite(dest + x.FullName)) 22 | { 23 | entryStream.CopyTo(destStream); 24 | } 25 | } 26 | } 27 | if (deleteAfterExtracted) 28 | File.Delete(filePath); 29 | } 30 | 31 | public static void Extract(string filePath, params Tuple[] files) 32 | { 33 | using (var fileStream = new FileStream(filePath, FileMode.Open)) 34 | using (var archive = new ZipArchive(fileStream)) 35 | { 36 | foreach (var file in files) 37 | { 38 | var entry = archive.GetEntry(file.Item1); 39 | if (entry == null) 40 | throw new Exception("Could not find file '" + file.Item1 + "'."); 41 | 42 | Directory.CreateDirectory(Path.GetDirectoryName(file.Item2)); 43 | 44 | using (var entryStream = entry.Open()) 45 | using (var dllStream = File.OpenWrite(file.Item2)) 46 | { 47 | entryStream.CopyTo(dllStream); 48 | } 49 | } 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Common/VideoInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace System 8 | { 9 | public class VideoInfo 10 | { 11 | /// 12 | /// 片长 13 | /// 14 | public TimeSpan Duration { get; set; } 15 | 16 | /// 17 | /// 比特率 18 | /// 19 | public int Biterate { get; set; } 20 | 21 | /// 22 | /// 宽(px) 23 | /// 24 | public int Width { get; set; } 25 | 26 | /// 27 | /// 高(px) 28 | /// 29 | public int Height { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.Common/Zip.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.IO.Compression; 3 | 4 | namespace Pomelo.Package 5 | { 6 | public static class Zip 7 | { 8 | public static void Compress(string path, string dest, CompressionLevel level = CompressionLevel.Optimal) 9 | { 10 | using (var stream = new FileStream(dest, FileMode.OpenOrCreate)) 11 | using (var archive = new ZipArchive(stream, ZipArchiveMode.Update)) 12 | { 13 | var files = Directory.GetFiles(path, "*", SearchOption.AllDirectories); 14 | foreach(var x in files) 15 | { 16 | var entry = archive.CreateEntry(x.Replace(path, "").Trim('/').Trim('\\'), level); 17 | using (StreamWriter writer = new StreamWriter(entry.Open())) 18 | { 19 | var file = new FileStream(x, FileMode.Open); 20 | file.CopyTo(writer.BaseStream); 21 | } 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.RuntimeEnvironment.Sources/Native/NativeMethods.Windows.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace Microsoft.Extensions.Internal.Native 8 | { 9 | internal static partial class NativeMethods 10 | { 11 | public static class Windows 12 | { 13 | [StructLayout(LayoutKind.Sequential)] 14 | internal struct RTL_OSVERSIONINFOEX 15 | { 16 | internal uint dwOSVersionInfoSize; 17 | internal uint dwMajorVersion; 18 | internal uint dwMinorVersion; 19 | internal uint dwBuildNumber; 20 | internal uint dwPlatformId; 21 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 22 | internal string szCSDVersion; 23 | } 24 | 25 | // This call avoids the shimming Windows does to report old versions 26 | [DllImport("ntdll")] 27 | private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation); 28 | 29 | internal static string RtlGetVersion() 30 | { 31 | RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX(); 32 | osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi); 33 | if (RtlGetVersion(out osvi) == 0) 34 | { 35 | return $"{osvi.dwMajorVersion}.{osvi.dwMinorVersion}.{osvi.dwBuildNumber}"; 36 | } 37 | else 38 | { 39 | return null; 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.RuntimeEnvironment.Sources/Native/PlatformApis.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.IO; 6 | using System.Runtime.InteropServices; 7 | 8 | namespace Microsoft.Extensions.Internal.Native 9 | { 10 | internal static class PlatformApis 11 | { 12 | public static string GetOSVersion() 13 | { 14 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) 15 | { 16 | return NativeMethods.Windows.RtlGetVersion() ?? string.Empty; 17 | } 18 | throw new PlatformNotSupportedException(); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Pomelo.Extensions.RuntimeEnvironment.Sources/Pomelo.Extensions.RuntimeEnvironment.Sources.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.Extensions.RuntimeEnvironment.Sources 7 | Pomelo.Extensions.RuntimeEnvironment.Sources 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | 2.0.0-preview2-25401-01 12 | git 13 | https://github.com/PomeloFoundation/dotNETCore-Extensions 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions.RuntimeEnvironment.Sources/RuntimeEnvironment.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Extensions.Internal 7 | { 8 | internal static class RuntimeEnvironment 9 | { 10 | private static readonly Lazy _operatingSystemVersion = new Lazy(() => Native.PlatformApis.GetOSVersion()); 11 | 12 | /// 13 | /// Don't use in shipping packages 14 | /// 15 | static public string OperatingSystemVersion => _operatingSystemVersion.Value; 16 | 17 | static public string RuntimeType { get; } = GetRuntimeType(); 18 | 19 | static private string GetRuntimeType() 20 | { 21 | #if NET451 22 | return Type.GetType("Mono.Runtime") != null ? "Mono" : "CLR"; 23 | #else 24 | return "CoreCLR"; 25 | #endif 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Pomelo.Extensions/Pomelo.Extensions.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.Extensions 7 | Pomelo.Extensions 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Pomelo.Extensions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.Extensions")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("ec85425d-3de9-450f-823f-c466aa45a46d")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/EncodingFoundException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Pomelo Foundation. All rights reserved. 2 | // Licensed under the MIT License. See License.txt in the project root for license information. 3 | using System; 4 | using System.Text; 5 | 6 | namespace Pomelo.HtmlAgilityPack 7 | { 8 | internal class EncodingFoundException : Exception 9 | { 10 | #region Fields 11 | 12 | private Encoding _encoding; 13 | 14 | #endregion 15 | 16 | #region Constructors 17 | 18 | internal EncodingFoundException(Encoding encoding) 19 | { 20 | _encoding = encoding; 21 | } 22 | 23 | #endregion 24 | 25 | #region Properties 26 | 27 | internal Encoding Encoding 28 | { 29 | get { return _encoding; } 30 | } 31 | 32 | #endregion 33 | } 34 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/HtmlCommentNode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Pomelo Foundation. All rights reserved. 2 | // Licensed under the MIT License. See License.txt in the project root for license information. 3 | namespace Pomelo.HtmlAgilityPack 4 | { 5 | /// 6 | /// Represents an HTML comment. 7 | /// 8 | public class HtmlCommentNode : HtmlNode 9 | { 10 | #region Fields 11 | 12 | private string _comment; 13 | 14 | #endregion 15 | 16 | #region Constructors 17 | 18 | internal HtmlCommentNode(HtmlDocument ownerdocument, int index) 19 | : 20 | base(HtmlNodeType.Comment, ownerdocument, index) 21 | { 22 | } 23 | 24 | #endregion 25 | 26 | #region Properties 27 | 28 | /// 29 | /// Gets or Sets the comment text of the node. 30 | /// 31 | public string Comment 32 | { 33 | get 34 | { 35 | if (_comment == null) 36 | { 37 | return base.InnerHtml; 38 | } 39 | return _comment; 40 | } 41 | set { _comment = value; } 42 | } 43 | 44 | /// 45 | /// Gets or Sets the HTML between the start and end tags of the object. In the case of a text node, it is equals to OuterHtml. 46 | /// 47 | public override string InnerHtml 48 | { 49 | get 50 | { 51 | if (_comment == null) 52 | { 53 | return base.InnerHtml; 54 | } 55 | return _comment; 56 | } 57 | set { _comment = value; } 58 | } 59 | 60 | /// 61 | /// Gets or Sets the object and its content in HTML. 62 | /// 63 | public override string OuterHtml 64 | { 65 | get 66 | { 67 | if (_comment == null) 68 | { 69 | return base.OuterHtml; 70 | } 71 | return ""; 72 | } 73 | } 74 | 75 | #endregion 76 | } 77 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/HtmlConsoleListener.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Pomelo Foundation. All rights reserved. 2 | // Licensed under the MIT License. See License.txt in the project root for license information. 3 | using System; 4 | using System.Diagnostics; 5 | 6 | namespace Pomelo.HtmlAgilityPack 7 | { 8 | internal class HtmlConsoleListener : TraceListener 9 | { 10 | #region Public Methods 11 | 12 | public override void Write(string Message) 13 | { 14 | Write(Message, ""); 15 | } 16 | 17 | public override void Write(string Message, string Category) 18 | { 19 | Console.Write("T:" + Category + ": " + Message); 20 | } 21 | 22 | public override void WriteLine(string Message) 23 | { 24 | Write(Message + "\n"); 25 | } 26 | 27 | public override void WriteLine(string Message, string Category) 28 | { 29 | Write(Message + "\n", Category); 30 | } 31 | 32 | #endregion 33 | } 34 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/HtmlDocument.Xpath.cs: -------------------------------------------------------------------------------- 1 |  2 | using System.Xml.XPath; 3 | 4 | namespace Pomelo.HtmlAgilityPack 5 | { 6 | public partial class HtmlDocument : IXPathNavigable 7 | { 8 | /// 9 | /// Creates a new XPathNavigator object for navigating this HTML document. 10 | /// 11 | /// An XPathNavigator object. The XPathNavigator is positioned on the root of the document. 12 | public XPathNavigator CreateNavigator() 13 | { 14 | return new HtmlNodeNavigator(this, _documentnode); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/HtmlElementFlag.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | 4 | namespace Pomelo.HtmlAgilityPack 5 | { 6 | /// 7 | /// Flags that describe the behavior of an Element node. 8 | /// 9 | [Flags] 10 | public enum HtmlElementFlag 11 | { 12 | /// 13 | /// The node is a CDATA node. 14 | /// 15 | CData = 1, 16 | 17 | /// 18 | /// The node is empty. META or IMG are example of such nodes. 19 | /// 20 | Empty = 2, 21 | 22 | /// 23 | /// The node will automatically be closed during parsing. 24 | /// 25 | Closed = 4, 26 | 27 | /// 28 | /// The node can overlap. 29 | /// 30 | CanOverlap = 8 31 | } 32 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/HtmlNameTable.cs: -------------------------------------------------------------------------------- 1 | 2 | using System.Xml; 3 | 4 | namespace Pomelo.HtmlAgilityPack 5 | { 6 | internal class HtmlNameTable : XmlNameTable 7 | { 8 | #region Fields 9 | 10 | private NameTable _nametable = new NameTable(); 11 | 12 | #endregion 13 | 14 | #region Public Methods 15 | 16 | public override string Add(string array) 17 | { 18 | return _nametable.Add(array); 19 | } 20 | 21 | public override string Add(char[] array, int offset, int length) 22 | { 23 | return _nametable.Add(array, offset, length); 24 | } 25 | 26 | public override string Get(string array) 27 | { 28 | return _nametable.Get(array); 29 | } 30 | 31 | public override string Get(char[] array, int offset, int length) 32 | { 33 | return _nametable.Get(array, offset, length); 34 | } 35 | 36 | #endregion 37 | 38 | #region Internal Methods 39 | 40 | internal string GetOrAdd(string array) 41 | { 42 | string s = Get(array); 43 | if (s == null) 44 | { 45 | return Add(array); 46 | } 47 | return s; 48 | } 49 | 50 | #endregion 51 | } 52 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/HtmlNode.Xpath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.XPath; 3 | 4 | namespace Pomelo.HtmlAgilityPack 5 | { 6 | public partial class HtmlNode : IXPathNavigable 7 | { 8 | 9 | /// 10 | /// Creates a new XPathNavigator object for navigating this HTML node. 11 | /// 12 | /// An XPathNavigator object. The XPathNavigator is positioned on the node from which the method was called. It is not positioned on the root of the document. 13 | public XPathNavigator CreateNavigator() 14 | { 15 | return new HtmlNodeNavigator(OwnerDocument, this); 16 | } 17 | 18 | /// 19 | /// Creates an XPathNavigator using the root of this document. 20 | /// 21 | /// 22 | public XPathNavigator CreateRootNavigator() 23 | { 24 | return new HtmlNodeNavigator(OwnerDocument, OwnerDocument.DocumentNode); 25 | } 26 | 27 | /// 28 | /// Selects a list of nodes matching the expression. 29 | /// 30 | /// The XPath expression. 31 | /// An containing a collection of nodes matching the query, or null if no node matched the XPath expression. 32 | public HtmlNodeCollection SelectNodes(string xpath) 33 | { 34 | HtmlNodeCollection list = new HtmlNodeCollection(null); 35 | 36 | HtmlNodeNavigator nav = new HtmlNodeNavigator(OwnerDocument, this); 37 | XPathNodeIterator it = nav.Select(xpath); 38 | while (it.MoveNext()) 39 | { 40 | HtmlNodeNavigator n = (HtmlNodeNavigator)it.Current; 41 | list.Add(n.CurrentNode); 42 | } 43 | if (list.Count == 0) 44 | { 45 | return null; 46 | } 47 | return list; 48 | } 49 | 50 | /// 51 | /// Selects the first XmlNode that matches the XPath expression. 52 | /// 53 | /// The XPath expression. May not be null. 54 | /// The first that matches the XPath query or a null reference if no matching node was found. 55 | public HtmlNode SelectSingleNode(string xpath) 56 | { 57 | if (xpath == null) 58 | { 59 | throw new ArgumentNullException("xpath"); 60 | } 61 | 62 | HtmlNodeNavigator nav = new HtmlNodeNavigator(OwnerDocument, this); 63 | XPathNodeIterator it = nav.Select(xpath); 64 | if (!it.MoveNext()) 65 | { 66 | return null; 67 | } 68 | 69 | HtmlNodeNavigator node = (HtmlNodeNavigator)it.Current; 70 | return node.CurrentNode; 71 | } 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/HtmlNodeType.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace Pomelo.HtmlAgilityPack 3 | { 4 | /// 5 | /// Represents the type of a node. 6 | /// 7 | public enum HtmlNodeType 8 | { 9 | /// 10 | /// The root of a document. 11 | /// 12 | Document, 13 | 14 | /// 15 | /// An HTML element. 16 | /// 17 | Element, 18 | 19 | /// 20 | /// An HTML comment. 21 | /// 22 | Comment, 23 | 24 | /// 25 | /// A text node is always the child of an element or a document node. 26 | /// 27 | Text, 28 | } 29 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/HtmlParseError.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace Pomelo.HtmlAgilityPack 3 | { 4 | /// 5 | /// Represents a parsing error found during document parsing. 6 | /// 7 | public class HtmlParseError 8 | { 9 | #region Fields 10 | 11 | private HtmlParseErrorCode _code; 12 | private int _line; 13 | private int _linePosition; 14 | private string _reason; 15 | private string _sourceText; 16 | private int _streamPosition; 17 | 18 | #endregion 19 | 20 | #region Constructors 21 | 22 | internal HtmlParseError( 23 | HtmlParseErrorCode code, 24 | int line, 25 | int linePosition, 26 | int streamPosition, 27 | string sourceText, 28 | string reason) 29 | { 30 | _code = code; 31 | _line = line; 32 | _linePosition = linePosition; 33 | _streamPosition = streamPosition; 34 | _sourceText = sourceText; 35 | _reason = reason; 36 | } 37 | 38 | #endregion 39 | 40 | #region Properties 41 | 42 | /// 43 | /// Gets the type of error. 44 | /// 45 | public HtmlParseErrorCode Code 46 | { 47 | get { return _code; } 48 | } 49 | 50 | /// 51 | /// Gets the line number of this error in the document. 52 | /// 53 | public int Line 54 | { 55 | get { return _line; } 56 | } 57 | 58 | /// 59 | /// Gets the column number of this error in the document. 60 | /// 61 | public int LinePosition 62 | { 63 | get { return _linePosition; } 64 | } 65 | 66 | /// 67 | /// Gets a description for the error. 68 | /// 69 | public string Reason 70 | { 71 | get { return _reason; } 72 | } 73 | 74 | /// 75 | /// Gets the the full text of the line containing the error. 76 | /// 77 | public string SourceText 78 | { 79 | get { return _sourceText; } 80 | } 81 | 82 | /// 83 | /// Gets the absolute stream position of this error in the document, relative to the start of the document. 84 | /// 85 | public int StreamPosition 86 | { 87 | get { return _streamPosition; } 88 | } 89 | 90 | #endregion 91 | } 92 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/HtmlParseErrorCode.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace Pomelo.HtmlAgilityPack 3 | { 4 | /// 5 | /// Represents the type of parsing error. 6 | /// 7 | public enum HtmlParseErrorCode 8 | { 9 | /// 10 | /// A tag was not closed. 11 | /// 12 | TagNotClosed, 13 | 14 | /// 15 | /// A tag was not opened. 16 | /// 17 | TagNotOpened, 18 | 19 | /// 20 | /// There is a charset mismatch between stream and declared (META) encoding. 21 | /// 22 | CharsetMismatch, 23 | 24 | /// 25 | /// An end tag was not required. 26 | /// 27 | EndTagNotRequired, 28 | 29 | /// 30 | /// An end tag is invalid at this position. 31 | /// 32 | EndTagInvalidHere 33 | } 34 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/HtmlTextNode.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace Pomelo.HtmlAgilityPack 3 | { 4 | /// 5 | /// Represents an HTML text node. 6 | /// 7 | public class HtmlTextNode : HtmlNode 8 | { 9 | #region Fields 10 | 11 | private string _text; 12 | 13 | #endregion 14 | 15 | #region Constructors 16 | 17 | internal HtmlTextNode(HtmlDocument ownerdocument, int index) 18 | : 19 | base(HtmlNodeType.Text, ownerdocument, index) 20 | { 21 | } 22 | 23 | #endregion 24 | 25 | #region Properties 26 | 27 | /// 28 | /// Gets or Sets the HTML between the start and end tags of the object. In the case of a text node, it is equals to OuterHtml. 29 | /// 30 | public override string InnerHtml 31 | { 32 | get { return OuterHtml; } 33 | set { _text = value; } 34 | } 35 | 36 | /// 37 | /// Gets or Sets the object and its content in HTML. 38 | /// 39 | public override string OuterHtml 40 | { 41 | get 42 | { 43 | if (_text == null) 44 | { 45 | return base.OuterHtml; 46 | } 47 | return _text; 48 | } 49 | } 50 | 51 | /// 52 | /// Gets or Sets the text of the node. 53 | /// 54 | public string Text 55 | { 56 | get 57 | { 58 | if (_text == null) 59 | { 60 | return base.OuterHtml; 61 | } 62 | return _text; 63 | } 64 | set { _text = value; } 65 | } 66 | 67 | #endregion 68 | } 69 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/HtmlWebException.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | 4 | namespace Pomelo.HtmlAgilityPack 5 | { 6 | /// 7 | /// Represents an exception thrown by the HtmlWeb utility class. 8 | /// 9 | public class HtmlWebException : Exception 10 | { 11 | #region Constructors 12 | 13 | /// 14 | /// Creates an instance of the HtmlWebException. 15 | /// 16 | /// The exception's message. 17 | public HtmlWebException(string message) 18 | : base(message) 19 | { 20 | } 21 | 22 | #endregion 23 | } 24 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/IOLibrary.cs: -------------------------------------------------------------------------------- 1 | 2 | using System.IO; 3 | 4 | namespace Pomelo.HtmlAgilityPack 5 | { 6 | internal struct IOLibrary 7 | { 8 | #region Internal Methods 9 | 10 | internal static void CopyAlways(string source, string target) 11 | { 12 | if (!File.Exists(source)) 13 | return; 14 | Directory.CreateDirectory(Path.GetDirectoryName(target)); 15 | MakeWritable(target); 16 | File.Copy(source, target, true); 17 | } 18 | #if !PocketPC && !WINDOWS_PHONE 19 | internal static void MakeWritable(string path) 20 | { 21 | if (!File.Exists(path)) 22 | return; 23 | File.SetAttributes(path, File.GetAttributes(path) & ~FileAttributes.ReadOnly); 24 | } 25 | #else 26 | internal static void MakeWritable(string path) 27 | { 28 | } 29 | #endif 30 | #endregion 31 | } 32 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/MixedCodeDocumentCodeFragment.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace Pomelo.HtmlAgilityPack 3 | { 4 | /// 5 | /// Represents a fragment of code in a mixed code document. 6 | /// 7 | public class MixedCodeDocumentCodeFragment : MixedCodeDocumentFragment 8 | { 9 | #region Fields 10 | 11 | private string _code; 12 | 13 | #endregion 14 | 15 | #region Constructors 16 | 17 | internal MixedCodeDocumentCodeFragment(MixedCodeDocument doc) 18 | : 19 | base(doc, MixedCodeDocumentFragmentType.Code) 20 | { 21 | } 22 | 23 | #endregion 24 | 25 | #region Properties 26 | 27 | /// 28 | /// Gets the fragment code text. 29 | /// 30 | public string Code 31 | { 32 | get 33 | { 34 | if (_code == null) 35 | { 36 | _code = FragmentText.Substring(Doc.TokenCodeStart.Length, 37 | FragmentText.Length - Doc.TokenCodeEnd.Length - 38 | Doc.TokenCodeStart.Length - 1).Trim(); 39 | if (_code.StartsWith("=")) 40 | { 41 | _code = Doc.TokenResponseWrite + _code.Substring(1, _code.Length - 1); 42 | } 43 | } 44 | return _code; 45 | } 46 | set { _code = value; } 47 | } 48 | 49 | #endregion 50 | } 51 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/MixedCodeDocumentFragmentType.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace Pomelo.HtmlAgilityPack 3 | { 4 | /// 5 | /// Represents the type of fragment in a mixed code document. 6 | /// 7 | public enum MixedCodeDocumentFragmentType 8 | { 9 | /// 10 | /// The fragment contains code. 11 | /// 12 | Code, 13 | 14 | /// 15 | /// The fragment contains text. 16 | /// 17 | Text, 18 | } 19 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/MixedCodeDocumentTextFragment.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace Pomelo.HtmlAgilityPack 3 | { 4 | /// 5 | /// Represents a fragment of text in a mixed code document. 6 | /// 7 | public class MixedCodeDocumentTextFragment : MixedCodeDocumentFragment 8 | { 9 | #region Constructors 10 | 11 | internal MixedCodeDocumentTextFragment(MixedCodeDocument doc) 12 | : 13 | base(doc, MixedCodeDocumentFragmentType.Text) 14 | { 15 | } 16 | 17 | #endregion 18 | 19 | #region Properties 20 | 21 | /// 22 | /// Gets the fragment text. 23 | /// 24 | public string Text 25 | { 26 | get { return FragmentText; } 27 | set { FragmentText = value; } 28 | } 29 | 30 | #endregion 31 | } 32 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/NameValuePair.cs: -------------------------------------------------------------------------------- 1 | // HtmlAgilityPack V1.0 - Simon Mourier 2 | namespace Pomelo.HtmlAgilityPack 3 | { 4 | internal class NameValuePair 5 | { 6 | #region Fields 7 | 8 | internal readonly string Name; 9 | internal string Value; 10 | 11 | #endregion 12 | 13 | #region Constructors 14 | 15 | internal NameValuePair() 16 | { 17 | } 18 | 19 | internal NameValuePair(string name) 20 | : 21 | this() 22 | { 23 | Name = name; 24 | } 25 | 26 | internal NameValuePair(string name, string value) 27 | : 28 | this(name) 29 | { 30 | Value = value; 31 | } 32 | 33 | #endregion 34 | } 35 | } -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/Pomelo.HtmlAgilityPack.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.HtmlAgilityPack 7 | Pomelo.HtmlAgilityPack 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.HtmlAgilityPack")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("f6224349-9abc-4e1c-8100-c5f007577f17")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/Trace.FullFramework.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Pomelo.HtmlAgilityPack 6 | { 7 | partial class Trace 8 | { 9 | partial void WriteLineIntern(string message,string category) 10 | { 11 | System.Diagnostics.Debug.WriteLine(message,category); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/Trace.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Pomelo.HtmlAgilityPack 6 | { 7 | internal partial class Trace 8 | { 9 | internal static Trace _current; 10 | internal static Trace Current 11 | { 12 | get 13 | { 14 | if(_current == null) 15 | _current = new Trace(); 16 | return _current; 17 | } 18 | } 19 | partial void WriteLineIntern(string message,string category); 20 | public static void WriteLine(string message,string category) 21 | { 22 | Current.WriteLineIntern(message,category); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Pomelo.HtmlAgilityPack/Utilities.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Pomelo.HtmlAgilityPack 6 | { 7 | internal static class Utilities 8 | { 9 | public static TValue GetDictionaryValueOrNull(Dictionary dict, TKey key) where TKey: class 10 | { 11 | return dict.ContainsKey(key) ? dict[key] : default(TValue); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Pomelo.Marked/Marked.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Pomelo.Marked 7 | { 8 | public static class Instance 9 | { 10 | private static _Marked marked = new _Marked(); 11 | public static string Parse(string MarkdownContent) 12 | { 13 | return marked.Parse(MarkdownContent); 14 | } 15 | } 16 | 17 | internal class _Marked 18 | { 19 | public Options Options { get; set; } 20 | 21 | public _Marked() 22 | : this(null) 23 | { 24 | } 25 | 26 | public _Marked(Options options) 27 | { 28 | Options = options ?? new Options(); 29 | } 30 | 31 | 32 | public virtual string Parse(string src) 33 | { 34 | if (String.IsNullOrEmpty(src)) 35 | { 36 | return src; 37 | } 38 | 39 | var tokens = Lexer.Lex(src, Options); 40 | var result = Parser.Parse(tokens, Options); 41 | return result; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Pomelo.Marked/Objects.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Pomelo.Marked 7 | { 8 | internal class TableCellFlags 9 | { 10 | public bool Header { get; set; } 11 | public string Align { get; set; } 12 | } 13 | 14 | internal class LinkObj 15 | { 16 | public string Href { get; set; } 17 | public string Title { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Pomelo.Marked/Options.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Pomelo.Marked 7 | { 8 | internal class Options 9 | { 10 | #region Fields 11 | 12 | private Renderer _renderer; 13 | 14 | #endregion 15 | 16 | #region Properties 17 | 18 | public Func Highlight { get; set; } 19 | 20 | public Func Sanitizer { get; set; } 21 | 22 | public Renderer Renderer 23 | { 24 | get { return _renderer; } 25 | set { _renderer = value; if (_renderer != null) _renderer.Options = this; } 26 | } 27 | 28 | public string LangPrefix { get; set; } 29 | 30 | public string HeaderPrefix { get; set; } 31 | 32 | public bool XHtml { get; set; } 33 | 34 | public bool Sanitize { get; set; } 35 | 36 | public bool Pedantic { get; set; } 37 | 38 | public bool Mangle { get; set; } 39 | 40 | public bool Smartypants { get; set; } 41 | 42 | public bool Breaks { get; set; } 43 | 44 | public bool Gfm { get; set; } 45 | 46 | public bool Tables { get; set; } 47 | 48 | public bool SmartLists { get; set; } 49 | 50 | #endregion 51 | 52 | #region Constructors 53 | 54 | public Options() 55 | { 56 | Highlight = null; 57 | Sanitizer = null; 58 | Renderer = new Renderer(this); 59 | 60 | LangPrefix = "lang-"; 61 | HeaderPrefix = ""; 62 | XHtml = false; 63 | Sanitize = false; 64 | Pedantic = false; 65 | Mangle = true; 66 | Smartypants = false; 67 | Breaks = false; 68 | Gfm = true; 69 | Tables = true; 70 | SmartLists = false; 71 | } 72 | 73 | #endregion 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Pomelo.Marked/Pomelo.Marked.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.0.0 5 | netstandard2.0 6 | Pomelo.Marked 7 | Pomelo.Marked 8 | https://avatars2.githubusercontent.com/u/19828814?v=3 9 | https://github.com/PomeloFoundation/dotNETCore-Extensions 10 | https://github.com/PomeloFoundation/dotNETCore-Extensions/blob/master/LICENSE 11 | git 12 | https://github.com/PomeloFoundation/dotNETCore-Extensions 13 | 2.0.0-preview2-25401-01 14 | false 15 | false 16 | false 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Pomelo.Marked/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Pomelo.Marked")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("392bcacf-a74d-48d8-933b-83efbe47a624")] 20 | -------------------------------------------------------------------------------- /src/Pomelo.Marked/StringHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace Pomelo.Marked 8 | { 9 | public static class StringHelper 10 | { 11 | public static string DecodeURIComponent(string str) 12 | { 13 | return Uri.UnescapeDataString(str); 14 | } 15 | 16 | public static string Escape(string html, bool encode = false) 17 | { 18 | return Regex.Replace(html, !encode ? @"&(?!#?\w+;)" : @"&", "&") 19 | .Replace("<", "<") 20 | .Replace(">", ">") 21 | .Replace("\"", """) 22 | .Replace("'", "'"); 23 | } 24 | 25 | public static string Unescape(string html) 26 | { 27 | return Regex.Replace(html, @"&([#\w]+);", (Match match) => 28 | { 29 | var n = match.Groups[1].Value; 30 | 31 | n = n.ToLower(); 32 | if (n == "colon") return ":"; 33 | if (n[0] == '#') 34 | { 35 | return n[1] == 'x' 36 | ? ((char)Convert.ToInt32(n.Substring(2), 16)).ToString() 37 | : ((char)Convert.ToInt32(n.Substring(1))).ToString(); 38 | } 39 | return String.Empty; 40 | }); 41 | } 42 | 43 | 44 | 45 | public static string NotEmpty(IList source, int index1, int index2) 46 | { 47 | return (source.Count > index1 && !String.IsNullOrEmpty(source[index1])) ? source[index1] : source[index2]; 48 | } 49 | 50 | 51 | public static string ReplaceRegex(this string input, string pattern, string replacement) 52 | { 53 | return Regex.Replace(input, pattern, replacement); 54 | } 55 | 56 | public static IList SplitRegex(this string input, string pattern) 57 | { 58 | return Regex.Split(input, pattern); 59 | } 60 | 61 | public static IList Exec(this Regex regex, string src) 62 | { 63 | var match = regex.Match(src); 64 | if (!match.Success) return new string[0]; 65 | 66 | return match.Groups.Cast().Select(x => x.Value).ToArray(); 67 | } 68 | 69 | public static string[] Match(this string src, Regex regex) 70 | { 71 | return regex.Matches(src).Cast().Select(x => x.Value).ToArray(); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Pomelo.Marked/Token.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | 7 | namespace Pomelo.Marked 8 | { 9 | internal class Token 10 | { 11 | public string Text { get; set; } 12 | public string Type { get; set; } 13 | 14 | 15 | public int Depth { get; set; } 16 | public bool Escaped { get; set; } 17 | public string Lang { get; set; } 18 | public bool Ordered { get; set; } 19 | 20 | public bool Pre { get; set; } 21 | 22 | public IList Header { get; set; } 23 | public IList Align { get; set; } 24 | public IList> Cells { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Pomelo.Marked/TokensResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Pomelo.Marked 7 | { 8 | internal class TokensResult 9 | { 10 | public IList Tokens { get; set; } 11 | public IDictionary Links { get; set; } 12 | public int Length { get { return Tokens.Count; } } 13 | 14 | public IEnumerable Reverse() 15 | { 16 | return Tokens.Reverse(); 17 | } 18 | 19 | public TokensResult() 20 | { 21 | Tokens = new List(); 22 | Links = new Dictionary(); 23 | } 24 | 25 | 26 | public void Add(Token token) 27 | { 28 | Tokens.Add(token); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Pomelo.Net.Smtp/Attachment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.Net.Smtp 7 | { 8 | public class Attachment 9 | { 10 | public string FileName { get; set; } 11 | 12 | public byte[] File { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Pomelo.Net.Smtp/EmailSender.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Pomelo.Net.Smtp 7 | { 8 | public abstract class EmailSender : IEmailSender 9 | { 10 | public Task SendEmailAsync(string to, string subject, string message, params Attachment[] Attachments) 11 | { 12 | return PostEmailAsync(null, to, null, null, subject, message, Attachments); 13 | } 14 | 15 | public Task PostEmailAsync(string name, string to, string subject, string message, params Attachment[] Attachments) 16 | { 17 | return PostEmailAsync(name, to, null, null, subject, message, Attachments); 18 | } 19 | 20 | public Task SendEmailAsync(string to, string cc, string bcc, string subject, string message, params Attachment[] Attachments) 21 | { 22 | return PostEmailAsync(null, to, cc, bcc, subject, message, Attachments); 23 | } 24 | 25 | public Task SendEmailAsync(string[] to, string[] cc, string[] bcc, string subject, string message, params Attachment[] Attachments) 26 | { 27 | return PostEmailAsync(null, to, cc, bcc, subject, message, Attachments); 28 | } 29 | 30 | public Task PostEmailAsync(string name, string to, string cc, string bcc, string subject, string message, params Attachment[] Attachments) 31 | { 32 | var _to = new string[0]; 33 | var _cc = new string[0]; 34 | var _bcc = new string[0]; 35 | if (!string.IsNullOrEmpty(to)) 36 | _to = to.Split(',').Select(x => x.Trim()).ToArray(); 37 | if (!string.IsNullOrEmpty(cc)) 38 | _cc = cc.Split(',').Select(x => x.Trim()).ToArray(); 39 | if (!string.IsNullOrEmpty(bcc)) 40 | _bcc = bcc.Split(',').Select(x => x.Trim()).ToArray(); 41 | return PostEmailAsync(name, _to, _cc, _bcc, subject, message, Attachments); 42 | } 43 | 44 | public abstract Task PostEmailAsync(string name, string[] to, string[] cc, string[] bcc, string subject, string message, params Attachment[] Attachments); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Pomelo.Net.Smtp/HtmlHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Text; 6 | using System.Text.RegularExpressions; 7 | 8 | namespace Pomelo.Net.Smtp 9 | { 10 | public static class HtmlHelper 11 | { 12 | public static string NoHTML(string Htmlstring) 13 | { 14 | //删除脚本 15 | Htmlstring = Regex.Replace(Htmlstring, @"]*?>.*?", "", 16 | RegexOptions.IgnoreCase); 17 | //删除HTML 18 | Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", 19 | RegexOptions.IgnoreCase); 20 | Htmlstring = Regex.Replace(Htmlstring, @"([\r\n])[\s]+", "", 21 | RegexOptions.IgnoreCase); 22 | Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase); 23 | Htmlstring = Regex.Replace(Htmlstring, @"