实现本地上传、FTP上传、阿里云OSS上传三者合一处理

news2024/11/23 19:27:05

1、选项模式【Options】的处理

文件上传处理应该由程序进行配置,决定使用那种方式,那么这里面我们为了弹性化处理, 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传的配置参数信息。

微软引入选项模式,它是用于配置框架服务使用的设置. 选项模式由Microsoft.Extensions.OptionsNuGet包实现,除了ASP.NET Core应用,它还适用于任何类型的应用程序,如果需要了解,微软的文档详细解释了选项模式。

选项模式的限制之一是你只能解析(注入) IOptions <MyOptions> 并在依赖注入配置完成(即所有模块的ConfigureServices方法完成)后获取选项值。如果你正在开发一个模块,可能需要让开发者能够设置一些选项,并在依赖注入注册阶段使用这些选项. 你可能需要根据选项值配置其他服务或更改依赖注入的注册代码。IOptions<>是单例,因此一旦生成了,除非通过代码的方式更改,它的值是不会更新的。

 之前介绍过的文件上传处理,

一个是本地文件处理,一个是FTP文件处理,它们选择那种方式,依赖于配置参数的信息,如下示意图所示。

当我们增加了对象存储OSS方式后,可以扩展下这个图示如下所示。

在本地文件处理过程中,如果是Web API方式调用服务层,那么就在Web API所在的文件系统中,如果是Winform界面直接调用服务层,那么就是在当前系统中处理文件,这种方式可以有效的管理我们的文件信息。

在FTP文件处理过程中,则是根据选项参数的信息,调用FluentFTP类库进行文件的上传操作。

在OSS对象存储处理过程中,我们一般基于阿里云、腾讯云等这些云服务OSS的处理方式,一般它们会提供相应开发语言的SDK,我们引用并进行整合即可。

基于选项模式,根据我们的处理方式,我们定义一个对象,用于承载上传参数的信息,如下代码所示。

    /// <summary>
    /// 文件上传处理的选项信息
    /// </summary>
    public class UploadSettingOptions
    {
        /// <summary>
        /// 可指定的存储物理地址,如C:\\Attachment,如果没有配置项AttachmentBasePath,则默认一个相对目录。
        /// </summary>
        public string AttachmentBasePath { get; set; }

        /// <summary>
        /// 指定附件上传的方式,如ftp为FTP方式,为空则为普通方式
        /// </summary>
        public string AttachmentUploadType { get; set; }


        /// <summary>
        /// FTP上传配置
        /// </summary>
        public FtpProviderOptions FtpProvider { get; set; }

        /// <summary>
        /// OSS存储的配置
        /// </summary>
        public OSSProviderOptions OSSProvider { get; set; }
    }

其中本地介绍OSS存储处理的配置选项对象如下所示。

    /// <summary>
    /// OSS对象存储配置选项
    /// </summary>
    public sealed class OSSProviderOptions
    {
        /// <summary>
        /// 指定提供商
        /// </summary>
        public OSSProvider Provider { get; set; }
        /// <summary>
        /// 终结点
        /// </summary>
        public string Endpoint { get; set; }
        public string AccessKey { get; set; }
        public string SecretKey { get; set; }
        public string Region { get; set; }
        public bool IsEnableHttps { get; set; } = true;
        public bool IsEnableCache { get; set; }
        public string Bucket { get; set; }
    }

对应WebAPI的appSettngs.json文件配置项内容如下:

2、阿里云的OSS存储设置处理

对于阿里云的OSS来说,对应的AccesKey和SecretKey自己可以通过查看账户的信息可以获取到。

我们开始需要添加一个Bucket节点,用来存放相关的文件,并且需要开启对应的权限,如下所示。

一旦正式允许可以上传文件,那么文件存储在对应的Bucket项目中,如下所示。

 准备好这些前期工作后,我们如果需要在WebAPI端进行OSS存储的处理,可以利用阿里云的OSS 的SDK进行处理即可,如下所示。

 SDK的常规使用很简单,我们可以参考它的aliyun-oss-csharp-sdk 案例来上传处理即可。

