ファイルのアップロード (VB)

作成者: Scott Mitchell

PDF のダウンロード

ユーザーがバイナリ ファイル (Wordや PDF ドキュメントなど) を Web サイトにアップロードし、サーバーのファイル システムまたはデータベースに保存できるようにする方法について説明します。

はじめに

これまでに調べたすべてのチュートリアルでは、テキスト データのみを使用してきました。 ただし、多くのアプリケーションには、テキスト データとバイナリ データの両方をキャプチャするデータ モデルがあります。 オンライン出会い系サイトでは、ユーザーが自分のプロファイルに関連付ける画像をアップロードできる場合があります。 採用 Web サイトでは、ユーザーが履歴書を Microsoft Word または PDF ドキュメントとしてアップロードできます。

バイナリ データを操作すると、新しい課題のセットが追加されます。 バイナリ データをアプリケーションに格納する方法を決定する必要があります。 新しいレコードの挿入に使用されるインターフェイスは、ユーザーがコンピューターからファイルをアップロードできるように更新する必要があります。また、レコードに関連付けられているバイナリ データをダウンロードするための手段を表示または提供するための追加の手順を実行する必要があります。 このチュートリアルと次の 3 つのチュートリアルでは、これらの課題を解決する方法について説明します。 これらのチュートリアルの最後に、画像と PDF パンフレットを各カテゴリに関連付ける完全に機能するアプリケーションを構築します。 この特定のチュートリアルでは、バイナリ データを格納するためのさまざまな手法について説明し、ユーザーが自分のコンピューターからファイルをアップロードし、Web サーバーのファイル システムに保存できるようにする方法について説明します。

注意

アプリケーションのデータ モデルの一部であるバイナリ データは、バイナリ ラージ OBject の頭字語である BLOB と呼ばれることもあります。 これらのチュートリアルでは、用語バイナリ データを使用することを選択しましたが、BLOB という用語は同義です。

手順 1: バイナリ データ Web ページの操作の作成

バイナリ データのサポートの追加に関連する課題を調べる前に、まず、このチュートリアルと次の 3 つで必要となる ASP.NET ページを Web サイト プロジェクトに作成してみましょう。 まず、 という名前 BinaryDataの新しいフォルダーを追加します。 次に、次の ASP.NET ページをそのフォルダーに追加し、各ページをマスター ページに Site.master 関連付けます。

  • Default.aspx
  • FileUpload.aspx
  • DisplayOrDownloadData.aspx
  • UploadInDetailsView.aspx
  • UpdatingAndDeleting.aspx

バイナリ Data-Related チュートリアルの ASP.NET ページを追加する

図 1: バイナリ Data-Related チュートリアルの ASP.NET ページを追加する

他のフォルダーと同様に、 Default.aspx フォルダーには BinaryData セクションにチュートリアルが一覧表示されます。 ユーザー コントロールに SectionLevelTutorialListing.ascx この機能があることを思い出してください。 したがって、このユーザー コントロールを にDefault.aspx追加するには、ソリューション エクスプローラーからページのデザイン ビューにドラッグします。

SectionLevelTutorialListing.ascx ユーザー コントロールを Default.aspx に追加する

図 2: ユーザー コントロールを SectionLevelTutorialListing.ascx に追加する Default.aspx (クリックするとフルサイズの画像が表示されます)

最後に、これらのページをエントリとしてファイルに追加します Web.sitemap 。 具体的には、GridView <siteMapNode>の拡張の後に次のマークアップを追加します。

