.NET 文件上傳服務設計

来源:https://www.cnblogs.com/ZYPLJ/archive/2023/06/15/17483162.html
-Advertisement-
Play Games

# .NET文件上傳服務設計 # 前言 在b站學習了一個後端小項目,然後發現這個文件上傳設計還挺不錯,來實現講解一下。 項目結構如下: ![image](https://img2023.cnblogs.com/blog/3091176/202306/3091176-20230615155702089 ...


.NET文件上傳服務設計

前言

在b站學習了一個後端小項目,然後發現這個文件上傳設計還挺不錯,來實現講解一下。

項目結構如下:

image

基於策略+工廠模式實現文件上傳服務

枚舉

在Model層創建即可

    public enum UploadMode
    {
        Local = 1, //本地上傳
        Qiniu = 2 //七牛雲上傳
    }

第一步:創建文件策略和工廠

在Service層中創建FileStrategy文件夾,在該文件夾下分別創建StrategyQiNiuStrategyLocalStrategyFileFactoryFileContext

Strategy 文件操作抽象類

/// <summary>
/// 文件操作抽象類
/// </summary>
public abstract class Strategy
{
    public abstract Task<string> Upload(List<IFormFile> formFiles);
}

LocalStrategy 本地策略

繼承Strategy 文件操作抽象類並實現他裡面的方法

後續要實現該方法

public class LocalStrategy:Strategy
{
    public override async Task<string> Upload(List<IFormFile> formFiles)
    {
        throw new NotImplementedException();
    }
}

QiNiuStrategy 七牛雲策略

同上

public class QiNiuStrategy:Strategy
{
    public override async Task<string> Upload(List<IFormFile> formFiles)
    {
        throw new NotImplementedException();
    }
}

FileContext 上下文

在策略模式中通過上下文調用具體的策略

這裡的好處就是我如果new LocalStrategy則是本地上傳服務,如果是new QiNiuStrategy則是七牛雲上傳,詳情看下方工廠的設計

/// <summary>
/// 上下文,通過這個來調用具體的策略
/// </summary>
public class FileContext
{
    private Strategy _strategy;
    private List<IFormFile> _formFiles;

    public FileContext(Strategy strategy, List<IFormFile> formFiles)
    {
        _formFiles = formFiles;
        _strategy = strategy;
    }

    public async Task<string> ContextInterface()
    {
        return await _strategy.Upload(_formFiles);
    }
}

FileFactory 工廠

通過工廠去負責對象的實例化

枚舉的作用就來了,更據枚舉去判斷實例化那一個對象

/// <summary>
/// 工廠類,負責對象的實例化
/// </summary>
public class FileFactory
{
    public static Strategy CreateStrategy(UploadMode mode)
    {
        switch (mode)
        {
            case UploadMode.Qiniu:
                return new QiNiuStrategy();
            case UploadMode.Local:
                return new LocalStrategy();
            default:
                return new QiNiuStrategy();
        }
    }
}

第二步:對接服務層

在Interface介面層創建IFileService介面

這裡需要安裝HttpNuget包,不然沒有IFormFile,我下的是Microsoft.AspNetCore.Http/2.2.2

public interface IFileService
{
    Task<string> Upload(List<IFormFile> files, UploadMode mode);
}

在Service層創建FileService類實現上面的介面

public class FileService:IFileService
{
    public async Task<string> Upload(List<IFormFile> files, UploadMode mode)
    {
        FileContext fileContext = new FileContext(FileFactory.CreateStrategy(mode), files);
        return await fileContext.ContextInterface();
    }
}

上述通過上下文調用具體的策略,通過工廠去創建具體的類,工廠更據傳入的枚舉作為參數(構造函數傳參),通過上下文的ContextInterface就可以完成上傳的邏輯了。

策略+工廠的好處就是,以後需要修改上傳文件,只需要對策略進行更改和補充即可。意思就是新增一個上傳策略,只需要創建一個策略類,然後去工廠類new一個就行了,不需要動Service層的東西。

本地上傳功能實現

在本地策略類中實現上傳方法

註意var filePath = $"{AppContext.BaseDirectory}/wwwroot";是將文件保存在bin目錄下的wwwroot目錄了

public class LocalStrategy:Strategy
{
    public override async Task<string> Upload(List<IFormFile> formFiles)
    {
        var res = await Task.Run(() =>
        {
            //存放多個文件路徑
            List<string> result = new List<string>();
            foreach (var formFile in formFiles)
            {
                if (formFile.Length > 0)
                {
                    var filePath = $"{AppContext.BaseDirectory}/wwwroot";
                    var fileName = $"/{DateTime.Now:yyyyMMddHHmmssffff}{formFile.FileName}";
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
                    using (var stream = System.IO.File.Create(filePath + fileName))
                    {
                        formFile.CopyTo(stream);
                    }
                    result.Add(fileName);
                }
            }
            return string.Join(",", result);
        });
        return res;
    }
}

七牛雲上傳功能實現

註冊七牛雲:https://www.qiniu.com/

從個人中心獲取秘鑰信息,安裝SDK,編寫上傳邏輯

在Service層安裝QiniuNuget包

ak、sk為七牛雲的秘鑰,在個人中心查看

