NetMvc通过亚马逊方式服务器端和客户端上传MinIO顺利解决

news/2024/9/28 6:14:13

前言:

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的URLServiceURL = ServiceURL,// 必须设为trueForcePathStyle = 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前端框架如下:

上传组件 upload - 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) {//startvar 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);}
});

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

HbuilderX 4.15版本 text标签不能用v-html渲染,会失效

如题,注意uni-notice-bar组件,里面用了标签v-html渲染,所以4.15版本的uni-notice-bar组件不要用,坑

论文阅读:T-RAG: LESSONS FROM THE LLM TRENCHES

T-RAG: LESSONS FROM THE LLM TRENCHES(https://arxiv.org/abs/2402.07483) https://github.com/jiangnanboy/paper_read_note一.概述大型语言模型(llm)越来越多地应用于各个领域,包括对私有企业文档的问答,其中数据安全性和鲁棒性至关重要。检索增强生成(retrieve - augment…

论文阅读:UniMS-RAG: Unified Multi-Source RAG for Personalised Dialogue

UniMS-RAG: Unified Multi-Source RAG for Personalised Dialogue(https://arxiv.org/abs/2401.13256) https://github.com/jiangnanboy/paper_read_note一.概述本研究探讨如何分解RAG过程,加入多文件检索、记忆和个人信息等元素。大型语言模型(llm)在自然语言任务中表现出色…

Windows defender:威胁服务已经停止

前言 最近遇到了一件棘手的事情,Windows defender无法启动,Windows更新失败。 我是发现电脑的好多文件被劫持,图片,excel表格,pdf文档,好多文件后缀被改为.locked,想解锁得花费0.1bit,大概5万元。 网上的操作挺多的,又是命令行又是搞注册表的,没啥卵用。 环境 版本:…

学习记录

1. 用户注册用户可以通过注册功能创建自己的账户。注册信息包括以下内容: - 用户ID(学号) - 用户名(姓名) - 手机号码 - 用户单位(班级)首次注册后,用户的姓名将被记录,无需每次输入。2. 设定每周学习目标每周一,用户可以设定学习目标,包括具体的任务目标,如完成数…

redis——P2:对P1的思考

到P1结束,redis都已经是一个不错的服务了,具体体现在缓存应用程序需要的数据,甚至在内存爆满的条件下还可以提供服务,似乎目的已经达成。但是实际上可能会遇到一些极端的情况,比如宕机。如果redis宕机了怎么办?目前所有的数据都存储在内存当中,宕机意为着失去所有缓存的…

会议预约管理信息系统

1、项目背景: 会议是企业进行决策、协商的重要组织形式,是企业日常办公处理事务的重要手段,是办公流程中不可缺少的重要环节,作为企业,如何有效的进行会议组织,管理各种会议文档和会议资源,是关系到企业领导进行日常企业运作处理的大事。提高会议效率、发挥会议功能、规…

量化交易:Dual Thrust策略

哈喽,大家好,我是木头左!Dual Thrust策略起源于20世纪80年代,由美国著名交易员和金融作家Larry Williams首次提出。这一策略的核心思想是通过捕捉市场中的短期波动来实现盈利。Larry Williams通过多年的研究和实践,发现市场中存在一种周期性的波动模式,通过这种模式可以预…