前提・実現したいこと
javascriptのnew formData()を利用して、コントローラーへファイルデータを渡す方法について、うまくいかなくて困っています。
「画像ファイルのドラッグアンドドロップまたはダブルクリックしてファイル選択」
を行うjavascriptを作成しています。
javascript ES5 クラス形式で作成しているため、jqueryは使用しない前提です。
Google Chromeでは問題なく動作したのですが、Internet Explorer 11に対応できるように変更しようとしています。
サーバー側はASP.NET MVC5(C#)を使用しています。
ご教授お願いします。
発生している問題
・画像ファイルのドラッグアンドドロップについて
Internet Explorer 11では、drop時にevent.dataTransfer.filesから、input fileのfilelistに追加ができないので、代替方法として、formData.appendで、filesをappendしたいのですが、うまくいかなくて困っています。
filelistは取得できていますが、xmlHttpRequest送信時にコントローラーは実行されるが、filesはnullになっています。
input fileのnameはControllerの引数名に合わせないと実行できないため、filesとしています。
new FormData(this._form)をしている理由は、追加のパラメータをHTMLファイルにinputタグで直接記載して利用したいためです。
javascript
1 2var formData = new FormData(this._form); 3formData.append("files", files); 4 5var xhr = new XMLHttpRequest(); 6xhr.open("POST", uploadUrl, true); 7xhr.send(formData); 8
該当のソースコード
・index.cshtml
html
1<div class="row"> 2 <div class="col col-md-6"> 3 @using (Html.BeginForm("Upload", "Test", FormMethod.Post, new { @class = "imagedrop", @id = "imagedrop", name = "imagedrop", enctype = "multipart/form-data" })) { 4 @Html.AntiForgeryToken() 5 @Html.Editor("addId", new { htmlAttributes = new { @id = "addId", name = "addId", style = "display: none" } }) 6 <!-- その他のコードはjavascriptで動的に生成 --> 7 } 8 </div> 9</div> 10 11@section Scripts { 12 <script> 13 var imagedrop = new Imagedrop(); 14 </script> 15}
・TestController.cs
C#
1[HttpPost] 2[ValidateAntiForgeryToken] 3public ActionResult Upload(HttpPostedFileBase[] files, long addId) { 4 var test1 = files; // filesのみnullになる 5 var test2 = addId; // addIdは問題なし 6}
・index.js
javascript
1// 画像ファイルをドラッグ&ドロップ、またはダブルクリックして選択 を行うコード 2// jqueryを使用しないコードで記述してます。 3// 説明用の必要最低限のため、細かな動作のコード、ファイルチェック等は省略しています。 4var Imagedrop = (function () { 5 var Imagedrop = function () { 6 this.init(); 7 } 8 9 Imagedrop.prototype.init = function () { 10 var form = document.getElementById("Imagedrop"); 11 var dragAndDropArea = document.getElementById("dragAndDropArea"); 12 13 var template = "\n" + 14 "<div class=\"drag-and-drop-area\" id=\"dragAndDropArea\">\n" + 15 " <input type=\"file\" id=\"files\" name=\"files\" accept=\"image/jpeg\" style=\"display: none\" />\n" + 16 " <div class=\"default-message\" id=\"defaultMessage\">\n" + 17 " <p>ここに画像ファイルをドラッグ&ドロップ、またはダブルクリックして選択</p>\n" + 18 " <p>(.jpgファイル、1MBまで)</p>\n" + 19 " </div>\n" + 20 " <div class=\"preview-image\" id=\"previewImage\" style=\"display: none\"></div>\n" + 21 " <div class=\"preview-filename\" id=\"previewFileName\" style=\"display: none\"></div>\n" + 22 "</div>\n"; 23 24 dragAndDropArea ? dragAndDropArea.parentNode.removeChild(dragAndDropArea) : null; 25 form.insertAdjacentHTML("afterbegin", template); 26 27 var _self = this; 28 29 this._form = document.getElementById("Imagedrop"); 30 this._dragAndDropArea = document.getElementById("dragAndDropArea"); 31 this._inputFile = document.getElementById("files"); 32 this._defaultMessage = document.getElementById("defaultMessage"); 33 this._previewImage = document.getElementById("previewImage"); 34 this._previewFileName = document.getElementById("previewFileName"); 35 this._files = null; 36 37 this._dragAndDropArea.addEventListener("dragenter", function (event) { 38 event.stopPropagation(); 39 event.preventDefault(); 40 }); 41 42 this._dragAndDropArea.addEventListener("dragover", function (event) { 43 event.stopPropagation(); 44 event.preventDefault(); 45 }); 46 47 this._dragAndDropArea.addEventListener("drop", function (event) { 48 event.stopPropagation(); 49 event.preventDefault(); 50 51 // Google Chromeの方法。Internet Explorer 11はinput fileには追加できない 52 // _self._inputFile.files = event.dataTransfer.files; 53 54 // 代替案 55 _self._files = event.dataTransfer.files; 56 _self.upload(true); 57 }); 58 59 this._dragAndDropArea.addEventListener("dblclick", function (event) { 60 _self._inputFile.click(); 61 }); 62 63 this._inputFile.addEventListener("change", function (event) { 64 _self._files = _self._inputFile.files; 65 _self.upload(false); 66 }); 67 } 68 69 Imagedrop.prototype.upload = function (dragAndDropMode) { 70 var _self = this; 71 var uploadUrl = this._form.action; 72 73 // ドラッグアンドドロップの時のみファイル追加処理 74 if (drapAndDropMode) { 75 var files = this._files; 76 this._inputFile.parentNode.removeChild(this._inputFile); 77 78 var formData = new FormData(this._form); 79 formData.append("files", files); // filesにfilelistはある 80 } else { 81 var formData = new FormData(this._form); 82 } 83 84 var xhr = new XMLHttpRequest(); 85 xhr.open("POST", uploadUrl, true); 86 87 // sendはできているが、画像のドラッグアンドドロップではファイルデータを渡せていない 88 xhr.send(formData); 89 xhr.onreadystatechange = function () { 90 if (xhr.readyState === XMLHttpRequest.DONE) { 91 if (xhr.status == 200) { 92 // ファイルの表示処理 93 } 94 95 xhr.abort(); 96 } 97 } 98 } 99 100 return Imagedrop; 101})();
試したこと
上記のjavascriptコード上でのコメント箇所あたりで試行錯誤しています。
### 補足情報(FW/ツールのバージョンなど) .NET Framework 4.7.1 Visual Studio Express 2012 for Web ASP.NET MVC5(C#)
回答1件
あなたの回答
tips
プレビュー