<siteMapNode 
    title="Working with Binary Data" 
    url="~/BinaryData/Default.aspx" 
    description="Extend the data model to include collecting binary data.">
    
    <siteMapNode 
        title="Uploading Files" 
        url="~/BinaryData/FileUpload.aspx" 
        description="Examine the different ways to store binary data on the 
                     web server and see how to accept uploaded files from users 
                     with the FileUpload control." />
    <siteMapNode 
        title="Display or Download Binary Data" 
        url="~/BinaryData/DisplayOrDownloadData.aspx" 
        description="Let users view or download the captured binary data." />
    <siteMapNode 
        title="Adding New Binary Data" 
        url="~/BinaryData/UploadInDetailsView.aspx" 
        description="Learn how to augment the inserting interface to 
                     include a FileUpload control." />
    <siteMapNode 
        title="Updating and Deleting Existing Binary Data" 
        url="~/BinaryData/UpdatingAndDeleting.aspx" 
        description="Learn how to update and delete existing binary data." />
</siteMapNode>

を更新した Web.sitemap後、ブラウザーを使用してチュートリアル Web サイトを表示します。 左側のメニューに、バイナリ データの操作に関するチュートリアルの項目が含まれるようになりました。

サイト マップに、バイナリ データの操作に関するチュートリアルのエントリが含まれるようになりました

図 3: バイナリ データの操作に関するチュートリアルのエントリがサイト マップに含まれるようになりました

手順 2: バイナリ データを格納する場所を決定する

アプリケーションのデータ モデルに関連付けられているバイナリ データは、データベースに格納されているファイルへの参照を使用して、Web サーバーのファイル システム上の 2 つの場所のいずれかに格納できます。またはデータベース自体内で直接実行します (図 4 を参照)。 各アプローチには独自の長所と短所のセットがあり、より詳細な議論を行うメリットがあります。

バイナリ データは、ファイル システムに格納することも、データベースに直接格納することもできます

図 4: バイナリ データは、ファイル システムに格納することも、データベースに直接格納することもできます (フルサイズの画像を表示するには、ここをクリックします)

Northwind データベースを拡張して、画像を各製品に関連付けたいとします。 1 つのオプションは、これらのイメージ ファイルを Web サーバーのファイル システムに格納し、パスをテーブルに Products 記録することです。 この方法では、型varchar(200)のテーブルに列をProducts追加ImagePathします。おそらくです。 ユーザーが Chai の画像をアップロードすると、その画像は Web サーバーの ファイル システム ~/Images/Tea.jpgに に格納される可能性があります。これは、 ~ アプリケーションの物理パスを表します。 つまり、Web サイトが物理パスC:\Websites\Northwind\~/Images/Tea.jpgにルート化されている場合、 は とC:\Websites\Northwind\Images\Tea.jpg同じになります。 イメージ ファイルをアップロードした後、テーブル内の Chai レコードを Products 更新して、その ImagePath 列が新しいイメージのパスを参照するようにします。 すべての製品イメージをアプリケーションのImagesフォルダーに配置することにした場合はTea.jpg、 または を使用~/Images/Tea.jpgできます。

ファイル システムにバイナリ データを格納するメインの利点は次のとおりです。

  • 簡単に実装できます。データベース内に直接格納されているバイナリ データの格納と取得には、ファイル システムを介してデータを操作する場合よりも少し多くのコードが必要です。 さらに、ユーザーがバイナリ データを表示またはダウンロードするには、そのデータの URL を表示する必要があります。 データが Web サーバーのファイル システムに存在する場合、URL は簡単です。 ただし、データがデータベースに格納されている場合は、データベースからデータを取得して返す Web ページを作成する必要があります。
  • バイナリ データへのより広範なアクセスバイナリ データ は、データベースからデータをプルできない他のサービスまたはアプリケーションからアクセスできる必要がある場合があります。 たとえば、各製品に関連付けられているイメージを FTP 経由でユーザーが使用できるようにする必要がある場合もあります。その場合は、バイナリ データをファイル システムに格納する必要があります。
  • バイナリ データがファイル システムに格納されている場合のパフォーマンスは、バイナリ データがデータベース内に直接格納されている場合よりも、データベース サーバーと Web サーバー間の需要とネットワークの輻輳が小さくなります。

ファイル システムにバイナリ データを格納するメインの欠点は、データをデータベースから分離することです。 テーブルから Products レコードが削除された場合、Web サーバーのファイル システム上の関連付けられているファイルは自動的には削除されません。 ファイルを削除する追加のコードを記述する必要があります。または、ファイル システムが未使用の孤立したファイルで乱雑になります。 さらに、データベースをバックアップする場合は、関連付けられているバイナリ データのバックアップもファイル システムで行う必要があります。 データベースを別のサイトまたはサーバーに移動すると、同様の課題が発生します。

または、 型varbinaryの列を作成することで、バイナリ データを Microsoft SQL Server 2005 データベースに直接格納することもできます。 他の可変長データ型と同様に、この列に保持できるバイナリ データの最大長を指定できます。 たとえば、最大 5,000 バイトを予約するには、 を使用 varbinary(5000)します varbinary(MAX) 。最大ストレージ サイズは約 2 GB です。

バイナリ データをデータベースに直接格納するメインの利点は、バイナリ データとデータベース レコードの間の緊密な結合です。 これにより、バックアップやデータベースを別のサイトまたはサーバーに移動するなどのデータベース管理タスクが大幅に簡素化されます。 また、レコードを削除すると、対応するバイナリ データが自動的に削除されます。 また、バイナリ データをデータベースに格納する方が微妙な利点もあります。

注意

Microsoft SQL Server 2000 以前のバージョンでは、varbinaryデータ型の上限は 8,000 バイトでした。 最大 2 GB のバイナリ データを格納するには、 image 代わりにデータ型 を使用する必要があります。 ただし、SQL Server 2005 に が追加MAXされたため、imageデータ型は非推奨になりました。 下位互換性は引き続きサポートされていますが、データ型は将来のimageバージョンのSQL Serverで削除されると Microsoft が発表しました。

古いデータ モデルを使用している場合は、データ型が image 表示される場合があります。 Northwind データベースの Categories テーブルには、 Picture カテゴリのイメージ ファイルのバイナリ データを格納するために使用できる列があります。 Northwind データベースのルートは Microsoft Access 以前のバージョンのSQL Serverであるため、この列の型imageは です。

このチュートリアルと次の 3 つのチュートリアルでは、両方の方法を使用します。 テーブルには Categories 、カテゴリの Picture 画像のバイナリ コンテンツを格納するための列が既に含まれています。 追加の列 () を追加して、 BrochurePathWeb サーバーのファイル システム上の PDF へのパスを格納します。このパスを使用すると、カテゴリの印刷品質と洗練された概要を提供できます。

手順 3: テーブルにBrochurePath列を追加するCategories

現在、Categories テーブルには、および Pictureの 4 つの列DescriptionCategoryIDCategoryNameしかありません。 これらのフィールドに加えて、カテゴリのパンフレット (存在する場合) を指す新しいフィールドを追加する必要があります。 この列を追加するには、[サーバー] エクスプローラーに移動し、[テーブル] にドリルダウンし、テーブルを右クリックして [テーブル定義をCategories開く] を選択します (図 5 を参照)。 [サーバー] エクスプローラーが表示されない場合は、[表示] メニューの [サーバー エクスプローラー] オプションを選択して表示するか、Ctrl + Alt + S キーを押します。

という名前の新varchar(200)しい列をCategoriesテーブルに追加し、s を許可NULLして [保存] アイコンをクリックします (または Ctrl + S キーを押BrochurePathします)。

Categories テーブルに BrochurePath 列を追加する

図 5: テーブルに列を BrochurePath 追加する Categories (フルサイズの画像を表示する をクリックします)

手順 4: 列とBrochurePath列を使用するようにアーキテクチャをPicture更新する

