using Aliyun.OSS; using Microsoft.AspNetCore.Http; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Security.Cryptography; using System.Threading.Tasks; using Wicture.DbRESTFul; namespace JiaZhiQuan.Common.AliOSS { public class FileUpload { private static readonly string[] ImageFileExtensions = new[] { "png", "jpg", "jpeg", "gif", "bmp" }; public async static Task UploadFromRequest(IHttpClientFactory httpClientFactory, IFormFile file, string destFileName, string destDir, OSSConfig config, int maxSize = 2, bool isImage = true) { OssClient ossClient = new OssClient(config.EndPoint, config.AccessKeyId, config.AccessKeySecret); return await UploadFromRequest(httpClientFactory, file, destFileName, destDir, config, ossClient, maxSize, isImage); } public class UploadResult { public int width { get; set; } public int height { get; set; } public string url { get; set; } } public async static Task UploadFromRequest(IHttpClientFactory httpClientFactory, IFormFile file, string destFileName, string destDir, OSSConfig config, OssClient ossClient, int maxSize = 2, bool isImage = true) { var extension = Path.GetExtension(file.FileName); if (isImage && ImageFileExtensions.All(e => !extension.ToLower().Equals("." + e))) { throw new LogicalException("仅支持上传图片格式", ErrorCodes.UploadFileFormatError); } if (file.Length > maxSize * 1024 * 1024) { throw new LogicalException("上传的" + (isImage ? "图片" : "文件") + "不能大于" + maxSize + "M", ErrorCodes.UploadFileSizeLimitError); } var dir = destDir.Trim(new char[] { '\\', '/' }); if (string.IsNullOrEmpty(dir)) { destFileName = destFileName.Trim(new char[] { '\\', '/' }) + extension; } else { destFileName = dir + "/" + destFileName.Trim(new char[] { '\\', '/' }) + extension; } using Stream fileStream = file.OpenReadStream(); if (isImage) { int width = 0; int height = 0; string url = await UploadToAliyun(destFileName, fileStream, config, ossClient); var reqUrl = string.IsNullOrEmpty(config.InternalDomainUrl) ? url : config.InternalDomainUrl + destFileName; var client = httpClientFactory.CreateClient(); client.Timeout = new TimeSpan(0, 0, 2); try { var content = JToken.Parse(await client.GetStringAsync(reqUrl + "?x-oss-process=image/info")); width = content.Value("ImageWidth").Value("value"); height = content.Value("ImageHeight").Value("value"); } catch (Exception ex) { LoggerManager.Logger.Error(ex, "获取图片属性出错 >>> " + reqUrl + "\r\n" + ex.Message); } return new UploadResult() { url = url, width = width, height = height }; } else { var url = await UploadToAliyun(destFileName, fileStream, config, ossClient); return new UploadResult() { url = url }; } } //public static string UploadToAliyun(string destFilePath, string localFilePath, OSSConfig config) //{ // OssClient ossClient = new OssClient(config.EndPoint, config.AccessKeyId, config.AccessKeySecret); // return UploadToAliyun(destFilePath, localFilePath, config.OSSBucket, config.DomainUrl, ossClient); //} public async static Task UploadToAliyun(string destFilePath, Stream stream, OSSConfig config, ObjectMetadata metadata = null) { OssClient ossClient = new OssClient(config.EndPoint, config.AccessKeyId, config.AccessKeySecret); return await UploadToAliyun(destFilePath, stream, config.OSSBucket, config.DomainUrl, ossClient, metadata); } //public static string UploadToAliyun(string destFilePath, string localFilePath, OSSConfig config, OssClient ossClient) //{ // return UploadToAliyun(destFilePath, localFilePath, config.OSSBucket, config.DomainUrl, ossClient); //} public async static Task UploadToAliyun(string destFilePath, Stream stream, OSSConfig config, OssClient ossClient, ObjectMetadata metadata = null) { return await UploadToAliyun(destFilePath, stream, config.OSSBucket, config.DomainUrl, ossClient, metadata); } //public async static string UploadToAliyun(string destFilePath, string localFilePath, string ossBucket, string domainUrl, OssClient ossClient) //{ // var rst = await Task.Factory.FromAsync(ossClient.BeginPutObject, ossClient.EndPutObject, ossBucket, localFilePath, null); // var result = ossClient.PutObject(ossBucket, destFilePath, localFilePath); // if (result.HttpStatusCode == System.Net.HttpStatusCode.OK) // { // return domainUrl + destFilePath; // } // else // { // throw new LogicalException("上传失败", ErrorCodes.UploadFileToOSSError); // } //} public async static Task UploadToAliyun(string destFilePath, Stream stream, string ossBucket, string domainUrl, OssClient ossClient, ObjectMetadata metadata = null) { using (stream) { stream.Position = 0; var tcs = new TaskCompletionSource(); ossClient.BeginPutObject(ossBucket, destFilePath, stream, metadata, iar => { tcs.SetResult(ossClient.EndPutObject(iar)); }, null); var result = await tcs.Task; // var result = await Task.Factory.FromAsync(ossClient.BeginPutObject, ossClient.EndPutObject, ossBucket, destFilePath, stream, null); if (result.ResponseStream != null) { result.ResponseStream.Close(); } if (result.HttpStatusCode == System.Net.HttpStatusCode.OK) { return domainUrl + destFilePath; } else { throw new LogicalException("上传失败", ErrorCodes.UploadFileToOSSError); } } } public static string GetFileIdByUrl(string url) { if (string.IsNullOrEmpty(url)) { return string.Empty; } url = url.Split(new char[] { '?' })[0]; var parts = url.Split(new string[] { "cdndev.olssglobal.com/", "olscdn.olssglobal.com/", "videodev.olssglobal.com/", "video.olssglobal.com/" }, StringSplitOptions.None); if (parts.Length > 1) { return parts[parts.Length - 1]; } return string.Empty; } public static void RemoveFile(List keys, string bucketName, OssClient ossClient) { ossClient.DeleteObjects(new DeleteObjectsRequest(bucketName, keys)); } } }