【发布时间】:2017-11-17 06:41:20
【问题描述】:
我正在尝试上传将从我的站点发送的电子邮件的附件。我正在使用指定了多个关键字的文件类型的输入标记,并使用 ajax 将文件和其他模型属性发送回控制器。
但是,一旦到达控制器,所有模型属性都会被绑定,但包含文件的属性除外。
当使用提琴手检查请求时,上传的文件存在,并且它们也存在于控制器上的 Request.Files 集合中。
我的文件应该使用这种方法自动绑定到模型,还是我必须编写一个自定义绑定器来完成这个?
[不相关的代码已被删除]
这是应该包含文件的对象
public class Attachment
{
public IEnumerable<HttpPostedFileBase> Files { get; set; }
public Attachment()
{
Files = new List<HttpPostedFileBase>();
}
}
这是包含附件和其他模型属性的对象
public class QuoteRequest
{
public Attachment Attachment { get; set; }
public QuoteRequest()
{
Attachment = new Attachment();
}
}
用户将用于上传的视图具有以下形式
@using (Html.BeginForm("Index", "Quote", FormMethod.Post, new { required = "true", id = "frm-quote", enctype = "multipart/form-data" })) {
@Html.AntiForgeryToken()
@Html.EditorFor(model => model.Contact, "ContactForm")
@Html.EditorFor(model => model.Enquiry, "EnquiryForm")
@Html.EditorFor(model => model.Attachment, "AttachmentForm")
<div class="row">
<div class="col l10 offset-l2 m6 s12 add-pad-bot center">
<button class="col s12 btn waves-effect orange" type="reset" data-test-clear>CLEAR</button>
</div>
<div class="col l10 offset-l2 m6 s12 center">
<button class="col s12 btn waves-effect waves-green green" type="button" data-test-submit>SUBMIT</button>
</div>
</div> }
这是处理文件输入标签的部分视图
@using Domain.Models
@model Attachment
<section id="attachment" class="row no-mar-bot">
<div class="file-field input-field col s12">
<div class="btn primary">
<span id="icon-attachment">
<i class="medium material-icons">note_add</i>
</span>
@Html.TextBoxFor(m => m.Files, new {type = "file", multiple =
"multiple"})
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text" placeholder="Upload one or more files">
</div>
</div>
</section>
获取表单输入以发布到控制器的 javascript 函数
function getFormData() {
var formData;
formData = new FormData();
var fileUpload = $("#Attachment_Files").get(0);
var files = fileUpload.files;
if (files) {
// Looping over all files and add it to FormData object
for (var i = 0; i < files.length; i++) {
console.log("files[i].name:" + files[i].name);
formData.append(files[i].name, files[i]);
}
}
// You can update the jquery selector to use a css class if you want
$("input:not([type='file']), textarea").each(function (x, y) {
formData.append($(y).attr("name"), $(y).val());
});
return formData; }
ajax 帖子的代码
$.ajax({
url: "/quote",
method: "POST",
cache: false,
contentType: false,
processData: false,
data: getFormData()
headers: {
'__RequestVerificationToken':
$("input[name='__RequestVerificationToken']").val()
}
})
.fail(function(jqXHR, textStatus) { })
.done(function(data) { });
这是接收帖子的控制器操作方法
[HttpPost]
[ValidateAntiForgeryHeader]
[Route("")]
public ActionResult Index(QuoteRequest model) { }
【问题讨论】:
-
您所需要的只是
data: new FormData($("#frm-quote").get(0)),,它将序列化所有表单控件,包括文件输入和防伪令牌。您的代码未在主视图中显示部分代码,并且您没有带有id="Attachment_Files"的文件输入 -
即使您确实使用
id="Attachment_Files"输入了文件,使用formData.append(files[i].name, files[i]);也永远不会起作用 - 您根据与您的模型无关的文件名添加属性名称 -
感谢 Stephen,添加行“FormData($("#frm-quote").get(0));”为我解决了这个问题。
-
@StephenMuecke 我无法将您的评论标记为答案,因此我已将其添加到下方并归功于您,谢谢一百万!
标签: javascript c# ajax asp.net-mvc-5