使用ajax发布视图模型,其中包含MVC Core中的IFormFile属性

我正在尝试使用jquery AJAXpost在MVC核心中发布一个简单的viewmodel,但IFormFile属性似乎在模型上为null。

我有以下视图模型:

[Required] public IFormFile File { get; set; } [Required] [Display(Name = "Owner")] public int DocumentOwner { get; set; } [Required] [Display(Name = "Document Type")] public int DocumentTypeId { get; set; } 

然后我在我视图底部的脚本中使用jQuery ajaxpost:

 $("form").submit(function (e) { e.preventDefault(); var model = $('form').serialize(); $.ajax({ type: "POST", url: "/Client/AddDocument", contentType: false, processData: false, data: model, success: function (message) { alert(message); }, error: function () { alert("There was error uploading files!"); } }); }); 

viewmodel已成功将其他值传递给控制器​​,但该文件将作为null传递。

有人能帮忙吗?

不幸的是,jQuery serialize()方法将不包含输入文件元素。 因此,所选的文件用户不会包含在序列化值中。

你可能会做的是,创建一个FormData对象,将文件附加到该对象。 您还需要将表单字段值附加到此相同的FormData对象。 您可以简单地遍历所有输入字段并添加它。 此外,在ajax调用中,您需要将processDatacontentType属性值指定为false

这应该工作

 $(function () { $("form").submit(function (e) { e.preventDefault(); var formAction = $(this).attr("action"); var fdata = new FormData(); var fileInput = $('#File')[0]; var file = fileInput.files[0]; fdata.append("File", file); // You can update the jquery selector to use a css class if you want $("input[type='text'").each(function (x, y) { fdata.append($(y).attr("name"), $(y).val()); }); $.ajax({ type: 'post', url: formAction , data: fdata, processData: false, contentType: false }).done(function(result) { // do something with the result now console.log(result); }); }); }); 

上面的代码是从表单(已提交)中读取action属性,并将其用作ajax表单提交的url。

 @model YourViewModel 

在HttpPost操作方法中,您可以使用与参数相同的视图模型。 下面的示例代码读取File属性并将其保存到wwwroot目录中的uploads目录中。

 public class HomeController : Controller { private readonly IHostingEnvironment hostingEnvironment; public HomeController(IHostingEnvironment environment) { hostingEnvironment = environment; } [HttpPost] public IActionResult Index(YourViewModel vm) { if (ModelState.IsValid) { if (vm.File != null) { var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads"); var filePath = Path.Combine(uploads, GetUniqueFileName(vm.File.FileName)); vm.File.CopyTo(new FileStream(filePath, FileMode.Create)); return Json(new {status = "success", message = "Successfully saved"}); } } else { // handle what to do when model validation fails } return Json(new {status = "error", message = "something wrong!"}); } private string GetUniqueFileName(string fileName) { fileName = Path.GetFileName(fileName); return Path.GetFileNameWithoutExtension(fileName) + "_" + Guid.NewGuid().ToString().Substring(0, 4) + Path.GetExtension(fileName); } }