データ アクセス層 (DAL) の にはCategoriesDataTable、現在、および の 4 つの DataColumn が定義DescriptionCategoryIDCategoryNameされていますNumberOfProducts。 データ アクセス層の作成 チュートリアルでこの DataTable を最初に設計したとき、最初の CategoriesDataTable 3 つの列 NumberOfProducts だけが含まれています。列は、詳細 DataList チュートリアルでマスター レコードの箇条書きリストを使用してマスター/詳細 に追加されました。

「データ アクセス層の作成」で説明したように、型指定された DataSet の DataTable によってビジネス オブジェクトが構成されます。 TableAdapters は、データベースと通信し、ビジネス オブジェクトにクエリ結果を設定する役割を担います。 CategoriesDataTableは によってCategoriesTableAdapter設定されます。このメソッドには、次の 3 つのデータ取得方法があります。

  • GetCategories()は TableAdapter の メイン クエリを実行し、テーブル内のすべてのレコードの 、CategoryName、および Description フィールドをCategoriesCategoryIDします。 メイン クエリは、自動生成Insertされた メソッドと Update メソッドによって使用されるクエリです。
  • GetCategoryByCategoryID(categoryID)は、CategoryIDcategoryID と等しいカテゴリCategoryIDの 、CategoryName、および Description フィールドを返します。
  • GetCategoriesAndNumberOfProducts() - テーブル内のすべてのレコードの CategoryIDCategoryName、および Description フィールドを Categories 返します。 また、サブクエリを使用して、各カテゴリに関連付けられている製品の数を返します。

これらのクエリのいずれもテーブルまたはPictureBrochurePath列をCategories返さないことに注意してください。また、 ではこれらのフィールドに CategoriesDataTable 対して が提供DataColumnされません。 Picture プロパティと BrochurePath プロパティを操作するには、まずそれらを に CategoriesDataTable 追加してから、 クラスを更新してこれらの列を CategoriesTableAdapter 返す必要があります。

BrochurePath``DataColumnPicture追加

まず、これら 2 つの列を に追加します CategoriesDataTable。 s ヘッダーを CategoriesDataTable 右クリックし、コンテキスト メニューから [追加] を選択し、[列] オプションを選択します。 これにより、 という名前Column1の DataTable に新しい DataColumn が作成されます。 この列の名前を に Picture変更します。 プロパティ ウィンドウから、 プロパティDataTypeDataColumnSystem.Byte[]設定します (これはドロップダウン リストのオプションではありません。入力する必要があります)。

DataType が System.Byte[] である DataColumn 名前付き画像を作成する

図 6: を持つ名前付き PictureSystem.Byte[]DataType作成DataColumnします (フルサイズの画像を表示する 場合は クリックします)

DataTable にもう 1 つDataColumn追加し、既定値 DataType (System.String) を使用して名前を付けますBrochurePath

PictureTableAdapter から とBrochurePathの値を返す

これら 2 つの DataColumn を に CategoriesDataTable追加して、 を更新 CategoriesTableAdapterする準備ができました。 これらの両方の列値を メイン TableAdapter クエリで返すことができますが、これにより、メソッドが呼び出されるたびにバイナリ データがGetCategories()返されます。 代わりに、メイン TableAdapter クエリを更新して、BrochurePath特定のカテゴリのPicture列を返す追加のデータ取得メソッドを作成しましょう。

メイン TableAdapter クエリを更新するには、s ヘッダーをCategoriesTableAdapter右クリックし、コンテキスト メニューから [構成] オプションを選択します。 これにより、テーブル アダプター構成ウィザードが表示されます。このウィザードは、過去のチュートリアルの多くで見てきました。 クエリを更新して を元に BrochurePath 戻し、[完了] をクリックします。

SELECT ステートメントの列リストを更新して、BrochurePath も返すようにします

図 7: ステートメントの列リストを SELECT 更新しても返すように BrochurePath します (フルサイズの画像を表示する場合はクリックします)

