3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ASP.NET core画像投稿 脳筋

Last updated at Posted at 2025-06-23

自分用備忘録です

何にせよviewのフォームから画像をローカルに保存してみたかった

1. モデルにプロパティを追加

model
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.AspNetCore.Http;

public class Hoges
{
    public int Id { get; set; }
    public string Name { get; set; }
    // …既存プロパティ…

    // 画像のファイル名・パスを保存するカラム(DBにマイグレーション)
    public string ImagePath { get; set; }

    // ファイルアップロード用(DBマッピングしない)
    [NotMapped]
    public IFormFile ImageFile { get; set; }
}

ImagePath が nvarchar(string)カラムになる。ここに例として "uploads/abc123.jpg" のような相対パスを保存

ImageFile は [NotMapped] にして、ビュー→コントローラ間の受け渡し用にだけ使用

2.フォームに enctype と を設定

Create.cshtml(または Edit.cshtml)の

に必ず enctype="multipart/form-data"を付与し、ファイル入力を追加
Create.cshtml
@model App.Models.Hoges

<form asp-action="Create" method="post" enctype="multipart/form-data">
    @Html.AntiForgeryToken()

    <!-- 既存フィールド(Name, Lat, Lng など) -->

    <div class="form-group">
        <label asp-for="ImageFile">画像アップロード</label>
        <input asp-for="ImageFile" type="file" class="form-control" />
        <span asp-validation-for="ImageFile" class="text-danger"></span>
    </div>

    <button type="submit" class="btn btn-primary">登録</button>
</form>

3.コントローラでファイル保存&パスをカラムにセット

hoges_controller

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Hoges hoges)
{
    if (!ModelState.IsValid)
        return View(hoges);

    // ファイルが選択されていれば
    if (hoges.ImageFile != null && hoges.ImageFile.Length > 0)
    {
        // 保存先フォルダ(wwwroot/uploads)を用意
        var uploads = Path.Combine(_env.WebRootPath, "uploads");
        if (!Directory.Exists(uploads))
            Directory.CreateDirectory(uploads);

        // ユニークファイル名を生成
        var fileName = Guid.NewGuid().ToString() 
                       + Path.GetExtension(hoges.ImageFile.FileName);

        var filePath = Path.Combine(uploads, fileName);
        using (var stream = System.IO.File.Create(filePath))
        {
            await hoges.ImageFile.CopyToAsync(stream);
        }

        // DB に保存する相対パス
        hoges.ImagePath = $"uploads/{fileName}";
    }

    _context.Add(hoges);
    await _context.SaveChangesAsync();
    return RedirectToAction(nameof(Index));
}

_env はコントローラに DI した IWebHostEnvironment。(_env.WebRootPath が wwwroot の物理パス)

ファイル名は Guid と元拡張子で重複しないようにする

保存後、Hoges.ImagePath に URL 相対パス ("uploads/...") をセット。

4.画像を表示する

Details.cshtml(または Index.cshtml)に を追加。

View

@model App.Models.Hoges

<h1>@Model.Name</h1>
@if (!string.IsNullOrEmpty(Model.ImagePath))
{
    <img src="~/@Model.ImagePath" class="img-thumbnail mb-3" 
         alt="@Model.Name" style="max-width:300px;" />
}

"~/" を付けることで ASP.NET Core が /uploads/... にマッピング

ポイントまとめ

  • DBカラムは文字列 にして、「ファイルをどこに置いたか」を保存する

  • フォームに enctype="multipart/form-data" を指定し、IFormFile プロパティで受け取る

  • コントローラで物理ファイルを wwwroot に保存 → 相対パスをモデルの文字列カラムにセット

  • ビューに <img src="~/相対パス"> を書いて表示

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?