iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
Modern Web

.NET教我做人系列 第 25

Day25 檔案上傳

  • 分享至 

  • xImage
  •  

在前幾天的鐵人賽中我們已經說了CRUD 的操作,但是有個問題是,我們傳的資料不是txt、json或者xml的格式,但還沒有講到現在要傳圖片或檔案的話要怎麼做,今天的話就要來說說我們要怎麼在ASP.NET Core 上傳檔案或圖片

在之前講Postman 時應該是知道我們無法透過json、xml 的格式來上傳檔案,所以要上傳檔案我們必須用到form-data 來上傳檔案,所以我們要先建立一個接收檔案的Controller,在Action 參數中使用IFormFile 型別就可以收到客戶端傳來的檔案,如果要多筆檔案也可以用List<IFormFile>

實際練習

確認儲存圖片的路徑是否存在,不存在新創一個

private readonly string _folder;
public UploadFileController()
{
    _folder = $"Storage";
    if (!Directory.Exists(_folder))
    {
        Directory.CreateDirectory(_folder);
    }
}

這裡會接受到Form 傳過來的檔案,並把檔案儲存在Storage的資料夾下

public async Task<IActionResult> UploadFile(List<IFormFile> files)
{
    long size = files.Sum(f => f.Length);
    foreach (IFormFile file in files)
    {
        if (file.Length > 0)
        {
            var filePath = Path.Combine(_folder, file.FileName);
            using (var steam = System.IO.File.Create(filePath))
            {
                await file.CopyToAsync(steam);
            }
        }
    }
    return Ok(new { count = files.Count, size });
}

完整程式碼

using Microsoft.AspNetCore.Mvc;
using System.Web.Http.Results;
using Microsoft.AspNetCore.Hosting;
using System.IO;

namespace DB_CRUD.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UploadFileController : ControllerBase
    {
        private readonly string _folder;
        public UploadFileController()
        {
            _folder = $"Storage";
            if (!Directory.Exists(_folder))
            {
                Directory.CreateDirectory(_folder);
            }
        }
        [HttpPost]
        public async Task<IActionResult> UploadFile(List<IFormFile> files)
        {
            long size = files.Sum(f => f.Length);
            foreach (IFormFile file in files)
            {
                if (file.Length > 0)
                {
                    var filePath = Path.Combine(_folder, file.FileName);
                    using (var steam = System.IO.File.Create(filePath))
                    {
                        await file.CopyToAsync(steam);
                    }
                }
            }
            return Ok(new { count = files.Count, size });
        }
    }
}

Swaggr 的實際畫面,應該可以看到我們可以去上傳檔案的格子

Response 的資料應該會是

{
    "count": 1,
    "size": 5149
}

這是用Postman來做的範例,這裡使用陣列的方式很特別

哪如果我們現在要除了要上傳檔案以外還要填入名稱跟描述的話,我們要先去創一個model 來使用

public class UploadData
{
    [Required]
    public string Name { get; set; }
    public string? Description { get; set; }
    public List<IFormFile> formFiles { get; set; }
}

接著去改動我們的Controller

[HttpPost]
public async Task<IActionResult> UploadFile([FromForm]UploadData data)
{
    List<IFormFile> files = data.formFiles;
    string name = data.Name;
    string description = data.Description;

    long size = files.Sum(f => f.Length);
    foreach (IFormFile file in files)
    {
        if (file.Length > 0)
        {
            var filePath = Path.Combine(_folder, file.FileName);
            using (var steam = System.IO.File.Create(filePath))
            {
                await file.CopyToAsync(steam);
            }
        }
    }
    return Ok(new { name, count = files.Count, size, description});
}

在這裡可以注意到在參數的部分有多加[FromForm],這是因為在沒有特別規定時都是抓body的直也就是使用[FromBody],但是我們在這是要傳檔案所以會用到form的格式來傳

今天只說了如何上傳檔案而已,下載的部分我可能還要找看看怎麼使用,因為我有事著去寫看看但都不知道為甚麼會錯,所以如果之後我有找到解決方法再來補充給大家知道,哪金天的鐵人賽就先到這裡啦~~~


上一篇
Day24 同步與非同步
下一篇
Day26 CORS(跨來源資源共用)
系列文
.NET教我做人30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言