TableAdapter にアドホック SQL ステートメントを使用する場合、メイン クエリの列リストを更新すると、TableAdapter 内のすべてのクエリ メソッドのSELECT列リストが更新されます。 つまり、メソッドは列を GetCategoryByCategoryID(categoryID)BrochurePath すように更新されています。これは、意図したとおりである可能性があります。 ただし、 メソッドの GetCategoriesAndNumberOfProducts() 列リストも更新され、各カテゴリの製品数を返すサブクエリが削除されました。 したがって、このメソッドの SELECT クエリを更新する必要があります。 メソッドを GetCategoriesAndNumberOfProducts() 右クリックし、[構成] を選択して、クエリを元の SELECT 値に戻します。

SELECT CategoryID, CategoryName, Description, 
       (SELECT COUNT(*) 
            FROM Products p 
            WHERE p.CategoryID = c.CategoryID) 
       as NumberOfProducts
FROM Categories c

次に、特定のカテゴリの列値を返す新しい TableAdapter メソッドを Picture 作成します。 s ヘッダーを CategoriesTableAdapter 右クリックし、[クエリの追加] オプションを選択して TableAdapter クエリ構成ウィザードを起動します。 このウィザードの最初の手順では、アドホック SQL ステートメント、新しいストアド プロシージャ、または既存のストアド プロシージャを使用してデータのクエリを実行するかどうかを確認します。 [SQL ステートメントの使用] を選択し、[次へ] をクリックします。 行を返すので、2 番目の手順から [行を返す SELECT] オプションを選択します。

[SQL ステートメントを使用する] オプションを選択します

図 8: [SQL ステートメントを使用する] オプションを選択します (フルサイズの画像を表示するには、ここをクリックします)

クエリは Categories テーブルからレコードを返すので、行を返す SELECT を選択します

図 9: クエリはカテゴリ テーブルからレコードを返すので、行を返す SELECT を選択します (フルサイズの画像を表示する場合はクリックします)

3 番目の手順で、次の SQL クエリを入力し、[次へ] をクリックします。

SELECT     CategoryID, CategoryName, Description, BrochurePath, Picture
FROM       Categories
WHERE      CategoryID = @CategoryID

最後の手順では、新しいメソッドの名前を選択します。 DataTable を塗りつぶすパターンと GetCategoryWithBinaryDataByCategoryID DataTable パターンを返す場合は、 と をそれぞれ使用FillCategoryWithBinaryDataByCategoryIDします。 [完了] をクリックしてウィザードを終了します。

TableAdapter s メソッドの名前を選択する

図 10: TableAdapter のメソッドの名前を選択します (フルサイズの画像を表示する をクリックします)

注意

テーブル アダプター クエリ構成ウィザードを完了すると、新しいコマンド テキストが、メイン クエリのスキーマとは異なるスキーマのデータを返すというダイアログ ボックスが表示されることがあります。 つまり、TableAdapter の メイン クエリGetCategories()は、先ほど作成したスキーマとは異なるスキーマを返すという点がウィザードで示されています。 しかし、これは私たちが望むものなので、このメッセージを無視することができます。

また、アドホック SQL ステートメントを使用していて、ウィザードを使用して後で TableAdapter の メイン クエリを変更する場合は、メソッドのSELECTステートメントの列リストが変更GetCategoryWithBinaryDataByCategoryIDされ、メイン クエリの列だけが含まれるようになります (つまり、クエリから列がPicture削除されます)。 この手順で前にメソッドを使用した場合と同様に、列リストを手動で更新して列をGetCategoriesAndNumberOfProducts()返すPicture必要があります。

2 つの DataColumn s を にCategoriesDataTable追加しGetCategoryWithBinaryDataByCategoryID、 メソッドを にCategoriesTableAdapter追加した後、Typed DataSet Designerのこれらのクラスは図 11 のスクリーンショットのようになります。

DataSet Designerには、新しい列とメソッドが含まれています

図 11: DataSet Designerには、新しい列とメソッドが含まれています

ビジネス ロジック レイヤー (BLL) の更新

