使用 Web API 上传和下载多个文件

原文作者:Jay Krishna Reddy

原文链接:https://www.c-sharpcorner.com/article/upload-and-download-multiple-files-using-web-api/

翻译:沙漠尽头的狼(谷歌翻译加持,文中版本使用.NET 6升级)

---正文开始---

今天,我们将通过一个简单的过程介绍使用 ASP.Net Core 6.0 Web API 上传和下载多个文件。

步骤

首先在 Visual Studio 中创建一个空的 Web API 项目,目标框架选择.Net 6.0

此项目中没有使用外部包。

创建一个 Services 文件夹,并在其中创建一个 FileService 类和 IFileService 接口。

我们在这个 FileService.cs 中使用了三个方法

  • UploadFile

  • DownloadFile

  • SizeConverter

由于我们需要一个文件夹来存储这些上传文件,因此我们在这里添加了一个参数来将文件夹名称作为字符串传递,它将存储所有上传的这些文件。

FileService.cs

using System.IO.Compression;

namespace FileUploadAndDownload.Services;

public class FileService : IFileService
{
    #region Property

    private readonly IWebHostEnvironment _webHostEnvironment;

    #endregion

    #region Constructor

    public FileService(IWebHostEnvironment webHostEnvironment)
    {
        _webHostEnvironment = webHostEnvironment;
    }

    #endregion

    #region Upload File

    public void UploadFile(List<IFormFile> files, string subDirectory)
    {
        subDirectory = subDirectory ?? string.Empty;
        var target = Path.Combine(_webHostEnvironment.ContentRootPath, subDirectory);

        Directory.CreateDirectory(target);

        files.ForEach(async file =>
        {
            if (file.Length <= 0) return;
            var filePath = Path.Combine(target, file.FileName);
            await using var stream = new FileStream(filePath, FileMode.Create);
            await file.CopyToAsync(stream);
        });
    }

    #endregion

    #region Download File

    public (string fileType, byte[] archiveData, string archiveName) DownloadFiles(string subDirectory)
    {
        var zipName = $"archive-{DateTime.Now:yyyy_MM_dd-HH_mm_ss}.zip";

        var files = Directory.GetFiles(Path.Combine(_webHostEnvironment.ContentRootPath, subDirectory)).ToList();

        using var memoryStream = new MemoryStream();
        using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
        {
            files.ForEach(file =>
            {
                var theFile = archive.CreateEntry(Path.GetFileName(file));
                using var binaryWriter = new BinaryWriter(theFile.Open());
                binaryWriter.Write(File.ReadAllBytes(file));
            });
        }

        return ("application/zip", memoryStream.ToArray(), zipName);
    }

    #endregion

    #region Size Converter

    public string SizeConverter(long bytes)
    {
        var fileSize = new decimal(bytes);
        var kilobyte = new decimal(1024);
        var megabyte = new decimal(1024 * 1024);
        var gigabyte = new decimal(1024 * 1024 * 1024);

        return fileSize switch
        {
            _ when fileSize < kilobyte => "Less then 1KB",
            _ when fileSize < megabyte =>
                $"{Math.Round(fileSize / kilobyte, 0, MidpointRounding.AwayFromZero):##,###.##}KB",
            _ when fileSize < gigabyte =>
                $"{Math.Round(fileSize / megabyte, 2, MidpointRounding.AwayFromZero):##,###.##}MB",
            _ when fileSize >= gigabyte =>
                $"{Math.Round(fileSize / gigabyte, 2, MidpointRounding.AwayFromZero):##,###.##}GB",
            _ => "n/a"
        };
    }

    #endregion
}

SizeConverter 函数用于获取我们上传文件到服务器的实际大小。

IFileService.cs

namespace FileUploadAndDownload.Services;

public interface IFileService
{
    void UploadFile(List<IFormFile> files, string subDirectory);
    (string fileType, byte[] archiveData, string archiveName) DownloadFiles(string subDirectory);
    string SizeConverter(long bytes);
}

让我们在 Program.cs 文件中添加这个服务依赖项

Program.cs

using FileUploadAndDownload.Services;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// 主要是添加下面这句代码,注入文件服务
builder.Services.AddTransient<IFileService, FileService>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

创建一个 FileController,并 FileController 中的构造函数注入 IFileService

FileController.cs

using FileUploadAndDownload.Services;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;

namespace FileUploadAndDownload.Controllers;

[Route("api/[controller]")]
[ApiController]
public class FileController : ControllerBase
{
    private readonly IFileService _fileService;

    public FileController(IFileService fileService)
    {
        _fileService = fileService;
    }

    [HttpPost(nameof(Upload))]
    public IActionResult Upload([Required] List<IFormFile> formFiles, [Required] string subDirectory)
    {
        try
        {
            _fileService.UploadFile(formFiles, subDirectory);

            return Ok(new { formFiles.Count, Size = _fileService.SizeConverter(formFiles.Sum(f => f.Length)) });
        }
        catch (Exception ex)
        {
            return BadRequest(ex.Message);
        }
    }

    [HttpGet(nameof(Download))]
    public IActionResult Download([Required] string subDirectory)
    {
        try
        {
            var (fileType, archiveData, archiveName) = _fileService.DownloadFiles(subDirectory);

            return File(archiveData, fileType, archiveName);
        }
        catch (Exception ex)
        {
            return BadRequest(ex.Message);
        }
    }
}

