概念
集成阿里云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
没有回复内容