ASP.NETで進行状況インジケーターを使用してマルチローディングファイルを実装する

この記事では、Mark Sullivanが、ASP.NETおよびUploadifyライブラリを使用して、動的な進行状況インジケーターを備えたマルチブートファイルを実装する方法について説明しています。 プロセスで作成されたHttp-handlerクラスは、コントロールのクラスとともに、他のASP.NETアプリケーションに適しています。このコードは、一方では便利なプラグインプレイソリューションであり、もう一方ではHttpでの作業の視覚的なデモンストレーションです。 -プロセッサー。 また、ファイル拡張子によるフィルタリング、完了時のポストバック、セッションベースのセキュリティなど、ASP.NETレイヤーにいくつかの追加機能を追加しました。







一般的な情報



HTML5のリリースにより、ActiveXまたは他のプラグインを使用せずに複数のファイルを同時にダウンロードできることが期待されていました。 ただし、純粋なHTML5は起動時に動的インジケータをサポートしません。また、一部のブラウザでは異なる方法で処理されます。 しかし、ファイル拡張子によるフィルタリングを可能にする安全なソリューションが必要でした。



以前のソリューションの代替品を探していたときに、Uploadifyを発見しました。 このライブラリはもともと無料のFlashプラグインとして作成されていましたが、2012年にはHTML5ソリューションも導入されました。 HTML5ライブラリのコストは、配布するかどうかによって5ドルから100ドルまでさまざまです。 私の意見では、これはそのような高品質の製品の低価格ですが、もちろんあなたが決めることです。 いずれにせよ、私がFlashバージョンの実装を作成したのは、誰かにとって突然便利になった場合です。 おそらく、私自身が古いブラウザで私のプロジェクトのいくつかをサポートするためにそれを適用することができるでしょう。 残念ながら、ASP.NETでこのソリューションを実装するインターネット上の明確な例を見たことはありません。







C#WebコントロールとC#クラスのシェルでオプションをラップしました(コントロールなしで出力ストリームに直接書き込むため)。 クラスは、ライブラリで処理されるほとんどのオプションを処理します。 サーバーとクライアントからダウンロードしたファイルをフィルタリングするためのJavaScriptサポートも追加しました。 セキュリティとサーバー側のフィルタリングについては、それらを実装するにはセッション状態が必要です。 ただし、これらは不要なダウンロードの防止に役立ちます。 他のプロジェクトオプションもC#クラスまたはコントロールに追加されます。



コードの使用



はじめに



提供されたコードを使用する前に、無料のFlashライブラリまたは有料のHTML5ライブラリを選択する必要があります。 最初のコンテンツはすべて空のUploadifyサブフォルダーに、2番目のコンテンツはUploadiFiveに配置する必要があります。 フラッシュバージョンは3番目のデモ(Demo3.aspx)で使用され、HTML5バージョンは最初の2つで使用されます。



または、HTML5のマルチファイルロードフィールドをクラスでラップすることもできます。



ライブラリを接続する



目的のjQueryライブラリと選択したUploadifyライブラリへのリンクを追加する必要があります。 標準のCSSファイルにはパッケージが付属しているため、コードにリンクを追加しました。 ASPXフォームのheadタグ内に次の行を追加します。



<script src="jquery/jquery-1.10.2.js" type="text/javascript"></script> <script src="uploadifive/jquery.uploadifive.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="uploadifive/uploadifive.css" />
      
      





または:



 <script src="jquery/jquery-1.10.2.js" type="text/javascript"></script> <script src="uploadify/jquery.uploadify.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="uploadify/uploadify.css" />
      
      







ページへのコントロールの追加



ASP.NET Webフォームでは、UploadiFiveControlクラスコードのインスタンスを作成し、それをフォームまたはプレースホルダーに追加することにより、ページにコントロールを追加できます。



 // Get the save path string savepath = Context.Server.MapPath("files"); // Create the upload control and add to the form UploadiFiveControl uploadControl = new UploadiFiveControl { UploadPath = savepath, RemoveCompleted = true, SubmitWhenQueueCompletes = true, AllowedFileExtensions = ".jpg|.bmp" }; form1.Controls.Add(uploadControl);
      
      