例如它的上传文件的处理代码如下所示:

    OssClient client = new OssClient(endpoint, accessKeyId, accessKeySecret); 
    client.PutObject(bucketName, key, filePathToUpload);

在文件处理的通用上传处理函数里面,我们根据配置内容选择不同的上传模式。

        /// <summary>
        /// 上传文件(根据配置文件选择合适的上传方式)
        /// </summary>
        /// <param name="info">文件信息(包含流数据)</param>
        /// <returns></returns>
        public async Task<CommonResult> Upload(FileUploadInfo info)
        {
            var uploadType = this._options.AttachmentUploadType;

            if (string.IsNullOrEmpty(uploadType))
            {
                return await this.UploadByNormal(info);
            }
            else if (uploadType.Equals("ftp", StringComparison.OrdinalIgnoreCase))
            {
                return await this.UploadByFTP(info);
            }
            else if(uploadType.Equals("oss", StringComparison.OrdinalIgnoreCase))
            {
                return await this.UploadByOSS(info);
            }
            else
            {
                throw new ArgumentException("AttachmentUploadType配置指定了无效的值, 请置空, 填写ftp或者填写oss。");
            }
        }

由于本篇主要介绍OSS的对象存储方式,因此我们来看看对应的OSS上传处理的操作。

和其他上传(如FTP上传)方式类似,我们也是构建对应的信息后调用OSS的SDK处理即可,如下代码所示。

/// <summary>
/// 使用阿里云的OSS服务上传文件
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public async Task<CommonResult> UploadByOSS(FileUploadInfo info)
{
    var result = new CommonResult();
    var ossOptions = this._options.OSSProvider;
    if(ossOptions != null)
    {
        //上传获得的相对路径
        string category = info.Category;
        if (string.IsNullOrEmpty(category))
        {
            category = "Photo";
        }

        //OSS的文件路径不能以正斜线(/)或者反斜线(\)字符开头。
        //确定日期时间目录(格式:yyyy-MM),不存在则创建
        string savePath = string.Format("{0}-{1:D2}/{2}", DateTime.Now.Year, DateTime.Now.Month, category);
        var ext = FileUtil.GetExtension(info.FileName);
        var finalName = string.Format("{0}{1}", Guid.NewGuid().ToString(), ext);//FileUtil.GetFileName(file);

        var filePath = string.Concat(savePath, "/", finalName);
        var stream = FileUtil.BytesToStream(info.FileData);

        //使用阿里云的OSS服务上传文件
        var client = new OssClient(ossOptions.Endpoint, ossOptions.AccessKey, ossOptions.SecretKey);
        client.PutObject(ossOptions.Bucket, filePath, stream);

        //基础路径和部分路径
        info.BasePath = $"{(ossOptions.IsEnableHttps ? "https" : "http")}://{ossOptions.Bucket}.{ossOptions.Endpoint}";
        info.SavePath = filePath;
        info.AddTime = DateTime.Now;


        result.Success = await base.InsertAsync(info);
        if (result.Success)
        {
            //记录返回值, Data1为具体的URL路径
            //生成外链地址 方便前端预览
            result.Data1 = info.BasePath.UriCombine(savePath);
            result.Data2 = savePath;
        }
        else
        {
            result.ErrorMessage = "数据写入数据库出错。";
        }
    }
    else
    {
        result.ErrorMessage = "OSS配置信息不正确或没有启用";
    }

    return result;
}

最终我们上传的文件列表如上图所示。

3、在Vue3+ElementPlus+Vite的前端项目上测试前端上传文件的处理

我们在一个前端的编辑器 @wangeditor 上整合图片上传的处理来展示这个OSS对象保存的操作。案例需要前端项目安装对应的插件,如下所示。

 前端页面引用插件对象的代码如下所示

    <div class="wangeditor">
      <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
      <Editor style="height: 500px; overflow-y: hidden" v-model="valueHtml" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" />
    </div>

