.net6之阿里云OSS

news/2025/1/8 16:30:51/文章来源:https://www.cnblogs.com/inclme/p/18650626

概念

集成阿里云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)};};});}#endregionprivate 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); //accessKeyIdformData.append("policy", res.content.policy); //policyformData.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);}});},

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/865327.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React数值滚动效果,支持数值变化变化

效果:组件:(NumberScroller.jsx)/*** 数字滚动效果*/ import React, { useEffect, useState } from react; import PropTypes from prop-types;const NumberScroller = ({ targetValue = 0, decimalPlaces = 0, duration = 2000 }) => {const [value, setValue] = useSt…

C#笔记(1、钉钉机器人推送帆软报表图片)

C#笔记——钉钉机器人推送帆软报表图片(一)1、前言 ​ 2024年最后一个月,家里多了个小公主,在家休息了一段时间。2025年,休完假上班第一天,领导就说:哎,我看总部那边做了个每日产出的报表推送到钉钉群,来看计划达成率。我们基地这边能不能做啊。我心里默默一想,然后大…

Javascript实现asp.net mvc的checkbox基本功能

Html的checkbox使用很广的,它的状态,勾选与非选。初始状态,默认为非选。你可以设置它是勾选, 直在checkbox 标签中,添加checked属性。另外,在javascript可以这样,getById(Checkbox_IsPublished).checked = true; 或者,getById(Checkbox_IsPublished).setAttribute(che…

“非旺玖原装的PL2303,请联系您的供应商”232串口转换器解决办法

偶尔会用到PL2303这种十几年前的旧芯片做的232串口转换器,如果手头没有别的工具必须使用的话,需要配置一下才能使用。该串口调试器在不同的USB口插入可能出现COM口无效或者端口号变动(COM 4/7/8等),需要通过设备管理器进行修改 当提示题目上的错误时,需要重装旧版本驱动1…

记录一个Github推送的问题(ssh推送出现:Connection closed by 198.18.0.9 port 22)

一、前言: 在公司需要将一个文档推送到GitHub仓库,由于Github对Https的推送已经移除了对密码认证的支持(2021.8.13),所以想要进行身份验证就只能使用两种方式:使用Persional Access Token(PAT) 使用SSH认证 PAT认证太麻烦了,每次都要输入,这里就主要介绍使用SSH认证的方…

安川机器人的独特优势

安川机器人,这一源自日本安川电机(Yaskawa Electric Corporation)的杰出产物,是工业自动化领域中的佼佼者,其核心价值在于生产线上那精准无误的自动化作业能力。这款机器人集成了电机、减速器、传感器、控制器等一系列精密部件,如同一套高效协同的作战系统,为企业带来了生…

2020-2024 IDEA安装+激活

一、下载 1. IDEA各版本官方下载入口 IDEA官网下载地址 2. 选择左边,然后点击【20xx.x.x-Windows(exe)】 PS: 如需下载特定版本,可以往下拉,都是选择【202x.x-Windows(exe)】下载二、安装 1. 点击运行 ps: 安全警告是部分电脑有,没有跳过就可以了~2. 点击下一步3. 选择安…

CDS标准视图:维护包描述 I_MaintPackageTextData

视图名称:维护包描述 I_MaintPackageTextData 视图类型:基础 视图代码:点击查看代码 @EndUserText.label: Maintenance Package - Text @ObjectModel.dataCategory: #TEXT @VDM.viewType: #COMPOSITE @AbapCatalog.sqlViewName: IMNTPCKGTXTDATA @AbapCatalog.compiler.comp…

CDS标准视图:维护包数据 I_MaintenancePackageData

视图名称:维护包数据 I_MaintenancePackageData 视图类型:基础 视图代码:点击查看代码 @AbapCatalog.sqlViewName: IMAINTPCKGDATA @AbapCatalog.compiler.compareFilter: true @AccessControl.authorizationCheck: #PRIVILEGED_ONLY @EndUserText.label: Maintenance Packa…

让跨 project 联查更轻松,SLS StoreView 查询和分析实践

在业务场景中,日志数据可能存储在日志服务 Project 的不同 Logstore/MetricStore 中或不同地域的 Project 中。日志服务的数据集(StoreView)功能支持跨地域、跨 Store 联合查询和分析,让用户基于数据集就能高效便捷地查询分析全地域的数据,真正做到数据分析不受地域边界的…

流程配置中心同步后流程版本ID不一致

不同的账套进行流程发布时会产生不同的版本ID , BOS同步后的流程设计的ID是相同的.

大语言模型提示技巧(六)-文本转换

大语言模型是基于自然语言的人工智能,所以它在语言上的表现相当出色,使用大语言模型进行可以进行诸如翻译、语气转换、润色、语言评价、扩写、润色等语言处理,对于日常文字工作,它是一名合格甚至优秀的私人秘书。 (一)翻译 在不同语言之间进行翻译是众多大语言模型都支持…