ASP.NET Core Web APIでのファイルアップロードの実装

ASP.NET Core Web APIでファイルをアップロードする方法

ASP.NET Core Web APIでファイルをアップロードするには、通常、POSTメソッドを使用するコントローラーを実装します。クライアントは一般的にMultipartFormDataContentを使ってリクエストを構築し、トークンやファイルに加えて追加のパラメータも送信できます。サーバー側では、HttpContext.Request.Formからパラメータとアップロードされたファイルを取得できます。

1. コントローラーの実装

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace FileUploadSample.Controllers
{
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class UploadController : ControllerBase
    {
        private readonly ILogger<UploadController> _log;
        private readonly string _storagePath;

        private static readonly string BaseDirectory = "Uploads";

        public UploadController(ILogger<UploadController> logger, IWebHostEnvironment env)
        {
            _log = logger;

            var wwwRoot = env.WebRootPath;
            _storagePath = Path.Combine(wwwRoot, BaseDirectory);

            if (!Directory.Exists(_storagePath))
            {
                Directory.CreateDirectory(_storagePath);
            }
        }

        [HttpPost]
        public async Task<ActionResult> Upload()
        {
            // フォームからパラメータを取得
            HttpContext.Request.Form.TryGetValue("uploadId", out var uploadId);

            if (string.IsNullOrWhiteSpace(uploadId))
            {
                _log.LogError("Upload ID is missing.");
                return BadRequest("Upload ID is required.");
            }

            var targetPath = Path.Combine(_storagePath, uploadId);
            if (!Directory.Exists(targetPath))
            {
                try
                {
                    Directory.CreateDirectory(targetPath);
                }
                catch (Exception ex)
                {
                    _log.LogError($"Failed to create directory: {ex.Message}");
                    return StatusCode(500, "Directory creation failed.");
                }
            }

            var uploadedFiles = new List<string>();
            var files = HttpContext.Request.Form.Files;

            foreach (var file in files)
            {
                var originalName = file.FileName;
                var filePath = Path.Combine(targetPath, originalName);

                try
                {
                    using (var stream = new FileStream(filePath, FileMode.Create))
                    {
                        await file.CopyToAsync(stream);
                    }

                    uploadedFiles.Add(originalName);
                }
                catch (Exception ex)
                {
                    _log.LogError($"Error saving file {originalName}: {ex.Message}");
                }
            }

            var summary = string.Join(", ", uploadedFiles);
            _log.LogInformation($"Uploaded files: {summary}");

            return Ok(new { Count = uploadedFiles.Count, Files = uploadedFiles });
        }
    }
}

2. クライアント側の実装(WinForms/WPF)

public bool SendFile(string uploadId, List<string> paths)
{
    using (var client = new HttpClient())
    {
        var payload = new MultipartFormDataContent
        {
            { new StringContent(uploadId), "\"uploadId\"" }
        };

        foreach (var path in paths)
        {
            var info = new FileInfo(path);
            if (!info.Exists)
            {
                Console.WriteLine($"File not found: {path}");
                return false;
            }

            var fileBytes = File.ReadAllBytes(path);
            payload.Add(new ByteArrayContent(fileBytes), "file", info.Name);
        }

        var response = client.PostAsync("http://localhost:5000/api/upload/upload", payload).Result;
        var result = response.Content.ReadAsStringAsync().Result;

        Console.WriteLine($"Upload result: {result}");
        return result.Contains("OK");
    }
}

タグ: asp.net-core web-api file-upload httpclient multipartformdatacontent

6月20日 22:37 投稿