在脚本代码中引入对象的样式和对象。

<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';


defineOptions({
  name: 'Editor'
});

const mode = 'default';
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();

为了配置上传图片文件的处理操作,我们需要根据编辑器的介绍,以及我们WebAPI端的处理函数定义,在脚本部分中增加对应的配置信息,如下代码所示

const editorConfig = {
  placeholder: '请输入内容...',
  MENU_CONF: {
    // 配置默认字号
    // 配置上传图片
    uploadImage: {
      // 上传图片请求接口路径
      server: '/api/FileUpload/PostUpload',
      // 后端接收的文件名称
      fieldName: 'multipartFile',
      maxFileSize: 10 * 1024 * 1024, // 上传图片10M
      // 上传的图片类型
      allowedFileTypes: ['image/*'],
      // 自定义增加 http  header
      headers: {
        Authorization: 'Bearer ' + getAccessToken()
      },
      // 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
      meta: {
        guid: '',
        folder: '文档图片'
      },
      // 将 meta 拼接到 url 参数中,默认 false
      metaWithUrl: false,
      // 小于该值就插入 base64 格式(而不上传),默认为 0
      base64LimitSize: 10 * 1024, // 10MB
      // 自定义上传图片返回格式【后端返回的格式】
      customInsert(res: any, insertFn: InsertFnType) {
        console.log(res);
        if (!res.success) {
          ElMessage.error('上传文件失败,' + res.error);
          return;
        }
        // 从 res 中找到 url alt href ,然后插入图片 ,根据后端实际返回的字段来
        var result = res.result as Array<ResponseFileInfo>;
        if (result.length > 0) {
          console.log(result[0]);
          insertFn(result[0].url, result[0].name, result[0].url);
        }
      },
      // 单个文件上传成功之后
      onSuccess(file: File, res: any) {
        if (res.success) {
          ElMessage.success(`${file.name} 上传成功`);
          return;
        } else {
          ElMessage.warning(`${file.name} 上传出了点异常`);
          return;
        }
      },
      // 单个文件上传失败
      onFailed(file: File, res: any) {
        console.log(res);
        ElMessage.error(`${file.name} 上传失败`);
      },
      // 上传错误,或者触发 timeout 超时
      onError(file: File, err: any, res: any) {
        console.log(err, res);
        ElMessage.error(`${file.name} 上传出错`);
      }
    }
  }
};

其中主要的就是需要增加授权的令牌头部信息,以及对应上传需要用到的参数,还有就是返回的接口对象里面,需要根据Web API的定义,然后转换为本地识别的类别进行展示即可,如定义的 customInsert 函数

 文件上传成功后,可以看到在编辑器中插入了对应的图片文件,图片地址指向的是阿里云OSS的路径。

在数据库的文件记录中,我们可以看到对应的路径信息,如下所示。

如果我们需要在项目中实现业务的图片上传功能,如下界面所示的效果。

可以参考随笔《基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用》介绍内容进行自定义上传文件的处理即可。

<el-form-item label="资料文档">
     <my-upload v-model="viewForm.attachGUID" :data="{ guid: viewForm.attachGUID, folder: '用户图片' }"   disabled />
 </el-form-item>

以上就是我们针对不同的上传方式处理的操作,对于OSS的文件上传,我们通过整合阿里云的OSS的SDK,直接调用进行处理即可,非常方便,对于其他类似的平台,也可以针对它们提供的SDK进行扩展即可。

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

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

相关文章

宇凡微2.4g遥控船开发方案,采用合封芯片

2.4GHz遥控船的开发方案是一个有趣且具有挑战性的项目。这样的遥控船可以通过无线2.4GHz频率进行远程控制&#xff0c;让用户在池塘或湖泊上畅游。以下是一个简要的2.4GHz遥控船开发方案&#xff1a; 基本构想如下 mcu驱动两个小电机&#xff0c;小电机上安装两个螺旋桨&#…

