自分用備忘録です
何にせよviewのフォームから画像をローカルに保存してみたかった
1. モデルにプロパティを追加
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"
を付与し、ファイル入力を追加
@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.コントローラでファイル保存&パスをカラムにセット
[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)に を追加。
@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="~/相対パス">
を書いて表示