posts - 52,comments - 30,views - 13万

.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

 

 

好了目前到这里就结束了 可自行扩展  仅供参考

 

posted on   白码一号  阅读(1407)  评论(1编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示