public class QiNiuStrategy : Strategy
{
    public override async Task<string> Upload(List<IFormFile> formFiles)
    {
        //先上傳到本地,才能上傳到七牛雲,上傳完成後本地的文件可刪除
        var res = await Task.Run(() =>
        {
            Mac mac = new Mac("ak", "sk");
            List<string> result = new List<string>();
            foreach (var formFile in formFiles)
            {
                if (formFile.Length > 0)
                {
                    var filePath_temp = $"{AppContext.BaseDirectory}/Images_temp";
                    var fileName = $"{DateTime.Now:yyyyMMddHHmmssffff}{formFile.FileName}";
                    if (!Directory.Exists(filePath_temp))
                    {
                        Directory.CreateDirectory(filePath_temp);
                    }

                    using (var stream = System.IO.File.Create($"{filePath_temp}/{fileName}"))
                    {
                        formFile.CopyTo(stream);
                    }

                    // 上傳文件名
                    string key = fileName;
                    // 本地文件路徑
                    string filePath = $"{filePath_temp}/{fileName}";
                    // 存儲空間名
                    string Bucket = "pl-static";
                    // 設置上傳策略
                    PutPolicy putPolicy = new PutPolicy();
                    // 設置要上傳的目標空間
                    putPolicy.Scope = Bucket;
                    // 上傳策略的過期時間(單位:秒)
                    //putPolicy.SetExpires(3600);
                    // 文件上傳完畢後,在多少天後自動被刪除
                    //putPolicy.DeleteAfterDays = 1;
                    // 生成上傳token
                    string token = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
                    Config config = new Config();
                    // 設置上傳區域
                    config.Zone = Zone.ZONE_CN_East;
                    // 設置 http 或者 https 上傳
                    config.UseHttps = true;
                    config.UseCdnDomains = true;
                    config.ChunkSize = ChunkUnit.U512K;
                    // 表單上傳
                    FormUploader target = new FormUploader(config);
                    HttpResult httpResult = target.UploadFile(filePath, key, token, null);
                    result.Add(fileName);
                    //刪除備份文件夾
                    Directory.Delete(filePath_temp, true);
                }
            }

            return string.Join(",", result);
        });
        return res;
    }
}

Controller的實現

mode為1則會執行本地上傳的邏輯代碼,為2則會執行七牛雲上傳的服務代碼。

[Route("api/[controller]/[action]")]
[ApiController]
public class FileController : ControllerBase
{
    private readonly IFileService _fileService;
    public FileController(IFileService fileService)
    {
        _fileService = fileService;
    }
    /// <summary>
    /// 上傳文件
    /// </summary>
    /// <param name="file">文件對象</param>
    /// <param name="mode">上傳方式:本地或者七牛雲</param>
    /// <returns></returns>
    [HttpPost]
    public async Task<ApiResult> UploadFile(List<IFormFile> file, UploadMode mode)
    {
        return ResultHelper.Success(await _fileService.Upload(file, mode));
    }
}

測試

image

image

返回的圖片路徑可以根據自己的需求進行更改。

去bin目錄查看圖片是否上傳成功

image

總結

上述內容就是對於文件上傳服務的設計,有其他文件上傳需求,比如分片斷點上傳、上傳到其他的服務商,只需要新增策略,完成邏輯代碼即可,還是很方便的一種文件上傳設計。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ## 概述 RMI 是 Java 提供的一個完善的簡單易用的遠程方法調用框架,採用客戶/伺服器通信方式,在伺服器上部署了提供各種服務的遠程對象,客戶端請求訪問伺服器上遠程對象的方法,它要求客戶端與伺服器端都是 Java 程式 RMI 框架採用代理來負責客戶與遠程對象之間通過 Socket 進行通信的 ...
  • 基於java的智能停車場管理系統設計與實現,可適用於java車輛管理,java停車場信息管理平臺,小區停車管理平臺,小區停車,物業停車管理,智慧停車場管理系統,智慧小區停車場平臺,車輛AI識別,車輛識別。 ...
  • 在調用超類型構造函數之前無法引用“XxxClass.xxx” -----在一個類的構造器方法還未執行的時候,我們無法使用這個類的成員屬性或成員方法。 ...
  • 基於java的校園教務系統設計與實現,可適用於學生教務系統,教務管理系統,學生管理系統,學生選課系統,學生評教,評價教師系統,教務系統設計,java教務管理系統,學生成績管理系統,學生信息管理系統。 ...
  • 在某些時候我們的系統中會出現一些無法被正常刪除的文件,如果想要強制刪除則需要在驅動層面對其進行解鎖後才可刪掉,而所謂的解鎖其實就是釋放掉文件描述符(句柄表)占用,文件解鎖的核心原理是通過調用`ObSetHandleAttributes`函數將特定句柄設置為可關閉狀態,然後在調用`ZwClose`將其... ...
  • 本文將通過閱讀源碼方式分析SpringBoot應用的啟動流程,不涉及Spring啟動部分(有相應的文章介紹)。 本文不會對各個流程做展開分析,後續會有文章介紹詳細流程。 # SpringApplication類 ## 應用啟動入口 使用以下方式啟動一個SpringBoot應用: ```java @S ...
  • 學習 Code 總有這樣一個過程:入門時候比較依賴設計器、標記語言等輔助工具;等到玩熟練了就會發現純代碼寫 UI 其實更高效。而且,純代碼編寫也是最靈活的。Windows Forms 項目是肯定可以全代碼編寫的,哪怕你使用了設計器,它最後也是生成代碼文件;而 WPF 就值得探索一下了。咱們知道,WP ...
  • ## 一:背景 ### 1. 講故事 前段時間有位朋友找到我,說他們在查詢報表的時候發現程式的穩定性會受到影響,但伺服器的記憶體,CPU都是正常的,讓我幫忙看下怎麼回事,問了下程式的穩定性指的是什麼?指的是卡死,那既然是卡死,就抓一個卡死的dump吧。 ## 二:Windbg 分析 ### 1. 當前 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...