Simple WPF: WPF实现一个MINIO等S3兼容对象存储上传文件的小工具

最新内容优先发布于个人博客:小虎技术分享站,随后逐步搬运到博客园。

创作不易,如果觉得有用请在Github上为博主点亮一颗小星星吧!

目的

之前在阿里云ECS 99元/年的活动实例上搭建了一个测试用的MINIO服务,以前都是直接当基础设施来使用的,这次准备自己学一下S3兼容API相关的对象存储开发,因此有了这个小工具。目前仅包含上传功能,后续计划开发一个类似图床的对象存储应用。

完整代码托管于Github:mrchipset/simple-wpf

包含的小知识点

  1. 通过AWSSDK使用S3 API
  2. 通过App.config对服务器的Endpoint和AccessKey进行设置
  3. 使用异步的方法响应按钮事件

小工具的界面可以实现简单地选择文件上传到桶存储中。

实现过程

  1. 创建一个WPF项目,并完成如上图的布局
  2. 在项目中添加用户配置文件 App.config来保存服务调用的地址和访问密钥等信息
xml 复制代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<appSettings>
		<add key="endpoint" value="YOUR_S3_ENDPOINT_URL"/>
		<add key="accessKey" value="YOUR_ACCESS_KEY"/>
		<add key="secretKey" value="YOUR_SECRET_KEY"/>
	</appSettings>
</configuration>

编写一个方法,在程序启动的时候导入连接参数配置

c# 复制代码
private void loadConfiguration()
{
    NameValueCollection appConfig = ConfigurationManager.AppSettings;
    if (string.IsNullOrEmpty(appConfig["endpoint"]))
    {
        ConfigurationManager.AppSettings.Set("endpoint", "endpoint");
        MessageBox.Show(this, "Endpoint is not set in the App.Config", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
        this.Close();
        return;
    }

    if (string.IsNullOrEmpty(appConfig["accessKey"]))
    {
        MessageBox.Show(this, "AccessKey is not set in the App.Config", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
        this.Close();
        return;
    }

    if (string.IsNullOrEmpty(appConfig["secretKey"]))
    {
        MessageBox.Show(this, "SecretKey is not set in the App.Config", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
        this.Close();
        return;
    }

    _endpoint = appConfig["endpoint"];
    _accessKey = appConfig["accessKey"];
    _secretKey = appConfig["secretKey"];
}
  1. 为按钮添加响应处理函数
    由于上传需要一定的时间来完成,因此我们用async 关键字修饰上传按钮的点击事件处理函数,这样即时在上传过程中UI界面的操作也不会卡顿。函数原型如下,如果对C#的异步操作不是很熟悉的同学可以参考这篇博文:C# 使用基本的async/await实现异步
c# 复制代码
private async void uploadBtn_Click(object sender, RoutedEventArgs e)
{
    StringBuilder sb = new StringBuilder();
    sb.AppendLine($"Bucket: {Bucket}");
    sb.AppendLine($"File: {UploadFile}");
    statusTxtBlk.Text = sb.ToString();
    var ret = await UploadFileAsync();
    if (ret)
    {
        statusTxtBlk.Text = "Upload Successfully!";
    }
}
  1. 编写上传函数
    现在到了本文最关键的一步,编写S3 Object上传接口。其实S3的接口都替我们封装好了,只需要按照官方demo的流程进行调用即可。
    先创建凭据对象和配置对象,然后创建客户端对象和上传请求,即可用客户端对象的上传方法进行上传。服务函数的完整代码如下:
c# 复制代码
 private async Task<bool> UploadFileAsync()
 {
     var credentials = new BasicAWSCredentials(_accessKey, _secretKey);

     var clientConfig = new AmazonS3Config
     {
         ForcePathStyle = true,
         ServiceURL = _endpoint,
     };

     bool ret = true;
     using (var client = new AmazonS3Client(credentials, clientConfig)) 
     {
         try
         {
             var putRequest = new PutObjectRequest
             {
                 BucketName = _bucket,
                 FilePath = UploadFile
             };
             var response = await client.PutObjectAsync(putRequest);
         }
         catch(FileNotFoundException e)
         {
             ret = false;
             this.Dispatcher.Invoke(new Action(() => this.statusTxtBlk.Text = e.Message));
         }
         catch (AmazonS3Exception e)
         {
             ret = false;
             if (e.ErrorCode != null &&
                 (e.ErrorCode.Equals("InvalidAccessKeyId") ||
             e.ErrorCode.Equals("InvalidSecurity")))
             {
                 this.Dispatcher.Invoke(new Action(() => this.statusTxtBlk.Text = "Please check the provided AWS Credentials"));
             } else
             {
                 this.Dispatcher.Invoke(new Action(() => this.statusTxtBlk.Text = $"An error occurred with the message '{e.Message}' when writing an object"));
             }
         }   
     }
     return ret;
 }

注意
MINIO 在使用S3函数时必须要在AmazonS3Config 中设置ForcePathStyleTrue

最终实现的效果

相关推荐
IT技术分享社区5 小时前
C#实战:使用腾讯云识别服务轻松提取火车票信息
开发语言·c#·云计算·腾讯云·共识算法
△曉風殘月〆12 小时前
WPF MVVM入门系列教程(二、依赖属性)
c#·wpf·mvvm
逐·風14 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
m0_6569747417 小时前
C#中的集合类及其使用
开发语言·c#
九鼎科技-Leo17 小时前
了解 .NET 运行时与 .NET 框架:基础概念与相互关系
windows·c#·.net
九鼎科技-Leo19 小时前
什么是 ASP.NET Core?与 ASP.NET MVC 有什么区别?
windows·后端·c#·asp.net·mvc·.net
.net开发19 小时前
WPF怎么通过RestSharp向后端发请求
前端·c#·.net·wpf
小乖兽技术19 小时前
C#与C++交互开发系列(二十):跨进程通信之共享内存(Shared Memory)
c++·c#·交互·ipc
幼儿园园霸柒柒20 小时前
第七章: 7.3求一个3*3的整型矩阵对角线元素之和
c语言·c++·算法·矩阵·c#·1024程序员节
平凡シンプル1 天前
C# EF 使用
c#