diff --git a/FileService.sln b/FileService.sln
index ba4579d..8b8d74e 100644
--- a/FileService.sln
+++ b/FileService.sln
@@ -7,7 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileServices", "FileService
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestWeb", "TestWeb\TestWeb.csproj", "{B64F2077-52A2-472F-883F-57EBE8805F8D}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QiniuFileService", "Qiniu\QiniuFileService.csproj", "{218AEB0B-2C51-42D7-98E0-4C1FE7E09E69}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Qiniu.FileService", "Qiniu\Qiniu.FileService.csproj", "{218AEB0B-2C51-42D7-98E0-4C1FE7E09E69}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/FileService/FileServices.csproj b/FileService/FileServices.csproj
index 78dcc81..a1891ff 100644
--- a/FileService/FileServices.csproj
+++ b/FileService/FileServices.csproj
@@ -4,6 +4,16 @@
netstandard2.0;netcoreapp2.0;netstandard2.1;netcoreapp3.0
Ufangx.FileServices
FileServices
+ Jackson.bruce
+ Ufangx
+ File management, super large file upload, breakpoint renewal
+ MIT
+ https://github.com/JacksonBruce/FileServices.git
+ https://github.com/JacksonBruce/FileServices
+ git
+ file service web uploader html5 uploader breakpoint renewal
+ Copyright (c) 2020-$([System.DateTime]::Now.Year) Jackson.Bruce
+ 1.0.0-beta.1
diff --git a/FileService/Local/LocalFileService.cs b/FileService/Local/LocalFileService.cs
index 48a7887..c8a572f 100644
--- a/FileService/Local/LocalFileService.cs
+++ b/FileService/Local/LocalFileService.cs
@@ -22,7 +22,7 @@ namespace Ufangx.FileServices.Local
}
protected string physicalPath(string path) {
- return Path.Combine(option.StorageRootDir, path.Trim().Replace('/', '\\').TrimStart('\\'));
+ return Path.Combine(option.StorageRootDir, path.Trim().Replace('\\', '/').TrimStart('/'));
}
protected bool CreateDirIfNonexistence(string path) {
diff --git a/FileService/Local/LocalResumableService.cs b/FileService/Local/LocalResumableService.cs
index 326fc86..210b7c4 100644
--- a/FileService/Local/LocalResumableService.cs
+++ b/FileService/Local/LocalResumableService.cs
@@ -22,14 +22,15 @@ namespace Ufangx.FileServices.Local
}
string GetTempDir(string path, string key)
{
- return Path.Combine(Path.GetDirectoryName(path), $"_tmp{key}");
+ return Path.Combine(Path.GetDirectoryName(path), $"_tmp{key}").Replace('\\','/');
}
bool CheckFiles(string dir, long count) {
//Console.WriteLine("正在检查文件。。。");
//Stopwatch sw = Stopwatch.StartNew();
for (long i = 0; i < count; i++)
{
- if (!File.Exists(Path.Combine(dir, $"{i}"))) { return false; }
+ string path = Path.Combine(dir, $"{i}").Replace('\\', '/');
+ if (!File.Exists(path)) { return false; }
}
//sw.Stop();
//Console.WriteLine($"检查{count}个文件,用时:{sw.Elapsed.TotalMilliseconds}毫秒");
@@ -51,8 +52,8 @@ namespace Ufangx.FileServices.Local
using (var fs = GetFileStream(path))
{
for (long i = 0; i < count; i++)
- {
- var blob = await GetBlob(Path.Combine(dir, $"{i}"), token);
+ {
+ var blob = await GetBlob(Path.Combine(dir, $"{i}").Replace('\\','/'), token);
await fs.WriteAsync(blob, 0, blob.Length, token);
}
await fs.FlushAsync(token);
@@ -87,7 +88,7 @@ namespace Ufangx.FileServices.Local
}
var p = physicalPath(info.StoreName);
string tempdir = GetTempDir(p,info.Key);
- var tmp = Path.Combine(tempdir, $"{blob.BlobIndex}");
+ var tmp = Path.Combine(tempdir, $"{blob.BlobIndex}").Replace('\\','/');
if (CreateDirIfNonexistence(tmp))
{
var stream = blob.Data;
diff --git a/FileService/Services/Uploader.cs b/FileService/Services/Uploader.cs
index b988851..b5a0ded 100644
--- a/FileService/Services/Uploader.cs
+++ b/FileService/Services/Uploader.cs
@@ -41,26 +41,26 @@ namespace Ufangx.FileServices.Services
nameRule = FileNameRule.Ascending;
}
if (directory == null) { directory = string.Empty; }
- directory = Path.Combine(scheme?.StoreDirectory ?? string.Empty, directory);
+ directory = Path.Combine(scheme?.StoreDirectory ?? string.Empty, directory).Replace('\\', '/');
string fileName;
switch (nameRule)
{
case FileNameRule.Ascending:
- fileName = Path.Combine(directory, originName);
+ fileName = Path.Combine(directory, originName).Replace('\\', '/');
int index = 0;
while (await fileService.Exists(fileName))
{
- fileName = Path.Combine(directory, $"{Path.GetFileNameWithoutExtension(originName)}({++index}){Path.GetExtension(originName)}");
+ fileName = Path.Combine(directory, $"{Path.GetFileNameWithoutExtension(originName)}({++index}){Path.GetExtension(originName)}").Replace('\\', '/');
}
break;
case FileNameRule.Date:
- fileName = Path.Combine(directory, string.Format(fileNameRuleOptions?.Format ?? "{0:yyyyMMddHHmmss}", DateTime.Now) + Path.GetExtension(originName));
+ fileName = Path.Combine(directory, string.Format(fileNameRuleOptions?.Format ?? "{0:yyyyMMddHHmmss}", DateTime.Now) + Path.GetExtension(originName)).Replace('\\', '/');
break;
case FileNameRule.Custom:
- fileName = Path.Combine(directory, fileNameRuleOptions.Custom(originName));
+ fileName = Path.Combine(directory, fileNameRuleOptions.Custom(originName)).Replace('\\', '/');
break;
default:
- fileName = Path.Combine(directory, originName);
+ fileName = Path.Combine(directory, originName).Replace('\\', '/');
break;
}
return fileName.Replace('\\', '/');
diff --git a/Qiniu/Http/ContentType.cs b/Qiniu/Http/ContentType.cs
deleted file mode 100644
index 0322502..0000000
--- a/Qiniu/Http/ContentType.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Diagnostics.CodeAnalysis;
-
-namespace Qiniu.Http
-{
- ///
- /// HTTP 内容类型(Content-Type)
- ///
- [SuppressMessage("ReSharper", "InconsistentNaming")]
- public class ContentType
- {
- ///
- /// 资源类型:普通文本
- ///
- public static readonly string TEXT_PLAIN = "text/plain";
-
- ///
- /// 资源类型:JSON字符串
- ///
- public static readonly string APPLICATION_JSON = "application/json";
-
- ///
- /// 资源类型:未知类型(数据流)
- ///
- public static readonly string APPLICATION_OCTET_STREAM = "application/octet-stream";
-
- ///
- /// 资源类型:表单数据(键值对)
- ///
- public static readonly string WWW_FORM_URLENC = "application/x-www-form-urlencoded";
-
- ///
- /// 资源类型:多分部数据
- ///
- public static readonly string MULTIPART_FORM_DATA = "multipart/form-data";
- }
-}
diff --git a/Qiniu/Http/HttpCode.cs b/Qiniu/Http/HttpCode.cs
deleted file mode 100644
index 99ffb78..0000000
--- a/Qiniu/Http/HttpCode.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-using System.Diagnostics.CodeAnalysis;
-
-namespace Qiniu.Http
-{
- ///
- /// HTTP 状态码
- ///
- [SuppressMessage("ReSharper", "InconsistentNaming")]
- public enum HttpCode
- {
- #region _PRE_
-
- ///
- /// 成功
- ///
- OK = 200,
-
- ///
- /// 部分OK
- ///
- PARTLY_OK = 298,
-
- ///
- /// 请求错误
- ///
- BAD_REQUEST = 400,
-
- ///
- /// 认证授权失败
- ///
- AUTHENTICATION_FAILED = 401,
-
- ///
- /// 拒绝访问
- ///
- ACCESS_DENIED = 403,
-
- ///
- /// 资源不存在
- ///
- OBJECT_NOT_FOUND = 404,
-
- ///
- /// CRC32校验失败
- ///
- CRC32_CHECK_FAILEd = 406,
-
- ///
- /// 上传文件大小超限
- ///
- FILE_SIZE_EXCEED = 413,
-
- ///
- /// 镜像回源失败
- ///
- PREFETCH_FAILED = 478,
-
- ///
- /// 错误网关
- ///
- BAD_GATEWAY = 502,
-
- ///
- /// 服务端不可用
- ///
- SERVER_UNAVAILABLE = 503,
-
- ///
- /// 服务端操作超时
- ///
- SERVER_TIME_EXCEED = 504,
-
- ///
- /// 单个资源访问频率过高
- ///
- TOO_FREQUENT_ACCESS = 573,
-
- ///
- /// 回调失败
- ///
- CALLBACK_FAILED = 579,
-
- ///
- /// 服务端操作失败
- ///
- SERVER_OPERATION_FAILED = 599,
-
- ///
- /// 资源内容被修改
- ///
- CONTENT_MODIFIED = 608,
-
- ///
- /// 文件不存在
- ///
- FILE_NOT_EXIST = 612,
-
- ///
- /// 文件已存在
- ///
- FILE_EXISTS = 614,
-
- ///
- /// 空间数量已达上限
- ///
- BUCKET_COUNT_LIMIT = 630,
-
- ///
- /// 空间或者文件不存在
- ///
- BUCKET_NOT_EXIST = 631,
-
- ///
- /// 列举资源(list)使用了非法的marker
- ///
- INVALID_MARKER = 640,
-
- ///
- /// 在断点续上传过程中,后续上传接收地址不正确或ctx信息已过期。
- ///
- CONTEXT_EXPIRED = 701,
-
- #endregion _PRE_
-
- #region _USR_
-
- ///
- /// 自定义HTTP状态码 (默认值)
- ///
- USER_UNDEF = 0,
-
- ///
- /// 自定义HTTP状态码 (用户取消)
- ///
- USER_CANCELED = -2,
-
- ///
- /// 自定义HTTP状态码 (用户暂停)
- ///
- USER_PAUSED = 1,
-
- ///
- /// 自定义HTTP状态码 (用户继续)
- ///
- USER_RESUMED = 2,
-
- ///
- /// 自定义HTTP状态码 (需要重试)
- ///
- USER_NEED_RETRY = 3,
-
- ///
- /// 自定义HTTP状态码 (异常或错误)
- ///
- INVALID_ARGUMENT = -4,
-
- ///
- /// 自定义HTTP状态码(文件不合法)
- ///
- INVALID_FILE = -3,
-
- ///
- /// 自定义HTTP状态码(凭证不合法)
- ///
- INVALID_TOKEN = -5,
-
- #endregion _USR_
- }
-}
diff --git a/Qiniu/Http/HttpManager.cs b/Qiniu/Http/HttpManager.cs
deleted file mode 100644
index cdb15c4..0000000
--- a/Qiniu/Http/HttpManager.cs
+++ /dev/null
@@ -1,234 +0,0 @@
-using System;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Text;
-using System.Threading.Tasks;
-using Qiniu.Util;
-
-namespace Qiniu.Http
-{
- ///
- /// HttpManager for .NET 4.5+
- ///
- public class HttpManager : IDisposable
- {
- public static readonly HttpManager SharedInstance = new HttpManager();
-
- private readonly HttpClient _client;
- private string _userAgent;
-
- ///
- /// 初始化
- ///
- /// 是否允许HttpWebRequest的“重定向”,默认禁止
- public HttpManager(bool allowAutoRedirect = false) : this(null, allowAutoRedirect)
- {
- }
-
- ///
- /// 初始化
- ///
- /// API Host,可选
- /// 是否允许HttpWebRequest的“重定向”,默认禁止
- public HttpManager(string baseUrl, bool allowAutoRedirect = false)
- {
- _client = new HttpClient(new HttpClientHandler { AllowAutoRedirect = allowAutoRedirect });
- if (!string.IsNullOrEmpty(baseUrl)) _client.BaseAddress = new Uri(baseUrl);
- _client.DefaultRequestHeaders.ExpectContinue = false;
- SetUserAgent(GetUserAgent());
- }
-
- public void Dispose()
- {
- _client?.Dispose();
- }
-
- ///
- /// 客户端标识(UserAgent),示例:"SepcifiedClient/1.1 (Universal)"
- ///
- /// 客户端标识UA
- public static string GetUserAgent()
- {
-#if NETSTANDARD1_3
- var osDesc = $"{System.Runtime.InteropServices.RuntimeInformation.OSDescription}";
-#else
- var osDesc = $"{Environment.OSVersion.Platform}; {Environment.OSVersion.Version}";
-#endif
- return $"{QiniuCSharpSdk.Alias}/{QiniuCSharpSdk.Version} ({QiniuCSharpSdk.RTFX}; {osDesc})";
- }
-
- ///
- /// 设置自定义的客户端标识(UserAgent),示例:"SepcifiedClient/1.1 (Universal)"
- /// 如果设置为空白或者不设置,SDK会自动使用默认的UserAgent
- ///
- /// 用户自定义的UserAgent
- /// 客户端标识UA
- public void SetUserAgent(string userAgent)
- {
- _userAgent = userAgent;
- _client.DefaultRequestHeaders.UserAgent.Clear();
- if (!string.IsNullOrEmpty(userAgent))
- {
- _client.DefaultRequestHeaders.UserAgent.ParseAdd(userAgent);
- }
- }
-
- ///
- /// 多部分表单数据(multi-part form-data)的分界(boundary)标识
- ///
- /// 分界(boundary)标识字符串
- public static string CreateFormDataBoundary()
- {
- var now = DateTime.UtcNow.Ticks.ToString();
- return $"-------{QiniuCSharpSdk.Alias}Boundary{Hashing.CalcMd5X(now)}";
- }
-
- ///
- /// 发送HTTP请求
- ///
- /// 请求消息
- /// 令牌(凭证)[可选]
- /// 是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)
- /// HTTP请求的响应结果
- public async Task SendAsync(HttpRequestMessage request, string token = null, bool binaryMode = false)
- {
- var result = new HttpResult();
- HttpResponseMessage response = null;
-
- if (!string.IsNullOrEmpty(token))
- {
- request.Headers.Add("Authorization", token);
- }
-
- try
- {
- response = await _client.SendAsync(request);
- await result.ReadAsync(response, binaryMode);
- }
- catch (Exception exception)
- {
- var wrapper = new Exception($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.ffff}] [{_userAgent}] [HTTP-{request.Method.Method}] Error: ", exception);
- await result.ReadErrorAsync(wrapper, response);
- }
- finally
- {
- response?.Dispose();
- }
-
- return result;
- }
-
- ///
- /// HTTP-GET方法
- ///
- /// 请求目标URL
- /// 令牌(凭证)[可选]
- /// 是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)
- /// HTTP-GET的响应结果
- public Task GetAsync(string url, string token = null, bool binaryMode = false)
- {
- var request = new HttpRequestMessage(HttpMethod.Get, url);
- return SendAsync(request, token, binaryMode);
- }
-
- ///
- /// HTTP-POST方法(不包含body数据)
- ///
- /// 请求目标URL
- /// 令牌(凭证)[可选]
- /// 是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)
- /// HTTP-POST的响应结果
- public Task PostAsync(string url, string token = null, bool binaryMode = false)
- {
- var request = new HttpRequestMessage(HttpMethod.Post, url);
- return SendAsync(request, token, binaryMode);
- }
-
- ///
- /// HTTP-POST方法
- ///
- /// 请求目标URL
- /// 主体数据[可选]
- /// 令牌(凭证)[可选]
- /// 是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)
- /// HTTP-POST的响应结果
- public Task PostAsync(string url, HttpContent content = null, string token = null, bool binaryMode = false)
- {
- var request = new HttpRequestMessage(HttpMethod.Post, url) { Content = content };
- return SendAsync(request, token, binaryMode);
- }
-
- ///
- /// HTTP-POST方法(包含body数据)
- ///
- /// 请求目标URL
- /// 主体数据(字节数据)
- /// 主体数据内容类型
- /// 令牌(凭证)[可选]
- /// 是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)
- /// HTTP-POST的响应结果
- public Task PostDataAsync(string url, byte[] data, string mimeType = "application/octet-stream", string token = null, bool binaryMode = false)
- {
- var content = new ByteArrayContent(data);
- content.Headers.ContentType = MediaTypeHeaderValue.Parse(mimeType);
- return PostAsync(url, content, token, binaryMode);
- }
-
- ///
- /// HTTP-POST方法(包含表单数据)
- ///
- /// 请求目标URL
- /// 表单数据
- /// 令牌(凭证)[可选]
- /// 是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)
- /// HTTP-POST的响应结果
- public Task PostFormAsync(string url, string data, string token = null, bool binaryMode = false)
- {
- var content = new StringContent(data, Encoding.UTF8, ContentType.WWW_FORM_URLENC);
- return PostAsync(url, content, token, binaryMode);
- }
-
- ///
- /// HTTP-POST方法(包含表单数据)
- ///
- /// 请求目标URL
- /// 表单数据
- /// 令牌(凭证)[可选]
- /// 是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)
- /// HTTP-POST的响应结果
- public Task PostFormAsync(string url, byte[] data, string token = null, bool binaryMode = false)
- {
- var content = new ByteArrayContent(data);
- content.Headers.ContentType = MediaTypeHeaderValue.Parse(ContentType.WWW_FORM_URLENC);
- return PostAsync(url, content, token, binaryMode);
- }
-
- ///
- /// HTTP-POST方法(包含JSON文本的body数据)
- ///
- /// 请求目标URL
- /// 主体数据(JSON文本)
- /// 令牌(凭证)[可选]
- /// 是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)
- /// HTTP-POST的响应结果
- public Task PostJsonAsync(string url, string data, string token = null, bool binaryMode = false)
- {
- var content = new StringContent(data, Encoding.UTF8, ContentType.APPLICATION_JSON);
- return PostAsync(url, content, token, binaryMode);
- }
-
- ///
- /// HTTP-POST方法(包含普通文本的body数据)
- ///
- /// 请求目标URL
- /// 主体数据(普通文本)
- /// 令牌(凭证)[可选]
- /// 是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)
- /// HTTP-POST的响应结果
- public Task PostTextAsync(string url, string data, string token = null, bool binaryMode = false)
- {
- var content = new StringContent(data, Encoding.UTF8, ContentType.TEXT_PLAIN);
- return PostAsync(url, content, token, binaryMode);
- }
- }
-}
diff --git a/Qiniu/Http/HttpResult.cs b/Qiniu/Http/HttpResult.cs
deleted file mode 100644
index 9e0d912..0000000
--- a/Qiniu/Http/HttpResult.cs
+++ /dev/null
@@ -1,215 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Qiniu.Http
-{
- ///
- /// HTTP请求(GET,POST等)的返回消息
- ///
- public class HttpResult
- {
- ///
- /// 非法上传凭证错误
- ///
- public static readonly HttpResult InvalidToken = new HttpResult
- {
- Code = (int)HttpCode.INVALID_TOKEN,
- Text = "invalid uptoken"
- };
-
- ///
- /// 非法文件错误
- ///
- public static readonly HttpResult InvalidFile = new HttpResult
- {
- Code = (int)HttpCode.INVALID_FILE,
- Text = "invalid file"
- };
-
- ///
- /// 初始化(所有成员默认值,需要后续赋值)
- ///
- public HttpResult()
- {
- Code = (int)HttpCode.USER_UNDEF;
- Text = null;
- Data = null;
-
- RefCode = (int)HttpCode.USER_UNDEF;
- RefInfo = null;
- }
-
- ///
- /// 状态码 (200表示OK)
- ///
- public int Code { get; set; }
-
- ///
- /// 消息或错误文本
- ///
- public string Text { get; set; }
-
- ///
- /// 消息或错误(二进制格式)
- ///
- public byte[] Data { get; set; }
-
- ///
- /// 参考代码(用户自定义)
- ///
- public int RefCode { get; set; }
-
- ///
- /// 附加信息(用户自定义,如Exception内容)
- ///
- public string RefText { get; set; }
-
- ///
- /// 参考信息(从返回消息WebResponse的头部获取)
- ///
- public Dictionary RefInfo { get; set; }
-
- ///
- /// 对象复制
- ///
- /// 要复制其内容的来源
- public void Shadow(HttpResult source)
- {
- Code = source.Code;
- Text = source.Text;
- Data = source.Data;
- RefCode = source.RefCode;
- RefText += source.RefText;
- RefInfo = source.RefInfo;
- }
-
- ///
- /// 读取 数据
- ///
- /// Http响应
- /// 是否以二进制模式读取响应内容
- ///
- internal async Task ReadAsync(HttpResponseMessage response, bool binaryMode)
- {
- ReadInfo(response);
-
- if (binaryMode)
- {
- Data = await response.Content.ReadAsByteArrayAsync();
- }
- else
- {
- Text = await response.Content.ReadAsStringAsync();
- }
- }
-
- internal async Task ReadErrorAsync(Exception exception, HttpResponseMessage response)
- {
- var sb = new StringBuilder();
- var e = exception;
- while (e != null)
- {
- sb.Append(e.Message + " ");
- e = e.InnerException;
- }
-
- sb.AppendLine();
- RefText += sb.ToString();
- RefCode = (int)HttpCode.USER_UNDEF;
-
- if (response != null)
- {
- ReadInfo(response);
- Text = await response.Content.ReadAsStringAsync();
- }
- }
-
- private void ReadInfo(HttpResponseMessage response)
- {
- Code = (int)response.StatusCode;
- RefCode = (int)response.StatusCode;
-
- if (RefInfo == null)
- {
- RefInfo = new Dictionary();
- }
-
- RefInfo.Add("ProtocolVersion", response.Version.ToString());
-
- if (!string.IsNullOrEmpty(response.Content.Headers.ContentType.CharSet))
- {
- RefInfo.Add("Characterset", response.Content.Headers.ContentType.CharSet);
- }
-
- if (!response.Content.Headers.ContentEncoding.Any())
- {
- RefInfo.Add("ContentEncoding", string.Join("; ", response.Content.Headers.ContentEncoding));
- }
-
- RefInfo.Add("ContentType", response.Content.Headers.ContentType.ToString());
-
- RefInfo.Add("ContentLength", response.Content.Headers.ContentLength.ToString());
-
- foreach (var header in response.Headers) RefInfo.Add(header.Key, string.Join("; ", header.Value));
- }
-
- ///
- /// 转换为易读或便于打印的字符串格式
- ///
- /// 便于打印和阅读的字符串
- public override string ToString()
- {
- var sb = new StringBuilder();
-
- sb.Append($"code:{Code}");
- sb.AppendLine();
-
- if (!string.IsNullOrEmpty(Text))
- {
- sb.AppendLine("text:");
- sb.AppendLine(Text);
- }
-
- if (Data != null)
- {
- sb.AppendLine("data:");
- const int n = 1024;
- if (Data.Length <= n)
- {
- sb.AppendLine(Encoding.UTF8.GetString(Data));
- }
- else
- {
- sb.AppendLine(Encoding.UTF8.GetString(Data, 0, n));
- sb.Append($"<--- TOO-LARGE-TO-DISPLAY --- TOTAL {Data.Length} BYTES --->");
- sb.AppendLine();
- }
- }
-
- sb.AppendLine();
-
- sb.Append($"ref-code:{RefCode}");
- sb.AppendLine();
-
- if (!string.IsNullOrEmpty(RefText))
- {
- sb.AppendLine("ref-text:");
- sb.AppendLine(RefText);
- }
-
- if (RefInfo != null)
- {
- sb.AppendLine("ref-info:");
- foreach (var d in RefInfo) sb.AppendLine($"{d.Key}:{d.Value}");
- }
-
- sb.AppendLine();
-
- return sb.ToString();
- }
- }
-}
diff --git a/Qiniu/Qiniu.FileService.csproj b/Qiniu/Qiniu.FileService.csproj
new file mode 100644
index 0000000..6f8a333
--- /dev/null
+++ b/Qiniu/Qiniu.FileService.csproj
@@ -0,0 +1,22 @@
+
+
+
+ netstandard2.0;netcoreapp2.0;netstandard2.1;netcoreapp3.0
+ Qiniu.FileService
+ Jackson.bruce
+ Ufangx
+ File management, super large file upload, breakpoint renewal
+ https://github.com/JacksonBruce/FileServices/blob/master/LICENSE
+ https://github.com/JacksonBruce/FileServices.git
+ https://github.com/JacksonBruce/FileServices
+ git
+ file service web uploader html5 uploader breakpoint renewal
+ Copyright (c) 2020-$([System.DateTime]::Now.Year) Jackson.Bruce
+ 1.0.0-beta.1
+
+
+
+
+
+
+
diff --git a/Qiniu/QiniuFileService.csproj b/Qiniu/QiniuFileService.csproj
deleted file mode 100644
index cbc44c3..0000000
--- a/Qiniu/QiniuFileService.csproj
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- netcoreapp2.1
- QiniuFileService
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/TestWeb/Startup.cs b/TestWeb/Startup.cs
index ede93fd..115f897 100644
--- a/TestWeb/Startup.cs
+++ b/TestWeb/Startup.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
@@ -27,8 +28,40 @@ namespace TestWeb
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
- services.AddFileServices(opt=>opt.DefaultScheme="")
- .AddLocalServices(o => o.StorageRootDir = hostEnvironment.ContentRootPath);
+ services.AddFileServices(opt => {
+ opt.DefaultScheme = "documents";//Ĭĵ
+ opt.AddAuthenticationScheme(CookieAuthenticationDefaults.AuthenticationScheme);//֤
+ //ļʱļ
+ opt.RuleOptions = new Ufangx.FileServices.Models.FileNameRuleOptions()
+ {
+ Rule = Ufangx.FileServices.Models.FileNameRule.Custom,//ԶṩԶ巽
+ Custom = originFileName => string.Format("{0:yyyyMMddHHmmss}_xx_{1}", DateTime.Now, originFileName),
+ Format = "xxx_{0:yyyyMMddHHmmss}"//úRule=FileNameRule.DateһʹãĬǣ{0:yyyyMMddHHmmss}
+ };
+
+ })
+ //Ƭ
+ .AddScheme("pictures", opt => {
+ opt.StoreDirectory = "wwwroot/pictures";//ͼƬ洢Ŀ¼
+ opt.SupportExtensions = new string[] { ".jpg", ".png" };//ֵ֧չ
+ opt.HandlerType = null;//ϴɹļͣͱʵIFileHandlerӿ
+ opt.LimitedSize = 1024 * 1024 * 4;//ļСֵֽΪλ
+ })
+ .AddScheme("documents",opt => opt.StoreDirectory = "wwwroot/documents")//ĵ
+ //.AddScheme(name:"videos",storeDirectory:"",supportExtensions:new string[] { },LimitedSize:1024*1024*500)//Ƶ
+ //.AddLocalServices(o => o.StorageRootDir = hostEnvironment.ContentRootPath)//ļϵͳļڱ
+ //ţ洢
+ .AddQiniuFileService(opt => {
+ opt.AccessKey = "";//
+ opt.SecretKey = "";
+ opt.BasePath = "";
+ opt.Bucket = "";
+ opt.Domain = "";
+ opt.ChunkUnit = Qiniu.Storage.ChunkUnit.U1024K;
+ opt.Zone = "ZoneCnEast";
+
+ });
+
services.AddControllersWithViews();
}
diff --git a/TestWeb/TestWeb.csproj b/TestWeb/TestWeb.csproj
index edb168b..c193fe2 100644
--- a/TestWeb/TestWeb.csproj
+++ b/TestWeb/TestWeb.csproj
@@ -12,11 +12,7 @@
-
-
-
-
-
+