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# 通过 Vortice 使用 Direct2D 特效入门
本文将告诉大家如何通过 Vortice 使用 D2D 的特效 本文属于 DirectX 系列博客,更多 DirectX 和 D2D 以及 Vortice 库的博客,请参阅我的 博客导航 上一篇: Di ...
- 使用 Uno Islands 在现有 WPF 里面嵌入 Uno 框架
随着 2022 9 月份 Uno 发布了 4.5 版本,现有的 WPF 应用多了一个新的开发模式,那就是通过 Uno Islands 技术,在现有的 WPF 应用里面嵌入 Uno 应用.通过此方式可以 ...
- 2019-8-31-C#-简单读取文件
title author date CreateTime categories C# 简单读取文件 lindexi 2019-08-31 16:55:58 +0800 2018-07-19 16:48 ...
- 【PG】PostgreSQL12安装
场景:感受一下PostgreSQL12.可以通过如下方式安装: 1.创建psotgres用户 groupadd postgres useradd -g postgres postgres 2.查看操作 ...
- CCE云原生混部场景下的测试案例
本文分享自华为云社区<CCE云原生混部场景下在线任务抢占.压制离线任务CPU资源.保障在线任务服务质量效果测试>,作者:可以交个朋友. 背景 企业的 IT 环境通常运行两大类进程,一类是在 ...
- ESP8266资源整理
概述 整理下学习ESP8266期间有价值的资料 乐鑫官网文档中心 主要参考资料来源,一手资料最有价值,另外官网还有选型工具.产品对比等实用工具 https://www.espressif.com.cn ...
- uniapp SyntaxError: Unexpected token u in JSON at position 0 解决方案
今天在做页面跳转传值的时候,一直出现下面的报错: 后来查看了下文档,说如果你的JSON数据是在上一个页面传值过来的话, 这时候在接收数据页解析JSON也会报该错误,因为此时并没有相关的JSON数据从上 ...
- k8s核心组件详解和分层架构
k8s核心组件 master中的核心组件 api-server(接口服务,基于rest风格开放k8s接口的服务) kube-controller-manager(管理各个类型的控制器,针对k8s中的各 ...
- 修改linux默认启动界面——从命令行模式转换为图形化模式
从命令行模式转换为图形化模式 首先需要安装对应的图形化安装包 yum groupinstall "GNOME Desktop" "Graphical Administra ...
- codemirror-editor-vue3 输入框信息太多 输入框宽度溢出隐藏
我们把div注释看下之前溢出的效果 因为有form表单在里面任何标签上面设置都是不行 因为有校验要显示校验的信息overflow是不起作用的 要是单独的codemirror-editor-vue3 编 ...