在没有ajax调用的情况下使用带有@HTML.BeginForm的formdata append
Posted
技术标签:
【中文标题】在没有ajax调用的情况下使用带有@HTML.BeginForm的formdata append【英文标题】:Use formdata append with @HTML.BeginForm without ajax call 【发布时间】:2018-10-18 07:35:43 【问题描述】:我想要实现的是将文件附加到我从带有 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 上工作,这对我没有帮助,但也许它可以帮助其他人。您不需要附加所有表单字段,只需将输入类型文件设置为您放置的文件并提交......
【问题讨论】:
您确定 type="file" 存在于生成的 HTML 中吗? 是的,渲染时有一个典型的文件输入框,带有“浏览..”按钮 【参考方案1】:你有几个问题。问题之一是下面的代码。您在代码中遗漏了一个 。
如果你像下面这样写,最后一个值只是存储在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);
【讨论】:
缺少的大括号只在这里,不在我的代码中,对此感到抱歉。该文件也不是问题,因为当我通过 ajax 调用直接提交它而没有其他表单时它可以工作。以上是关于在没有ajax调用的情况下使用带有@HTML.BeginForm的formdata append的主要内容,如果未能解决你的问题,请参考以下文章
Ajax 将带有两个数组的 JSON 对象发送到一个 servlet 并在没有 jQuery 的情况下在 java servlet 中解析
如何将带有附加数据的 FormData 文件发送到 asp.net web api ajax 调用