javascript - 在没有 ajax 调用的情况下使用带有 @HTML.BeginForm 的 formdata append

标签 javascript jquery asp.net asp.net-mvc forms

我想要实现的是将一个文件附加到一个发布请求,该请求是我使用 javascript 从拖放字段中获得的。 问题是,我不想读取所有输入字段并通过 ajax 调用发布数据,我想使用 @HTML.BeginForm 中的默认提交方法。 当我这样做时,multipart 并不真正包含该文件。

(注意:当我只提交文件或当我手动读取所有输入字段并使用单独的 ajax 提交时它有效。)

我的代码: 拖放 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 上工作,所以这对我没有帮助,但也许对其他人有帮助。您不需要追加所有的表单字段,只需将输入类型文件设置为您拖放的文件并提交...

最佳答案

你有几个问题。问题之一是下面的代码。您在代码中遗漏了一个 }

如果你像下面这样写,最后一个值只是存储在 file 中,这是不正确的。

for (var i = 0; i < ev.dataTransfer.files.length; i++) {
        file = ev.dataTransfer.files[i];
} // missing }

如果你像下面这样写,最后一个值只是存储在 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。正如您在 File drag and drop 中看到的那样,最好检查 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);
        }
    }
}

关于javascript - 在没有 ajax 调用的情况下使用带有 @HTML.BeginForm 的 formdata append,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50232105/

相关文章:

php - jquery获取输入类型文本中写入的文本

javascript - 如何评估数组中每个项目包含 settimeout 的函数 (Javascript)

javascript - 当对象中使用的 nodeType() 在 jQuery 版本 '1.11.2' 和 '3.1.1' 中表现不同时

javascript - 具有可点击区域的网页图像,将数据发送到服务器脚本并保留在同一页面上,无需刷新

asp.net - 仅当用户有权查看该页面时,我如何显示链接到该页面的按钮? ASP.NET MVC

javascript - 如何更改 Telerik RadEditor 宽度

ASP.NET/IIS 安全(Windows 身份验证)

javascript - 将另一种 javascript 方法绑定(bind)到 Anchor 标记中的 href

javascript - 我如何在 Javascript 中干净地横向动画?

javascript - 带有数据库的 jQuery Mobile 可折叠项