ASP.NET Core アプリケーションのRazor Pages でファイルをアップロードしても IFormFile オブジェクトがnull になってしまう現象について紹介します。
ファイルをアップロードするRazor Pages を作成し実行すると、ページモデルでファイルのデータを受け取る変数がnullになってしまいます。
いくつか原因がありますが、次のいずれかの可能性が高いです。
以下のコードの場合に発生します。
@page
@model FileUpload.Pages.none_enctypeModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
<head>
</head>
<body>
<form method="post">
<div>ファイルのアップロード<input type="file" asp-for="FileData" /></div>
<input type="submit" value="POST" />
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Http;
namespace FileUpload.Pages
{
public class none_enctypeModel : PageModel
{
[BindProperty]
public IFormFile FileData { get; set; }
public void OnGet()
{
}
public IActionResult OnPost()
{
System.IO.Stream stream = FileData.OpenReadStream();
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
System.IO.FileStream fs = new System.IO.FileStream(FileData.FileName, System.IO.FileMode.CreateNew);
fs.Write(buffer, 0, buffer.Length);
fs.Close();
stream.Close();
return RedirectToPage("/simple-upload-complete");
}
}
}
プロジェクトを実行し"none-enctype"のRazor Pageを表示します。[ファイルの選択]ボタンをクリックしアップロードするファイルを
選択し、[POST]ボタンをクリックします。
FileData を参照する行でIFormFile オブジェクトのFileData変数がnullであるため例外が発生して停止します。
Razor PagesのFormタグに enctype="multipart/form-data" を指定します。
<form method="post" enctype="multipart/form-data" >
<div>ファイルのアップロード<input type="file" asp-for="FileData" /></div>
<input type="submit" value="POST" />
</form>
<form method="post">
<div>ファイルのアップロード<input type="file" asp-for="FileData" /></div>
<input type="submit" value="POST" />
</form>
以下のコードの場合に発生します。
@page
@model FileUpload.Pages.none_enctypeModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
<head>
</head>
<body>
<form method="post" enctype="multipart/form-data">
<div>ファイルのアップロード<input type="file" asp-for="FileData" /></div>
<input type="submit" value="POST" />
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Http;
namespace FileUpload.Pages
{
public class none_enctypeModel : PageModel
{
public IFormFile FileData;
public void OnGet()
{
}
public IActionResult OnPost()
{
System.IO.Stream stream = FileData.OpenReadStream();
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
System.IO.FileStream fs = new System.IO.FileStream(FileData.FileName, System.IO.FileMode.CreateNew);
fs.Write(buffer, 0, buffer.Length);
fs.Close();
stream.Close();
return RedirectToPage("/simple-upload-complete");
}
}
}
先の例と同様にファイルをアップロードすると、FileData を参照する行でIFormFile オブジェクトのFileData変数がnullであるため例外が発生して停止します。
ページオブジェクトの IFormFile の変数をプロパティで宣言します。
public IFormFile FileData;
[BindProperty]
public IFormFile FileData { get; set; }
Razor Pages のFormタグには enctype="multipart/form-data" が指定されており、
ページモデルオブジェクトもFileDataはプロパティとして宣言されています。ただし、BindProperty 属性が指定されていません。
@page
@model FileUpload.Pages.none_enctypeModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
<head>
</head>
<body>
<form method="post" enctype="multipart/form-data">
<div>ファイルのアップロード<input type="file" asp-for="FileData" /></div>
<input type="submit" value="POST" />
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Http;
namespace FileUpload.Pages
{
public class none_enctypeModel : PageModel
{
public IFormFile FileData { get; set; }
public void OnGet()
{
}
public IActionResult OnPost()
{
System.IO.Stream stream = FileData.OpenReadStream();
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
System.IO.FileStream fs = new System.IO.FileStream(FileData.FileName, System.IO.FileMode.CreateNew);
fs.Write(buffer, 0, buffer.Length);
fs.Close();
stream.Close();
return RedirectToPage("/simple-upload-complete");
}
}
}
ファイルを選択しPOSTボタンをクリックします。この場合はオブジェクトはnullにならず、ファイルのデータがFileDataプロパティにセットされています。
動作してしまうため、このままでも問題はありませんが、BindProperty 属性を追加しておくほうが良いかと思われます。
public IFormFile FileData { get; set; }
[BindProperty]
public IFormFile FileData { get; set; }