.net6之阿里云OSS-前端开发牛翰社区-编程开发-牛翰网

.net6之阿里云OSS

概念

集成阿里云OSS文件存储服务

引用阿里云包

封装AliyunSmsClient(二次封装阿里云短信基类)

   public class AliyunOssClient
    {
        private readonly AliyunOssOptions _options;
        private readonly OssClient _client;

        public AliyunOssClient(IOptions<AliyunOssOptions> options)
        {
            _options = options.Value;
            _client = new OssClient(_options.EndPoint, _options.AccessKeyId, _options.AccessKeySecret);
        }


        /// <summary>
        ///  推送文件
        /// </summary>
        /// <param name="formFile"></param>
        /// <returns></returns>
        public async Task<string> UpFileAsync(IFormFile  formFile)
        {
           return await Task.Run(() =>

            {
                var path = _options.ProjectName + "/" + _options.ServiceName + "/";
                path += IdGenerator.NextId() + "/";
                path+= formFile.FileName;
              
                try
                {
                    // 计算MD5。
                    string md5;
                    var stream = formFile.OpenReadStream();
                    md5 = OssUtils.ComputeContentMd5(stream, stream.Length);
                    var objectMeta = new ObjectMetadata
                    {
                        ContentMd5 = md5
                    };
                    
                    _client.PutObject(_options.BucketName, path, stream, objectMeta);
                    Console.WriteLine("Put object succeeded");
                
                }
                catch (OssException ex)
                {
                    Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
                        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Failed with error info: {0}", ex.Message);
                }
                return Task.FromResult(path);
            }
            );

        }


        /// <summary>
        /// 获取文件流
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<Stream> GetStreamAsync(string key)
        {
            return await Task.Run(() =>
            {
                return _client.GetObject(_options.BucketName, key).Content;
            });
        }

        #region 获取字节数组
        /// <summary>
        /// 获取字节数组
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<byte[]> GetBytesAsync(string key)
        {
            using (var sm = await GetStreamAsync(key))
            {
                var buf = new byte[1024];
                var ms = new MemoryStream();
                var len = 0;
                while ((len = sm.Read(buf, 0, 1024)) != 0)
                {
                    ms.Write(buf, 0, len);
                }
                ms.Position = 0;
                return ms.ToArray();
            }
        }
        #endregion

        #region 获取文件基本信息
        /// <summary>
        /// 获取文件基本信息
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<ObjectMetadata> GetMetadataAsync(string key)
        {
            return await Task.Run(() =>
            {
                return _client.GetObjectMetadata(_options.BucketName, key);
            });
        }
        #endregion

        #region 获取预签名地址
        /// <summary>
        /// 获取预签名地址
        /// </summary>
        /// <param name="key"></param>
        /// <param name="expirationMinutes"></param>
        /// <returns></returns>
        public async Task<string> GetPresignedUriAsync(string key, int? expirationMinutes = null)
        {
            return await Task.Run(() =>
            {
                return _client.GeneratePresignedUri(new GeneratePresignedUriRequest(_options.BucketName, key, SignHttpMethod.Get)
                {
                    Expiration = DateTime.Now.AddMinutes(expirationMinutes != null && expirationMinutes.Value > 0 ? expirationMinutes.Value : _options.PresignedUriExpirationMinutes)
                }).AbsoluteUri;
            });
        }
        #endregion


        #region 获取网页Post直传签名策略
        /// <summary>
        /// 获取网页Post直传签名策略
        /// https://help.aliyun.com/document_detail/31988.htm?spm=a2c4g.11186623.2.34.76e8295fUDcbJN#title-5go-s2f-dnw
        /// </summary>
        /// <param name="directory"></param>
        /// <returns></returns>
        public async Task<AliyunOssPostPolicyResponse> GeneratePostPolicyAsync(string directory)
        {
            return await Task.Run(() =>
            {
                directory = directory.Replace("//", "/").Replace("\\", "/");
                directory = directory.EndsWith("/") ? directory : directory + "/";

                var policyConds = new PolicyConditions();
                policyConds.AddConditionItem("bucket", _options.BucketName);
                policyConds.AddConditionItem(MatchMode.StartWith, PolicyConditions.CondKey, directory);
                policyConds.AddConditionItem(PolicyConditions.CondContentLengthRange, 1, int.MaxValue);

                var policy = _client.GeneratePostPolicy(DateTime.Now.AddMinutes(_options.PolicyExpirationMinutes), policyConds);
                var encPolicy = Convert.ToBase64String(Encoding.UTF8.GetBytes(policy));

                using (var algorithm = KeyedHashAlgorithm.Create("HmacSHA1".ToUpperInvariant()))
                {
                    algorithm.Key = Encoding.UTF8.GetBytes(_options.AccessKeySecret.ToCharArray());
                    var signature = Convert.ToBase64String(algorithm.ComputeHash(Encoding.UTF8.GetBytes(encPolicy.ToCharArray())));
                    return new AliyunOssPostPolicyResponse
                    {
                        Key = directory + "${filename}",
                        OssAccessKeyId = _options.AccessKeyId,
                        Policy = encPolicy,
                        Signature = signature,
                        Success_Action_Status = "200",
                        Host = BuildRequestUri(_options.EndPoint, _options.BucketName)
                    };
                };
            });
        }
        #endregion

        private static string BuildRequestUri(string endpoint, string bucketName)
        {
            var requestUriBuilder = new StringBuilder();

            if (endpoint.StartsWith("http://"))
            {
                requestUriBuilder.Append("http://");
                requestUriBuilder.Append(bucketName);
                requestUriBuilder.Append('.');
                requestUriBuilder.Append(endpoint.Substring("http://".Length));
            }
            else if (endpoint.StartsWith("https://"))
            {
                requestUriBuilder.Append("https://");
                requestUriBuilder.Append(bucketName);
                requestUriBuilder.Append('.');
                requestUriBuilder.Append(endpoint.Substring("https://".Length));
            }
            else
            {
                requestUriBuilder.Append("http://");
                requestUriBuilder.Append(bucketName);
                requestUriBuilder.Append('.');
                requestUriBuilder.Append(endpoint);
            }
            return requestUriBuilder.ToString();
        }

    }


