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

She*_*ock 2 c# ajax jquery asp.net-mvc-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) {
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

这是我的控制器:

  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";
                }
Run Code Online (Sandbox Code Playgroud)

所以这里发生的是我将serialized form数据与上传的文件一起发送到mvc控制器.

这里的问题是,当我添加这个ajax属性时contentType: false,,我可以成功回发文件,但绑定模型为null.

另一方面,如果我删除此属性,绑定模型工作正常.但问题是文件未在服务器中发送.

我怎样才能做到这一点?我希望表单和图像都在服务器端发送.

更新 现在正在运行,我改变的唯一一条就是这个

formData.append("product", form.serialize());

var other_data = $('#addProductForm').serializeArray(); $.each(other_data, function (key, input) { formData.append(input.name, input.value); });

有人可以解释发生了什么吗?我不知道

Shy*_*yju 9

不幸的是,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) {
    }
});
Run Code Online (Sandbox Code Playgroud)

和你的动作方法,你可以添加另一个类型参数,IEnumerable<HttpPostedFileBase>其名称与我们设置的形式数据相同,即productImg.

[HttpPost]
public virtual ActionResult Index(ProductModel model, 
                                               IEnumerable<HttpPostedFileBase> productImg)
{
  // to do :Look through productImg and do something  
}
Run Code Online (Sandbox Code Playgroud)