如何使用ajax上传文件到asp.net mvc控制器操作

问题描述 投票:0回答:3

我有这个提交代码,

$('#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);
});

有人可以解释发生了什么吗?我没有任何线索

c# jquery ajax asp.net-mvc-3
3个回答
10
投票

不幸的是,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  
}

0
投票

对于 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://learn.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!");
            }
        });
    });
});

0
投票

My StudentViewModel like 
```
   public class StudentViewModel{
   public int Id { get; set; }
public IFormFile StudentFile{ get; set; }
}
```
I have Controller Action As
```
public IActionResult UploadFiles(List<StudentViewModel> studentViewModel)
{

}

```
```
$(function () {
    $("#btnEventFilesUpload").click(function (evt) {
        
var formData = new FormData();
for (var j = 0; j < myValues.length; j++) {
var files = document.getElementById('File' + j);
formData.append('studentViewModel[' + j + '].Id', 1);
formData.append('studentViewModel[' + j +'].StudentFile', files[0]);
}
        $.ajax({
            type: "POST",
            url: "/Event/UploadFiles",
            contentType: false,
            processData: false,
            data: formData ,
            success: function (message) {
                alert(message);
            },
            error: function () {
                alert("There was error uploading files!");
            }
        });
    });
});
```

© www.soinside.com 2019 - 2024. All rights reserved.