12

I'm trying to upload a file using Ajax.BeginForm(), but it's not working out.

My view contains:

@using (Ajax.BeginForm("UploadFile", null, new AjaxOptions { HttpMethod="POST",     UpdateTargetId = "result" }, new { enctype = "multipart/form-data" }))
{
   <label id="lblUploadNewFile" for="fileUploadControl">Upload New File&lt;/label>
   <input type="file" name="fileToUpload" id="fileUploadControl"/>
   <input id="btnFileUpload" type="submit" value="Upload" />
   <span id="result" />
}

and the corresponding Controller is:

[HttpPost]
public string UploadFile(FormCollection formData)
{
   HttpPostedFileBase file=null;

   try
   {
      file = Request.Files[0];
   }
   catch { }

   if ( file!=null &amp;&amp; file.ContentLength &gt; 0)
   {
      file.SaveAs(string.Concat(
            AppDomain.CurrentDomain.BaseDirectory,
            Path.GetFileName(file.FileName)));

      return &quot;Successfully Uploaded&quot;;
   }
   else
   {
      return &quot;Upload Failed, please try again.&quot;;
   }
}

The problem is that it's uploading the file, but no longer doing any asynchronous posts when I remove jquery.unobtrusive-ajax.js. Instead, it does a full post-back.

When I add jquery.unobtrusive-ajax.js in my view, it's doing it asynchronously, but it is not sending an upload file in the form data. No file is being sent to the server in Request.Files[].

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sunny Sharma
  • 4,688
  • 5
  • 35
  • 73
  • 1
    It's not possible with Ajax for obvious reasons: you could build a page hat uploads any accessible file on the visitors filesystem to the server without telling him. – Rob Jun 11 '13 at 06:57

4 Answers4

17

You cannot upload files using AJAX. This is not supported. If you want to do that you could either use some file upload plugin such as Uploadify or Blueimp File Upload or use the HTML 5 File API if the client browser supports it.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • thanks Darin for your reply, I'll try implementing Blueimp as Uploadify requires flash. – Sunny Sharma Jun 11 '13 at 07:13
  • I'm using jQuery-asyncUpload shared by steven: http://blog.stevensanderson.com/2008/11/24/jquery-ajax-uploader-plugin-with-progress-bar/ – Sunny Sharma Jul 24 '13 at 07:31
  • @Darin Dimitrov, I don't understand your answer. As per [this other StackOverflow question](http://stackoverflow.com/questions/19042116/ajax-beginform-in-mvc-to-upload-files), file uploading is actually supported and the way to do it is given in that other answer. Can you please clear what you say up? – Iago Rodríguez Nov 29 '14 at 20:03
  • @Darin Dimitrov Yes, could you please clarify us a little bit more regarding to this issue? – Murat Yıldız Jun 18 '15 at 08:41
10

You can do this without additional libraries.

I came across this little hack, which resolves it nicely

window.addEventListener("submit", function (e) {
    var form = e.target;
    if (form.getAttribute("enctype") === "multipart/form-data") {
        if (form.dataset.ajax) {
            e.preventDefault();
            e.stopImmediatePropagation();
            var xhr = new XMLHttpRequest();
            xhr.open(form.method, form.action);
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    if (form.dataset.ajaxUpdate) {
                        var updateTarget = document.querySelector(form.dataset.ajaxUpdate);
                        if (updateTarget) {
                            updateTarget.innerHTML = xhr.responseText;
                        } 
                    }
                }
            };
            xhr.send(new FormData(form));
        }
    }
}, true);

Found http://www.acnenomor.com/1762557p1/c-mvc3-ajaxbeginform-to-upload-file-not-working

  • 1
    `http://www.acnenomor.com/1762557p1/c-mvc3-ajaxbeginform-to-upload-file-not-working` is no more; it was a scraper site copying Stack Overflow, you really found [this post](https://stackoverflow.com/questions/14972470/c-sharp-mvc3-ajax-beginform-to-upload-file-not-working). – Martijn Pieters May 05 '15 at 21:32
  • 2
    whoever you are I'll find you and love you! – Nomi Ali Mar 07 '16 at 12:02
  • But how to implement the call back for the form ?? – Aswin Arshad Aug 16 '17 at 01:59
0

You can do this to get this work: get jquery.form library from nuget and import it to your cshtml file.You should create your form with @Html.BeginForm. then bottom of your form write this script to ajax-ify your form:

$(function(){
  $('#formId').ajaxForm({
    complete:function(xhr){...},
    success:function(){...},
    error: function(){...}
  });
});

With these steps you can pass a file to controller.

0

very simple solution:

  @using (Ajax.BeginForm("action", "controller", new AjaxOptions
        {
            HttpMethod = "post",
            InsertionMode = InsertionMode.Replace,
            OnBegin = "startLoader",
            OnSuccess = "Update_Record",
            UpdateTargetId = "Succ_Msg"
        },new { enctype = "multipart/form-data" }))

notice the new { enctype = "multipart/form-data" } which tells the razor page to add the enctype that can pass HttpPostedFileBase

good luck:).

bradrn
  • 8,337
  • 2
  • 22
  • 51
  • hey @tzuk, that's exactly what I've posted in question! – Sunny Sharma May 21 '19 at 08:54
  • Does this technique require a particular version of .net framework? When I add `, new { enctype = "multipart/form-data" }` to an existing Ajax.BeginForm that has AjaxOptions, then the action loses resolution. As if it's illegal. Using Rider, if it makes a difference, and .net framework v4.7.2. – Craig Sep 29 '22 at 15:31