2

I am trying to upload files using AJAX to ASP.NET. I have this Javascript:

var xhr = new XMLHttpRequest();

for (var i = 0; i < files.length; i++) {
   xhr.open('post', '/File/Upload', true);
   xhr.setRequestHeader("Content-Type", "multipart/form-data");
   var formData = new FormData();
   formData.append("_file", files[i]);
   xhr.send(files[i]);
}

files is an Array()

Then I try to access the post file in C# code, but the value is always null. How can I resolve this issue?

// Method 1, Result: file = null
HttpPostedFileBase file = Request.Files["_file"];

// Method 2, Result: postedFile.Count = 0
HttpFileCollectionBase postedFile = Request.Files;
Elfayer
  • 23
  • 1
  • 1
  • 6

2 Answers2

3

Assuming you have the following form containing the file input field:

<form action="/home/index" method="post" enctype="multipart/form-data" onsubmit="return handleSubmit(this);">
    <input type="file" id="_file" name="_file" multiple="multiple" />
    <button type="submit">OK</button>
</form>

you could try the following function:

function handleSubmit(form) {
    if (!FormData) {
        alert('Sorry, your browser doesn\'t support the File API => falling back to normal form submit');
        return true;
    }

    var fd = new FormData();
    var file = document.getElementById('_file');
    for (var i = 0; i < file.files.length; i++) {
        fd.append('_file', file.files[i]);
    }

    var xhr = new XMLHttpRequest();
    xhr.open(form.method, form.action, true);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            alert(xhr.responseText);
        }
    };
    xhr.send(fd);

    return false;
}

Now on the server you should be able to retrieve the file using Request.Files.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I've seen that : http://stackoverflow.com/questions/6211145/upload-file-with-ajax-xmlhttprequest – Elfayer Oct 04 '12 at 11:56
  • Yeap, this is using the HTML5 File API. – Darin Dimitrov Oct 04 '12 at 11:57
  • What do you mean with File API? You mean the Browse button? – Elfayer Oct 04 '12 at 12:00
  • Sorry, I misread your question. You are already using the File API. I have updated my answer to show an example. – Darin Dimitrov Oct 04 '12 at 12:10
  • I don't know if it change something, but I'm not using HTML for my form. I'm using a sencha form with a filefield to open the browse window and get the files. Here is the filefield doc, see the Live Preview: http://docs.sencha.com/ext-js/4-1/#!/api/Ext.form.field.File – Elfayer Oct 04 '12 at 12:20
  • That's working, but How can I send multiple parameters? I tried : `xhr.send("files = " + formData + "&folderId = " + otherParameter);`, but with that I don't get any of the parametters... – Elfayer Oct 08 '12 at 11:43
  • You just add them to the `FormData` instance: `fd.append('folderId', otherParameter);`. As far as the send call is concerned it should stay unchanged, as shown in my answer: `xhr.send(fd);`. – Darin Dimitrov Oct 08 '12 at 12:15
  • How do I know when a file from the `file` array is uploaded? – Elfayer Oct 16 '12 at 07:30
  • A file is uploaded when the form is submitted, that's why you subscribed to the `onsubmit` event. – Darin Dimitrov Oct 16 '12 at 07:33
0

You can also use jQuery

you have 2 functions
Ajax : http://api.jquery.com/jQuery.ajax/
Load(shortcut, calls ajax) : http://api.jquery.com/load/
Examples : http://www.w3schools.com/jquery/jquery_ajax.asp

Edited : 2012-10-04 16:31
Reason : Got the following Comment :
Hm unless I don't understand, I don't want to load informations of the server, I want to get the informations I have in my JS code on my server. I already have the informations to send in the files Array(). – Elfayer

What you do is you make a AJAX call to the server like to an webservice. Here is an example

var value = 1;
var handlerUrl = [YOUR WEBSERVICE URL];

//Do the Ajax Call
jQuery.ajax({
  url: handlerUrl,
  data: { "params[]": [value] },
  type: 'POST',
  success: function (data)
  {
     alert("succes");
  },
  error: function (jxhr, msg, err)
  {
     alert("error");
  }
});

in the data parameter you give your data.
I send it here in the form of an array but you can send it also like 1 parameter. How do you access it in well in my case a generic handler.

//Split the parameters and set in Array of Strings
var param = context.Request.Form[0].Split(',');
var value = param[0];

Like I said I give it in the form of an array so I only have one parameter
and then I split it. But if you would give it like single properties then you
could get it like :

context.Request.Form[0]
context.Request.Form[1]
context.Request.Form[2]
context.Request.Form[3]
context.Request.Form[4]
VRC
  • 745
  • 7
  • 16
  • Hm unless I don't understand, I don't want to load informations of the server, I want to get the informations I have in my JS code on my server. I already have the informations to send in the `files` Array(). – Elfayer Oct 04 '12 at 13:31
  • Interesting ! But how can I send an object? Because files is an Array() of objects, and each object contain the informations of a file. If I do : `data: { "params[]": [files[i]] },` I get : `value = [Object File]`. Then, I already have an upload method that work with a single file upload (I'm doing a multiple file Upload). And this method currently work if I can get an `HttpPostedFile` or maybe (certainly) `HttpPostedFileBase`. – Elfayer Oct 04 '12 at 14:57
  • Hm... I never tried that tbh. But did a bit google search and it seems that's not possible. You have to use a file upload control. Look here for more info : http://stackoverflow.com/questions/408735/javascript-file-uploads – VRC Oct 04 '12 at 17:34
  • A little bit more googling and found a possible solution : http://www.openjs.com/articles/ajax/ajax_file_upload/ (It is a PHP tutorial though) – VRC Oct 04 '12 at 17:40