三、JVM-如何判断对象已死问题

内存模型以及如何判定对象已死问题 体验与验证 2.4.5.1 使用visualvm visualgc插件下载链接 &#xff1a;https://visualvm.github.io/pluginscenters.html 选择对应JDK版本链接—>Tools—>Visual GC 若上述链接找不到合适的&#xff0c;大家也可以自己在网上下载对应…

聊聊虚拟定位工具新宠儿:AnyGo的原理与识别

市面上已经有很多基于位置服务的应用场景&#xff0c;如运动品类应用基于地理位置生成运动轨迹&#xff0c;企业办公应用基于定位信息进行打卡&#xff0c;游戏品类应用基于位置信息开发区域排名&#xff0c;电商品类应用基于位置发放区域性优惠券等等。在黑灰产嗅探到背后的商…

自然语言处理学习笔记(二)————语料库与开源工具

目录 1.语料库 2.语料库建设 &#xff08;1&#xff09;规范制定 &#xff08;2&#xff09;人员培训 &#xff08;3&#xff09;人工标注 3.中文处理中的常见语料库 &#xff08;1&#xff09;中文分词语料库 &#xff08;2&#xff09;词性标注语料库 &#xff08;3…

Elasticsearch:语义搜索 - Semantic Search in python

当 OpenAI 于 2022 年 11 月发布 ChatGPT 时&#xff0c;引发了人们对人工智能和机器学习的新一波兴趣。 尽管必要的技术创新已经出现了近十年&#xff0c;而且基本原理的历史甚至更早&#xff0c;但这种巨大的转变引发了各种发展的“寒武纪大爆炸”&#xff0c;特别是在大型语…

电容笔和触控笔的区别是什么?好用的苹果平替电容笔

如今&#xff0c;随着无纸化学习以及办公的发展&#xff0c;电容笔更是倍受关注。但是&#xff0c;很多人都对于电容笔和触控笔之间的区别都存在着疑惑。其实&#xff0c;这两种产品很好区分&#xff0c;第一种是电容笔&#xff0c;它是适用于我们最常用的电容屏&#xff0c;例…

视频两侧有黑边怎么处理?教你裁切视频黑边方法

现在的大多数电视是16:9的宽屏&#xff0c;而大多数视频都是4:3的标清或是16:9的高清。当你看一个标清或高清视频时&#xff0c;如果它的比例与你的电视屏幕比例不同&#xff0c;视频两侧就会出现黑边。这些黑边会对视频的质量或观看体验产生影响&#xff0c;那么怎么处理呢&am…

双系统安装后开机时没有GRUB界面,直接进入windows系统

电脑配置&#xff1a;512固态1T机械&#xff0c;安装了win10Ubuntu22.04双系统&#xff0c;ubuntu安装在机械硬盘上。安装完成后没有出现GRUB启动管理供选择进入哪一个系统&#xff0c;直接进入windows系统。 解决办法&#xff1a; 进入Bios&#xff08;惠普电脑的快捷键是F1…

Python入门指南:从零开始学习Python编程

文章目录 前言安装Python变量以及数据类型总结 前言 Python是一种简单而又强大的编程语言&#xff0c;它在全球范围内广受欢迎&#xff0c;适用于各种应用场景&#xff0c;包括Web开发、数据分析、人工智能和科学计算等。本篇博客将为初学者提供一份Python入门指南&#xff0c;…

甄知科技新一代AIGC产品发布

文/玉娇龙 本文约3200字&#xff0c;阅读全文需要大约3分钟左右 演讲嘉宾&#xff1a;张礼军 甄知科技联合创始人&#xff0c;CTO 首席产品官 一、甄知科技简介 2023年7月29日&#xff0c;甄知科技联合创始人兼 CTO 张礼军作为演讲嘉宾&#xff0c;在2023汉得新一代产品体系发布…

webgpu之旅05