DAL が更新されると、残っているのは、新しい CategoriesTableAdapter メソッドのメソッドを含むようにビジネス ロジック レイヤー (BLL) を拡張することです。 次のメソッドを CategoriesBLL クラスに追加します。

<System.ComponentModel.DataObjectMethodAttribute _
    (System.ComponentModel.DataObjectMethodType.Select, False)> _
Public Function GetCategoryWithBinaryDataByCategoryID(categoryID As Integer) _
    As Northwind.CategoriesDataTable
    
    Return Adapter.GetCategoryWithBinaryDataByCategoryID(categoryID)
End Function

手順 5: クライアントから Web サーバーにファイルをアップロードする

バイナリ データを収集する場合、多くの場合、このデータはエンド ユーザーによって提供されます。 この情報をキャプチャするには、ユーザーが自分のコンピューターから Web サーバーにファイルをアップロードできる必要があります。 アップロードされたデータはデータ モデルと統合する必要があります。これは、ファイルを Web サーバーのファイル システムに保存し、データベース内のファイルへのパスを追加したり、バイナリ コンテンツをデータベースに直接書き込んだりすることを意味する場合があります。 この手順では、ユーザーが自分のコンピューターからサーバーにファイルをアップロードできるようにする方法について説明します。 次のチュートリアルでは、アップロードされたファイルとデータ モデルの統合に注目します。

ASP.NET 2.0 の新しい FileUpload Web コントロール は、ユーザーがコンピューターから Web サーバーにファイルを送信するためのメカニズムを提供します。 FileUpload コントロールは、属性が file に設定されている要素typeとして<input>レンダリングされ、ブラウザーは [参照] ボタンを含むテキスト ボックスとして表示されます。 [参照] ボタンをクリックすると、ユーザーがファイルを選択できるダイアログ ボックスが表示されます。 フォームがポストバックされると、選択したファイルの内容がポストバックと共に送信されます。 サーバー側では、アップロードされたファイルに関する情報には、FileUpload コントロールのプロパティを使用してアクセスできます。

ファイルのアップロードを示すには、フォルダー内のページをFileUpload.aspxBinaryData開き、ツールボックスから Designer に FileUpload コントロールをドラッグし、コントロールの プロパティIDを にUploadTest設定します。 次に、Button Web コントロールの プロパティIDと プロパティをそれぞれ にUploadButton設定しText、選択したファイルをアップロードします。 最後に、Button の下に Label Web コントロールを配置し、そのプロパティを Text クリアし、そのプロパティを IDUploadDetails設定します。

ASP.NET ページに FileUpload コントロールを追加する

図 12: ASP.NET ページに FileUpload コントロールを追加する (フルサイズの画像を表示する 場合はクリックします)

図 13 は、ブラウザーで表示された場合のこのページを示しています。 [参照] ボタンをクリックすると、ファイルの選択ダイアログ ボックスが表示され、ユーザーはコンピューターからファイルを選択できます。 ファイルが選択されると、[選択したファイルのアップロード] ボタンをクリックすると、選択したファイルのバイナリ コンテンツが Web サーバーに送信されるポストバックが発生します。

ユーザーは自分のコンピューターからサーバーにアップロードするファイルを選択できます

図 13: ユーザーは自分のコンピューターからサーバーにアップロードするファイルを選択できます (フルサイズの画像を表示するにはクリックします)

ポストバックでは、アップロードされたファイルをファイル システムに保存することも、バイナリ データをStreamを介して直接操作することもできます。 この例では、フォルダーを ~/Brochures 作成し、アップロードしたファイルをそこに保存します。 まず、 フォルダーを Brochures ルート ディレクトリのサブフォルダーとしてサイトに追加します。 次に、 イベントのイベント ハンドラーをUploadButtonClick作成し、次のコードを追加します。

