Используйте formdata append с @HTML.BeginForm без вызова ajax
То, что я пытаюсь достичь, - добавить файл в сообщение, которое я получил из поля drag & drop с javascript. Проблема в том, что я не хочу читать все поля ввода и отправлять данные по вызову ajax, я хочу использовать метод отправки по умолчанию из @HTML.BeginForm
. Когда я это делаю, multipart
действительно не содержит файл.
(Внимание: он работает, когда я просто отправлю файл или когда я прочитал все поля ввода вручную и отправлю с помощью отдельного ajax.)
Мой код: Drag & Drop js:
var file;
var isDragged = false;
var formData;
function dropHandler(ev) {
isDragged = true;
ev.preventDefault();
// Use DataTransfer interface to access the file(s)
for (var i = 0; i < ev.dataTransfer.files.length; i++) {
file = ev.dataTransfer.files[i];
formData = new FormData($("#form"));
formData.append("File.PayLoad", file);
formData.append("File.FileMetadataId", $('#File_FileMetadataId').val())
formData.append("File.FileObjectId", $('#File_FileObjectId').val())
}
}
HTML:
@using (Html.BeginForm("Edit", "DocumentTemplates", FormMethod.Post, new { role = "form", enctype = "multipart/form-data", id = "form" }))
{
@Html.AntiForgeryToken()
<div class="row">
<div class="col-xs-4">
@Html.LabelFor(model => model.Language)
</div>
<div class="col-xs-8">
@Html.HiddenFor(model => model.Language) @Html.DisplayFor(model => model.Language)
</div>
</div>
<div class="row">
<div class="col-xs-8">
@Html.TextBoxFor(model => model.File.Payload, new { type = "file", @id = "browseFile", ondrop = "dropHandler(event);", ondragover = "dragOverHandler(event);" })
@Html.ValidationMessageFor(model => model.File.Payload, null, new { @class = "text-danger" }) or Drag & Drop a File.
</div>
</div>
}
Запрос в Fiddler с пустым Имя файла:
-----------------------------7e27b381715d4
Content-Disposition: form-data; name="File.FileMetadataId"
44
-----------------------------7e27b381715d4
Content-Disposition: form-data; name="File.FileObjectId"
44
-----------------------------7e27b381715d4
Content-Disposition: form-data; name="File.Payload"; filename=""
Content-Type: application/octet-stream
-----------------------------7e27b381715d4--
ОБНОВЛЕНИЕ: Я узнал, вы можете перезаписать файлы из ввода файла, но только в Chrome. Так как мне нужно, чтобы он работал над IE 11, это не помогает мне, но, возможно, это помогает кому-то другому. Вам не нужно добавлять все поля формы, но просто установите файл типа ввода в ваш упавший файл и отправьте...
Ответы
Ответ 1
У вас есть несколько проблем. Одна из проблем - это код ниже. Вы пропустили один }
в своем коде.
Если вы поместите его так, как показано ниже, последнее значение просто хранится в file
который является неправильным.
for (var i = 0; i < ev.dataTransfer.files.length; i++) {
file = ev.dataTransfer.files[i];
} // missing }
Если вы поместите его так, как formData
ниже, последнее значение просто хранится в formData
который является неправильным.
function dropHandler(ev) {
isDragged = true;
ev.preventDefault();
// Use DataTransfer interface to access the file(s)
for (var i = 0; i < ev.dataTransfer.files.length; i++) {
file = ev.dataTransfer.files[i];
formData = new FormData($("#form"));
formData.append("File.PayLoad", file);
formData.append("File.FileMetadataId", $('#File_FileMetadataId').val());
formData.append("File.FileObjectId", $('#File_FileObjectId').val());
}
} // missing }
Вторая проблема - ev.dataTransfer.files
. Как вы можете видеть в перетаскивании файла, лучше проверить ev.dataTransfer.items
и иногда у него есть ваши файлы, а ev.dataTransfer.files
пуст.
Наконец, вы можете сделать это следующим образом:
function dropHandler(ev) {
isDragged = true;
ev.preventDefault();
formData = new FormData($("#form"));
if (ev.dataTransfer.items) {
// Use DataTransferItemList interface to access the file(s)
for (var i = 0; i < ev.dataTransfer.items.length; i++) {
// If dropped items aren't files, reject them
if (ev.dataTransfer.items[i].kind === 'file') {
var file = ev.dataTransfer.items[i].getAsFile();
formData.append("File.PayLoad" + i, file);
}
}
} else {
// Use DataTransfer interface to access the file(s)
for (var i = 0; i < ev.dataTransfer.files.length; i++) {
file = ev.dataTransfer.files[i];
formData.append("File.PayLoad" + i, file);
}
}
}