我们可以在 swaggerpostman 中测试我们的 API。

d1cd5743cd1e7ceeba6356b8055692f1.png

在这里,我们看到了我们创建的用于上传和下载的两个 API,因此让我们分别测试它们中的每一个。

619b3c7520625f8fc0e902bba0cf92cd.png

subDirectory字段中 输入文件保存的文件夹名称,并在下面添加文件用于保存在服务器对应的子文件夹名称下。作为响应,我们会看到文件的总数和所有上传文件的总实际大小。

22f787eff3cdfb76de49124620c8ebfc.png

现在将检查下载 API。由于我们的文件夹中有多个文件,它将作为Zip 文件下载,我们需要将其解压缩以检查文件。

e94e3d7131d2e4cf81a1b1747ac155e2.png

总结

使用Web API接口的方式上传和下载文件,适用于Blazor Server、Blazor Client、MAUI、Winform、WPF等客户端程序,后面有空写写客户端怎么调用这些接口。

  • 本文源码:FileUploadAndDownload[1]

.... 保持学习 !!!

参考资料

[1]

FileUploadAndDownload: https://github.com/dotnet9/ASP.NET-Core-Test/tree/master/src/FileUploadAndDownload

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: .NET Framework WebAPI 是一种用于构建基于HTTP协议的Web服务的框架。它提供了许多功能和工具来简化开发人员在.NET平台上构建和管理Web应用程序的过程。 在.NET Framework WebAPI中,我们可以使用HTTP协议的POST请求来实现文件。下面是一个上文件的示例代码: 1. 首先,创建一个WebAPI控制器,用于处理上文件的请求: ```csharp public class FileUploadController : ApiController { [HttpPost] public async Task<IHttpActionResult> UploadFile() { // 检查是否有文件 if (!Request.Content.IsMimeMultipartContent()) { return BadRequest("只支持上文件!"); } // 设置上文件路径 var uploadPath = HttpContext.Current.Server.MapPath("~/Uploads"); // 创建MultipartFormDataStreamProvider来处理文件 var provider = new MultipartFormDataStreamProvider(uploadPath); try { // 读取表单中的文件流 await Request.Content.ReadAsMultipartAsync(provider); // 处理每个上文件 foreach (var file in provider.FileData) { var fileInfo = new FileInfo(file.LocalFileName); // 在这里可以进行文件保存、数据库记录等操作 } return Ok("文件成功!"); } catch (Exception ex) { return InternalServerError(ex); } } } ``` 2. 在WebAPI的配置文件中注册该控制器: ```csharp public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 省略其他配置 // 注册文件控制器 config.Routes.MapHttpRoute( name: "FileUpload", routeTemplate: "api/upload", defaults: new { controller = "FileUpload" } ); } } ``` 3. 最后,通过发送POST请求到`/api/upload`路径即可实现文件。 以上是通过.NET Framework WebAPI实现文件的简单示例。我们可以根据需要对文件进行保存、数据库记录等操作。同时,还可以对文件大小、格式等进行验证和限制,确保文件的安全性和可靠性。 ### 回答2: 在.NET Framework WebAPI中,可以使用以下步骤来实现文件: 1. 首先,要确保项目中已经引用了相关的命名空间,包括System.Net.Http命名空间和System.Web.Http命名空间。 2. 在WebAPI控制器中,创建一个Post方法来接收文件请求,可以使用FromBody或者FromUri来指定文件的参数位置和名字。 3. 在Post方法中,使用HttpRequestMessage对象的Content属性来获取请求中的HttpContent对象。 4. 使用HttpContent对象的ReadAsStreamAsync方法将请求内容转换为流。 5. 使用FileStream对象来创建一个本地文件,可以指定保存路径和文件名。 6. 使用CopyToAsync方法将流复制到 FileStream 对象中,实现文件的上。 下面是一个示例代码: ``` public async Task<IHttpActionResult> PostFile() { if (!Request.Content.IsMimeMultipartContent()) { return BadRequest("请求不是有效的多部分内容。"); } var provider = new MultipartFormDataMemoryStreamProvider(); try { await Request.Content.ReadAsMultipartAsync(provider); foreach (var file in provider.Files) { var stream = await file.ReadAsStreamAsync(); // 指定保存路径和文件名 var filePath = "your_file_path" + file.Headers.ContentDisposition.FileName; using (var fileStream = File.Create(filePath)) { await stream.CopyToAsync(fileStream); } } return Ok("文件成功。"); } catch (System.Exception e) { return BadRequest("文件失败:" + e.Message); } } ``` 在这个示例代码中,我们首先检查请求是否是有效的多部分内容,然后创建一个自定义的 MultipartFormDataMemoryStreamProvider 对象来处理上文件的内存流。然后我们使用 ReadAsMultipartAsync 方法将请求内容转换为 MultipartFormDataMemoryStreamProvider 对象,并遍历提取的文件列表,然后将每个文件的流复制到指定的本地文件中。 这就是使用.NET Framework WebAPI进行文件的基本步骤。你可以根据实际需求来添加更多的逻辑,比如文件大小限制、文件格式校验等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值