如何通过HttpPostedFileBase和ViewModel一起发送上传的文件?

我有一个巨大的数据对象,应该通过控制器参数映射到视图模型。 我还有一个文件列表(照片),我需要在上述数据对象的数组中捕获。

我的型号:

public class TestPerson { public int Id { get; set; } public string Name { get; set; } public string Place { get; set; } public int Age { get; set; } public byte[] File { get; set; } //[FileSize(10240)] //[FileTypes("jpg,jpeg,png")] //public HttpPostedFileBase File { get; set; } } 

我的控制器方法:

  public void SavePersonData(HttpPostedFileBase personPhoto, TestPerson person) { var dataObject = Request.Form["person"]; var serializer = new JavaScriptSerializer(); TestPerson personReport = serializer.DeserializeObject(dataObject, typeOf(TestPerson)); System.Console.WriteLine("dummy line"); } 

我的.cshtml页面:

    
Name: Place:
Age:
$(document).ready(function () { $(document).ready(function () { var element = document.getElementById("testKo"); ko.applyBindings(viewModel, element); $("#submitForm").on("click", function () { var vmData = ko.toJSON(viewModel); //$("#personId").val({ person: vmData }); var formData = new FormData($("#photoForm")[0]); formData.append("person", vmData, "person"); //var data = new FormData(); //data.append("vmData", vmData); //data.append("photo", $("#personPhoto").get(0).files[0]) $.ajax({ type: "POST", url: '@Url.Action("SavePersonData", "Home")', //cache: false, //async: false, contentType: false, processData: false, enctype: "multipart/form-data", dataType: "json", //data: { // testPerson: vmData //}, //data: { // personPhoto: formData, // person: vmData //}, data: formData, success: function (data) { alert("success!"); } }); }); }); function generatedViewModel() { var self = this; self.Id = ko.observable("1"); self.Name = ko.observable(); self.Place = ko.observable(); self.Age = ko.observable(); self.File = ko.observable(); } var viewModel = new generatedViewModel(); });

有什么办法可以用我的代码在我的控制器动作方法中接收这两个参数吗? 或者我需要以任何方式调整它吗? 我只需要将包括文件/图像上传数据和非表格数据对象在内的所有内容发送到我的控制器方法。

任何帮助将不胜感激!。

那么,对此最好的解决方案是在另一个内部进行2个同步的ajax调用。 首先发送“personPhoto”数据,然后将其转换为字节数组并将其设置为Session变量,并在此ajax调用的成功事件中,对main方法进行另一个ajax调用,在该方法中处理Form / Model数据并使用“personPhoto”的缓存会话对象。

用以下内容替换您的ajax代码:

  var data = new FormData($("#photoForm").get(0)); $.ajax({ type: "POST", url: '@Url.Action("CacheUploads", "Home")', data: data, processData: false, contentType: false, dataType: "json", success: function () { var vmData = ko.toJS(viewModel); $.ajax({ type: "POST", url: '@Url.Action("SavePersonData", "Home")', data: { person: vmData }, success: function (data) { } }); } }); 

并使用以下内容替换您的控制器方法:

  public void SavePersonData(TestPerson person) { // You no longer need to deserialize as you'll have data properly mapped to the TestPerson object. //var dataObject = Request.Form["person"]; //var serializer = new JavaScriptSerializer(); //object personReport = serializer.DeserializeObject(dataObject); person.File = (byte[])Session["UploadedPhoto"]; System.Console.WriteLine("dummy line"); } public JsonResult CacheUploads(HttpPostedFileBase personPhoto) { byte[] photoAsBytes = null; using (var binaryReader = new BinaryReader(personPhoto.InputStream)) { photoAsBytes = binaryReader.ReadBytes(personPhoto.ContentLength); } Session.Add("UploadedPhoto", photoAsBytes); return Json(new { success = true }, JsonRequestBehavior.AllowGet); } 

没有其他方法可以在单个ajax调用中一起处理FormData和Non-Form ViewModel数据。 这是我从解决方案的角度来看最接近的。 祝好运!。

用这个。

 @using (Html.BeginForm("Action", "Controller", System.Web.Mvc.FormMethod.Post, new { @id = "formid", enctype = "multipart/form-data" })) { @Html.AntiForgeryToken()    }