如何在MVC 5中的单个Ajax POST请求中发送ViewModel和文件?

如何在MVC 5中的单个Ajax POST请求中发送ViewModel和文件?

问题描述:

我有一个ASP.NET MVC 5应用程序。我试图用模型数据发送POST请求,并且还包括用户选择的文件。 这是我的视图模型(为了清楚而简化):如何在MVC 5中的单个Ajax POST请求中发送ViewModel和文件?

public class Model 
{ 
    public string Text { get; set; } 
    public long Id { get; set; } 
} 

这里是控制器的操作:

[HttpPost] 
public ActionResult UploadFile(long userId, Model model) 
{ 
    foreach (string file in Request.Files) 
    { 
     // process files 
    } 

    return View("Index"); 
} 

HTML输入元件:

<div> 
    <input type="file" name="UploadFile" id="txtUploadFile" /> 
</div> 

和JavaScript代码:

$('#txtUploadFile').on('change', function (e) { 
    var data = new FormData(); 
    for (var x = 0; x < files.length; x++) { 
     data.append("file" + x, files[x]); 
    } 
    data.append("userId", 1); 
    data.append("model", JSON.stringify({ Text: 'test text', Id: 3 })); 

    $.ajax({ 
     type: "POST", 
     url: '/Home/UploadFile', 
     contentType: false, 
     processData: false, 
     data: data, 
     success: function (result) { }, 
     error: function (xhr, status, p3, p4) { } 
    }); 
}); 

问题是,当请求达到控制器操作时,我填充了文件和'userId',但'模型'参数始终为空。填充FormData对象时我做错了什么?

+1

W¯¯什么ith contentType:“application/json”它不会发送文件。 –

+1

参考[这个答案](http://*.com/questions/29293637/how-to-append-whole-set-of-model-to-formdata-and-obtain-it-in-mvc/29293681#29293681 ) - 而不是'data.append(“model”,JSON.stringify({Text:'test text',Id:3}));'它应该是'data.append(Text,'test text'); data.append(Id,3);' –

+0

谢谢,现在我看到了FormData的问题! –

这里是我的测试使用与MVC5和IE11 /铬

查看

<script> 
    $(function() { 
     $("#form1").submit(function() { 
      /*You can also inject values to suitable named hidden fields*/ 
      /*You can also inject the whole hidden filed to form dynamically*/ 
      $('#name2').val(Date); 
      var formData = new FormData($(this)[0]); 
      $.ajax({ 
       url: $(this).attr('action'), 
       type: $(this).attr('method'), 
       data: formData, 
       async: false, 
       success: function (data) { 
        alert(data) 
       }, 
       error: function(){ 
        alert('error'); 
       }, 
       cache: false, 
       contentType: false, 
       processData: false 
      }); 
      return false; 
     }); 
    }); 
</script> 

<form id="form1" action="/Home/Index" method="post" enctype="multipart/form-data"> 
    <input type="text" id="name1" name="name1" value="value1" /> 
    <input type="hidden" id ="name2" name="name2" value="" /> 
    <input name="file1" type="file" /> 
    <input type="submit" value="Sublit" /> 
</form> 

控制器

public class HomeController : Controller 
{ 
    [HttpGet] 
    public ActionResult Index() 
    { 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Index(HttpPostedFileBase file1, string name1, string name2) 
    { 
     var result = new List<string>(); 
     if (file1 != null) 
      result.Add(string.Format("{0}: {1} bytes", file1.FileName, file1.ContentLength)); 
     else 
      result.Add("No file"); 
     result.Add(string.Format("name1: {0}", name1)); 
     result.Add(string.Format("name2: {0}", name2)); 
     return Content(string.Join(" - ", result.ToArray())); 
    } 
} 

感谢Silver89他answer

+0

问题是我没有窗体上的所有必填字段,因此模型是在发送POST请求之前使用JS代码构建的。 –

+0

@IgorGoroshko我认为有很多方法可以解决这个问题,您可以测试的方法是将您的值注入合适的命名隐藏字段中。 –

+0

@IgorGoroshko已更新为在隐藏字段中注入值。 –