.net 5 上傳文件到阿里雲的OSS


.net 5 上傳文件到阿里雲的OSS   文件的上傳、下載 和文件的管理

1.先購買阿里雲的oss服務器

2.添加子用戶 會生成  AccessKeyId  和 AccessKeySecret 記錄下來

3.給當前子用戶添加管理阿里雲oss 的權限

 

//所需要用到的類

    public class FileBaseRequest
    {
        /// <summary>
        /// 文件名稱
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 文件大小
        /// </summary>
        public long? Size { get; set; }

        /// <summary>
        /// 文件寬度
        /// </summary>
        public int? Width { get; set; }

        /// <summary>
        /// 文件高度
        /// </summary>
        public int? Height { get; set; }

        /// <summary>
        /// 文件類型
        /// </summary>
        public string Type { get; set; }

        /// <summary>
        /// 文件唯一的Guid
        /// </summary>
        public string Guid { get; set; }

        /// <summary>
        /// 圖片形狀
        /// </summary>
        public int ShapeTypeId { get; set; }

        /// <summary>
        /// url 地址
        /// </summary>
        public string FilebaseUrl { get; set; }

        /// <summary>
        /// hash
        /// </summary>
        public string Hash { get; set; }

    }
    public class DownFileInfo
    {
        public string Name { get; set; }

        public string Url { get; set; }
    }

 

    public class ReturnBox
    {
        public int Code { get; set; } = 200;
        public object Data { get; set; }
        public string Message { get; set; } = "Success";

    }

 

 

