在ASP.NET Core MVC6中将文件和模型发布到控制器

我正在将项目从ASP.NET RC1迁移到ASP.NET Core 1.0。

我有一个视图,允许用户上传一个或多个文件,我使用Jquery Ajax发布。 我还在同一篇文章中序列化并发布了一些设置。

以下所有都在RC1(和pre-asp.net核心)中工作:

JS:

$('#submit').click(function () { var postData = $('#fields :input').serializeArray(); var fileSelect = document.getElementById('file-select'); var files = fileSelect.files; var data = new FormData(); for (var i = 0; i < files.length; i++) { data.append('file' + i, files[i]); } $.each(postData, function (key, input) { data.append(input.name, input.value); }); var url = '/ajax/uploadfile'; $.ajax({ url: url, type: "POST", contentType: false, processData: false, cache: false, data: data, success: function (result) { alert('success'); }, error: function () { alert('error'); } }); }); 

控制器:

  public IActionResult UploadFile(UploadFileModel model) { var result = new JsonResultData(); try { if (Request.Form.Files.Count > 0) { IFormFile file = Request.Form.Files[0]; //etc } } } 

所以上面不再起作用,没有文件上传,也没有模型绑定 。 我设法修复了一半的问题所以现在我可以让模型与以下代码绑定。 但是,控制器仍然会在Request.Files上给我一个例外。 我添加了’headers’属性,我使用了serializeObject (自定义方法)。 在控制器中我添加了FromBody

JS:

  $('#submit').click(function () { var postData = $('#fields :input').serializeArray(); var fileSelect = document.getElementById('file-select'); var files = fileSelect.files; var data = new FormData(); for (var i = 0; i < files.length; i++) { data.append('file' + i, files[i]); } $.each(postData, function (key, input) { data.append(input.name, input.value); }); var url = '/ajax/uploadfile'; $.ajax({ url: url, type: "POST", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, processData: false, cache: false, data: serializeAndStingifyArray(data), success: function (result) { alert('success'); }, error: function () { alert('error'); } }); }); function serializeAndStingifyArray(array) { var o = {}; var a = array; $.each(a, function () { if (o[this.name] !== undefined) { if (!o[this.name].push) { o[this.name] = [o[this.name]]; } o[this.name].push(this.value || ''); } else { o[this.name] = this.value || ''; } }); return JSON.stringify(o); }; 

控制器:

  [HttpPost] public IActionResult UploadFile([FromBody]UploadFileModel model) { var result = new JsonResultData(); try { if (Request.Form.Files.Count > 0) { IFormFile file = Request.Form.Files[0]; //etc } } } 

HTML:

  

我从这篇文章开始,它有一些与你的代码几乎相同的代码在ASP.NET Core 1.0中上传文件 (参见Ajax案例)。

这在1.0.0上对我很有用,所以我实现了你的更改,我看到的是它未能在请求中发送文件(客户端问题)。

这是在使用chrome中的F12工作正常时有效负载的样子:(不确定为什么文件内容被chrome隐藏)​​。

有效载荷

一点点调试,你将错误的数据传递给data.append

修复就在这一行

  $(".file-select").each(function () { data.append($(this).val(), $(this).get(0).files[0]); i++; }) 

完整代码:

 $(document).ready(function () { $("#submit").click(function (evt) { var data = new FormData(); i = 0; $(".file-select").each(function () { data.append($(this).val(), $(this).get(0).files[0]); i++; }) var postData = $('#fields :input'); $.each(postData, function (key, input) { data.append(input.name, input.value); }); $.ajax({ type: "POST", url: "/ajax/uploadfile", // <--- Double check this url. contentType: false, processData: false, data: data, success: function (message) { alert(message); }, error: function () { alert("There was error uploading files!"); } }); }); }); 

无需使用[FromBody]或serializeArray()

  [HttpPost] public IActionResult UploadFilesAjax(MyViewModel xxx ) { 

这是我的HTML,以防万一: