ファイル フィールド コントロールを使用したファイルのアップロード
作成者: Bill Evjen
Reuters
2004 年 2 月
適用対象:
Microsoft® ASP.NET
概要: Microsoft ASP.NET ファイル フィールド コントロールを使用して、エンド ユーザーが 1 つ以上のファイルをサーバーにアップロードできるようにする方法について説明します。 (16ページ印刷)
内容
はじめに
ファイル フィールド コントロールを詳しく見る
ファイル サイズの制限に関する回避策
アップロードされたファイルの種類の制御
複数のファイルを同時にアップロードする
まとめ
関連書籍
はじめに
Microsoft® ASP.NET Web Formsは、エンド ユーザーと通信して、管理されるサービスに応じて必要な情報を抽象化します。 Web Formsを使用する多くの場合、通常は単に収集および格納されるテキスト データです。 ただし、単純なテキスト データ以上のものが必要になる場合は多数あります。ユーザーにファイルをサーバーにアップロードする必要がある場合があります。
たとえば、アプリケーションは、すべてのユーザーと共有されるドキュメント ライブラリを持つことができます。 多くの例がありますが、ストレージ用に任意の種類のドキュメントをアップロードしたり、アップロード後にアプリケーションでドキュメントに対してアクションを実行したりするには、この機能が必ず必要です。
いずれの場合も、ASP.NET では、少し作業するだけでドキュメントをサーバーにアップロードする簡単な機能が提供されます。 この記事では、Web サーバーにドキュメントをアップロードするためにファイル フィールド コントロールを使用する方法について説明します。
ファイル フィールド コントロールを詳しく見る
File Field コントロールは クラスを HtmlInputFile
使用し、単純に、ASP.NET する前に行うのが難しいことを行うため (つまり、サードパーティ製のコンポーネントを購入せずに)、クールなコントロールです。 ファイル フィールド コントロールは、クライアントのコンピューターからサーバーにファイルをアップロードします。
このコントロールは、すべてのバージョンの Microsoft Visual Studio® .NET では ファイル フィールド コントロールと呼ばれますが、ASP.NET Web マトリックスでは、このコントロールは FileUpload コントロールと呼ばれます。 どちらの場合も、ツールボックスの HTML セクションにコントロールがあります。
ファイル フィールド コントロールを使用すると、HTML <input type="file">
タグをプログラムできます。 このタグは、HTML フォーム内のファイル データを操作するために使用されます。 従来の ASP (ASP 3.0 以前) を使用する場合、多くのプログラマはサードパーティコンポーネントを使用してクライアントからサーバーにファイルをアップロードしました。 これで、.NET とこの新しいコントロールを使用すると、アップロードが処理され、より簡単にすることはできませんでした。 一覧 1 は、ファイル フィールド コントロールを使用してファイルをサーバーにアップロードする方法を示しています。
メモ サンプル コードは、Microsoft Visual Basic® (VB) と C# の両方で提供されています。
リスト 1。 ファイル フィールド コントロールを使用してサーバーにファイルをアップロードする
VB
<%@ Page Language="VB" %> <script runat="server"> Sub SubmitButton_Click(Source As Object, e As EventArgs) If Not (File1.PostedFile Is Nothing) Then Try File1.PostedFile.SaveAs("C:\Uploads\uploadedfile.txt") Span1.InnerHtml = "Upload Successful!" Catch ex As Exception Span1.InnerHtml = "Error saving file <b>C:\\" & _ File1.Value & "</b><br>" & ex.ToString() End Try End If End Sub </script> <html> <head> </head> <body> <form runat="server" enctype="multipart/form-data"> Select a file to upload:<br /> <input type="file" id="File1" runat="Server"> <p> <input type="submit" id="Submit1" runat="Server" value="Upload File" OnServerClick="SubmitButton_Click"> <p> <span id="Span1" runat="Server" /> </form> </body> </html>
C#
<%@ Page Language="C#" %> <script runat="server"> void SubmitButton_Click(Object sender, EventArgs e) { if (File1.PostedFile != null) { try { File1.PostedFile.SaveAs("C:\\Uploads\\uploadedfile.txt"); Span1.InnerHtml = "Upload Successful!"; } catch (Exception ex) { Span1.InnerHtml = "Error saving file <b>C:\\" + File1.Value + "</b><br>" + ex.ToString(); } } } </script> <html> <head> </head> <body> <form runat="server" enctype="multipart/form-data"> Select a file to upload:<br /> <input type="file" id="File1" runat="Server"> <p> <input type="submit" id="Submit1" runat="Server" value="Upload File" OnServerClick="SubmitButton_Click"> <p> <span id="Span1" runat="Server" /> </form> </body> </html>
リスト 1 のページを実行すると、ページの [ファイルのアップロード] ボタンをクリックして、ファイルを選択してサーバーにアップロードできます。 これは、ASP 3.0 プログラマが常に望む優れた機能です。 これで .NET に入っています。 数行のコードだけで、任意の種類のファイルをサーバーに簡単にアップロードできます。
この例では、この作業を行うために必要なすべての要素を理解するために必要な重要な項目がいくつかあります。 まず、リスト 1 の例を機能させるには、指定したフォルダーにファイルを保存できるように、ASP.NET で使用されるアカウントに対して、サーバー上のコピー先フォルダーを書き込み可能にする必要があります。
ASP.NET アカウントで目的のフォルダーへの書き込みが有効になっていないと思われる場合は、Microsoft Windows® エクスプローラーを開き、このアクセス許可を追加するフォルダーに移動するだけです。 フォルダー (この場合は Uploads フォルダー) を右クリックし、[プロパティ] を選択します。 [プロパティ] ダイアログ ボックスで、[セキュリティ] タブをクリックし、ASP.NET コンピューター アカウントが一覧に含まれており、ディスクに書き込む適切なアクセス許可があることを確認します (図 1 を参照)。
図 1. [アップロード] フォルダーの [セキュリティ] タブを確認する
[セキュリティ] タブに [コンピューター アカウントの ASP.NET] が表示されない場合は、図 2 に示すように、[追加] ボタンをクリックし、テキスト領域に ASPNET (ピリオドなし) を入力して追加できます。
図 2. ASP.NET コンピューター アカウントをフォルダー セキュリティ定義に追加する
[OK] をクリックして、ASP.NET コンピューター アカウントを一覧に追加します。 ここから、このアカウントに適切なアクセス許可を付与してください。[OK] をクリックすると、準備が整います。
リスト 1 のコードを見ると、すぐに非常に重要なことに気付くかもしれません。 最初に <form>
、タグは別の属性の追加によって変更されています。 ファイルをサーバーにアップロードするには、タグに <form>
属性 enctype="multipart/form-data"
が必要です。 この属性がないと、Web フォームはファイルをアップロードできません。
ページの [送信] ボタンをクリックすると、イベントが OnServerClick
発生します。 このイベントは、ファイルをアップロードし、アップロードが成功したかどうかを示すメッセージを表示します。 失敗した場合、アップロードが失敗した理由を説明するエラー メッセージがページに表示されます。
タグを <input type="file">
使用すると、ブラウザーは ASP.NET ページのテキスト フィールドの横に [参照] ボタンを自動的に配置します。 これを行うために、他のプログラムを作成する必要はありません。 エンド ユーザーが [参照] ボタンをクリックすると、ローカル ファイル システム内を移動して、サーバーにアップロードするファイルを見つけることができます。 これを図 3 に示します。 [開く] をクリックすると、そのファイル名とファイルのパスがテキスト フィールド内に配置されます。
図 3: ファイルの選択
ファイル サイズの制限に関する回避策
気付かないかもしれませんが、この手法を使用してアップロードできるファイルのサイズには制限があります。 既定では、ファイル フィールド コントロールを使用してサーバーにアップロードするファイルの最大サイズは約 4 MB です。 この制限を超えるものはアップロードできません。
ただし、.NET の優れた点の 1 つは、通常、制限を回避する方法を提供する点です。 通常は、設定されている既定の設定を変更できます。 このサイズ制限を変更するには、 または web.config
ファイルでいくつかの変更をmachine.config
行います。
ファイルで machine.config
、次のような というノード <httpRuntime>
を見つけます。
<httpRuntime executionTimeout="90" maxRequestLength="4096" useFullyQualifiedRedirectUrl="false" minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="100" />
この単一ノードでは多くのことが行われますが、アップロードするファイルのサイズを処理する設定は 属性です maxRequestLength
。 既定では、これは 4096 キロバイト (KB) に設定されています。 この値を変更して、サーバーにアップロードできるファイルのサイズを大きくするだけです。 10 MB (MB) のファイルをサーバーにアップロードできるようにする場合は、 の値を に11264
設定maxRequestLength
します。つまり、アプリケーションでは、最大 1,1000 KB のファイルをサーバーにアップロードできます。
ファイルでこの変更を行った場合、 machine.config
この設定はサーバー上のすべてのアプリケーションに適用されます。 これを使用しているアプリケーションにのみ適用する場合は、このノードをアプリケーションのファイルに web.config
適用し、ファイル内 machine.config
の設定をオーバーライドします。 このノードが構成ファイル内のノード間 <system.web>
に存在することを確認します。
アップロードするファイルのサイズ制限に関連するもう 1 つの設定は、ノードの <httpRuntime>
属性にexecutionTimeout
指定された値です。
属性に指定された executionTimeout
値は、ASP.NET によってシャットダウンされるまでのアップロードが許可される秒数です。 大きなファイルをサーバーにアップロードできるようにする場合は、値と maxRequestLength
共にこの値を増やします。
アップロードできるファイルのサイズを大きくすると、多数の要求を投げかけることでサーバーを攻撃するハッカーがいます。 これを防ぐために、アップロードが許可されているファイルのサイズを実際に 小さく することができます。そうしないと、数百または数千の 10 MB の要求がサーバーに送信される可能性があります。
アップロードされたファイルの種類の制御
サーバーにアップロードされるファイルの種類を制御するために使用できる方法はいくつかあります。 残念ながら、悪意があると見なされるファイルをアップロードするユーザーから保護するための防弾方法はありません。 ただし、いくつかの手順を実行して、エンド ユーザーがファイルをアップロードできるようにするこのプロセスを、もう少し管理しやすくすることができます。
使用できる優れている方法の 1 つは、ASP.NET で無料で提供される ASP.NET 検証コントロールを使用することです。 これらのコントロールを使用すると、アップロードするファイルに対して正規表現チェックを実行して、ファイルの拡張子がアップロードを許可したファイルであるかどうかを確認できます。
これは、検証コントロールのクライアント側での使用を許可するブラウザーに最適です。これは、クライアントで強制的にチェックを実行するためです。署名が許可されていない場合、ファイルはサーバーにアップロードされません。 リスト 2 は、検証コントロールを使用してこのタスクを実行する例を示しています。
メモ 検証コントロールの使用については、ここでは説明しません。 検証コントロールの完全な説明と 、ASP.NET ページでの検証コントロールの使用方法については、「ASP.NET サーバー コントロールの検証」を参照してください。
リスト 2: 検証コントロールを使用してサーバーにアップロードされるファイルの種類を制限する
VB
<%@ Page Language="VB" %> <script runat="server"> Sub SubmitButton_Click(Source As Object, e As EventArgs) If Not (File1.PostedFile Is Nothing) Then Try File1.PostedFile.SaveAs("C:\Uploads\uploadedfile.txt") Span1.InnerHtml = "Upload Successful!" Catch ex As Exception Span1.InnerHtml = "Error saving file <b>C:\\" & _ File1.Value & "</b><br>" & ex.ToString() End Try End If End Sub </script> <html> <head> </head> <body> <form enctype="multipart/form-data" runat="server"> <input id="File1" type="file" runat="Server" /> <p> <input id="Submit1" type="submit" value="Upload File" runat="Server" onserverclick="SubmitButton_Click" /> </p> <span id="Span1" runat="Server" /> <p> <asp:RegularExpressionValidator id="RegularExpressionValidator1" runat="server" ErrorMessage="Only mp3, m3u or mpeg files are allowed!" ValidationExpression="^(([a-zA- Z]:)|(\\{2}\w+)\$?)(\\(\w[\w ].*))+(.mp3|.MP3|.mpeg|.MPEG|.m3u|.M3U)$" ControlToValidate="File1"> </asp:RegularExpressionValidator> <br /> <asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server" ErrorMessage="This is a required field!" ControlToValidate="File1"> </asp:RequiredFieldValidator> </p> </form> </body> </html>
C#
<%@ Page Language="C#" %> <script runat="server"> void SubmitButton_Click(Object sender, EventArgs e) { if (File1.PostedFile != null) { try { File1.PostedFile.SaveAs("C:\\Uploads\\uploadedfile.txt"); Span1.InnerHtml = "Upload Successful!"; } catch (Exception ex) { Span1.InnerHtml = "Error saving file <b>C:\\" + File1.Value + "</b><br>" + ex.ToString(); } } } </script> <html> <head> </head> <body> <form enctype="multipart/form-data" runat="server"> <input id="File1" type="file" runat="Server" /> <p> <input id="Submit1" type="submit" value="Upload File" runat="Server" onserverclick="SubmitButton_Click" /> </p> <span id="Span1" runat="Server" /> <p> <asp:RegularExpressionValidator id="RegularExpressionValidator1" runat="server" ErrorMessage="Only mp3, m3u or mpeg files are allowed!" ValidationExpression="^(([a-zA- Z]:)|(\\{2}\w+)\$?)(\\(\w[\w ].*))+(.mp3|.MP3|.mpeg|.MPEG|.m3u|.M3U)$" ControlToValidate="File1"> </asp:RegularExpressionValidator> <br /> <asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server" ErrorMessage="This is a required field!" ControlToValidate="File1"> </asp:RequiredFieldValidator> </p> </form> </body> </html>
この単純な ASP.NET ページでは検証コントロールが使用されるため、エンド ユーザーは、.mpeg
または .m3u
ファイルのみをサーバーにアップロード.mp3
できます。 ファイルの種類がこれら 3 つの選択肢ではない場合、検証コントロールは画面に例外をスローします。 これを図 4 に示します。
図 4: 検証コントロールを使用したファイルの種類の検証
検証コントロールを使用することは、サーバーにアップロードされるファイルを制御するための確実な方法ではありません。 誰かがファイルのファイル拡張子を変更してサーバーに受け入れてアップロードするので、この単純なセキュリティ モデルをバイパスするのは難しいことではありません。
複数のファイルを同時にアップロードする
ここまでは、多くの手間をかけずにファイルをサーバーにアップロードする方法の良い例をいくつか見てきました。 次に、1 つのページから複数のファイルをサーバーにアップロードする方法を見てみましょう。
1 つの ASP.NET ページから複数のファイルをアップロードできる Microsoft .NET Frameworkの組み込み機能はありません。 ただし、少しの作業では、このタスクを簡単に実行できます。
1 つのトリックは、クラスを System.IO
ASP.NET ページにインポートし、 クラスを HttpFileCollection
使用して、 オブジェクトと共に送信されるすべてのファイルを Request
キャプチャすることです。 この方法では、1 つのページから必要な数のファイルをアップロードできます。
この例では、4 つのファイル入力ボックスと 1 つの [送信] ボタンを含む ASP.NET ページを作成できます。 ユーザーが [送信] ボタンをクリックし、ファイルがサーバーに投稿されると、分離コードによってファイルが取得され、サーバー上の特定の場所に保存されます。 ファイルが保存されると、投稿されたファイル情報が ASP.NET ページに表示されます (リスト 3 を参照)。
一覧 3: 複数のファイルをサーバーにアップロードする
VB
<%@ Import Namespace="System.IO" %> <%@ Page Language="VB" %> <script runat="server"> Sub SubmitButton_Click(Source As Object, e As EventArgs) Dim filepath As String = "C:\Uploads" Dim uploadedFiles As HttpFileCollection = Request.Files Dim i As Integer = 0 Do Until i = uploadedFiles.Count Dim userPostedFile As HttpPostedFile = uploadedFiles(i) Try If (userPostedFile.ContentLength > 0) Then Span1.InnerHtml += "<u>File #" & (i+1) & "</u><br>" Span1.InnerHtml += "File Content Type: " & _ userPostedFile.ContentType & "<br>" Span1.InnerHtml += "File Size: " & _ userPostedFile.ContentLength & "kb<br>" Span1.InnerHtml += "File Name: " & _ userPostedFile.FileName & "<br>" userPostedFile.SaveAs(filepath & "\" & _ Path.GetFileName(userPostedFile.FileName)) Span1.InnerHtml += "Location where saved: " & _ filepath & "\" & _ Path.GetFileName(userPostedFile.FileName) & _ "<p>" End If Catch ex As Exception Span1.InnerHtml += "Error:<br>" & ex.Message End Try i += 1 Loop End Sub </script> <html> <head> </head> <body> <form enctype="multipart/form-data" runat="server"> <p> Select File1:<br /> <input id="File1" type="file" runat="Server" /> <br /> Select File2:<br /> <input id="File2" type="file" runat="Server" /> <br /> Select File3:<br /> <input id="File3" type="file" runat="Server" /> <br /> Select File4:<br /> <input id="File4" type="file" runat="Server" /> </p> <p> <input id="Submit1" type="submit" value="Upload Files" runat="Server" onserverclick="SubmitButton_Click" /> <br /> </p> <span id="Span1" runat="Server"></span> </form> </body> </html>
C#
<%@ Import Namespace="System.IO" %> <%@ Page Language="C#" %> <script runat="server"> protected void SubmitButton_Click(Object sender, EventArgs e){ string filepath = "C:\\Uploads"; HttpFileCollection uploadedFiles = Request.Files; for (int i = 0; i < uploadedFiles.Count; i++) { HttpPostedFile userPostedFile = uploadedFiles[i]; try { if (userPostedFile.ContentLength > 0 ) { Span1.InnerHtml += "<u>File #" + (i+1) + "</u><br>"; Span1.InnerHtml += "File Content Type: " + userPostedFile.ContentType + "<br>"; Span1.InnerHtml += "File Size: " + userPostedFile.ContentLength + "kb<br>"; Span1.InnerHtml += "File Name: " + userPostedFile.FileName + "<br>"; userPostedFile.SaveAs(filepath + "\\" + Path.GetFileName(userPostedFile.FileName)); Span1.InnerHtml += "Location where saved: " + filepath + "\\" + Path.GetFileName(userPostedFile.FileName) + "<p>"; } } catch (Exception Ex) { Span1.InnerText += "Error: <br>" + Ex.Message; } } } </script> <html> <head> </head> <body> <form enctype="multipart/form-data" runat="server"> <p> Select File1:<br /> <input id="File1" type="file" runat="Server" /> <br /> Select File2:<br /> <input id="File2" type="file" runat="Server" /> <br /> Select File3:<br /> <input id="File3" type="file" runat="Server" /> <br /> Select File4:<br /> <input id="File4" type="file" runat="Server" /> </p> <p> <input id="Submit1" type="submit" value="Upload Files" runat="Server" onserverclick="SubmitButton_Click" /> <br /> </p> <span id="Span1" runat="Server"></span> </form> </body> </html>
エンド ユーザーは最大 4 つのファイルを選択し、[ファイルのアップロード] ボタンをクリックしてイベントを SubmitButton_Click
初期化できます。 プロパティで HttpFileCollection
クラスを Request.Files
使用すると、ページからアップロードされるすべてのファイルを制御できます。 ファイルがこの状態の場合は、必要に応じて任意の操作を実行できます。 この場合、ファイルのプロパティが調べられ、画面に書き込まれます。 最後に、ファイルはサーバーの Uploads
ルート ディレクトリ内の フォルダーに保存されます。 このアクションの結果を図 5 に示します。
図 5: 1 つの ASP.NET ページから 4 つのファイルをサーバーに一度にアップロードする
ご存じかもしれませんが、この例の興味深い点の 1 つは、ファイル入力テキスト ボックスの状態がポストバックと共に保存されないことです。 これは図 5 で確認できます。 ASP.NET では、ファイル入力テキスト ボックスの状態を保存できません。これは、セキュリティ上のリスクが発生する可能性があるためです。
まとめ
ASP.NET によって提供されるファイル フィールド コントロールは、Active Server Pages 3.0 の時代に実現するのが非常に困難だった強力なコントロールです。 この新機能により、エンドユーザーは 1 つ以上のファイルをサーバーにアップロードできます。 または ファイルの設定を使用して、アップロードするファイルのサイズを制御できることにmachine.config
web.config
注意してください。