封装参数构造类AliyunSmsSendRequestBuilder

   public class AliyunSmsSendRequestBuilder
    {
        private readonly SendSmsRequest _request;
        private readonly List<string> _phones;
        private readonly Dictionary<string, object> _templateParams;

        public AliyunSmsSendRequestBuilder(string templateCode)
        {
            _request = new SendSmsRequest();
            _request.TemplateCode = templateCode;
            _phones = new List<string>();
            _templateParams = new Dictionary<string, object>();
        }

        public AliyunSmsSendRequestBuilder AddPhone(IEnumerable<string> phones) => AddPhone(phones.ToArray());

        public AliyunSmsSendRequestBuilder AddPhone(params string[] phones)
        {
            _phones.AddRange(phones);
            return this;
        }

        public AliyunSmsSendRequestBuilder AddSignName( string signName)
        {
            _request.SignName = signName;
            return this;
        }       

        public AliyunSmsSendRequestBuilder AddTemplateParam(string key, object value)
        {
            _templateParams.Add(key, value);
            return this;
        }

        public SendSmsRequest Build()
        {
            _request.PhoneNumbers = string.Join(",", _phones.Distinct());
            _request.TemplateParam = JsonConvert.SerializeObject(_templateParams as dynamic);
            return _request;
        }
    }

封装初始化参数类AliyunSmsOptions

   public class AliyunSmsOptions
    {
        public string AccessKeyId { get; set; }
        public string AccessKeySecret { get; set; }
        public string SignName { get; set; }
    }

封装服务扩展静态类ServiceCollectionExtensions

 public static class ServiceCollectionExtensions
    {
        public static IServiceCollection AddAliyunSms(this IServiceCollection services, Action<AliyunSmsOptions> setup)
        {
            services.Configure(setup);
            services.AddSingleton<AliyunSmsClient>();
            return services;
        }
    }

项目打包推送至nuget仓库

打包传送门 https://www.cnblogs.com/inclme/p/16053978.html

.net6中使用

引用上述nuget包

添加扩展服务

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAliyunSms((op) =>
{
    builder.Configuration.Bind("BPA:AliyunSms", op);
});

参数参考

    "AliyunSms": {
      "AccessKeyId": "参考Key",
      "AccessKeySecret": "参考Secret",
      "SignName": "参考"
    },

封装接口

    public class AliyunOssGeneratePostPolicyRequest
    {
        /// <summary>
        /// 根目录
        /// </summary>
        [DisplayName("根目录")]
        [Required(ErrorMessage = "[{0}] 不能为空")]
        public string Directory { get; set; }

        /// <summary>
        /// 是否构建唯一目录
        /// </summary>
        public bool BuildUniqueDirectory { get; set; }
    }
    /// <summary>
        /// 构建网页Post直传策略
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("GeneratePostPolicy")]
        public async Task<AliyunOssPostPolicyResponse> GeneratePostPolicyAsync(AliyunOssGeneratePostPolicyRequest request)
        {
            var dir = request.Directory;
            dir = request.BuildUniqueDirectory ? $"{request.Directory}{(request.Directory.EndsWith("/") ? "" : "/")}{DateTime.Now.ToString("yyyyMMdd")}/{IdGenerator.NextId()}/" : dir;
            dir = !dir.EndsWith("/") ? dir + "/" : dir;
            var data =await _aliyunOssClient.GeneratePostPolicyAsync(dir);
            return data;
        }

前端使用

async uploadData(params) {

				const res = await this.$api.games.upload({
					directory: "good",
					buildUniqueDirectory: true
				});

				if (res.code != 200) {
					uni.showToast({
						title: "文件保存失败",
						icon: 'none'
					});
				}
				var formData = new FormData(); //注意formData里append添加的键的大小写
				formData.append("name", params.name); //文件名
				formData.append("key", res.content.key); //存储在oss的文件路径
				formData.append("ossAccessKeyId", res.content.ossAccessKeyId); //accessKeyId
				formData.append("policy", res.content.policy); //policy
				formData.append("signature", res.content
					.signature); //签名 //如果是base64文件,那么直接把base64字符串转成blob对象进行上传就可以了
				formData.append("file", params.file);
				formData.append("success_Action_Status", 200); //成功后返回的操作码
				formData.append("host", res.content.host);
				var fileUrl = "";
				let _this = this;
				await $.ajax({
					url: res.content.host,
					type: "POST",
					data: formData,
					cache: false,
					contentType: false,
					processData: false,
					success: function(data) {
						_this.imageValue.push({
							url: res.content.host +
								"/" +
								res.content.key.replace("${filename}", params.name),
							//extname: params.extname,
							name: params.name

						})
					},
					error: function(data) {
						console.log(data);
					}
				});
			},


来源链接:https://www.cnblogs.com/inclme/p/18650626

请登录后发表评论

    没有回复内容