看一下粒子 这次看官方的demo吧分析 这次看官方的demo吧 演示了一个粒子如何用cs动起来 分析 这里是着色部分&#xff0c;看起来没什么特别的&#xff0c;接下来看cs部分 binding(0) group(0) var<uniform> sim_params : SimulationParams; binding(1) group(0) var&l…

《向量数据库指南》——当前向量数据库的赛道有哪些?

当前&#xff0c;向量数据库赛道主要分为四个类别&#xff1a; 基于PG、Clickhouse 等进行魔改或者插件化实现的向量数据库&#xff1a;这类解决方案以现有的关系数据库或列存数据库作为基础&#xff0c;通过修改或插件扩展的方式添加向量搜索功能。PG Vector 是这类解决方案的…

领航ADR新赛道 边界无限靖云甲究竟新在哪儿?

随着5G、物联网、大数据、人工智能和云计算等新技术的加速落地应用&#xff0c;全球已经迈入数字化时代&#xff0c;传统的网络边界持续瓦解&#xff0c;物联网安全、云安全、移动安全、数据安全、安全智能运维等全新的挑战越发受到业界关注&#xff0c;产业技术的发展尤其是云…

Django框架之路由用法

简介 路由简单的来说就是根据用户请求的 URL 链接来判断对应的处理程序&#xff0c;并返回处理结果&#xff0c;也就是 URL 与 Django 的视图建立映射关系。 Django 路由在 urls.py 配置&#xff0c;urls.py 中的每一条配置对应相应的处理方法。 Django 不同版本 urls.py 配…

【NLP概念源和流】 05-引进LSTM网络(第 5/20 部分)

一、说明 在上一篇博客中,我们讨论了原版RNN架构,也讨论了它的局限性。梯度消失是一个非常重要的缺点,它限制了RNN对较短序列的建模。香草 RNN 在相关输入事件和目标信号之间存在超过 5-10 个离散时间步长的时间滞时无法学习。这基本上限制了香草RNN在许多实际问题上的应用,…

【组合计数】CF1151E

Problem - 1151E - Codeforces 题意&#xff1a; 思路&#xff1a; 我们要统计区间数量&#xff0c;有两个思考方向 一个是枚举右端点r&#xff0c;然后计算左端点l的贡献 还有一个就是&#xff0c;更换枚举对象 这道题是后者 因为答案是连通块数量 连通块数量点数-边数…

基于量子同态加密的改进多方量子私有比较

摘要量子同态加密在隐私保护方面具有明显的优势。本文提出了一种改进的基于量子同态加密的多方量子私钥比较协议。首先&#xff0c;引入可信密钥中心&#xff0c;安全辅助加密密钥的分发和解密密钥的更新&#xff0c;同时防止恶意服务器发布虚假结果的攻击;在保证所有参与者得到…

视频太大怎么压缩变小?视频压缩技巧快来学

我们都知道&#xff0c;视频分辨率越高&#xff0c;文件体积也就越大&#xff0c;为了更好的存储、传输和播放&#xff0c;我们需要适当压缩视频的大小&#xff0c;那么怎么才能轻松的将视频文件压缩变小呢&#xff1f;下面就给大家分享几个简单的方法&#xff0c;一起来看看吧…

GlobalSign证书是什么?

GlobalSign自1996年起开始签发可信赖的SSL数字证书&#xff0c;为全球各类企业提供SSL证书服务&#xff0c;在国内大中型企业中普及度高&#xff0c;且支持本地化服务&#xff0c;获得BAT高度认可。GlobalSign证书是电商行业优选证书&#xff0c;也是中国各大互联网公司青睐的S…

危化品行业防雷检测综合解决方案

危化品是指具有毒害、腐蚀、爆炸、燃烧、助燃等性质&#xff0c;能够对人体、设施或者环境造成危害的化学品。危化品的生产、储存、运输、使用等过程中&#xff0c;都存在着遭受雷击引发火灾或者爆炸事故的风险。因此&#xff0c;对危化品场所进行防雷检测&#xff0c;是保障危…