MVCへのコントロールの追加も同様です。



Flashバージョンの操作は非常に簡単です。同じクラスとコントロールを使用しますが、バージョンフラグはデフォルトではなくFlashに設定されているためです。 一部のオプションの名前を含むその他の変更は、コントロールによって処理されます。



 // Create the upload control and add to the form UploadiFiveControl uploadControl = new UploadiFiveControl { UploadPath = savepath, RemoveCompleted = true, SubmitWhenQueueCompletes = true, AllowedFileExtensions = ".jpg|.bmp", Version = UploadiFive_Version_Enum.Flash }; form1.Controls.Add(uploadControl);
      
      





アップロードされたファイルのHttpハンドラー



また、UploadiFiveFileHandler Httpハンドラークラスをプロジェクトに追加する必要があります。これは、サーバーにアップロードされたファイルを処理します。 実装のこの部分については、ディレクトリやブログのどこか他の部分ではあまり説明されていないため、次のセクション全体を取り上げました。 このクラスを含めるには、UploadiFiveFileHandler.ashxおよびUploadiFiveFileHandler.ashx.csファイルをプロジェクトにコピーします。



HTTPハンドラーとセキュリティ



Httpハンドラーの作成は非常に簡単ですが、柔軟性を提供し、いくつかの追加機能を導入することははるかに困難です。 セッション状態を使用してセキュリティを確保し、読み込みページからハンドラーに情報を転送しました。 これを行うために、UploadiFive_Security_Tokenクラスを作成しました。 彼の広告は次のようになります。



 /// <summary> Token used to add security, via adding a key to the session /// state, for uploading documents through this system </summary> public class UploadiFive_Security_Token { /// <summary> Path where the uploaded files should go </summary> public readonly string UploadPath; /// <summary> List of file extensions allowed </summary> public readonly string AllowedFileExtensions; /// <summary> Name of the file object to use in your server-side script</summary> public readonly string FileObjName; /// <summary> The GUID for this security token </summary> public readonly Guid ThisGuid; /// <summary> Constructor for a new instance of the UploadiFive_Security_Token class </summary> /// <param name="UploadPath" /> Path where the uploaded files should go /// <param name="AllowedFileExtensions" /> List of file extensions allowed /// <param name="FileObjName" /> Name of file object to use in your server-side script public UploadiFive_Security_Token(string UploadPath, string AllowedFileExtensions, string FileObjName ) { this.UploadPath = UploadPath; this.AllowedFileExtensions = AllowedFileExtensions; this.FileObjName = FileObjName; ThisGuid = Guid.NewGuid(); } }
      
      





このクラスには、ファイルへのパス、有効なファイル拡張子、およびハンドラーがファイルを見つけるためのキーが含まれます。 UploadiFiveControlクラスをレンダリングすると、新しいセキュリティトークンが作成され、GUIDの下のセッション状態で保存されます。 GUID自体がFormDataディクショナリに追加され、Uploadifyライブラリに転送されてから、ファイルデータとともにハンドラーに返されます。 その後、ハンドラーは、対応するGUIDに基づいてセッション内のセキュリティトークンを取得できます。



 // Create a new security token with all the configuration info UploadiFive_Security_Token newToken = new UploadiFive_Security_Token(UploadPath, AllowedFileExtensions, FileObjName); // Add this token to the current session for the HttpHandler HttpContext.Current.Session["#UPLOADIFIVE::" + newToken.ThisGuid.ToString()] = newToken; // Save the token into the formdata so comes to the HttpHandler FormData["token"] = newToken.ThisGuid.ToString();
      
      





Uploadifyコントロールを作成するために、フォームデータがJavaScriptコードに含まれています。 以下は、ファイル拡張子に制限のない結果のHTMLコードの例です。



 <input id="file_upload" name="file_upload" class="file_upload" type="file" /> <script type="text/javascript"> $(document).ready(function() { $('#file_upload').uploadifive({ 'fileObjName': 'Filedata', 'formData': { 'token' : 'da66e0ad-750b-4d76-a016-72633dea8b53' }, 'onQueueComplete': function (uploads) { $('#file_upload').closest("form").submit(); }, 'uploadScript': 'UploadiFiveFileHandler.ashx' }); }); </script>
      
      





上記を見るとわかるように、セキュリティトークンによって生成されたGUIDは、ライブラリを初期化するJavaScriptコードに含まれています。



HTTPハンドラーはセッション状態にアクセスする必要があるため、IReadOnlySessionStateインターフェイスを実装する必要があります。 以下に、ファイル拡張子の制限がないProcessRequestハンドラーメソッドの完全なコードを示します。



 Context.Response.ContentType = "text/plain"; Context.Response.Expires = -1; // Try to get the security token key string tokenKey = Context.Request["token"]; if (tokenKey == null) { Context.Response.Write("No token provided with this request"); Context.Response.StatusCode = 401; return; } // Try to get the matching token object from the session UploadiFive_Security_Token tokenObj = Context.Session["#UPLOADIFIVE::" + tokenKey] as UploadiFive_Security_Token; if (tokenObj == null) { Context.Response.Write("No matching server-side token found for this request"); Context.Response.StatusCode = 401; return; } try { // Get the posted file from the appropriate file key HttpPostedFile postedFile = Context.Request.Files[ tokenObj.FileObjName ]; if (postedFile != null) { // Get the path from the token and ensure it exists string path = tokenObj.UploadPath; if (!Directory.Exists(path)) Directory.CreateDirectory(path); string filename = Path.GetFileName(postedFile.FileName); postedFile.SaveAs(path + @"\" + filename); // Post a successful status Context.Response.Write(filename); Context.Response.StatusCode = 200; } } catch (Exception ex) { Context.Response.Write("Error: " + ex.Message); Context.Response.StatusCode = 500; }
      
      





セッションでトークンが見つからない場合、ファイルのダウンロードは許可されません。



ファイル拡張子の制限



ブートローダーを開発する際の良い習慣は、拡張子によってファイルを制限するメカニズムを追加することです。 このセクションでは、上記で説明したセキュリティパラメータを考慮して、クライアント側とサーバー側でこれをどのように実行したかを示します。



クライアント側の検証は、UploadiFiveライブラリのイベントとして実装されます。 ただし、onChangeファイルを追加するイベントは、ライブラリの外部で使用できます。



有効な拡張子は、コンマ区切りの文字列としてUploadiFiveControlに渡されます。



 uploadControl.AllowedFileExtensions = ".jpg|.bmp";
      
      





すべてが正しく設定されていれば、HTMLのレンダリング時にJavaScriptコードがonAddQueueItemイベントに添付されます。



 <script type="text/javascript"> $(document).ready(function() { $('#file_upload').uploadifive({ 'fileObjName': 'Filedata', 'formData': { 'token' : '4c893799-fd21-4d85-80c4-e32e6cacc794' }, 'removeCompleted': true, 'onAddQueueItem' : function(file) { var extArray = JSON.parse('[ ".jpg", ".bmp" ]'); var fileName = file.name; var ext = fileName.substring(fileName.lastIndexOf('.')).toLowerCase(); var isExtValid = false; for(var i = 0; i < extArray.length; i++) { if ( ext == extArray[i] ) { isExtValid = true; break; } } if ( !isExtValid ) { alert("File types of '<extension>' are not allowed".replace('<extension>', ext)); $('#file_upload').uploadifive('cancel', file); } }, 'uploadScript': 'UploadiFiveFileHandler.ashx' }); }); </script>
      
      





このコードは、C#コントロールによってJSON配列に変換された拡張機能のリストを取得し、配列データに対して特定の拡張機能をチェックします。 この拡張子が無効な場合、ユーザーは警告を受け取り、ファイルはダウンロードキューから削除されます。



サーバー側のHttpハンドラコードは次のようになります。 セキュリティトークンを使用して、有効な拡張子のリストを取得します。



 // Get the filename for the uploaded file string filename = Path.GetFileName(postedFile.FileName); // Are there file extension restrictions? if ( !String.IsNullOrEmpty(tokenObj.AllowedFileExtensions)) { string extension = Path.GetExtension(postedFile.FileName).ToLower(); List<string> allowed = tokenObj.AllowedFileExtensions.Split("|,".ToCharArray()).ToList(); if (!allowed.Contains(extension)) { Context.Response.Write("Invalid extension"); Context.Response.StatusCode = 401; return; } } // Save this file locally postedFile.SaveAs(path + @"\" + filename);
      
      





これで、クライアント側とサーバー側の無効な形式の制限が実装されたと見なすことができます。



ファイルサイズの制限



ファイルのダウンロードをサイズで制限する方法もいくつかあります。 IISサーバーにはこのような制限があり、作業時にはこれに留意する必要があります。 さらに、Uploadifyには、ダウンロードしたファイルのサイズを制限する方法もあります。



web.configファイルでは、有効なタイプのコンテンツの最大サイズを指定できます。これにより、ダウンロードされるファイルに制限が課されます。 requestLimitsタグはこれを担当し、バイト数で値を取ります。 たとえば、次のコードスニペットでは、ダウンロードされるファイルのサイズを約200 MBに制限しています。 このスニペットは、web.configファイルのコードにも含まれていました。



 <configuration> <system.webServer> <security> <requestLimits maxAllowedContentLength="209715200" /> </security> </system.webServer> </configuration>
      
      





さらに、Uploadifyライブラリは、JavaScriptのfileSizeLimitプロパティをC#クラスのFileSizeLimitとして使用します。 「100KB」や「200MB」のような文字列のように見えます。



フォールバックとしてのフラッシュと互換性の問題



一部の一般的なブラウザ、特にIE9は、HTML5をサポートするために必要な更新を受け取りません。 したがって、この場合、バックアップオプションを考慮しないと、古いブラウザのユーザーには、ダウンロードボタンのない標準のHTMLファイルダウンロードフィールドのみが表示されます。 もちろんこの場合、何も機能しません。



幸い、バックアップオプションとしてFlashバージョンを使用できます。これは、HTML5バージョンと非常によく似ています。 これを行うには、onFallbackイベントを使用します。 ここからダウンロードできるC#クラスでさらに実装されました。 UploadiFiveControlコントロールを使用してこの関数を現在のコードに追加すると、次のようになります。



 // Create the upload control and add to the form UploadiFiveControl uploadControl = new UploadiFiveControl { UploadPath = savepath, RemoveCompleted = true, Version = UploadiFive_Version_Enum.HTML5, RevertToFlashVersion = true, NoHtml5OrFlashMessage = "Please try a more current browser" };
      
      





以下のコードでは、RevertToFlashVersionプロパティをtrueに設定して、Flashのフォールバックバージョンを追加するようクラスに指示します。 ブラウザがHTML5またはFlashをサポートしていない場合、NoHtml5OrFlashMessageプロパティを使用して警告ウィンドウを表示できます。



上記の例は、aspxページのHTMLコードに含まれる次のJavaScriptコードを生成します。



 <script type="text/javascript"> $(document).ready(function() { $('#file_upload').uploadifive({ 'fileObjName': 'Filedata', 'formData': { 'token' : 'f8916a9f-9dda-441f-a58b-13948e61f7e7' }, 'removeCompleted': true, 'uploadScript': 'UploadiFiveFileHandler.ashx', 'onFallback': function() { // Revert to flash version if no HTML5 $('#file_upload').uploadify({ 'fileObjName': 'Filedata', 'formData': { 'token' : 'f8916a9f-9dda-441f-a58b-13948e61f7e7' }, 'removeCompleted': true, 'swf': 'uploadify/uploadify.swf', 'uploader': 'UploadiFiveFileHandler.ashx', 'onFallback': function() { alert('Please try a more current browser'); } }); } }); }); </script>
      
      





これで、古いブラウザの作業用バックアップができました。これはメインバージョンとほぼ同じです。 バックアップメカニズムを有効にするには、Flashバージョンが必要ですが、私の例のように、セカンダリオプションとしてのみです。 もちろん、両方のバージョンをダウンロードし、headタグ内の対応するCSSファイルとJSファイルをリンクする必要があります。



コードへのリンク:



すべてのコードと4つのaspxデモページは、ここからダウンロードできます。



All Articles