//連接的Helper  在使用前 在包管理工具中安裝阿里雲的包  Aliyun.OSS.Core, Version=2.13.0.0 按着自己的EF 或者 Core 都行

     

    public class OSSHelper
    {
        #region Fields
        //https://zww1.oss-cn-shenzhen.aliyuncs.com/xxxxxx/filebase_dev/oringinal/123456dfsf.png

        private static OssClient _ossClient;

        private static AutoResetEvent _event;

        //賬號Id
        private const string AccessKeyId = "xxxxxxxxxx";

        //賬號key
        private const string AccessKeySecret = "xxxxxxxxxx";

        //oss所在的服務區域
        private const string Endpoint = "https://oss-cn-shenzhen.aliyuncs.com";

        //生成的圖片的路徑地址
        private const string Branch = @"xxxxxx/filebase_dev/";

        // 填寫Bucket名稱。
        private const string BucketName = "zww1";

        // 填寫Object完整路徑。Object完整路徑中不能包含Bucket名稱。
        private const string objectName = "/xxxxxx/filebase_dev/";

        // 填寫字符串。
        private const string objectContent = "";

        private const string ThumbSize = "350";

        private const string DefaultSize = "750";
        #endregion

        #region Constructors

        private OSSHelper()
        {
            _event = new AutoResetEvent(false);
            _ossClient = new OssClient(Endpoint, AccessKeyId, AccessKeySecret);
        }

        public static OSSHelper _()
        {
            return new OSSHelper();
        }

        #endregion

        #region Method

        /// <summary>
        /// 通過文件流普通上傳 10 普通上傳  20 斷點續傳上傳  30進度條上傳
        /// </summary>
        /// <returns></returns>
        public async Task<FileBaseRequest> HttpUpload(IFormFile file, int uploadtype = 10)
        {
            string nameStr = string.Empty;
            string name = file.FileName;
            if (!string.IsNullOrEmpty(name) && name.Contains('.'))
            {
                nameStr = name.Split('.')[0];
            }
            string type = file.ContentType;
            string guid = Guid.NewGuid().ToString();
            string filebaseUrl = string.Empty;
            string hash = "";
            long? size = 0;

            int? width = 0;
            int? height = 0;
            int? shapeTypeId = 0;

            var strArr = type.Split('/');

            using (var memoryStream = new MemoryStream())
            {
                await file.CopyToAsync(memoryStream);
                size = file.Length;
                hash = ComputeMd5Hash(memoryStream);

                if (strArr[0].ToString() == "image")
                {
                    using (Bitmap pic = new Bitmap(memoryStream))
                    {
                        width = pic.Size.Width;
                        height = pic.Size.Height;
                        if (width > height)
                            shapeTypeId = (int)ShapeType.Sideways;
                        if (width < height)
                            shapeTypeId = (int)ShapeType.vertical;
                        if (width == height)
                            shapeTypeId = (int)ShapeType.Square;
                    }
                }

                if (strArr[0].ToString() == "video")
                {

                }

                byte[] oringinalBuffer, thumbBuffer, defaultBuffer;
                oringinalBuffer = memoryStream.ToArray();
                thumbBuffer = GetThumbnail(oringinalBuffer, int.Parse(ThumbSize));
                defaultBuffer = GetThumbnail(oringinalBuffer, int.Parse(DefaultSize));

                switch (uploadtype)
                {
                    case 10:
                        using (MemoryStream requestContent = new MemoryStream(oringinalBuffer))
                        {
                            filebaseUrl = $"{Branch}oringinal/{guid}.jpg";
                            _ossClient.PutObject(BucketName, filebaseUrl, requestContent);
                        }
                        using (MemoryStream requestContent = new MemoryStream(thumbBuffer))
                        {
                            _ossClient.PutObject(BucketName, $"{Branch}thumb/{guid}.jpg", requestContent);
                        }

                        using (MemoryStream requestContent = new MemoryStream(defaultBuffer))
                        {
                            _ossClient.PutObject(BucketName, $"{Branch}default/{guid}.jpg", requestContent);
                        }
                        break;

                    case 20:
                        using (MemoryStream requestContent = new MemoryStream(oringinalBuffer))
                        {
                            filebaseUrl = $"{Branch}oringinal/{guid}.jpg";
                            var result = BreakPoint(BucketName, filebaseUrl, requestContent, nameStr);
                        }
                        using (MemoryStream requestContent = new MemoryStream(thumbBuffer))
                        {
                            var result = BreakPoint(BucketName, $"{Branch}thumb/{guid}.jpg", requestContent, nameStr);
                        }
                        using (MemoryStream requestContent = new MemoryStream(defaultBuffer))
                        {
                            var result = BreakPoint(BucketName, $"{Branch}default/{guid}.jpg", requestContent, nameStr);
                        }
                        break;

                    case 30:
                        using (MemoryStream requestContent = new MemoryStream(oringinalBuffer))
                        {
                            filebaseUrl = $"{Branch}oringinal/{guid}.jpg";
                            var result = PutObjectProgress(BucketName, filebaseUrl, requestContent);
                        }
                        using (MemoryStream requestContent = new MemoryStream(thumbBuffer))
                        {
                            var result = PutObjectProgress(BucketName, $"{Branch}thumb/{guid}.jpg", requestContent);
                        }
                        using (MemoryStream requestContent = new MemoryStream(defaultBuffer))
                        {
                            var result = PutObjectProgress(BucketName, $"{Branch}default/{guid}.jpg", requestContent);
                        }
                        break;

                    default:
                        break;
                }
            }
            return new FileBaseRequest
            {
                FilebaseUrl = $"https://zww1.oss-cn-shenzhen.aliyuncs.com/{filebaseUrl}",
                Guid = guid,
                Hash = hash,
                Height = height,
                Name = name,
                ShapeTypeId = (int)shapeTypeId,
                Size = size,
                Type = type,
                Width = width,
            };
        }


        /// <summary>
        /// 單條下載
        /// </summary>
        /// <returns></returns>
        public async Task<byte[]> HttpDownload(string url)
        {
            try
            {
                RestClient restClient = new RestClient();
                var request = new RestRequest(url);
                var byteFile = restClient.DownloadData(request);
                return byteFile;
            }
            catch (Exception ex)
            {
                throw new AggregateException(ex.Message);
            }
        }


        /// <summary>
        /// 單條下載文件並轉流
        /// </summary>
        /// <param name="fileName">文件路徑</param>
        /// <param name="isDelete">是否刪除臨時文件</param>
        /// <returns></returns>
        public Stream FileToStream(string fileName, bool isDelete = false, string url = null)
        {
            using (var client = new WebClient())
            {
                string tempFile = Path.GetTempFileName();
                client.DownloadFile(url, tempFile);//下載臨時文件
                                                   //Console.WriteLine("Using " + tempFile);

                //打開文件
                FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);

                // 讀取文件的 byte[]
                byte[] bytes = new byte[fileStream.Length];

                fileStream.Read(bytes, 0, bytes.Length);

                fileStream.Close();

                // 把 byte[] 轉換成 Stream
                Stream stream = new MemoryStream(bytes);
                if (isDelete)
                {
                    File.Delete(fileName);//刪除臨時文件
                }
                return stream;
            }
        }


        /// <summary>
        /// 通過文件列表的Url地址下載文件
        /// </summary>
        /// <param name="url">下載文件地址</param>
        /// <returns></returns>
        public async Task<Stream> HttpDownloadList(List<DownFileInfo> downFileInfos)
        {
            byte[] buffer = new byte[] { };

            foreach (var item in downFileInfos)
            {
                RestClient restClient = new RestClient();
                var request = new RestRequest(item.Url);
                buffer = restClient.DownloadData(request);
            }
            return new MemoryStream(buffer);
        }
        #endregion


        #region Utilities
        /// <summary>
        /// 進度條上傳方法
        /// </summary>
        /// <param name="BucketName"></param>
        /// <param name="objectName"></param>
        /// <param name="stream"></param>
        /// <param name="CheckpointDir"></param>
        /// <returns></returns>
        public async Task<bool> PutObjectProgress(string bucketName, string objectName, Stream stream)
        {
            bool state = true;
            try
            {
                var putObjectRequest = new PutObjectRequest(bucketName, objectName, stream);
                putObjectRequest.StreamTransferProgress += streamProgressCallback;
                _ossClient.PutObject(putObjectRequest);
            }
            catch (OssException ex)
            {
                throw new AggregateException($"Failed with error code: {ex.ErrorCode}; Error info: { ex.Message}. \nRequestID: {ex.RequestId}\tHostID: {ex.HostId}");
            }
            catch (Exception ex)
            {
                throw new AggregateException(ex.Message);
            }
            return state;
        }

        // 獲取上傳進度。
        private static void streamProgressCallback(object sender, StreamTransferProgressArgs args)
        {
            System.Console.WriteLine($"ProgressCallback - Progress: {args.TransferredBytes * 100 / args.TotalBytes}%, TotalBytes:{args.TotalBytes}, TransferredBytes:{args.TransferredBytes}");
        }


        /// <summary>
        /// 斷點續傳上傳方法
        /// </summary>
        /// <param name="BucketName"></param>
        /// <param name="objectName"></param>
        /// <param name="stream"></param>
        /// <param name="CheckpointDir"></param>
        /// <returns></returns>
        /// <exception cref="AggregateException"></exception>
        public async Task<bool> BreakPoint(string BucketName, string objectName, Stream stream, string CheckpointDir)
        {
            bool back = false;
            try
            {
                // 通過UploadFileRequest設置多個參數。
                UploadObjectRequest request = new UploadObjectRequest(BucketName, objectName, stream)
                {
                    // 指定上傳的分片大小。
                    PartSize = 8 * 1024 * 1024,
                    // 指定並發線程數。
                    ParallelThreadCount = 10,
                    // checkpointDir保存斷點續傳的中間狀態,用於失敗后繼續上傳。
                    // 如果checkpointDir為null,斷點續傳功能不會生效,每次失敗后都會重新上傳。
                    CheckpointDir = CheckpointDir,
                    UploadStream = stream
                };
                // 斷點續傳上傳。
                _ossClient.ResumableUploadObject(request);
                return true;
            }
            catch (OssException ex)
            {
                throw new AggregateException($"Failed with error code: {ex.ErrorCode}; Error info: {ex.Message}. \nRequestID:{ex.RequestId}\tHostID:{ex.HostId}");
            }
            catch (Exception ex)
            {
                throw new AggregateException(ex.Message);
            }
        }

        /// <summary>
        /// 壓縮圖片
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="targetSize">目標大小</param>
        /// <param name="orientation">旋轉方向</param>
        /// <returns></returns>
        private Byte[] GetThumbnail(byte[] buffer, int targetSize, int orientation = 0)
        {
            using (var memoryStream = new MemoryStream(buffer))
            {
                if (targetSize == 0)
                {
                    return buffer;
                }

                using (Image image = new Bitmap(memoryStream))
                {
                    if (image.Width < targetSize)
                    {
                        return buffer;
                    }
                    //方向旋轉
                    Rotation(image, image.Width, image.Height, 0);

                    //計算比例
                    var data = CalculateDimensions(image.Size, targetSize);

                    //開始壓縮
                    System.Drawing.Image thumbImage = image.GetThumbnailImage(data.Width, data.Height, new Image.GetThumbnailImageAbort(ThumbnailCallback), System.IntPtr.Zero);

                    using MemoryStream backStream = new MemoryStream();
                    thumbImage.Save(backStream, ImageFormat.Jpeg);
                    //關閉縮略圖對象
                    thumbImage.Dispose();

                    return backStream.GetBuffer();
                }
            }
        }


        private bool ThumbnailCallback()
        {
            return false;
        }

        /// <summary>
        /// 方向選擇 旋轉
        /// </summary>
        /// <param name="image"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="orientation"></param>
        private void Rotation(Image image, int width, int height, int orientation)
        {
            int ow = width;
            switch (orientation)
            {
                case 2:
                    image.RotateFlip(RotateFlipType.RotateNoneFlipX);
                    break;
                case 3:
                    image.RotateFlip(RotateFlipType.Rotate180FlipNone);
                    break;
                case 4:
                    image.RotateFlip(RotateFlipType.RotateNoneFlipY);
                    break;
                case 5:
                    image.RotateFlip(RotateFlipType.Rotate90FlipX);
                    break;
                case 6:
                    image.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    width = height;
                    height = ow;
                    break;
                case 7:
                    image.RotateFlip(RotateFlipType.Rotate270FlipX);
                    break;
                case 8:
                    image.RotateFlip(RotateFlipType.Rotate270FlipNone);
                    width = height;
                    height = ow;
                    break;
                default:
                    break;
            }
        }


        private Size CalculateDimensions(Size oldSize, int targetSize, bool autoResize = false)
        {
            Size newSize = new Size();
            if (autoResize && oldSize.Height > oldSize.Width)
            {
                newSize.Width = (int)(oldSize.Width * ((float)targetSize / (float)oldSize.Height));
                newSize.Height = targetSize;
            }
            else
            {
                newSize.Width = targetSize;
                newSize.Height = (int)(oldSize.Height * ((float)targetSize / (float)oldSize.Width));
            }
            return newSize;
        }


        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        private string ComputeMd5Hash(MemoryStream stream)
        {
            string hash = "";
            using (MD5 md5 = MD5.Create())
            {
                stream.Position = 0;
                foreach (var item in md5.ComputeHash(stream))
                {
                    hash += item.ToString("x2");
                }
            }
            return hash;
        }


        /// <summary>
        /// 獲取圖片的寬高
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public async Task<Tuple<int, int>> GetImagesInfo(IFormFile file)
        {
            int width = 0;
            int height = 0;
            using (var memoryStream = new MemoryStream())
            {
                await file.CopyToAsync(memoryStream);
                using (Bitmap pic = new Bitmap(memoryStream))
                {
                    width = pic.Size.Width;
                    height = pic.Size.Height;
                }
            }
            return new Tuple<int, int>(width, height);
        }
        #endregion

    }

 

    //最后在Controller 中調用  
    [Authorize(Policy = "UniPermission")]
    public class FileManageController : ControllerBase
    {

        [HttpGet]
        [Route("/")]
        [AllowAnonymous]
        public IActionResult Get()
        {
            return Ok("this is test");
        }

        /// <summary>
        /// 上傳  10 普通上傳  20 斷點續傳上傳  30進度條上傳
        /// </summary>
        /// <returns></returns>
        [HttpPost("/upload")]
        public async Task<IActionResult> Upload()
        {
            try
            {
                int type = 10;
                var files = Request.Form.Files;
                if (Request.Form.ContainsKey("Type"))
                {
                    string str = Request?.Form["Type"].ToString();
                    type = int.Parse(string.IsNullOrEmpty(str) ? "10" : str);
                }
                List<FileBaseRequest> fileBaseRequests = new List<FileBaseRequest>();
                foreach (var file in files)
                {
                    var result = await OSSHelper._().HttpUpload(file, type);
                    fileBaseRequests.Add(result);
                }

                return Ok(new ReturnBox
                {
                    Data = fileBaseRequests
                });
            }
            catch (System.Exception ex)
            {
                return Ok(new ReturnBox
                {
                    Code = 400,
                    Message = ex.Message.ToString()
                });
                throw;
            }
        }


        /// <summary>
        /// 批量下載
        /// </summary>
        /// <param name="downFileInfos"></param>
        /// <returns></returns>
        [HttpPost("/downloads")]
        public async Task<IActionResult> Download([FromBody] List<DownFileInfo> downFileInfos)
        {
            var result = await OSSHelper._().HttpDownloadList(downFileInfos);
            return Ok(result);
        }


        /// <summary>
        /// 單條下載
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        [HttpGet("/download")]
        [AllowAnonymous]
        public async Task<IActionResult> Packing(string url)//JsonElement jsonElement
        {
            var result = await OSSHelper._().HttpDownload(url);
            return File(result, "image/jpeg");
        }


    }

 

一切准備就緒后  使用 postman 測試

 

 

 

成功后返回當前圖片的信息,在oss 中 生成不同類型的圖片 選中圖片能看到圖片對應的 url 

 

 在本項目上傳中使用的是簡單上傳

 

 針對更多的上傳方式 參考官方文檔 https://www.alibabacloud.com/help/zh/doc-detail/91093.htm?spm=a2c63.p38356.b99.680.5fab7207rHS5QX

 

 

好了目前到這里就結束了 可自行擴展  僅供參考

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM