ASP.NET RC1からASP.NET Core 1.0にプロジェクトを移行しています。
ユーザーが1つ以上のファイルをアップロードできるビューがあり、それをJquery Ajaxを使用して投稿します。また、同じ投稿内でいくつかの設定をシリアル化して投稿します。
以下はすべてRC1(およびpre-asp.netコア)で機能しました。
Js:
$('#submit').click(function () {
var postData = $('#fields :input').serializeArray();
var fileSelect = document.getElementById('file-select');
var files = fileSelect.files;
var data = new FormData();
for (var i = 0; i < files.length; i++) {
data.append('file' + i, files[i]);
}
$.each(postData, function (key, input) {
data.append(input.name, input.value);
});
var url = '/ajax/uploadfile';
$.ajax({
url: url,
type: "POST",
contentType: false,
processData: false,
cache: false,
data: data,
success: function (result) {
alert('success');
},
error: function () {
alert('error');
}
});
});
コントローラ:
public IActionResult UploadFile(UploadFileModel model)
{
var result = new JsonResultData();
try
{
if (Request.Form.Files.Count > 0)
{
IFormFile file = Request.Form.Files[0];
//etc
}
}
}
上記は機能しなくなり、ファイルはアップロードされず、モデルはバインドされません。問題の半分を修正できたので、次のコードでモデルをバインドできます。ただし、コントローラーはRequest.Files
。 'headers'プロパティを追加し、serializeObject
(カスタムメソッド)を使用しました。コントローラにFromBody
を追加しました。
Js:
$('#submit').click(function () {
var postData = $('#fields :input').serializeArray();
var fileSelect = document.getElementById('file-select');
var files = fileSelect.files;
var data = new FormData();
for (var i = 0; i < files.length; i++) {
data.append('file' + i, files[i]);
}
$.each(postData, function (key, input) {
data.append(input.name, input.value);
});
var url = '/ajax/uploadfile';
$.ajax({
url: url,
type: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
processData: false,
cache: false,
data: serializeAndStingifyArray(data),
success: function (result) {
alert('success');
},
error: function () {
alert('error');
}
});
});
function serializeAndStingifyArray(array) {
var o = {};
var a = array;
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].Push) {
o[this.name] = [o[this.name]];
}
o[this.name].Push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return JSON.stringify(o);
};
コントローラ:
[HttpPost]
public IActionResult UploadFile([FromBody]UploadFileModel model)
{
var result = new JsonResultData();
try
{
if (Request.Form.Files.Count > 0)
{
IFormFile file = Request.Form.Files[0];
//etc
}
}
}
html:
<div id="file-list">
<input type="file" name="file" class="file-select" accept="application/pdf,application">
<input type="file" name="file" class="file-select" accept="application/pdf,application" />
</div>
私はあなたのコードとほとんど同じであるいくつかのコードを含むこの記事から始めました ASP.NET Core 1.0でファイルをアップロード (Ajaxのケースを参照)。
1.0.0では問題なく動作したため、変更を実装しましたが、リクエストでファイルを送信できなかった(クライアント側の問題)ことがわかりました。
これは、ChromeでF12を使用して問題なく動作するときのペイロードの外観です(ファイルの内容がChromeによって非表示になっている理由がわかりません)。
少しデバッグして、間違ったデータをdata.append
に渡しています
修正はこの行にあります
$(".file-select").each(function () { data.append($(this).val(), $(this).get(0).files[0]); i++; })
完全なコード:
$(document).ready(function () {
$("#submit").click(function (evt) {
var data = new FormData();
i = 0;
$(".file-select").each(function () { data.append($(this).val(), $(this).get(0).files[0]); i++; })
var postData = $('#fields :input');
$.each(postData, function (key, input) {
data.append(input.name, input.value);
});
$.ajax({
type: "POST",
url: "/ajax/uploadfile", // <--- Double check this url.
contentType: false,
processData: false,
data: data,
success: function (message) {
alert(message);
},
error: function () {
alert("There was error uploading files!");
}
});
});
});
[FromBody]
またはserializeArray()を使用する必要はありません
[HttpPost]
public IActionResult UploadFilesAjax(MyViewModel xxx )
{
これは念のため私のhtmlです:
<form method="post" enctype="multipart/form-data">
<div id="file-list">
<input type="file" name="file" class="file-select" accept="application/pdf,application">
<input type="file" name="file" class="file-select" accept="application/pdf,application" />
</div>
<div id="fields">
<input type="text" name="Email" />
</div>
<input type="button"
id="submit"
value="Upload Selected Files" />
</form>