Le téléchargement de fichier via ajax n'ajoute pas de fichier dans la requête dans MVC

J'ai un formulaire simple qui contient une entrée de type fichier qui n'accepte que des images. Je souhaite juste publier le fichier dans le tableau ainsi que sur le serveur.

Voici mon 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>&nbsp; <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> } 

C'est ma partie jj 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; } }); } 

C'est ma partie contrôleur

 [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!" }); } 

Lorsque je débogue et vérifie le formulaire Request.Files.Count, il sera toujours nul. Existe-t-il une solution de rechange ou est-ce que je fais des erreurs dans l'affichage du fichier? J'ai suivi ce lien et j'ai apporté des modifications en fonction de mes besoins.

Au lieu de:

 $.each($(fileInput).get(0).files, function (index, value) { formdata.append($(this).attr('name'), $(this)); }); 

Vous pourriez utiliser:

 $.each($(fileInput).get(0).files, function (index, value) { formdata.append(value.name, value); }); 

La différence principale est que, dans votre approche, la partie Contenu-Disposition ne contient pas de filename et, par conséquent, ASP.NET ne le reconnaît pas comme un contenu de fichier:

 ------WebKitFormBoundaryZxwCwBC0O8Q3hOAO Content-Disposition: form-data; name="foo.png" [object Object] ------WebKitFormBoundaryZxwCwBC0O8Q3hOAO Content-Disposition: form-data; name="bar.png" [object Object] ------WebKitFormBoundaryZxwCwBC0O8Q3hOAO-- 

Et avec mon approche, la demande ressemblera à ceci:

 ------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-- 

Maintenant, vous pouvez voir la différence réelle. Dans le premier cas, vous n'avez pas de filename ni Content-Type des fichiers et ASP.NET ne traite ces éléments que sous forme de données standard et ne sont pas des fichiers.

Aussi, au lieu d'utiliser le nom de fichier réel comme name vous pouvez envisager de le remplacer par un générique:

 $.each($(fileInput).get(0).files, function (index, value) { formdata.append('sliderFiles', value); }); 

Maintenant, vous pouvez améliorer encore votre action de contrôleur en le faisant prendre un paramètre de List<HttpPostedFileBase> au lieu d'utiliser Request.Files :

 [HttpPost] public ActionResult UploadSlider(List<HttpPostedFileBase> sliderFiles) { ... } 

Une autre remarque à propos de votre code est que HTML5 FormData n'est pas disponible pour les navigateurs et votre code échouera silencieusement. Si vous devez prendre en charge les navigateurs plus anciens, vous devrez effectuer une amélioration progressive en testant les capacités du navigateur et en revenant à un formulaire standard POST si le navigateur ne prend pas en charge 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(); ... } });