Protected Sub UploadButton_Click(sender As Object, e As EventArgs) _
    Handles UploadButton.Click
    
    If UploadTest.HasFile = False Then
        ' No file uploaded!
        UploadDetails.Text = "Please first select a file to upload..."
    Else
        ' Display the uploaded file's details
        UploadDetails.Text = String.Format( _
                "Uploaded file: {0}<br />" & _
                "File size (in bytes): {1:N0}<br />" & _
                "Content-type: {2}", _
                UploadTest.FileName, _
                UploadTest.FileBytes.Length, _
                UploadTest.PostedFile.ContentType)
        ' Save the file
        Dim filePath As String = _
            Server.MapPath("~/Brochures/" & UploadTest.FileName)
        UploadTest.SaveAs(filePath)
    End If
End Sub

FileUpload コントロールには、アップロードされたデータを操作するためのさまざまなプロパティが用意されています。 たとえば、 プロパティはHasFile、ファイルがユーザーによってアップロードされたかどうかを示しますFileBytesが、 プロパティは、アップロードされたバイナリ データへのアクセスをバイト配列として提供します。 イベント ハンドラーは Click 、ファイルがアップロードされたことを確認することから始まります。 ファイルがアップロードされている場合、Label には、アップロードされたファイルの名前、そのサイズ (バイト単位)、およびそのコンテンツ タイプが表示されます。

注意

ユーザーがファイルを確実にアップロードできるようにするには、 プロパティをチェックHasFileし、 の場合Falseは警告を表示するか、代わりに RequiredFieldValidator コントロールを使用します。

FileUpload s SaveAs(filePath) は、アップロードされたファイルを指定された filePath に保存します。 filePath は、仮想パス () ではなく物理パス (/Brochures/SomeFile.pdfC:\Websites\Brochures\SomeFile.pdf) である必要があります。 メソッドはServer.MapPath(virtPath)仮想パスを受け取り、対応する物理パスを返します。 ここで、仮想パスは です ~/Brochures/fileNameここで、fileName はアップロードされたファイルの名前です。 仮想パスと物理パスと を使用する方法の詳細については、「 Server.MapPath メタス 」を参照 Server.MapPathしてください。

イベント ハンドラーが Click 完了したら、ブラウザーでページをテストします。 [参照] ボタンをクリックし、ハード ドライブからファイルを選択し、[選択したファイルのアップロード] ボタンをクリックします。 ポストバックは、選択したファイルの内容を Web サーバーに送信し、フォルダーに保存する前にファイルに関する情報を ~/Brochures 表示します。 ファイルをアップロードした後、Visual Studio に戻り、ソリューション エクスプローラーの [更新] ボタンをクリックします。 アップロードしたファイルが ~/Brochures フォルダーに表示されます。

ファイル EvolutionValley.jpg が Web サーバーにアップロードされました

図 14: ファイル EvolutionValley.jpg が Web サーバーにアップロードされました (フルサイズの画像を表示する をクリックします)

EvolutionValley.jpg が ~/Brochures フォルダーに保存されました

図 15: EvolutionValley.jpg フォルダーに ~/Brochures 保存されました

アップロードしたファイルをファイル システムに保存する場合の機微

Web サーバーのファイル システムにファイルをアップロードするときに対処する必要があるいくつかの微妙な点があります。 まず、セキュリティの問題があります。 ファイル をファイル システムに保存するには、ASP.NET ページが実行されているセキュリティ コンテキストに書き込みアクセス許可が必要です。 ASP.NET 開発 Web サーバーは、現在のユーザー アカウントのコンテキストで実行されます。 Microsoft のインターネット インフォメーション サービス (IIS) を Web サーバーとして使用している場合、セキュリティ コンテキストは IIS のバージョンとその構成によって異なります。

