.NET TIPS

[ASP.NET MVC]ASP.NET MVCでアップロードしたファイルをデータベースに登録するには?[3.5、C#、VB]

山田 祥寛
2009/10/29

 「TIPS:[ASP.NET MVC]ファイルのアップロードを行うには?」では、アップロードしたファイルをサーバのファイル・システム上に保存する方法について紹介した。もっとも、アップロード・ファイルをファイル・システムで管理するのは、何かと面倒な点も多い。ファイル名の重複やアクセスの管理、複数ユーザーの同時アクセスなどなど、アプリケーションで意識しなければならないポイントが多いためだ。その点、アップロード・ファイルをデータベースに格納してしまえば、このような問題の大部分は確実に(かつ簡単に)解消することができる。

 そこで本稿では、ブラウザ上からアップロードしたファイルをデータベースに登録する方法について紹介することにしよう。

 このサンプルを動作させるには、データベースに以下のようなPhotoテーブルを用意し、Entity Data Model(エンティティ・データ・モデル。以下EDM)にもテーブルに対応したエンティティを追加しておく必要がある。EDMの作成方法については、「連載:ASP.NET MVC入門 第2回 スキャフォールディング機能で軽々DB連携アプリケーション」で解説しているので、参考にしていただきたい。

フィールド名 データ型 概要
Id INT 画像コード(主キー/自動連番)
Name NVARCHAR(70) ファイル名
Mime VARCHAR(50) コンテンツ・タイプ
Data VARBINARY(MAX) データ本体
Photoテーブルのフィールド・レイアウト

 それでは、具体的なコードを見ていくことにしよう。

// アップロード・フォームを生成するUpload/DbUploadアクション
public ActionResult DbUpload() {
  return View();
}

// アップロード処理を行うUpload/DbUploadアクション
// (HTTP POSTによる実行)
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult DbUpload(HttpPostedFileBase fl) {

  // コンテンツ・タイプが「image/*」であるか(画像ファイルか)
  // をチェック
  if (fl.ContentType.StartsWith("image/")) {

    // EDMのコンテキスト・オブジェクトを生成
    var _db = new MyMvcEntities();

    // エンティティにアップロード・ファイルの情報をセット
    var ph = new Photo();
    ph.Name = Path.GetFileName(fl.FileName);  // ファイル名
    ph.Mime = fl.ContentType;  // コンテンツ・タイプ

    byte[] data = new Byte[fl.ContentLength];
    fl.InputStream.Read(data, 0, fl.ContentLength);
    ph.Data = data;  // データ本体

    // エンティティを追加&データソースに反映
    _db.AddObject("Photo", ph);
    _db.SaveChanges();
    ViewData["msg"] = String.Format(
      "{0}をアップロードしました。", fl.FileName);
  } else {
    // 画像ファイルでない場合はエラー
    ViewData["msg"] = "画像以外はアップロードできません。";
  }
  // 入力元のフォームに結果を表示
  return View();
}
' アップロード・フォームを生成するUpload/DbUploadアクション
Function DbUpload() As ActionResult
  Return View()
End Function

' アップロード処理を行うUpload/DbUploadアクション
' (HTTP POSTによる実行)
<AcceptVerbs(HttpVerbs.Post)> _
Function DbUpload(ByVal fl As HttpPostedFileBase) As ActionResult

  ' コンテンツ・タイプが"image/*"であるか(画像ファイルか)を
  ' チェック
  If fl.ContentType.StartsWith("image/") Then

    ' EDMのコンテキスト・オブジェクトを生成
    Dim _db As New MyMvcEntities()

    ' エンティティにアップロード・ファイルの情報をセット
    Dim ph As New Photo()
    ph.Name = Path.GetFileName(fl.FileName)  ' ファイル名
    ph.Mime = fl.ContentType  ' コンテンツ・タイプ

    Dim data(fl.ContentLength) As Byte
    fl.InputStream.Read(data, 0, fl.ContentLength)
    ph.Data = data  ' データ本体

    ' エンティティを追加&データソースに反映
    _db.AddObject("Photo", ph)
    _db.SaveChanges()
    ViewData("msg") = String.Format( _
      "{0}をアップロードしました。", fl.FileName)
  Else
    ' 画像ファイルでない場合はエラー
    ViewData("msg") = "画像以外はアップロードできません。"
  End If
  ' 入力元のフォームに結果を表示
  Return View()
End Function
アップロード処理を行うためのUpload/DbUploadアクション(上がUploadController.cs/下がUploadController.vb)

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>ファイルアップロード</title>
</head>
<body>
  <div>
  <% using (Html.BeginForm("DbUpload", "Upload", FormMethod.Post, new {enctype = "multipart/form-data"})) { %>
    アップロードするファイル:
    <input type="file" name="fl" size="50" />
    <input type="submit" value="送信" />
  <% } %>
  <%--アップロード結果を表示させるためのプレイスホルダ--%>
  <div style="color:Red"><%=Html.Encode(ViewData["msg"])%></div>
  </div>
</body>
</html>
<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>ファイルアップロード</title>
</head>
<body>
  <div>
  <% Using (Html.BeginForm("DbUpload", "Upload", FormMethod.Post, New With {.enctype = "multipart/form-data"}))%>
    アップロードするファイル:
    <input type="file" name="fl" size="50" />
    <input type="submit" value="送信" />
  <% End Using%>
  <%--アップロード結果を表示させるためのプレイスホルダ--%>
  <div style="color:Red"><%=Html.Encode(ViewData("msg"))%></div>
  </div>
</body>
</html>
アップロード・フォームを表すビュー・スクリプト(Upload/DbUpload.aspx。上がC#、下がVisual Basic)

 以上のサンプルの実行結果は、以下のとおりである。

本稿で作成するサンプル・アプリケーションの実行結果
[参照]ボタンで画像ファイルを選択し、[送信]ボタンをクリック。これにより、バイナリ・データがサーバにアップロードされ、データベースに格納される。

 このWebページ上で画像ファイルを指定してアップロードしてみよう。以下のようにそのバイナリ・データがデータベースに登録されているのが確認できるはずである。

アップロード後、データベースの内容を確認したところ
あらかじめ用意したPhotoテーブルにアップロード・ファイルが登録されている。

 リストの内容を確認しても分かるように、バイナリ・データを扱うといっても、さほどのことはない。まず、バインド機能を使って、HttpPostedFileBaseオブジェクトにアップロード・ファイルを格納するところまでは、前述のTIPSで解説したままである。あとは、HttpPostedFileBaseクラス(System.Web名前空間)の内容をエンティティ(ここではPhotoクラス)の対応するプロパティに詰め替えていくだけだ。

 この際、データ本体は、HttpPostedFileBase.InputStreamプロパティを介してバイト配列に格納している点に注目である。データベースでVARBINARY型として定義されたフィールドは、エンティティではバイト配列のプロパティとして割り当てられるので、変換したバイト配列は、そのままプロパティ値としてセットできる。

 エンティティに必要なデータをセットし終えたら、AddObjectメソッドでコンテキスト・オブジェクト(ここではMyMvcEntities)に追加した後、SaveChangesメソッドを呼び出すことで、データベースにアップロード内容を反映できる。

 EDMを介したデータの登録方法については、「.NETの新データアクセス・テクノロジ『ADO.NET Entity Framework』」で解説しているので、参考にしていただきたい。

 このようにしてデータベースに登録したデータを、再びアクション・メソッドから読み込む方法については、後日「TIPS:[ASP.NET MVC]データベースから取り出したバイナリ・データを出力するには?」で紹介の予定である。End of Article

利用可能バージョン:.NET Framework 3.5
カテゴリ:Webフォーム 処理対象:ASP.NET MVC
使用ライブラリ:HttpPostedFileBaseクラス(System.Web名前空間)
関連TIPS:[ASP.NET MVC]ファイルのアップロードを行うには?
関連TIPS:[ASP.NET MVC]データベースから取り出したバイナリ・データを出力するには?(後日公開予定)

この記事と関連性の高い別の.NET TIPS
[ASP.NET]バイナリ・データをアップロードしてデータベースに登録するには?
[ASP.NET MVC]データベースから取り出したバイナリ・データを出力するには?
[ASP.NET MVC]ファイルのアップロードを行うには?
[ASP.NET]ブラウザからファイルをアップロードできるようにするには?
[ASP.NET]データベースに登録したバイナリ・データを表示するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間