diff --git a/Util.sln b/Util.sln
index cbb8af7e3..1df835ea9 100644
--- a/Util.sln
+++ b/Util.sln
@@ -267,11 +267,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Util.Generators.Tests", "te
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "08-FileStorage", "08-FileStorage", "{E069CEB0-8092-4907-BC9D-C6B8BDE20AD2}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "01-Util.FileStorage", "src\Util.FileStorage\01-Util.FileStorage.csproj", "{6FC29D15-7581-4E29-9897-76DC5AEF2042}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "02-Util.FileStorage", "src\Util.FileStorage\02-Util.FileStorage.csproj", "{6FC29D15-7581-4E29-9897-76DC5AEF2042}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "02-Util.FileStorage.Minio", "src\Util.FileStorage.Minio\02-Util.FileStorage.Minio.csproj", "{3E81F8D0-06C7-4FD4-A5B0-E3D96E909646}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "03-Util.FileStorage.Minio", "src\Util.FileStorage.Minio\03-Util.FileStorage.Minio.csproj", "{3E81F8D0-06C7-4FD4-A5B0-E3D96E909646}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "03-Util.FileStorage.Aliyun", "src\Util.FileStorage.Aliyun\03-Util.FileStorage.Aliyun.csproj", "{C233FF83-E15D-4A17-8FF1-BBFF9E9DE210}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "04-Util.FileStorage.Aliyun", "src\Util.FileStorage.Aliyun\04-Util.FileStorage.Aliyun.csproj", "{C233FF83-E15D-4A17-8FF1-BBFF9E9DE210}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "08-FileStorage", "08-FileStorage", "{16175228-03CA-414A-8786-E5BA844110C4}"
EndProject
@@ -339,10 +339,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "07-Util.Http", "src\Util.Ht
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Util.FileStorage.Tests.Integration", "test\Util.FileStorage.Tests.Integration\Util.FileStorage.Tests.Integration.csproj", "{A23BA1A3-8EC7-4937-B0AA-69CCEE40453C}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "04-Util.FileStorage.All", "src\Util.FileStorage.All\04-Util.FileStorage.All.csproj", "{4938D59D-CF50-4090-B936-36DB29EBE344}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "05-Util.FileStorage.All", "src\Util.FileStorage.All\05-Util.FileStorage.All.csproj", "{4938D59D-CF50-4090-B936-36DB29EBE344}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Util.FileStorage.Aliyun.Tests.Integration", "test\Util.FileStorage.Aliyun.Tests.Integration\Util.FileStorage.Aliyun.Tests.Integration.csproj", "{58C01936-5D8F-4077-8663-EE0E35776D65}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "01-Util.FileStorage.Abstractions", "src\Util.FileStorage.Abstractions\01-Util.FileStorage.Abstractions.csproj", "{814E42E9-508E-487F-BCD3-0F07AE7D1492}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -857,6 +859,10 @@ Global
{58C01936-5D8F-4077-8663-EE0E35776D65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{58C01936-5D8F-4077-8663-EE0E35776D65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{58C01936-5D8F-4077-8663-EE0E35776D65}.Release|Any CPU.Build.0 = Release|Any CPU
+ {814E42E9-508E-487F-BCD3-0F07AE7D1492}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {814E42E9-508E-487F-BCD3-0F07AE7D1492}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {814E42E9-508E-487F-BCD3-0F07AE7D1492}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {814E42E9-508E-487F-BCD3-0F07AE7D1492}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1027,6 +1033,7 @@ Global
{A23BA1A3-8EC7-4937-B0AA-69CCEE40453C} = {16175228-03CA-414A-8786-E5BA844110C4}
{4938D59D-CF50-4090-B936-36DB29EBE344} = {E069CEB0-8092-4907-BC9D-C6B8BDE20AD2}
{58C01936-5D8F-4077-8663-EE0E35776D65} = {16175228-03CA-414A-8786-E5BA844110C4}
+ {814E42E9-508E-487F-BCD3-0F07AE7D1492} = {E069CEB0-8092-4907-BC9D-C6B8BDE20AD2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {94347832-A36D-4C42-9C4D-B848BD4F5DA9}
diff --git a/build/version.props b/build/version.props
index 92d67f8b7..d100b181f 100644
--- a/build/version.props
+++ b/build/version.props
@@ -2,7 +2,7 @@
7
1
- 123
+ 125
$(VersionMajor).$(VersionMinor).$(VersionPatch)
diff --git a/src/Util.Aop.AspectCore/AopOptions.cs b/src/Util.Aop.AspectCore/AopOptions.cs
new file mode 100644
index 000000000..6e56f1701
--- /dev/null
+++ b/src/Util.Aop.AspectCore/AopOptions.cs
@@ -0,0 +1,15 @@
+namespace Util.Aop;
+
+///
+/// Aop配置
+///
+public class AopOptions {
+ ///
+ /// 是否启用IAopProxy接口标记
+ ///
+ public bool IsEnableIAopProxy { get; set; }
+ ///
+ /// 是否启用参数拦截器,默认值: true
+ ///
+ public bool IsEnableParameterAspect { get; set; } = true;
+}
\ No newline at end of file
diff --git a/src/Util.Aop.AspectCore/AppBuilderExtensions.cs b/src/Util.Aop.AspectCore/AppBuilderExtensions.cs
index dfc53b9c4..6c52982c2 100644
--- a/src/Util.Aop.AspectCore/AppBuilderExtensions.cs
+++ b/src/Util.Aop.AspectCore/AppBuilderExtensions.cs
@@ -39,10 +39,22 @@ public static IAppBuilder AddAop( this IAppBuilder builder, ActionAspectCore拦截器配置操作
/// 是否启用IAopProxy接口标记
private static IAppBuilder AddAop( this IAppBuilder builder, Action setupAction, bool isEnableIAopProxy ) {
+ return builder.AddAop( setupAction, t => t.IsEnableIAopProxy = isEnableIAopProxy );
+ }
+
+ ///
+ /// 启用AspectCore拦截器
+ ///
+ /// 应用生成器
+ /// AspectCore拦截器配置操作
+ /// 配置操作
+ private static IAppBuilder AddAop( this IAppBuilder builder, Action setupAction, Action action ) {
builder.CheckNull( nameof( builder ) );
builder.Host.UseServiceProviderFactory( new DynamicProxyServiceProviderFactory() );
builder.Host.ConfigureServices( ( context, services ) => {
- ConfigureDynamicProxy( services, setupAction, isEnableIAopProxy );
+ var options = new AopOptions();
+ action?.Invoke( options );
+ ConfigureDynamicProxy( services, setupAction, options.IsEnableParameterAspect,options.IsEnableIAopProxy );
RegisterAspectScoped( services );
} );
return builder;
@@ -51,11 +63,12 @@ private static IAppBuilder AddAop( this IAppBuilder builder, Action
/// 配置拦截器
///
- private static void ConfigureDynamicProxy( IServiceCollection services, Action setupAction, bool isEnableIAopProxy ) {
+ private static void ConfigureDynamicProxy( IServiceCollection services, Action setupAction,bool isEnableParameterAspect, bool isEnableIAopProxy ) {
services.ConfigureDynamicProxy( config => {
if ( setupAction == null ) {
config.NonAspectPredicates.Add( t => !IsProxy( t.DeclaringType, isEnableIAopProxy ) );
- config.EnableParameterAspect();
+ if( isEnableParameterAspect )
+ config.EnableParameterAspect();
return;
}
setupAction.Invoke( config );
@@ -69,9 +82,7 @@ private static bool IsProxy( Type type, bool isEnableIAopProxy ) {
if ( type == null )
return false;
if ( isEnableIAopProxy == false ) {
- if ( type.SafeString().Contains( "Xunit.DependencyInjection.ITestOutputHelperAccessor" ) )
- return false;
- return true;
+ return type.SafeString().Contains( "Xunit.DependencyInjection.ITestOutputHelperAccessor" ) == false;
}
var interfaces = type.GetInterfaces();
if ( interfaces == null || interfaces.Length == 0 )
diff --git a/src/Util.FileStorage.Abstractions/01-Util.FileStorage.Abstractions.csproj b/src/Util.FileStorage.Abstractions/01-Util.FileStorage.Abstractions.csproj
new file mode 100644
index 000000000..e81d9142a
--- /dev/null
+++ b/src/Util.FileStorage.Abstractions/01-Util.FileStorage.Abstractions.csproj
@@ -0,0 +1,33 @@
+
+
+
+ $(NetTargetFramework)
+ icon.jpg
+ Util.FileStorage.Abstractions
+ Util.FileStorage
+ Util.FileStorage.Abstractions是Util应用框架文件存储操作接口定义类库
+
+
+
+
+ .\obj\Debug\$(NetTargetFramework)\Util.FileStorage.Abstractions.xml
+
+
+
+
+ .\obj\Release\$(NetTargetFramework)\Util.FileStorage.Abstractions.xml
+
+
+
+
+ True
+ False
+
+
+
+
+
+
+
+
+
diff --git a/src/Util.FileStorage/DeleteFileArgs.cs b/src/Util.FileStorage.Abstractions/DeleteFileArgs.cs
similarity index 100%
rename from src/Util.FileStorage/DeleteFileArgs.cs
rename to src/Util.FileStorage.Abstractions/DeleteFileArgs.cs
diff --git a/src/Util.FileStorage/DirectUploadParam.cs b/src/Util.FileStorage.Abstractions/DirectUploadParam.cs
similarity index 100%
rename from src/Util.FileStorage/DirectUploadParam.cs
rename to src/Util.FileStorage.Abstractions/DirectUploadParam.cs
diff --git a/src/Util.FileStorage/FileExistsArgs.cs b/src/Util.FileStorage.Abstractions/FileExistsArgs.cs
similarity index 100%
rename from src/Util.FileStorage/FileExistsArgs.cs
rename to src/Util.FileStorage.Abstractions/FileExistsArgs.cs
diff --git a/src/Util.FileStorage/FileResult.cs b/src/Util.FileStorage.Abstractions/FileResult.cs
similarity index 100%
rename from src/Util.FileStorage/FileResult.cs
rename to src/Util.FileStorage.Abstractions/FileResult.cs
diff --git a/src/Util.FileStorage/FileSize.cs b/src/Util.FileStorage.Abstractions/FileSize.cs
similarity index 72%
rename from src/Util.FileStorage/FileSize.cs
rename to src/Util.FileStorage.Abstractions/FileSize.cs
index 4b343059d..ed5355565 100644
--- a/src/Util.FileStorage/FileSize.cs
+++ b/src/Util.FileStorage.Abstractions/FileSize.cs
@@ -18,6 +18,15 @@ public FileSize( long size, FileSizeUnit unit = FileSizeUnit.Byte ) {
_size = GetSize( size, unit );
}
+ ///
+ /// 初始化文件大小
+ ///
+ /// 文件大小
+ /// 文件大小单位
+ public FileSize( double size, FileSizeUnit unit = FileSizeUnit.Byte ) {
+ _size = Util.Helpers.Convert.ToLong( GetSize( size, unit ) );
+ }
+
///
/// 获取文件大小
///
@@ -34,6 +43,22 @@ private static long GetSize( long size, FileSizeUnit unit ) {
}
}
+ ///
+ /// 获取文件大小
+ ///
+ private static double GetSize( double size, FileSizeUnit unit ) {
+ switch( unit ) {
+ case FileSizeUnit.K:
+ return size * 1024;
+ case FileSizeUnit.M:
+ return size * 1024 * 1024;
+ case FileSizeUnit.G:
+ return size * 1024 * 1024 * 1024;
+ default:
+ return size;
+ }
+ }
+
///
/// 文件字节长度
///
diff --git a/src/Util.FileStorage/FileSizeUnit.cs b/src/Util.FileStorage.Abstractions/FileSizeUnit.cs
similarity index 100%
rename from src/Util.FileStorage/FileSizeUnit.cs
rename to src/Util.FileStorage.Abstractions/FileSizeUnit.cs
diff --git a/src/Util.FileStorage/FileStorageArgs.cs b/src/Util.FileStorage.Abstractions/FileStorageArgs.cs
similarity index 100%
rename from src/Util.FileStorage/FileStorageArgs.cs
rename to src/Util.FileStorage.Abstractions/FileStorageArgs.cs
diff --git a/src/Util.FileStorage/FileStorageInfo.cs b/src/Util.FileStorage.Abstractions/FileStorageInfo.cs
similarity index 100%
rename from src/Util.FileStorage/FileStorageInfo.cs
rename to src/Util.FileStorage.Abstractions/FileStorageInfo.cs
diff --git a/src/Util.FileStorage/GenerateDownloadUrlArgs.cs b/src/Util.FileStorage.Abstractions/GenerateDownloadUrlArgs.cs
similarity index 100%
rename from src/Util.FileStorage/GenerateDownloadUrlArgs.cs
rename to src/Util.FileStorage.Abstractions/GenerateDownloadUrlArgs.cs
diff --git a/src/Util.FileStorage/GenerateUploadUrlArgs.cs b/src/Util.FileStorage.Abstractions/GenerateUploadUrlArgs.cs
similarity index 88%
rename from src/Util.FileStorage/GenerateUploadUrlArgs.cs
rename to src/Util.FileStorage.Abstractions/GenerateUploadUrlArgs.cs
index d20a3c3fe..132eee52f 100644
--- a/src/Util.FileStorage/GenerateUploadUrlArgs.cs
+++ b/src/Util.FileStorage.Abstractions/GenerateUploadUrlArgs.cs
@@ -48,4 +48,9 @@ public void AddHeader( string key,string value ) {
public IDictionary GetHeaders() {
return _headers;
}
+
+ ///
+ /// 文件大小限制,单位:字节
+ ///
+ public long SizeLimit { get; set; }
}
\ No newline at end of file
diff --git a/src/Util.FileStorage/GetFileStreamArgs.cs b/src/Util.FileStorage.Abstractions/GetFileStreamArgs.cs
similarity index 100%
rename from src/Util.FileStorage/GetFileStreamArgs.cs
rename to src/Util.FileStorage.Abstractions/GetFileStreamArgs.cs
diff --git a/src/Util.FileStorage/IBucketNameProcessor.cs b/src/Util.FileStorage.Abstractions/IBucketNameProcessor.cs
similarity index 100%
rename from src/Util.FileStorage/IBucketNameProcessor.cs
rename to src/Util.FileStorage.Abstractions/IBucketNameProcessor.cs
diff --git a/src/Util.FileStorage/IBucketNameProcessorFactory.cs b/src/Util.FileStorage.Abstractions/IBucketNameProcessorFactory.cs
similarity index 100%
rename from src/Util.FileStorage/IBucketNameProcessorFactory.cs
rename to src/Util.FileStorage.Abstractions/IBucketNameProcessorFactory.cs
diff --git a/src/Util.FileStorage/IFileExtensionInspector.cs b/src/Util.FileStorage.Abstractions/IFileExtensionInspector.cs
similarity index 100%
rename from src/Util.FileStorage/IFileExtensionInspector.cs
rename to src/Util.FileStorage.Abstractions/IFileExtensionInspector.cs
diff --git a/src/Util.FileStorage/IFileNameFilter.cs b/src/Util.FileStorage.Abstractions/IFileNameFilter.cs
similarity index 100%
rename from src/Util.FileStorage/IFileNameFilter.cs
rename to src/Util.FileStorage.Abstractions/IFileNameFilter.cs
diff --git a/src/Util.FileStorage/IFileNameProcessor.cs b/src/Util.FileStorage.Abstractions/IFileNameProcessor.cs
similarity index 100%
rename from src/Util.FileStorage/IFileNameProcessor.cs
rename to src/Util.FileStorage.Abstractions/IFileNameProcessor.cs
diff --git a/src/Util.FileStorage/IFileNameProcessorFactory.cs b/src/Util.FileStorage.Abstractions/IFileNameProcessorFactory.cs
similarity index 100%
rename from src/Util.FileStorage/IFileNameProcessorFactory.cs
rename to src/Util.FileStorage.Abstractions/IFileNameProcessorFactory.cs
diff --git a/src/Util.FileStorage/IFileStore.cs b/src/Util.FileStorage.Abstractions/IFileStore.cs
similarity index 100%
rename from src/Util.FileStorage/IFileStore.cs
rename to src/Util.FileStorage.Abstractions/IFileStore.cs
diff --git a/src/Util.FileStorage/ILocalFileStore.cs b/src/Util.FileStorage.Abstractions/ILocalFileStore.cs
similarity index 100%
rename from src/Util.FileStorage/ILocalFileStore.cs
rename to src/Util.FileStorage.Abstractions/ILocalFileStore.cs
diff --git a/src/Util.FileStorage/ProcessedName.cs b/src/Util.FileStorage.Abstractions/ProcessedName.cs
similarity index 100%
rename from src/Util.FileStorage/ProcessedName.cs
rename to src/Util.FileStorage.Abstractions/ProcessedName.cs
diff --git a/src/Util.FileStorage/SaveFileArgs.cs b/src/Util.FileStorage.Abstractions/SaveFileArgs.cs
similarity index 100%
rename from src/Util.FileStorage/SaveFileArgs.cs
rename to src/Util.FileStorage.Abstractions/SaveFileArgs.cs
diff --git a/src/Util.FileStorage/SaveFileByUrlArgs.cs b/src/Util.FileStorage.Abstractions/SaveFileByUrlArgs.cs
similarity index 100%
rename from src/Util.FileStorage/SaveFileByUrlArgs.cs
rename to src/Util.FileStorage.Abstractions/SaveFileByUrlArgs.cs
diff --git a/src/Util.FileStorage.Abstractions/Usings.cs b/src/Util.FileStorage.Abstractions/Usings.cs
new file mode 100644
index 000000000..a14c45150
--- /dev/null
+++ b/src/Util.FileStorage.Abstractions/Usings.cs
@@ -0,0 +1,11 @@
+global using System;
+global using System.Threading.Tasks;
+global using System.Collections.Generic;
+global using System.Threading;
+global using System.IO;
+global using System.ComponentModel;
+global using System.Linq;
+global using Microsoft.Extensions.Options;
+global using Microsoft.Extensions.DependencyInjection;
+global using Microsoft.Extensions.DependencyInjection.Extensions;
+global using Util.Dependency;
diff --git a/src/Util.FileStorage.Aliyun/03-Util.FileStorage.Aliyun.csproj b/src/Util.FileStorage.Aliyun/04-Util.FileStorage.Aliyun.csproj
similarity index 92%
rename from src/Util.FileStorage.Aliyun/03-Util.FileStorage.Aliyun.csproj
rename to src/Util.FileStorage.Aliyun/04-Util.FileStorage.Aliyun.csproj
index df0838c48..c940a47c6 100644
--- a/src/Util.FileStorage.Aliyun/03-Util.FileStorage.Aliyun.csproj
+++ b/src/Util.FileStorage.Aliyun/04-Util.FileStorage.Aliyun.csproj
@@ -31,7 +31,7 @@
-
+
diff --git a/src/Util.FileStorage.Aliyun/AliyunFileStore.cs b/src/Util.FileStorage.Aliyun/AliyunFileStore.cs
index 970e5c1f8..7a7b680dd 100644
--- a/src/Util.FileStorage.Aliyun/AliyunFileStore.cs
+++ b/src/Util.FileStorage.Aliyun/AliyunFileStore.cs
@@ -442,16 +442,16 @@ protected async Task ProcessBucketName( FileStorageArgs args ) {
args.CheckNull( nameof( args ) );
var processedFileName = ProcessFileName( args );
var processedBucketName = await ProcessBucketName( args );
- return await GenerateUploadUrlAsync( processedFileName, processedBucketName, cancellationToken );
+ return await GenerateUploadUrlAsync( processedFileName, processedBucketName, args.SizeLimit );
}
///
/// 生成直传Url
///
- protected async Task GenerateUploadUrlAsync( ProcessedName fileName, ProcessedName bucketName, CancellationToken cancellationToken ) {
+ protected async Task GenerateUploadUrlAsync( ProcessedName fileName, ProcessedName bucketName, long sizeLimit ) {
await InitConfig();
var url = CreateGenerateUploadHost( bucketName.Name );
- var data = await CreateGenerateUploadData( fileName, bucketName, cancellationToken );
+ var data = await CreateGenerateUploadData( fileName, bucketName, sizeLimit );
return new DirectUploadParam( fileName.Name, url, data, fileName.OriginalName, bucketName.Name );
}
@@ -472,8 +472,8 @@ protected string CreateGenerateUploadHost( string bucketName ) {
///
/// 创建直传数据
///
- protected async Task CreateGenerateUploadData( ProcessedName fileName, ProcessedName bucketName, CancellationToken cancellationToken ) {
- var policy = await GetPostPolicy( bucketName );
+ protected async Task CreateGenerateUploadData( ProcessedName fileName, ProcessedName bucketName, long sizeLimit ) {
+ var policy = await GetPostPolicy( bucketName, sizeLimit );
var signature = ComputeSignature( _config.AccessKeySecret, policy );
return new DirectUploadData( fileName.Name, policy, _config.AccessKeyId, signature );
}
@@ -481,11 +481,12 @@ protected async Task CreateGenerateUploadData( ProcessedName f
///
/// 获取Post策略
///
- protected virtual async Task GetPostPolicy( ProcessedName bucketName ) {
+ protected virtual async Task GetPostPolicy( ProcessedName bucketName,long sizeLimit ) {
var client = await GetClient();
var expiration = DateTime.Now.AddSeconds( _config.UploadUrlExpiration );
var policy = new PolicyConditions();
policy.AddConditionItem( "bucket", bucketName.Name );
+ policy.AddConditionItem( "content-length-range", 1,sizeLimit );
var postPolicy = client.GeneratePostPolicy( expiration, policy );
return Util.Helpers.Convert.ToBase64( postPolicy );
}
diff --git a/src/Util.FileStorage.All/04-Util.FileStorage.All.csproj b/src/Util.FileStorage.All/05-Util.FileStorage.All.csproj
similarity index 87%
rename from src/Util.FileStorage.All/04-Util.FileStorage.All.csproj
rename to src/Util.FileStorage.All/05-Util.FileStorage.All.csproj
index 5e8d68dc3..9467de684 100644
--- a/src/Util.FileStorage.All/04-Util.FileStorage.All.csproj
+++ b/src/Util.FileStorage.All/05-Util.FileStorage.All.csproj
@@ -27,8 +27,8 @@
-
-
+
+
diff --git a/src/Util.FileStorage.All/FileStoreFactory.cs b/src/Util.FileStorage.All/FileStoreFactory.cs
index 3f97ad522..e00551e9b 100644
--- a/src/Util.FileStorage.All/FileStoreFactory.cs
+++ b/src/Util.FileStorage.All/FileStoreFactory.cs
@@ -13,10 +13,6 @@ public class FileStoreFactory : IFileStoreFactory {
///
private readonly IBucketNameProcessorFactory _bucketNameProcessorFactory;
///
- /// 文件扩展名检查器
- ///
- private readonly IFileExtensionInspector _inspector;
- ///
/// Http操作
///
private readonly IHttpClient _httpClient;
@@ -32,19 +28,17 @@ public class FileStoreFactory : IFileStoreFactory {
/// 存储桶名称处理器工厂
/// Http客户端工厂
/// Http操作
- /// 文件扩展名检查器
public FileStoreFactory( IFileNameProcessorFactory fileNameProcessorFactory, IBucketNameProcessorFactory bucketNameProcessorFactory,
- IHttpClientFactory httpClientFactory, IHttpClient httpClient, IFileExtensionInspector inspector ) {
+ IHttpClientFactory httpClientFactory, IHttpClient httpClient ) {
_fileNameProcessorFactory = fileNameProcessorFactory ?? throw new ArgumentNullException( nameof( fileNameProcessorFactory ) );
_bucketNameProcessorFactory = bucketNameProcessorFactory ?? throw new ArgumentNullException( nameof( bucketNameProcessorFactory ) );
_httpClientFactory = httpClientFactory ?? throw new ArgumentNullException( nameof( httpClientFactory ) );
_httpClient = httpClient ?? throw new ArgumentNullException( nameof( httpClient ) );
- _inspector = inspector ?? throw new ArgumentNullException( nameof( inspector ) );
}
///
public IFileStore Create( LocalStoreOptions options ) {
- return new LocalFileStore( new LocalStoreConfigProvider( options ), _fileNameProcessorFactory, _inspector, _httpClient );
+ return new LocalFileStore( new LocalStoreConfigProvider( options ), _fileNameProcessorFactory, _httpClient );
}
///
diff --git a/src/Util.FileStorage.Minio/02-Util.FileStorage.Minio.csproj b/src/Util.FileStorage.Minio/03-Util.FileStorage.Minio.csproj
similarity index 92%
rename from src/Util.FileStorage.Minio/02-Util.FileStorage.Minio.csproj
rename to src/Util.FileStorage.Minio/03-Util.FileStorage.Minio.csproj
index 82ab966fe..18c956652 100644
--- a/src/Util.FileStorage.Minio/02-Util.FileStorage.Minio.csproj
+++ b/src/Util.FileStorage.Minio/03-Util.FileStorage.Minio.csproj
@@ -31,7 +31,7 @@
-
+
diff --git a/src/Util.FileStorage/01-Util.FileStorage.csproj b/src/Util.FileStorage/02-Util.FileStorage.csproj
similarity index 89%
rename from src/Util.FileStorage/01-Util.FileStorage.csproj
rename to src/Util.FileStorage/02-Util.FileStorage.csproj
index 4081506c9..9f22f2682 100644
--- a/src/Util.FileStorage/01-Util.FileStorage.csproj
+++ b/src/Util.FileStorage/02-Util.FileStorage.csproj
@@ -27,6 +27,7 @@
+
diff --git a/src/Util.FileStorage/IFileStoreExtensions.cs b/src/Util.FileStorage/FileStoreExtensions.cs
similarity index 96%
rename from src/Util.FileStorage/IFileStoreExtensions.cs
rename to src/Util.FileStorage/FileStoreExtensions.cs
index 5ad00c7bd..80c7bdf08 100644
--- a/src/Util.FileStorage/IFileStoreExtensions.cs
+++ b/src/Util.FileStorage/FileStoreExtensions.cs
@@ -3,7 +3,7 @@
///
/// 文件存储服务操作扩展
///
-public static class IFileStoreExtensions {
+public static class FileStoreExtensions {
///
/// 保存文件
///
diff --git a/src/Util.FileStorage/FileValidation.cs b/src/Util.FileStorage/FileValidation.cs
new file mode 100644
index 000000000..a66cc8ca6
--- /dev/null
+++ b/src/Util.FileStorage/FileValidation.cs
@@ -0,0 +1,23 @@
+namespace Util.FileStorage;
+
+///
+/// 文件验证操作
+///
+public static class FileValidation {
+ ///
+ /// 扩展名是否有效
+ ///
+ /// 文件名,范例: a.jpg
+ /// 接受的扩展名列表,以逗号分隔,范例: .jpg,.png,.gif
+ public static bool IsValidExtension( string fileName, string accepts ) {
+ if( fileName.IsEmpty() )
+ return false;
+ if( accepts.IsEmpty() )
+ return true;
+ var extension = Path.GetExtension( fileName );
+ var list = accepts.Split( ',' ).Where( t => t.IsEmpty() == false ).ToList();
+ if ( list.Count == 0 )
+ return true;
+ return list.Any( type => type.TrimStart( '.' ) == extension.TrimStart( '.' ) );
+ }
+}
\ No newline at end of file
diff --git a/src/Util.FileStorage/Local/LocalFileStore.cs b/src/Util.FileStorage/Local/LocalFileStore.cs
index 82180cc11..894d099ef 100644
--- a/src/Util.FileStorage/Local/LocalFileStore.cs
+++ b/src/Util.FileStorage/Local/LocalFileStore.cs
@@ -16,10 +16,6 @@ public class LocalFileStore : IFileStore {
///
private readonly IFileNameProcessorFactory _fileNameProcessorFactory;
///
- /// 文件扩展名检查器
- ///
- private readonly IFileExtensionInspector _inspector;
- ///
/// 本地文件存储配置
///
private LocalStoreOptions _config;
@@ -37,13 +33,10 @@ public class LocalFileStore : IFileStore {
///
/// 配置提供器
/// 文件名处理器工厂
- /// 文件扩展名检查器
/// Http操作
- public LocalFileStore( ILocalStoreConfigProvider configProvider, IFileNameProcessorFactory fileNameProcessorFactory,
- IFileExtensionInspector inspector, IHttpClient httpClient ) {
+ public LocalFileStore( ILocalStoreConfigProvider configProvider, IFileNameProcessorFactory fileNameProcessorFactory, IHttpClient httpClient ) {
_configProvider = configProvider ?? throw new ArgumentNullException( nameof( configProvider ) );
_fileNameProcessorFactory = fileNameProcessorFactory ?? throw new ArgumentNullException( nameof( fileNameProcessorFactory ) );
- _inspector = inspector ?? throw new ArgumentNullException( nameof( inspector ) );
_httpClient = httpClient ?? throw new ArgumentNullException( nameof( httpClient ) );
}
@@ -177,7 +170,6 @@ protected virtual async Task GetPhysicalPath( ProcessedName fileName ) {
///
public virtual async Task SaveFileAsync( Stream stream, ProcessedName fileName, CancellationToken cancellationToken = default ) {
stream.CheckNull( nameof( stream ) );
- ValidateExtension( stream, fileName.OriginalName );
var config = await GetConfig();
var filePath = Path.Combine( config.RootPath, fileName.Name );
var physicalPath = Path.Combine( Util.Helpers.Web.Environment.WebRootPath, filePath );
@@ -185,21 +177,6 @@ protected virtual async Task GetPhysicalPath( ProcessedName fileName ) {
return new FileResult( filePath, stream.Length, fileName.OriginalName );
}
- ///
- /// 验证扩展名
- ///
- protected virtual void ValidateExtension( Stream stream, string fileName ) {
- var extension = Path.GetExtension( fileName );
- if( extension.IsEmpty() )
- return;
- var result = _inspector.GetExtension( stream );
- if( result.IsEmpty() )
- return;
- extension = extension.TrimStart( '.' ).ToUpperInvariant();
- if( extension != result.ToUpperInvariant() )
- throw new InvalidOperationException( $"上传文件扩展名检查失败,文件名:{fileName},扩展名: {extension} != {result}" );
- }
-
#endregion
#region SaveFileByUrlAsync
diff --git a/src/Util.FileStorage/Usings.cs b/src/Util.FileStorage/Usings.cs
index 8866e559d..d87a5e5d0 100644
--- a/src/Util.FileStorage/Usings.cs
+++ b/src/Util.FileStorage/Usings.cs
@@ -4,6 +4,7 @@
global using System.Threading;
global using System.IO;
global using System.ComponentModel;
+global using System.Linq;
global using Microsoft.Extensions.Options;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.DependencyInjection.Extensions;
diff --git a/test/Util.FileStorage.Aliyun.Tests.Integration/Util.FileStorage.Aliyun.Tests.Integration.csproj b/test/Util.FileStorage.Aliyun.Tests.Integration/Util.FileStorage.Aliyun.Tests.Integration.csproj
index 320854b35..ee228c814 100644
--- a/test/Util.FileStorage.Aliyun.Tests.Integration/Util.FileStorage.Aliyun.Tests.Integration.csproj
+++ b/test/Util.FileStorage.Aliyun.Tests.Integration/Util.FileStorage.Aliyun.Tests.Integration.csproj
@@ -40,7 +40,7 @@
-
+
diff --git a/test/Util.FileStorage.Minio.Tests.Integration/Util.FileStorage.Minio.Tests.Integration.csproj b/test/Util.FileStorage.Minio.Tests.Integration/Util.FileStorage.Minio.Tests.Integration.csproj
index 09f4591fb..651e52ef1 100644
--- a/test/Util.FileStorage.Minio.Tests.Integration/Util.FileStorage.Minio.Tests.Integration.csproj
+++ b/test/Util.FileStorage.Minio.Tests.Integration/Util.FileStorage.Minio.Tests.Integration.csproj
@@ -39,7 +39,7 @@
-
+
diff --git a/test/Util.FileStorage.Tests.Integration/Tests/FileValidationTest.cs b/test/Util.FileStorage.Tests.Integration/Tests/FileValidationTest.cs
new file mode 100644
index 000000000..c3d774b9c
--- /dev/null
+++ b/test/Util.FileStorage.Tests.Integration/Tests/FileValidationTest.cs
@@ -0,0 +1,28 @@
+namespace Util.FileStorage.Tests;
+
+///
+/// 文件验证操作测试
+///
+public class FileValidationTest {
+ ///
+ /// 测试扩展名是否有效
+ ///
+ [Fact]
+ public void TestIsValidExtension() {
+ Assert.True( FileValidation.IsValidExtension( "a.jpg", "" ) );
+ Assert.False( FileValidation.IsValidExtension( "", ".jpg" ) );
+ Assert.True( FileValidation.IsValidExtension( "a.jpg", ".jpg" ) );
+ Assert.True( FileValidation.IsValidExtension( "a.jpg", "jpg" ) );
+ Assert.False( FileValidation.IsValidExtension( "a.png", ".jpg" ) );
+ Assert.True( FileValidation.IsValidExtension( "a.jpg", ".jpg,.png" ) );
+ Assert.True( FileValidation.IsValidExtension( "a.png", ".jpg,.png" ) );
+ Assert.True( FileValidation.IsValidExtension( "a.jpg", "jpg,png" ) );
+ Assert.True( FileValidation.IsValidExtension( "a.png", "jpg,png" ) );
+ Assert.True( FileValidation.IsValidExtension( ".jpg", ".jpg,png" ) );
+ Assert.True( FileValidation.IsValidExtension( ".png", "jpg,.png" ) );
+ Assert.True( FileValidation.IsValidExtension( "a.png", "," ) );
+ Assert.False( FileValidation.IsValidExtension( "a.png", ",.jpg" ) );
+ Assert.False( FileValidation.IsValidExtension( "a", ",.jpg" ) );
+ Assert.True( FileValidation.IsValidExtension( "a", ",." ) );
+ }
+}
\ No newline at end of file
diff --git a/test/Util.FileStorage.Tests.Integration/Util.FileStorage.Tests.Integration.csproj b/test/Util.FileStorage.Tests.Integration/Util.FileStorage.Tests.Integration.csproj
index 713d6c5d1..5740a1243 100644
--- a/test/Util.FileStorage.Tests.Integration/Util.FileStorage.Tests.Integration.csproj
+++ b/test/Util.FileStorage.Tests.Integration/Util.FileStorage.Tests.Integration.csproj
@@ -39,7 +39,7 @@
-
+