ファイルをファイル システムに保存するもう 1 つの課題は、ファイルの名前付けです。 現在、このページでは、クライアントのコンピューター上のファイル ~/Brochures と同じ名前を使用して、アップロードされたすべてのファイルをディレクトリに保存します。 ユーザー A が という名前 Brochure.pdfのパンフレットをアップロードすると、ファイルは として ~/Brochure/Brochure.pdf保存されます。 しかし、後でユーザー B が同じファイル名 (Brochure.pdf) を持つ別のパンフレット ファイルをアップロードした場合はどうなりますか? 現在のコードでは、ユーザー A のファイルがユーザー B のアップロードで上書きされます。

ファイル名の競合を解決するには、いくつかの手法があります。 1 つのオプションは、同じ名前のファイルが既に存在する場合にファイルのアップロードを禁止することです。 この方法では、ユーザー B が という名前 Brochure.pdfのファイルをアップロードしようとすると、システムはファイルを保存せず、代わりにファイルの名前を変更して再試行するようにユーザー B に通知するメッセージを表示します。 もう 1 つの方法は、一意のファイル名を使用してファイルを保存することです。これは、 グローバル一意識別子 (GUID) または対応するデータベース レコードの主キー列の値である可能性があります (アップロードがデータ モデルの特定の行に関連付けられている場合)。 次のチュートリアルでは、これらのオプションについて詳しく説明します。

非常に大量のバイナリ データに関連する課題

これらのチュートリアルでは、キャプチャされたバイナリ データのサイズが控えめであることを前提としています。 数メガバイト以上の非常に大量のバイナリ データ ファイルを操作すると、これらのチュートリアルの範囲を超える新しい課題が発生します。 たとえば、既定では、ASP.NET は 4 MB を超えるアップロードを拒否しますが、 の Web.config要素を<httpRuntime>使用して構成できます。 IIS では、独自のファイル アップロード サイズの制限も課されます。 さらに、大きなファイルのアップロードにかかった時間が、要求を待機 ASP.NET 既定の 110 秒を超える可能性があります。 また、大きなファイルを操作するときに発生するメモリとパフォーマンスの問題もあります。

FileUpload コントロールは、大きなファイルアップロードでは実用的ではありません。 ファイルの内容がサーバーに投稿されている間、エンド ユーザーはアップロードが進行していることを確認せずに辛抱強く待つ必要があります。 これは、数秒でアップロードできる小さなファイルを処理する場合はあまり問題ではありませんが、アップロードに数分かかる可能性がある大きなファイルを処理する場合に問題になる可能性があります。 大規模なアップロードの処理に適したさまざまなサードパーティ製のファイル アップロード コントロールがあり、これらのベンダーの多くは進行状況インジケーターと、より洗練されたユーザー エクスペリエンスを提供する ActiveX アップロード マネージャーを提供します。

アプリケーションで大きなファイルを処理する必要がある場合は、課題を慎重に調査し、特定のニーズに適した解決策を見つける必要があります。

まとめ

バイナリ データをキャプチャする必要があるアプリケーションを構築すると、多くの課題が発生します。 このチュートリアルでは、最初の 2 つについて説明しました。バイナリ データを格納する場所を決定し、ユーザーが Web ページを介してバイナリ コンテンツをアップロードできるようにします。 次の 3 つのチュートリアルでは、アップロードしたデータをデータベース内のレコードに関連付ける方法と、バイナリ データをテキスト データ フィールドと共に表示する方法について説明します。

幸せなプログラミング!

もっと読む

このチュートリアルで説明するトピックの詳細については、次のリソースを参照してください。

著者について

7 冊の ASP/ASP.NET 書籍の著者であり、 4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズ・ティーチ・自分自身 ASP.NET 24時間で2.0です。 にアクセスmitchell@4GuysFromRolla.comすることも、ブログを介して アクセスすることもできます。これは でhttp://ScottOnWriting.NET確認できます。

特別な感謝

このチュートリアル シリーズは、多くの役立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、テレサ マーフィーとベルナデット リーでした。 今後の MSDN 記事の確認に関心がありますか? その場合は、 に行mitchell@4GuysFromRolla.comをドロップしてください。