使用MinIO的过程中,我们这里遇到个需求,系统需要预览3D文件,前端操作,用浏览3D文件的工具打开3D文件的目录即可实现在线预览功能,这个时候问题来了,MinIO上传文件后进行了编译,如下图
这个时候在想读取文件(比如xx\xx\bb.txt),是读取不到的,所以,要在上传文件的时候再其他文件夹内,把上传的文件保存下来,给前端读取使用。一开始想的是放到同文件夹下,但是测试发现,虽然MinIO上传的文件夹名字是bb.txt,但是保存的文件无法与bb.txt文件夹放到同一目录下。
新建一个WebApi项目,其中配置信息与上一篇文章一样,这里不在赘述,主要讲一下区别点
配置中的"BucketDirectory": "D:\\aaa\\bbb\\ccc",是指文件要保存的目录
保存文件的主要代码
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.Logging;
- using Minio;
- using Newtonsoft.Json;
- using System.IO;
- using System.Linq;
- using System.Threading.Tasks;
-
- namespace MinIOTest.Controllers
- {
- public class MinioCallbackController : ControllerBase
- {
- private static string _bucketName = string.Empty;//"demo";//默认桶
-
- private readonly MinioClient _client;
- private readonly IConfiguration _configuration;
- private readonly ILogger
_logger; -
- public MinioCallbackController(MinioClient client,
- IConfiguration configuration,
- ILogger
logger ) - {
- _client = client;
- _configuration = configuration;
- _bucketName = configuration["MinIO:Bucket"];
- _logger = logger;
- }
-
- [Route("/path")] //这里不能随便改,要与webhook配置的路径对应
- [HttpPost]
- //public IActionResult Post([FromBody]Dictionary
args) - public async Task
CallBack([FromBody] object args) - {
- try
- {
- //_logger.LogInformation("aaaaaaaaaaa");
-
- string jsonStr = args.ToString();
- var jsonObj = JsonConvert.DeserializeObject
(jsonStr); - string bucketDirectory = _configuration["MinIO:BucketDirectory"];//文件保存目录
- var pathAll = jsonObj.Key;//获取文件路径
- var fileName = pathAll.Split('/').Last();
-
- //新增
- if (jsonObj.EventName.Contains("Put"))
- {
- if (!System.IO.File.Exists(bucketDirectory))
- {
- DirectoryInfo directoryInfo = new DirectoryInfo(bucketDirectory);
- directoryInfo.Create();
- }
-
- var memoryStream = new MemoryStream();
- var path = jsonObj.Key.Substring(pathAll.IndexOf('/') + 1, pathAll.Length - pathAll.IndexOf('/') - 1);
- await _client.GetObjectAsync(_bucketName, path,
- (stream) =>
- {
- stream.CopyTo(memoryStream);
- });
-
- using FileStream targetFileStream = new FileStream($"{bucketDirectory}\\{fileName}", FileMode.OpenOrCreate);
-
- memoryStream.WriteTo(targetFileStream);
- }
- else if (jsonObj.EventName.Contains("Delete"))
- {
- var path = $"{bucketDirectory}\\{fileName}";
- System.IO.File.Delete(path);
- }
-
-
- return Ok();
- }
- catch (System.Exception ex)
- {
- _logger.LogError($"ERROR:{ex}");
- }
-
- return null;
- }
-
- }
- }
注意路由[Route("/path")],这里是一个路径,要与下面配置Webhook时的路径一致。
Root类
这个实体写复杂了,其实只要第一层结构就行,这里往里面加了好几层,按实际情况来吧。
- using MinIOTest;
- using System.Collections.Generic;
-
- namespace MinIOTest
- {
-
- public class ValueKind
- {
-
- }
-
- public class UserIdentity
- {
- ///
- ///
- ///
- public string principalId { get; set; }
- }
-
- public class @object
- {
- ///
- ///
- ///
- public string key { get; set; }
- ///
- ///
- ///
- public int size { get; set; }
- ///
- ///
- ///
- public string eTag { get; set; }
- ///
- ///
- ///
- public string contentType { get; set; }
- ///
- ///
- ///
- public object userMetadata { get; set; }
- ///
- ///
- ///
- public string sequencer { get; set; }
- }
-
- public class S3
- {
- ///
- ///
- ///
- public string s3SchemaVersion { get; set; }
- ///
- ///
- ///
- public string configurationId { get; set; }
- ///
- ///
- ///
- public object bucket { get; set; }
- ///
- ///
- ///
- public @object @object { get; set; }
- }
-
- public class Source
- {
- ///
- ///
- ///
- public string host { get; set; }
- ///
- ///
- ///
- public string port { get; set; }
- ///
- ///
- ///
- public string userAgent { get; set; }
- }
-
- public class RecordsItem
- {
- ///
- ///
- ///
- public string eventVersion { get; set; }
- ///
- ///
- ///
- public string eventSource { get; set; }
- ///
- ///
- ///
- public string awsRegion { get; set; }
- ///
- ///
- ///
- public string eventTime { get; set; }
- ///
- ///
- ///
- public string eventName { get; set; }
- ///
- ///
- ///
- public UserIdentity userIdentity { get; set; }
- ///
- ///
- ///
- public object requestParameters { get; set; }
- ///
- ///
- ///
- public object responseElements { get; set; }
- ///
- ///
- ///
- public S3 s3 { get; set; }
- ///
- ///
- ///
- public Source source { get; set; }
- }
-
- public class Root
- {
- ///
- ///
- ///
- public string EventName { get; set; }
- ///
- /// demo/工程图纸/001/bb.txt
- ///
- public string Key { get; set; }
- ///
- ///
- ///
- public List
Records { get; set; } - }
-
-
-
- }
当走到下面这一步的时候,要提前把服务打开,服务地址一般是http://192.168.x.xx:5000,服务不打开的话,下一步创建会失败,一般会有类似“远程服务拒绝连接”的提示。说的直白一点,就是上面写的同步文件的程序要运行起来。
创建完成后,是看不到新创建的内容的,需要把MinIO服务重启一下才行,重启服务方式见下图,点击重新启动,或者停止-开始(注意:部署的过程中发现一个问题,有些电脑需要重启服务,有些电脑不需要重启服务就能看到新建的Webhook,如果新建完成就能看到结果,那就别重启服务了)
如果服务正常连接,状态显示online
如果服务异常,显示offline,这种情况一般是服务没启动起来,需要检查服务
保存完成后,在这里可以看到新建的事件
在代码里加上断点,当上传文件或下载文件的时候,会命中断点,可以查看相关参数。