NetMvc通过亚马逊方式服务器端和客户端上传MinIO顺利解决
前言:
1、由于项目是.NET Framework 4.7 MVC LayUI,所以需要找一个资源站点存放项目中静态资源文件;
2、需要支持服务端和客户端都支持上传文件方式;
3、调用简单,涉及库越少越好。
结果:
调用 AWSSDK.S3 和 AWSSDK.Core 实现文件上传到 MinIO ;调用MimeMapping获取文件ContentType
MinIO
Minio是Apache License v2.0下发布的对象存储服务器。它与Amazon S3云存储服务兼容。它最适合存储非结构化数据,如照片,视频,日志文件,备份和容器/ VM映像。对象的大小可以从几KB到最大5TB Minio服务器足够轻,可以与应用程序堆栈捆绑在一起,类似于NodeJS,Redis和MySQL。
AWS S3
全称:(Amazon Simple Storage Service), 是一种面向网络的存储服务,可以支持用户随时在Web的任何位置,存储和检索任意大小的数据本身也提供了简单而直观的管理控制台来处理这些任务,但我这里使用的是,面向C# 方向的S3网络存储服务。
具体调研实现方法如下
1、服务器的配置
推荐版本:minio.RELEASE.2022-05-26T05-48-41Z
当前版本文件可来取自如。
2、服务端上传实现代码
需要NuGit调用有三项
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AWSSDK.Core" version="3.7.304.16" targetFramework="net47" />
<package id="AWSSDK.S3" version="3.7.309.4" targetFramework="net47" />
<package id="MimeMapping" version="3.0.1" targetFramework="net47" />
</packages>
具体实现代码
using Amazon;
using Amazon.Runtime;
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
namespace DealMvc.AmazonS3 {
/// <summary>
/// 实现MinIO文件的上传
/// 调用 AWSSDK.S3 和 AWSSDK.Core
/// 文件的 ContentType 调用 MimeMapping 实现
/// </summary>
public class AmazonHelper {
/// <summary>
/// Bucket访问AccessKey
/// </summary>
readonly string AccessKey = "admin";
/// <summary>
/// Bucket访问SecretKey
/// </summary>
readonly string SecretKey = "123456+++";
/// <summary>
/// 存储桶名称
/// </summary>
readonly string BucketName = "test";
/// <summary>
/// 服务地址
/// </summary>
readonly string ServiceURL = "http://192.168.20.66:9000";
/// <summary>
/// 预览地址
/// </summary>
readonly string WebURL = "https://res.test.cn";
/// <summary>
///
/// </summary>
//readonly string awsRegion = "us-east-1";
readonly AmazonS3Client client;
/// <summary>
/// 构造函数
/// </summary>
public AmazonHelper() {
//提供awsAccessKeyId和awsSecretAccessKey构造凭证
var credentials = new BasicAWSCredentials(AccessKey, SecretKey);
//提供awsEndPoint(域名)进行访问配置
var clientConfig = new AmazonS3Config {
// 必须在设置ServiceURL前进行设置,并且需要和`MINIO_REGION`环境变量一致。
//RegionEndpoint = RegionEndpoint.GetBySystemName(awsRegion),
RegionEndpoint = RegionEndpoint.USEast1,
// 替换成你自己的MinIO Server的URL
ServiceURL = ServiceURL,
// 必须设为true
ForcePathStyle = true,
};
client = new AmazonS3Client(credentials, clientConfig);
}
#region 上传文件
/// <summary>
/// 上传文件[本地]
/// </summary>
/// <param name="key"></param>
/// <param name="filePath">路径</param>
/// <returns>网址</returns>
public async Task<string> UploadFilePath(string saveKey, string filePath) {
var request = new PutObjectRequest {
BucketName = BucketName,
Key = saveKey,
ContentType = GetContentType(saveKey),
FilePath = filePath,
};
var response = await client.PutObjectAsync(request);
//
return WebUrlKey(response.HttpStatusCode, saveKey);
}
/// <summary>
/// 上传文件[流]
/// </summary>
public async Task<string> UploadInputStream(string saveKey, Stream inputStream) {
var request = new PutObjectRequest {
BucketName = BucketName,
Key = saveKey,
ContentType = GetContentType(saveKey),
InputStream = inputStream //File.OpenRead
};
var response = await client.PutObjectAsync(request);
//
return WebUrlKey(response.HttpStatusCode, saveKey);
}
#endregion
/// <summary>
/// 客户端上传文件
/// </summary>
public string GetPreSignedUrl(string saveKey) {
var request = new GetPreSignedUrlRequest {
BucketName = BucketName,
Key = saveKey,
Expires = DateTime.UtcNow.AddMinutes(15),
Verb = HttpVerb.PUT,
ContentType = GetContentType(saveKey),
Protocol = Protocol.HTTP // 指定使用HTTPS协议
};
var url= client.GetPreSignedURL(request);
return url;
}
#region 私有方法
/// <summary>
/// 根据文件Key返回预览地址
/// </summary>
private string WebUrlKey(HttpStatusCode statusCode, string saveKey) {
if (statusCode != System.Net.HttpStatusCode.OK)
throw new Exception("上传文件失败");
return WebURL + "/" + BucketName + "/" + saveKey;
}
/// <summary>
/// 根据文件获取ContentType
/// </summary>
private string GetContentType(string saveKey) {
return MimeMapping.MimeUtility.GetMimeMapping(Path.GetFileName(saveKey));
}
#endregion
}
}
控制器中实现代码
// 用于服务端本地文件
[HttpGet]
public async Task<ActionResult> UpFilePathAmazon() {
var filePath = @"D:\a\KAT\01.jpg";
var key = "kat/" + 0L.NewLongId() + System.IO.Path.GetExtension(filePath);
var url = await amazon.UploadFilePath(key, filePath);
return Content(url);
}
// 用于服务端上传文件
[HttpGet]
public async Task<ActionResult> UpFileStreamAmazon() {
///pdfFile[0].OpenReadStream()
var filePath = @"D:\a\KAT\02.jpg";
var key = "kat/" + 0L.NewLongId() + System.IO.Path.GetExtension(filePath);
var stream = System.IO.File.OpenRead(filePath);
var url = await amazon.UploadInputStream(key, stream);
return Content(url);
}
// 用于客户端上传文件
[HttpPost]
public ActionResult UploadImgUrl(string filename) {
string fileType = "images";
string fileExt = System.IO.Path.GetExtension(filename).ToLower();
string saveKey = fileType+"/" + 0L.NewLongId() + fileExt;
var url = new DealMvc.AmazonS3.AmazonHelper().GetPreSignedUrl(saveKey);
return JsonMessageData(new{
url,
});
}
前端页面实现方式(代码中涉及到)
代码中涉及到LayUI前端框架如下:
HTML代码
<form class="layui-form" lay-filter="subform">
<div class="layui-form-item">
<label class="layui-form-label"><em>*</em>广告图片</label>
<div class="layui-input-inline" style="width: 660px;">
<div class="flex align-center margin-bottom-sm">
<button type="button" class="layui-btn layui-btn-primary layui-border-green layui-btn-sm margin-right-sm" id="ID-PicUrl">
<i class="layui-icon layui-icon-upload"></i> 上传图片
</button>
<div class="">宽高比例按4:3,格式png、jpg</div>
</div>
<input name="PicUrl" lay-verify="required" lay-reqtext="请上传 广告图片" autocomplete="off" class="layui-input" />
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button type="button" class="layui-btn" onclick="uploadFile()">Upload</button>
</div>
</div>
</form>
JavaScript代码
layui.use(function () {
var upload = layui.upload;
var layer = layui.layer;
//执行upload组件实例
upload.render({
auto: false,//选择文件后不自动上传
elem: '#ID-PicUrl', //绑定元素
acceptMime: 'image/jpeg, image/png, image/gif',
choose: function (obj) {
//start
var files = obj.pushFile(), thisStart = 0, keysArray = Object.keys(files);
if (files && keysArray.length > 0) {
keysArray.forEach(function (key) {
if (thisStart === keysArray.length - 1) {
let index = key
, file = files[key]
, resultObj = files[key]
;
let requestData = {};
if (file && file.name) {
thisFilename = file.name;
requestData = { filename: thisFilename };
}
UploadToken(file, requestData);
} else {
layer.msg("上传时发生异常,请重试 ~ ", { icon: 2, time: 1500 });
}
thisStart++;
});
}
}
, error: function () {
layer.alert("网络异常,请重试 ~ ", { title: "上传失败提示", icon: 2, })
}
});
// 通过文件名称获取到服务器存放路径
var UploadToken = (file, requestData) => {
$.ajax({
url: "/File/UploadImgUrl",
type: "POST",
data: requestData,
dataType: "json",
success: function (result) {
//console.log("token", result)
if (result.status) {
let thisData = result.data;
UploadLoadeer(file, thisData)
} else {
layer.alert("网络异常,请重试 ~ ", { title: "上传失败提示", icon: 2, })
}
},
error: function () {
layer.alert("网络异常,请重试 ~ ", { title: "上传失败提示", icon: 2, })
}
});
}
// 通过XMLHttpRequest 方式将文件上传到服务器
var UploadLoadeer = (file, thisData) => {
let { url } = thisData;
console.log(url);
// 使用预签名URL上传文件
const xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('Content-Type', file.type);
xhr.onload = function () {
if (xhr.status === 200) {
alert('File uploaded successfully.');
} else {
alert('File upload failed.');
}
};
xhr.send(file);
}
});
NetMvc通过亚马逊方式服务器端和客户端上传MinIO顺利解决的更多相关文章
- Node开发文件上传系统及向七牛云存储和亚马逊AWS S3的文件上传
背景起,有奏乐: 有伟人曰:学习技能的最好途径莫过于理论与实践相结合. 初学Node这货时,每每读教程必会Fall asleep. 当真要开发系统时,顿觉精神百倍,即便踩坑无数也不失斗志. 因为同团队 ...
- 商学院教授点评亚马逊、苹果、Facebook和谷歌的商业策略:3星|《互联网四大:亚马逊、苹果、脸书和谷歌的隐藏基因》
“ 谷歌依靠时报的内容吸引了数十亿点击量,而时报使用它们的搜索算法来引入流量.但是两者中显然谷歌拥有更大的权力.它如同地主一样统治着互联网的一个关键领域,而时报就相当于那块草地上的佃农.我们的结局从一 ...
- 当 EDA 遇到 Serverless,亚马逊云科技出招了
近二三十年来,软件开发领域毫无疑问是发展最为迅速的行业之一. 在上个世纪九十年代,世界上市值最高的公司大多是资源类或者重工业类的公司,例如埃克森美孚或者通用汽车,而现在市值最高的公司中,纯粹的软件公司 ...
- 【AWS】亚马逊云常用服务解释
新公司使用的是亚马逊服务,刚开始的时候,对很多名词不太明白,总结了一下如下 1,EC2 这个是亚马逊的一种服务器服务,可以理解为跟vmware差不多,EC2为虚拟机提供载体,EC2上跑虚拟机服务器. ...
- HTML5游戏开发进阶指南(亚马逊5星畅销书,教你用HTML5和JavaScript构建游戏!)
HTML5游戏开发进阶指南(亚马逊星畅销书,教你用HTML5和JavaScript构建游戏!) [印]香卡(Shankar,A.R.)著 谢光磊译 ISBN 978-7-121-21226-0 201 ...
- 微软、谷歌、亚马逊、Facebook等硅谷大厂91个开源软件盘点(附下载地址)
开源软件中有大量专家构建的代码,大大节省了开发人员的时间和成本,热衷于开源的大厂们总是能够带给我们新的惊喜.2016年9月GitHub报告显示,GitHub已经有超过 520 万的用户和超 30 万的 ...
- Authenticator App 两步验证会不会造成亚马逊账号关联?
今天听人说,因为用Authenticator App做亚马逊两步验证造成了帐号关联…… 我给大家解释一下Authenticator的实现原理,作为计算机专业科班出身的我,此次从各方面了解并经过自己亲测 ...
- 使用AWS亚马逊云搭建Gmail转发服务(三)
title: 使用AWS亚马逊云搭建Gmail转发服务(三) author:青南 date: 2015-01-02 15:42:22 categories: [Python] tags: [log,G ...
- 借助亚马逊S3和RapidMiner将机器学习应用到文本挖掘
本挖掘典型地运用了机器学习技术,例如聚类,分类,关联规则,和预测建模.这些技术揭示潜在内容中的意义和关系.文本发掘应用于诸如竞争情报,生命科学,客户呼声,媒体和出版,法律和税收,法律实施,情感分析和趋 ...
- 亚马逊云架设WordPress博客
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 这篇文章介绍如何在亚马逊云架设WordPress博客.最强的云,加上最流行的建站工 ...
随机推荐
- dotnet C# 调用委托的 GetInvocationList 的对象分配
本文也叫跟着 Stephen Toub 大佬学性能优化系列,这是我从 Stephen Toub 大佬给 WPF 框架做性能优化学到的知识,在热路径下,也就是频繁调用的模块,如果调用了委托的 GetIn ...
- WPF dotnet core 的 Blend SDK Behaviors 库
之前版本是通过安装 Blend SDK 支持 Behaviors 库的,但是这个方法都是通过引用 dll 的方式,不够优雅.在升级到 dotnet core 3.0 的时候就需要使用 WPF 官方团队 ...
- ubuntu 防火墙命令
# 防火墙状态,如果输出显示 Status: inactive,表示 UFW 处于禁用状态 sudo ufw status # 关闭防火墙 sudo ufw disable # 启动防火墙 sudo ...
- keil 中未编译的代码灰色显示
一.转载文章 转载:KEIL,#ifdef宏定义下失效代码差异性显示 注意keil的版本,太低的版本不具备灰色显示,据我所知在KEIL uVersion V5.31版本以上均可以. 二.使能灰色显示 ...
- vue解决二级路由redirect(默认路由)不传参的问题
场景: pageA----pageB(pageB包含三个二级路由) 默认进入pageB时进入第一个页面的路由,之后点击左侧按钮,分别进入其他二级路由 原router.js写法: //应用信息 ...
- kali 的 vim 中不能粘贴复制
kali 的 vim 中不能粘贴复制 进入 vim 命令行模式,输入 :set mouse=c 之后可以正常粘贴复制
- C# 实现Ping远程主机功能
C#实现Ping远程主机功能. 1.引用nuget包 Wesky.Net.OpenTools OpenTools是一个用于提高开发效率的开源工具库.该项目为个人开源项目,采用MIT开源协议,永不更改协 ...
- Scala集合flatten操作
一层嵌套,但是flatten的要求需要List内部类型都一样, 例如都为List scala> List(List(1), List(2), List(3)).flatten res4: Lis ...
- C语言:删除顺序表中重复的信息—(删除顺序表中重复的单词)
如何删除顺序表中的重复单词: (开始看内容之前容朕说一句:如果你最后怎么都运行不了你想要的结果,①我敢保证大概率是你的下标越界你的下标越界了你的下标越界了.②在我这程序里面你肯定打少了p--,少了p- ...
- 2023年Clion插件推荐
目录 搜素位置 插件 background-image plus 背景图片插件 Rainbow Brackets 彩虹括号 Xcode-Dark Theme 界面主题 Grep Console 日志颜 ...