如何使用 ajax 上传文件到 asp.net mvc 控制器操作
How to upload files using ajax to asp.net mvc controller action
我有这个提交代码,
$('#form').on('submit',function (e) {
e.preventDefault();
//var file = $("#productImg");
var fileUpload = $("#productImg").get(0);
var files = fileUpload.files;
var form = $("#form");
var formData = new FormData();
formData.append("product", form.serialize());
// Looping over all files and add it to FormData object
for (var i = 0; i < files.length; i++) {
formData.append(files[i].name, files[i]);
}
//formData.append("file", file);
$.ajax({
type: 'POST',
url: baseUrl + 'Controller/Action',
data: formData,
processData: false,
contentType: false,
success: function (data) {
}
});
});
这是我的控制器:
public JsonResult AddProduct(ProductModel product) // data is binded in the model if I remove content type property
{
var isSuccess = false;
if (product != null)
{
try
{
if (Request.Files.Count > 0) // works ok if I added the content type property
{
var sadas = "sad";
}
所以这里发生的是我将 serialized form
数据与上传的文件一起发送到 mvc 控制器。
这里的问题是,当我添加这个ajax 属性 contentType: false,
时,我可以成功回发文件,但是绑定的模型是空的。
另一方面,如果我删除这个 属性,绑定模型工作正常。但是问题是服务器没有发送文件。
我怎样才能完成这项工作?我希望在服务器端发送表单和图像。
更新
现在可以用了,我唯一改变的是这个
formData.append("product", form.serialize());
至
var other_data = $('#addProductForm').serializeArray();
$.each(other_data, function (key, input) {
formData.append(input.name, input.value);
});
有人可以解释一下发生了什么吗?我不知道
不幸的是,jQuery serialize()
方法将不包含输入文件元素。所以您的文件不会包含在序列化值中。
您可以做的是,创建一个 FormData
对象,将文件附加到该对象。您还需要将表单字段值附加到同一个 FormData 对象。您可以简单地遍历所有输入字段并添加它。
当您将文件添加到表单数据时,您需要提供一个与您将在 HttpPost 操作方法中使用的参数相匹配的名称。
这应该有效。
var fileUpload = $("#productImg").get(0);
var files = fileUpload.files;
var formData = new FormData();
// 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('productImg', files[i]);
}
// You can update the jquery selector to use a css class if you want
$("input[type='text'").each(function (x, y) {
formData.append($(y).attr("name"), $(y).val());
});
$.ajax({
type: 'POST',
url: 'ReplaceHereYourUrltotheActionMethod',
data: formData,
processData: false,
contentType: false,
success: function (data) {
}
});
和你的action方法,你可以添加另一个类型为IEnumerable<HttpPostedFileBase>
的参数,其名称与我们为表单数据设置的名称相同,即productImg
。
[HttpPost]
public virtual ActionResult Index(ProductModel model,
IEnumerable<HttpPostedFileBase> productImg)
{
// to do :Look through productImg and do something
}
对于 ASP.NET Core,您可以从您的模型开始:
public class FilesViewModel
{
public Guid? ParentObjectId { get; set; } // if you wish to associate these files with some parent record
public IEnumerable<IFormFile> Files { get; set; }
}
您的控制器:
[HttpPost]
public JsonResult UploadFiles(FilesViewModel model)
{
if (ModelState.IsValid)
{
// your code here
// see https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads
}
}
您的视图(或视图组件):
@model YourProject.ViewModels.EventFilesViewModel
<form method="post" enctype="multipart/form-data">
<input type="hidden" asp-for="ParentObjectId" />
<input type="file" asp-for="Files" multiple />
<span asp-validation-for="Files" class="text-danger"></span>
<input type="button" id="btnEventFilesUpload" value="Upload Selected Files" class="btn btn-default" />
</form>
最后,javascript(根据 Shyju 的回答修改以传递 ParentObjectId):
$(function () {
$("#btnEventFilesUpload").click(function (evt) {
var fileUpload = $("#Files").get(0);
var files = fileUpload.files;
var data = new FormData();
for (var i = 0; i < files.length; i++) {
data.append('Files', files[i]);
}
// if you wish to associate these files with some parent record
data.append('ParentObjectId', $('#ParentObjectId').val());
$.ajax({
type: "POST",
url: "/Event/UploadFiles",
contentType: false,
processData: false,
data: data,
success: function (message) {
alert(message);
},
error: function () {
alert("There was error uploading files!");
}
});
});
});
我有这个提交代码,
$('#form').on('submit',function (e) {
e.preventDefault();
//var file = $("#productImg");
var fileUpload = $("#productImg").get(0);
var files = fileUpload.files;
var form = $("#form");
var formData = new FormData();
formData.append("product", form.serialize());
// Looping over all files and add it to FormData object
for (var i = 0; i < files.length; i++) {
formData.append(files[i].name, files[i]);
}
//formData.append("file", file);
$.ajax({
type: 'POST',
url: baseUrl + 'Controller/Action',
data: formData,
processData: false,
contentType: false,
success: function (data) {
}
});
});
这是我的控制器:
public JsonResult AddProduct(ProductModel product) // data is binded in the model if I remove content type property
{
var isSuccess = false;
if (product != null)
{
try
{
if (Request.Files.Count > 0) // works ok if I added the content type property
{
var sadas = "sad";
}
所以这里发生的是我将 serialized form
数据与上传的文件一起发送到 mvc 控制器。
这里的问题是,当我添加这个ajax 属性 contentType: false,
时,我可以成功回发文件,但是绑定的模型是空的。
另一方面,如果我删除这个 属性,绑定模型工作正常。但是问题是服务器没有发送文件。
我怎样才能完成这项工作?我希望在服务器端发送表单和图像。
更新 现在可以用了,我唯一改变的是这个
formData.append("product", form.serialize());
至
var other_data = $('#addProductForm').serializeArray();
$.each(other_data, function (key, input) {
formData.append(input.name, input.value);
});
有人可以解释一下发生了什么吗?我不知道
不幸的是,jQuery serialize()
方法将不包含输入文件元素。所以您的文件不会包含在序列化值中。
您可以做的是,创建一个 FormData
对象,将文件附加到该对象。您还需要将表单字段值附加到同一个 FormData 对象。您可以简单地遍历所有输入字段并添加它。
当您将文件添加到表单数据时,您需要提供一个与您将在 HttpPost 操作方法中使用的参数相匹配的名称。
这应该有效。
var fileUpload = $("#productImg").get(0);
var files = fileUpload.files;
var formData = new FormData();
// 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('productImg', files[i]);
}
// You can update the jquery selector to use a css class if you want
$("input[type='text'").each(function (x, y) {
formData.append($(y).attr("name"), $(y).val());
});
$.ajax({
type: 'POST',
url: 'ReplaceHereYourUrltotheActionMethod',
data: formData,
processData: false,
contentType: false,
success: function (data) {
}
});
和你的action方法,你可以添加另一个类型为IEnumerable<HttpPostedFileBase>
的参数,其名称与我们为表单数据设置的名称相同,即productImg
。
[HttpPost]
public virtual ActionResult Index(ProductModel model,
IEnumerable<HttpPostedFileBase> productImg)
{
// to do :Look through productImg and do something
}
对于 ASP.NET Core,您可以从您的模型开始:
public class FilesViewModel
{
public Guid? ParentObjectId { get; set; } // if you wish to associate these files with some parent record
public IEnumerable<IFormFile> Files { get; set; }
}
您的控制器:
[HttpPost]
public JsonResult UploadFiles(FilesViewModel model)
{
if (ModelState.IsValid)
{
// your code here
// see https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads
}
}
您的视图(或视图组件):
@model YourProject.ViewModels.EventFilesViewModel
<form method="post" enctype="multipart/form-data">
<input type="hidden" asp-for="ParentObjectId" />
<input type="file" asp-for="Files" multiple />
<span asp-validation-for="Files" class="text-danger"></span>
<input type="button" id="btnEventFilesUpload" value="Upload Selected Files" class="btn btn-default" />
</form>
最后,javascript(根据 Shyju 的回答修改以传递 ParentObjectId):
$(function () {
$("#btnEventFilesUpload").click(function (evt) {
var fileUpload = $("#Files").get(0);
var files = fileUpload.files;
var data = new FormData();
for (var i = 0; i < files.length; i++) {
data.append('Files', files[i]);
}
// if you wish to associate these files with some parent record
data.append('ParentObjectId', $('#ParentObjectId').val());
$.ajax({
type: "POST",
url: "/Event/UploadFiles",
contentType: false,
processData: false,
data: data,
success: function (message) {
alert(message);
},
error: function () {
alert("There was error uploading files!");
}
});
});
});