我有一个简单的表单,其中包含类型文件的输入,该文件仅接受图像。我只想发布文件,将其保存在表以及服务器中。
下面是我的cshtml
@using (Html.BeginForm("UploadSlider", "Admin", FormMethod.Post, new { id = "frmUploadSliderImage", @class = "form-admin" })) { <h2 class="form-login-heading">upload images</h2> <div class="login-wrap"> <span class="btn btn-default btn-file"> Browse <input type="file" id="sliderFile" multiple="multiple"> </span> <span class="text-muted" id="filePlaceHolder">No files selected</span> <span class="text-danger"></span> <button class="btn btn-theme btn-block" name="upload" onclick="javascript: ValidateSliderImageandPost('frmUploadSliderImage', this);" id="btnUploadSliderImage" type="submit"><i class="fa fa-upload"></i> UPLOAD</button> </div> }
这是我的js ajax部分
function ValidateSliderImageandPost(form, ctrl) { $("#" + form).on("submit", function (e) { e.preventDefault(); var formContainer = $('#' + form + ' .text-danger'); var formdata = new FormData(); var fileInput = $('#sliderFile'); if ($(fileInput).get(0).files.length == 0) { $('.btn-file :file').parent().siblings().filter(".text-danger").html('Please select a file!'); } if ($(formContainer).text().length == 0) { run_waitMe('Uploading! Please wait...', 'stretch', '.container'); $.each($(fileInput).get(0).files, function (index,value) { formdata.append($(this).attr('name'), $(this)); }); postData('UploadSlider', formdata, '.upslider .status'); if (msg) { $(".container").find('#cont').waitMe('hide'); $("#" + form).find('input[type=text], textarea').val('').removeClass("alert-success"); } else { $(".container").find('#cont').waitMe('hide'); $("#" + form).find('input[type=text], textarea').removeClass("alert-success"); } } $("#" + form).unbind('submit'); return false; }); } function postData(url,data,target) { $.ajax({ url: url, type: "POST", dataType: 'json', data: data, processData: false, contentType:false, success: function (data) { if (data.result) { animateStatus("success", data.message, target); msg = true; } else { animateStatus("fail", data.message, target); msg = false; } }, error: function (data) { animateStatus("fail", data.message, target); msg = false; } }); }
这是我的控制器部分
[HttpPost] public JsonResult UploadSlider() { bool valid = false; bool val = false; if (Request.Files.Count > 0) { valid = true; } else { return Json(new { result = false, message = "Something went wrong! Please try again!" }); } if (valid) { List<string> fil = new List<string>(); foreach (HttpPostedFileBase f in Request.Files) { HttpPostedFileBase file = f; //Uploaded file string fileName = file.FileName; fil.Add("./Images/Galllery/" + fileName); System.IO.Stream fileContent = file.InputStream; file.SaveAs(Server.MapPath("~/Images/Gallery/") + fileName); } using (var context = new MCBConnectionString()) { foreach (string path in fil) { tbl_slider slider = new tbl_slider(); slider.slurl = path; slider.slalt = ""; context.tbl_slider.Add(slider); context.SaveChanges(); val = true; } } if (val) { return Json(new { result = true, message = "Uploaded video successfully." }); } else { return Json(new { result = false, message = "Could not upload video. Please try again!" }); } } return Json(new { result = false, message = "Could not upload video. Please try again!" }); }
当我调试并检查Request.Files.Count时,它将始终为零。是否有其他解决方法,或者我在发布文件时犯了任何错误。我已遵循 此 链接,并根据需要进行了更改。
代替:
$.each($(fileInput).get(0).files, function (index, value) { formdata.append($(this).attr('name'), $(this)); });
您可以使用:
$.each($(fileInput).get(0).files, function (index, value) { formdata.append(value.name, value); });
主要区别在于,使用您的方法,Content-Disposition部分不包含filename,因此ASP.NET无法将其识别为文件内容:
filename
------WebKitFormBoundaryZxwCwBC0O8Q3hOAO Content-Disposition: form-data; name="foo.png" [object Object] ------WebKitFormBoundaryZxwCwBC0O8Q3hOAO Content-Disposition: form-data; name="bar.png" [object Object] ------WebKitFormBoundaryZxwCwBC0O8Q3hOAO--
用我的方法,请求将如下所示:
------WebKitFormBoundary1ERBVX0wzdVczcR0 Content-Disposition: form-data; name="foo.png"; filename="foo.png" Content-Type: imag/png [object Object] ------WebKitFormBoundary1ERBVX0wzdVczcR0 Content-Disposition: form-data; name="bar.png"; filename="bar.png" Content-Type: image/png [object Object] ------WebKitFormBoundary1ERBVX0wzdVczcR0--
现在您可以看到实际的差异。在第一种情况下,您将没有文件filename或Content- Type文件,ASP.NET只会将这些元素视为标准表单发布的数据,而不是文件。
Content- Type
另外,不要使用实际的文件名,name而是可以考虑将其替换为一些通用的文件名:
name
$.each($(fileInput).get(0).files, function (index, value) { formdata.append('sliderFiles', value); });
现在,您可以通过采用List<HttpPostedFileBase>参数而不是使用来进一步改善控制器操作Request.Files:
List<HttpPostedFileBase>
Request.Files
[HttpPost] public ActionResult UploadSlider(List<HttpPostedFileBase> sliderFiles) { ... }
关于您的代码的另一句话是,HTML5 FormData在订购浏览器中不可用,并且您的代码将自动失败。如果您需要支持较旧的浏览器,则可能需要通过测试浏览器的功能来执行渐进式增强,如果浏览器不支持FormData,则退回到标准表格POST:
FormData
$("#" + form).on("submit", function (e) { if(window.FormData === undefined) { // The browser doesn't support uploading files with AJAX // falling back to standard form upload } else { // The browser supports uploading files with AJAX => // we prevent the default form POST and use AJAX instead e.preventDefault(); ... } });