添加IRootDirectory 接口,可通过注入IRootDirectory接口实现根据业务场景改变文件存储的位置
This commit is contained in:
12
FileService/Abstractions/IRootDirectory.cs
Normal file
12
FileService/Abstractions/IRootDirectory.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ufangx.FileServices.Abstractions
|
||||||
|
{
|
||||||
|
public interface IRootDirectory
|
||||||
|
{
|
||||||
|
Task<string> GetRoot();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ namespace Ufangx.FileServices.Abstractions
|
|||||||
{
|
{
|
||||||
FileValidateResult Validate(IFormFile file, string schemeName=null);
|
FileValidateResult Validate(IFormFile file, string schemeName=null);
|
||||||
FileValidateResult Validate(IFormFileCollection files, string schemeName=null);
|
FileValidateResult Validate(IFormFileCollection files, string schemeName=null);
|
||||||
Task<object> Handle(IFormFileCollection files, string schemeName = null);
|
Task<object> Handle(IFormFileCollection files, string schemeName = null, string dir = null);
|
||||||
Task<object> Handle(IFormFile file,string schemeName=null, string dir=null,string name=null);
|
Task<object> Handle(IFormFile file,string schemeName=null, string dir=null,string name=null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
<PackageTags>file service web uploader html5 uploader breakpoint renewal</PackageTags>
|
<PackageTags>file service web uploader html5 uploader breakpoint renewal</PackageTags>
|
||||||
<Copyright>Copyright (c) 2020-$([System.DateTime]::Now.Year) Jackson.Bruce</Copyright>
|
<Copyright>Copyright (c) 2020-$([System.DateTime]::Now.Year) Jackson.Bruce</Copyright>
|
||||||
<Version>1.0.2-beta</Version>
|
<Version>1.0.5</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(TargetFramework)|$(Platform)'=='netstandard2.0|AnyCPU'">
|
<PropertyGroup Condition="'$(TargetFramework)|$(Platform)'=='netstandard2.0|AnyCPU'">
|
||||||
@@ -41,4 +41,8 @@
|
|||||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
||||||
|
<Exec Command="del $(ProjectDir)$(OutDir)..\*.nupkg /s/q
exit 0" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -6,23 +7,34 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Ufangx.FileServices.Abstractions;
|
using Ufangx.FileServices.Abstractions;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Ufangx.FileServices.Local
|
namespace Ufangx.FileServices.Local
|
||||||
{
|
{
|
||||||
public class LocalFileService : IFileService
|
public class LocalFileService : IFileService
|
||||||
{
|
{
|
||||||
private readonly LocalFileOption option;
|
private readonly LocalFileOption option;
|
||||||
|
private readonly IHttpContextAccessor httpContextAccessor;
|
||||||
|
|
||||||
public LocalFileService(IOptions<LocalFileOption> option) {
|
public LocalFileService(IOptions<LocalFileOption> option,IHttpContextAccessor httpContextAccessor) {
|
||||||
|
|
||||||
this.option = option.Value; // option??new LocalFileOption();
|
this.option = option.Value; // option??new LocalFileOption();
|
||||||
if (string.IsNullOrWhiteSpace(this.option.StorageRootDir)) {
|
if (string.IsNullOrWhiteSpace(this.option.StorageRootDir)) {
|
||||||
this.option.StorageRootDir = AppContext.BaseDirectory;
|
this.option.StorageRootDir = AppContext.BaseDirectory;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
protected string physicalPath(string path) {
|
|
||||||
|
|
||||||
return Path.Combine(option.StorageRootDir, path.Trim().Replace('\\', '/').TrimStart('/'));
|
this.httpContextAccessor = httpContextAccessor;
|
||||||
|
}
|
||||||
|
protected async Task<string> physicalPath(string path) {
|
||||||
|
string root;
|
||||||
|
var rootService = httpContextAccessor.HttpContext.RequestServices.GetService<IRootDirectory>();
|
||||||
|
if (rootService == null || string.IsNullOrWhiteSpace(root = await rootService.GetRoot()))
|
||||||
|
{
|
||||||
|
return Path.Combine(option.StorageRootDir, path.Trim().Replace('\\', '/').TrimStart('/')).Replace('\\', '/');
|
||||||
|
}
|
||||||
|
return Path.Combine(option.StorageRootDir,
|
||||||
|
root.Trim().Replace('\\', '/').TrimStart('/'),
|
||||||
|
path.Trim().Replace('\\', '/').TrimStart('/')).Replace('\\', '/');
|
||||||
}
|
}
|
||||||
protected bool CreateDirIfNonexistence(string path) {
|
protected bool CreateDirIfNonexistence(string path) {
|
||||||
|
|
||||||
@@ -34,7 +46,7 @@ namespace Ufangx.FileServices.Local
|
|||||||
}
|
}
|
||||||
public async Task<bool> Delete(string path, CancellationToken token = default(CancellationToken))
|
public async Task<bool> Delete(string path, CancellationToken token = default(CancellationToken))
|
||||||
{
|
{
|
||||||
string p = physicalPath(path);
|
string p = await physicalPath(path);
|
||||||
if (File.Exists(p))
|
if (File.Exists(p))
|
||||||
{
|
{
|
||||||
File.Delete(p);
|
File.Delete(p);
|
||||||
@@ -45,12 +57,13 @@ namespace Ufangx.FileServices.Local
|
|||||||
|
|
||||||
public async Task<bool> Exists(string path, CancellationToken token = default(CancellationToken))
|
public async Task<bool> Exists(string path, CancellationToken token = default(CancellationToken))
|
||||||
{
|
{
|
||||||
return await Task.FromResult(File.Exists(physicalPath(path)));
|
var filePath = await physicalPath(path);
|
||||||
|
return File.Exists(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Stream> GetStream(string path, CancellationToken token = default(CancellationToken))
|
public async Task<Stream> GetStream(string path, CancellationToken token = default(CancellationToken))
|
||||||
{
|
{
|
||||||
var p = physicalPath(path);
|
var p =await physicalPath(path);
|
||||||
if (!File.Exists(p)) return null;
|
if (!File.Exists(p)) return null;
|
||||||
return await Task.FromResult(new FileStream(p, FileMode.Open, FileAccess.Read,FileShare.ReadWrite| FileShare.Delete));
|
return await Task.FromResult(new FileStream(p, FileMode.Open, FileAccess.Read,FileShare.ReadWrite| FileShare.Delete));
|
||||||
|
|
||||||
@@ -58,7 +71,7 @@ namespace Ufangx.FileServices.Local
|
|||||||
|
|
||||||
public async Task<byte[]> GetFileData(string path, CancellationToken token = default(CancellationToken))
|
public async Task<byte[]> GetFileData(string path, CancellationToken token = default(CancellationToken))
|
||||||
{
|
{
|
||||||
var p = physicalPath(path);
|
var p =await physicalPath(path);
|
||||||
if (!File.Exists(p)) return null;
|
if (!File.Exists(p)) return null;
|
||||||
#if netstandard20
|
#if netstandard20
|
||||||
return await Task.FromResult(File.ReadAllBytes(p));
|
return await Task.FromResult(File.ReadAllBytes(p));
|
||||||
@@ -70,7 +83,7 @@ namespace Ufangx.FileServices.Local
|
|||||||
|
|
||||||
public async Task<bool> Save(string path, Stream stream, CancellationToken token = default(CancellationToken))
|
public async Task<bool> Save(string path, Stream stream, CancellationToken token = default(CancellationToken))
|
||||||
{
|
{
|
||||||
var p = physicalPath(path);
|
var p =await physicalPath(path);
|
||||||
if (CreateDirIfNonexistence(p))
|
if (CreateDirIfNonexistence(p))
|
||||||
{
|
{
|
||||||
if (stream.CanSeek && stream.Position > 0) { stream.Position = 0; }
|
if (stream.CanSeek && stream.Position > 0) { stream.Position = 0; }
|
||||||
@@ -95,7 +108,7 @@ namespace Ufangx.FileServices.Local
|
|||||||
|
|
||||||
public async Task<bool> Save(string path, byte[] data, CancellationToken token = default(CancellationToken))
|
public async Task<bool> Save(string path, byte[] data, CancellationToken token = default(CancellationToken))
|
||||||
{
|
{
|
||||||
var p = physicalPath(path);
|
var p = await physicalPath(path);
|
||||||
if (CreateDirIfNonexistence(p))
|
if (CreateDirIfNonexistence(p))
|
||||||
{
|
{
|
||||||
#if netstandard20
|
#if netstandard20
|
||||||
@@ -110,19 +123,20 @@ namespace Ufangx.FileServices.Local
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public async Task Move(string sourceFileName,string destFileName) {
|
public async Task Move(string sourceFileName,string destFileName) {
|
||||||
sourceFileName = physicalPath(sourceFileName);
|
sourceFileName = await physicalPath(sourceFileName);
|
||||||
destFileName = physicalPath(destFileName);
|
destFileName = await physicalPath(destFileName);
|
||||||
File.Move(sourceFileName, destFileName);
|
File.Move(sourceFileName, destFileName);
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
public async Task<DateTime> GetModifyDate(string path, CancellationToken token = default(CancellationToken))
|
public async Task<DateTime> GetModifyDate(string path, CancellationToken token = default(CancellationToken))
|
||||||
{
|
{
|
||||||
return await Task.FromResult(File.GetLastWriteTime(physicalPath(path)));
|
var filePath = await physicalPath(path);
|
||||||
|
return File.GetLastWriteTime(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> Append(string path, Stream stream, CancellationToken token = default(CancellationToken))
|
public async Task<bool> Append(string path, Stream stream, CancellationToken token = default(CancellationToken))
|
||||||
{
|
{
|
||||||
var p = physicalPath(path);
|
var p = await physicalPath(path);
|
||||||
if (CreateDirIfNonexistence(p))
|
if (CreateDirIfNonexistence(p))
|
||||||
{
|
{
|
||||||
if (stream.CanSeek && stream.Position > 0) { stream.Position = 0; }
|
if (stream.CanSeek && stream.Position > 0) { stream.Position = 0; }
|
||||||
@@ -146,7 +160,7 @@ namespace Ufangx.FileServices.Local
|
|||||||
|
|
||||||
public async Task<bool> Append(string path, byte[] data, CancellationToken token = default(CancellationToken))
|
public async Task<bool> Append(string path, byte[] data, CancellationToken token = default(CancellationToken))
|
||||||
{
|
{
|
||||||
var p = physicalPath(path);
|
var p = await physicalPath(path);
|
||||||
if (CreateDirIfNonexistence(p))
|
if (CreateDirIfNonexistence(p))
|
||||||
{
|
{
|
||||||
using (var fs = new FileStream(p, FileMode.Append, FileAccess.Write, FileShare.Read))
|
using (var fs = new FileStream(p, FileMode.Append, FileAccess.Write, FileShare.Read))
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -14,7 +15,7 @@ namespace Ufangx.FileServices.Local
|
|||||||
public class LocalResumableService : LocalFileService, IResumableService
|
public class LocalResumableService : LocalFileService, IResumableService
|
||||||
{
|
{
|
||||||
private readonly IResumableInfoService resumableInfoService;
|
private readonly IResumableInfoService resumableInfoService;
|
||||||
public LocalResumableService(IResumableInfoService resumableInfoService, IOptions<LocalFileOption> option):base(option) {
|
public LocalResumableService(IResumableInfoService resumableInfoService, IOptions<LocalFileOption> option, IHttpContextAccessor httpContextAccessor) :base(option, httpContextAccessor) {
|
||||||
this.resumableInfoService = resumableInfoService;
|
this.resumableInfoService = resumableInfoService;
|
||||||
}
|
}
|
||||||
FileStream GetFileStream(string path) {
|
FileStream GetFileStream(string path) {
|
||||||
@@ -86,7 +87,7 @@ namespace Ufangx.FileServices.Local
|
|||||||
if (info == null) {
|
if (info == null) {
|
||||||
throw new Exception($"无效的{nameof(blob.ResumableKey)}");
|
throw new Exception($"无效的{nameof(blob.ResumableKey)}");
|
||||||
}
|
}
|
||||||
var p = physicalPath(info.StoreName);
|
var p =await physicalPath(info.StoreName);
|
||||||
string tempdir = GetTempDir(p,info.Key);
|
string tempdir = GetTempDir(p,info.Key);
|
||||||
var tmp = Path.Combine(tempdir, $"{blob.BlobIndex}").Replace('\\','/');
|
var tmp = Path.Combine(tempdir, $"{blob.BlobIndex}").Replace('\\','/');
|
||||||
if (CreateDirIfNonexistence(tmp))
|
if (CreateDirIfNonexistence(tmp))
|
||||||
@@ -141,7 +142,7 @@ namespace Ufangx.FileServices.Local
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (await resumableInfoService.Delete(info)) {
|
if (await resumableInfoService.Delete(info)) {
|
||||||
string tempdir = GetTempDir(physicalPath(info.StoreName), info.Key);
|
string tempdir = GetTempDir(await physicalPath(info.StoreName), info.Key);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Directory.Delete(tempdir, true);
|
Directory.Delete(tempdir, true);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace Ufangx.FileServices.Middlewares
|
|||||||
//如果有文件验证失败则返回
|
//如果有文件验证失败则返回
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await WriteJsonAsync(context, await uploader.Handle(context.Request.Form.Files, _scheme));
|
await WriteJsonAsync(context, await uploader.Handle(context.Request.Form.Files, _scheme,dir));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ namespace Ufangx.FileServices.Middlewares
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await WriteJsonAsync(context, await uploader.Handle(context.Request.Form.Files[0], _scheme));
|
await WriteJsonAsync(context, await uploader.Handle(context.Request.Form.Files[0], _scheme,dir,fileName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace Ufangx.FileServices.Models
|
|||||||
{
|
{
|
||||||
|
|
||||||
Services.Configure<FileServiceOptions>(opt => opt.AddScheme<THandler>(name, storeDirectory, supportExtensions, LimitedSize));
|
Services.Configure<FileServiceOptions>(opt => opt.AddScheme<THandler>(name, storeDirectory, supportExtensions, LimitedSize));
|
||||||
Services.AddTransient<THandler>();
|
//Services.AddTransient<THandler>();//外面注入
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,12 +76,12 @@ namespace Ufangx.FileServices.Services
|
|||||||
//否则生成文件名称
|
//否则生成文件名称
|
||||||
return await GenerateFileName(scheme, originName, dir);
|
return await GenerateFileName(scheme, originName, dir);
|
||||||
}
|
}
|
||||||
public async Task<object> Handle(IFormFileCollection files, string schemeName = null)
|
public async Task<object> Handle(IFormFileCollection files, string schemeName = null, string dir = null)
|
||||||
{
|
{
|
||||||
List<object> results = new List<object>();
|
List<object> results = new List<object>();
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
{
|
{
|
||||||
var result = await Handle(file, schemeName);
|
var result = await Handle(file, schemeName, dir);
|
||||||
if (result != null){ results.Add(result); }
|
if (result != null){ results.Add(result); }
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using Qiniu.Http;
|
using Qiniu.Http;
|
||||||
using Qiniu.Storage;
|
using Qiniu.Storage;
|
||||||
using Qiniu.Util;
|
using Qiniu.Util;
|
||||||
@@ -8,6 +9,7 @@ using System.Net.Http;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Ufangx.FileServices.Abstractions;
|
using Ufangx.FileServices.Abstractions;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Qiniu
|
namespace Qiniu
|
||||||
{
|
{
|
||||||
@@ -16,8 +18,9 @@ namespace Qiniu
|
|||||||
protected readonly FileServiceOptions options;
|
protected readonly FileServiceOptions options;
|
||||||
protected readonly Mac mac;
|
protected readonly Mac mac;
|
||||||
protected readonly Config config;
|
protected readonly Config config;
|
||||||
|
protected readonly IHttpContextAccessor contextAccessor;
|
||||||
|
|
||||||
public FileService(IOptions<FileServiceOptions> options)
|
public FileService(IOptions<FileServiceOptions> options, IHttpContextAccessor contextAccessor)
|
||||||
{
|
{
|
||||||
if (options is null)
|
if (options is null)
|
||||||
{
|
{
|
||||||
@@ -67,6 +70,8 @@ namespace Qiniu
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.contextAccessor = contextAccessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<bool> Append(string path, Stream stream, CancellationToken token = default)
|
public Task<bool> Append(string path, Stream stream, CancellationToken token = default)
|
||||||
@@ -85,7 +90,7 @@ namespace Qiniu
|
|||||||
=> await Append(path, new MemoryStream(data), token);
|
=> await Append(path, new MemoryStream(data), token);
|
||||||
|
|
||||||
public async Task<bool> Delete(string path, CancellationToken token = default)
|
public async Task<bool> Delete(string path, CancellationToken token = default)
|
||||||
=> (await GetBucketManager().Delete(options.Bucket, GetSaveKey(path))).Code == (int)HttpCode.OK;
|
=> (await GetBucketManager().Delete(options.Bucket,await GetSaveKey(path))).Code == (int)HttpCode.OK;
|
||||||
//(await Task.FromResult(GetBucketManager().Delete(options.Bucket, GetSaveKey(path)))).Code == (int)HttpCode.OK;
|
//(await Task.FromResult(GetBucketManager().Delete(options.Bucket, GetSaveKey(path)))).Code == (int)HttpCode.OK;
|
||||||
|
|
||||||
public async Task<bool> Exists(string path, CancellationToken token = default)
|
public async Task<bool> Exists(string path, CancellationToken token = default)
|
||||||
@@ -93,9 +98,9 @@ namespace Qiniu
|
|||||||
var result = await GetInfo(path);
|
var result = await GetInfo(path);
|
||||||
return result.Code == (int)HttpCode.OK;
|
return result.Code == (int)HttpCode.OK;
|
||||||
}
|
}
|
||||||
string GetDownloadUrl(string path)
|
async Task<string> GetDownloadUrl(string path)
|
||||||
{
|
{
|
||||||
var key = GetSaveKey(path);
|
var key =await GetSaveKey(path);
|
||||||
string baseUrl = options.Domain.Trim();
|
string baseUrl = options.Domain.Trim();
|
||||||
baseUrl = baseUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || baseUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase) ? baseUrl :
|
baseUrl = baseUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || baseUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase) ? baseUrl :
|
||||||
"http://" + baseUrl;
|
"http://" + baseUrl;
|
||||||
@@ -105,13 +110,13 @@ namespace Qiniu
|
|||||||
}
|
}
|
||||||
public async Task<byte[]> GetFileData(string path, CancellationToken token = default)
|
public async Task<byte[]> GetFileData(string path, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var url = GetDownloadUrl(path);
|
var url =await GetDownloadUrl(path);
|
||||||
HttpClient client = new HttpClient();
|
HttpClient client = new HttpClient();
|
||||||
return await client.GetByteArrayAsync(url);
|
return await client.GetByteArrayAsync(url);
|
||||||
|
|
||||||
}
|
}
|
||||||
async Task<StatResult> GetInfo(string path) => await
|
async Task<StatResult> GetInfo(string path) => await
|
||||||
GetBucketManager().Stat(options.Bucket, GetSaveKey(path));
|
GetBucketManager().Stat(options.Bucket,await GetSaveKey(path));
|
||||||
//Task.FromResult(GetBucketManager().Stat(options.Bucket, GetSaveKey(path)));
|
//Task.FromResult(GetBucketManager().Stat(options.Bucket, GetSaveKey(path)));
|
||||||
public async Task<DateTime> GetModifyDate(string path, CancellationToken token = default)
|
public async Task<DateTime> GetModifyDate(string path, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
@@ -124,7 +129,7 @@ namespace Qiniu
|
|||||||
}
|
}
|
||||||
public async Task<Stream> GetStream(string path, CancellationToken token = default)
|
public async Task<Stream> GetStream(string path, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var url = GetDownloadUrl(path);
|
var url =await GetDownloadUrl(path);
|
||||||
HttpClient client = new HttpClient();
|
HttpClient client = new HttpClient();
|
||||||
return await client.GetStreamAsync(url);
|
return await client.GetStreamAsync(url);
|
||||||
|
|
||||||
@@ -135,15 +140,15 @@ namespace Qiniu
|
|||||||
{
|
{
|
||||||
BucketManager bucket = GetBucketManager();
|
BucketManager bucket = GetBucketManager();
|
||||||
//var result = await Task.FromResult(bucket.Move(options.Bucket, GetSaveKey(sourceFileName), options.Bucket, GetSaveKey(destFileName)));
|
//var result = await Task.FromResult(bucket.Move(options.Bucket, GetSaveKey(sourceFileName), options.Bucket, GetSaveKey(destFileName)));
|
||||||
var result = await bucket.Move(options.Bucket, GetSaveKey(sourceFileName), options.Bucket, GetSaveKey(destFileName));
|
var result = await bucket.Move(options.Bucket,await GetSaveKey(sourceFileName), options.Bucket,await GetSaveKey(destFileName));
|
||||||
if (result.Code != (int)HttpCode.OK)
|
if (result.Code != (int)HttpCode.OK)
|
||||||
{
|
{
|
||||||
throw new Exception(result.Text);
|
throw new Exception(result.Text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
string GetSaveKey(string path)
|
Task<string> GetSaveKey(string path)
|
||||||
{
|
{
|
||||||
return Utils.GetSaveKey(options.BasePath, path);
|
return contextAccessor.GetSaveKey(options.BasePath, path);
|
||||||
}
|
}
|
||||||
string GetToken(string savekey)
|
string GetToken(string savekey)
|
||||||
{
|
{
|
||||||
@@ -179,7 +184,7 @@ namespace Qiniu
|
|||||||
|
|
||||||
public async Task<bool> Save(string path, byte[] data, CancellationToken token = default)
|
public async Task<bool> Save(string path, byte[] data, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var key = GetSaveKey(path);
|
var key =await GetSaveKey(path);
|
||||||
var uploadManager = GetUploadManager();
|
var uploadManager = GetUploadManager();
|
||||||
//var result = await Task.FromResult(uploadManager.UploadData(data, key, GetToken(key), null));
|
//var result = await Task.FromResult(uploadManager.UploadData(data, key, GetToken(key), null));
|
||||||
var result = await uploadManager.UploadData(data, key, GetToken(key), null);
|
var result = await uploadManager.UploadData(data, key, GetToken(key), null);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<Version>1.0.0-beta.1</Version>
|
<Version>1.0.0-beta.1</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FileServices" Version="1.0.0" />
|
<PackageReference Include="FileServices" Version="1.0.5" />
|
||||||
<PackageReference Include="Qiniu.SDK" Version="8.0.0" />
|
<PackageReference Include="Qiniu.SDK" Version="8.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace Qiniu
|
|||||||
info = (ResumableInfo)(await base.Create(storeName, fileName, fileSize, fileType, blobCount, blobSize));
|
info = (ResumableInfo)(await base.Create(storeName, fileName, fileSize, fileType, blobCount, blobSize));
|
||||||
}
|
}
|
||||||
if (string.IsNullOrWhiteSpace(info.UploadToken)) {
|
if (string.IsNullOrWhiteSpace(info.UploadToken)) {
|
||||||
info.UploadToken = Utils.GetToken(Utils.GetSaveKey(options.BasePath, info.StoreName), options.AccessKey, options.SecretKey, options.Bucket);
|
info.UploadToken = Utils.GetToken(await contextAccessor.GetSaveKey(options.BasePath, info.StoreName), options.AccessKey, options.SecretKey, options.Bucket);
|
||||||
await Update(info);
|
await Update(info);
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Qiniu.Http;
|
using Qiniu.Http;
|
||||||
@@ -20,7 +21,7 @@ namespace Qiniu
|
|||||||
private readonly ILogger<ResumableService> logger;
|
private readonly ILogger<ResumableService> logger;
|
||||||
private readonly HttpManager _httpManager;
|
private readonly HttpManager _httpManager;
|
||||||
|
|
||||||
public ResumableService(IResumableInfoService resumableInfoService,ILogger<ResumableService> logger, IOptions<FileServiceOptions> options) : base(options)
|
public ResumableService(IResumableInfoService resumableInfoService,ILogger<ResumableService> logger, IOptions<FileServiceOptions> options, IHttpContextAccessor contextAccessor) : base(options, contextAccessor)
|
||||||
{
|
{
|
||||||
this.resumableInfoService = resumableInfoService;
|
this.resumableInfoService = resumableInfoService;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
@@ -129,7 +130,7 @@ namespace Qiniu
|
|||||||
}
|
}
|
||||||
private async Task<bool> MakeFile(ResumableInfo info)
|
private async Task<bool> MakeFile(ResumableInfo info)
|
||||||
{
|
{
|
||||||
string key = Utils.GetSaveKey(options.BasePath, info.StoreName);
|
string key = await contextAccessor.GetSaveKey(options.BasePath, info.StoreName);
|
||||||
string fileName = key;
|
string fileName = key;
|
||||||
long size = info.FileSize;
|
long size = info.FileSize;
|
||||||
string upToken = info.UploadToken;
|
string upToken = info.UploadToken;
|
||||||
|
|||||||
@@ -1,21 +1,34 @@
|
|||||||
using Qiniu.Storage;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Qiniu.Storage;
|
||||||
using Qiniu.Util;
|
using Qiniu.Util;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Ufangx.FileServices.Abstractions;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Qiniu
|
namespace Qiniu
|
||||||
{
|
{
|
||||||
internal static class Utils
|
internal static class Utils
|
||||||
{
|
{
|
||||||
public static string GetSaveKey(string basePath, string path)
|
static async Task<string> GetRootDir(IHttpContextAccessor contextAccessor,string basePath)
|
||||||
|
{
|
||||||
|
string root;
|
||||||
|
var rootService = contextAccessor.HttpContext.RequestServices.GetService<IRootDirectory>();
|
||||||
|
if (rootService == null || string.IsNullOrWhiteSpace(root = await rootService.GetRoot())) return basePath;
|
||||||
|
return Path.Combine(basePath, root.Trim().Replace('\\', '/').TrimStart('/')).Replace('\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<string> GetSaveKey(this IHttpContextAccessor contextAccessor, string basePath, string path)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(path))
|
if (string.IsNullOrWhiteSpace(path))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("message", nameof(path));
|
throw new ArgumentException("message", nameof(path));
|
||||||
}
|
}
|
||||||
return Path.Combine(basePath, path.TrimStart('/', '\\')).Trim().ToLower().Replace('\\', '/');
|
var root =await GetRootDir(contextAccessor, basePath);
|
||||||
|
return Path.Combine(root, path.TrimStart('/', '\\')).Trim().ToLower().Replace('\\', '/');
|
||||||
}
|
}
|
||||||
public static string GetToken(string savekey,string ak,string sk,string bucket,int expires=3600)
|
public static string GetToken(string savekey,string ak,string sk,string bucket,int expires=3600)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
},
|
},
|
||||||
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
"applicationUrl": "https://localhost:8001;http://localhost:8000"
|
||||||
},
|
},
|
||||||
"Docker": {
|
"Docker": {
|
||||||
"commandName": "Docker",
|
"commandName": "Docker",
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ namespace TestWeb
|
|||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
app.UseFileServices("/api");
|
||||||
//app.Use(next => async ctx =>
|
//app.Use(next => async ctx =>
|
||||||
//{
|
//{
|
||||||
// try
|
// try
|
||||||
@@ -105,12 +106,11 @@ namespace TestWeb
|
|||||||
// throw ex;
|
// throw ex;
|
||||||
// }
|
// }
|
||||||
//});
|
//});
|
||||||
app.UseFileServices("/api");
|
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints(endpoints =>
|
||||||
{
|
{
|
||||||
endpoints.MapControllerRoute(
|
endpoints.MapControllerRoute(
|
||||||
name: "default",
|
name: "default",
|
||||||
pattern: "api/{controller=Home}/{action=Index}/{id?}");
|
pattern: "{controller=Home}/{action=Index}/{id?}");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,5 @@
|
|||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<h1 class="display-4">Welcome</h1>
|
<h1 class="display-4">Welcome</h1>
|
||||||
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
|
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
|
||||||
|
<a href="~/test.html">test</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
BIN
TestWeb/wwwroot/documents/20210720142003_xx_分享海报 (1).png
Normal file
BIN
TestWeb/wwwroot/documents/20210720142003_xx_分享海报 (1).png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
BIN
TestWeb/wwwroot/documents/test/kkk/20210720144348_xx_客户端哈希加密.zip
Normal file
BIN
TestWeb/wwwroot/documents/test/kkk/20210720144348_xx_客户端哈希加密.zip
Normal file
Binary file not shown.
Reference in New Issue
Block a user