Brandi
Brandi

Reputation: 1579

Can I use JavaScript/JQuery to add an uploaded file to Request.Files in ASP.NET?

I am not entirely sure how I can add a file into Request.Files using JavaScript? Here is what I'm going for...

var x = $('input[type=file]:eq(0)');

//Add the data to the hidden field
hiddenField.val(x.val());

//Add the html display
fileDisplayDiv.innerHTML += "<a href='#' class='filename'>display name</a>";

//Add this file to request.files
How to do???

//Clear the input so the user may add more files before postback.
x.val("");

The input is a regular HTML input . Yes, ultimately I am trying to develop a multiple file-upload (this is why I am clearing the input field) - I looked at 3rd party stuff, but I require custom functionality for what I'm doing. I figure it seems like this task should be possible, or else how would the ajax uploaders work?

Any help appreciated, thanks in advance.

Upvotes: 2

Views: 2718

Answers (2)

S&#233;bastien Renauld
S&#233;bastien Renauld

Reputation: 19662

I'm going to supply a pre-HTML5 method I tend to use. This has a few drawbacks but a lot of advantages - the main one is it being almost completely cross-browser (the only requirements are JavaScript and hidden IFRAMEs).

I'll list the drawbacks immediately so you know exactly what problems you might run into:

  • If you are posting to another domain, you will not be able to get a return from it
  • You cannot get anything other than content from it, and HTTP errors will cause it to silently fail.
  • If it fails, you'll have to re-generate the form. And if that happens, you cannot automatically re-select the files for the user.

The solution: put your input type="file" in a friendly IFRAME and use this to submit. It's not AJAX, and it's a pretty old method, but it works.

How to

Step 1. Create an IFRAME and give it an ID or class to be able to select it efficiently. Create it on DOMReady rather than cluttering up the pre-ready stuff. When you create it, assign a load event to it using $('#yourIframe').load(function() { }); . When this triggers, you'll know that you can now add content to your iframe. The trick is to copy all your form elements to it, and to leave "clones" behind - and to bind all the useful events to the ones in the IFRAME. In order:

  • click() and change() for input type="file", input type="text" and select
  • change() for anything else

The click event should simply be forwarded to the element in the IFRAME. The change() event, when bound to the element within the IFRAME, allows you to recover the name of the file.

When you click your phantom submit button, have it bind a load() event to the IFRAME, and then submit the form inside the IFRAME. When the form gets submitted, you'll be able to access the content of the iframe inside the load handler with $("body",$(this).contents()).

I've written a small fiddle to illustrate: http://jsfiddle.net/WQhnM/2/ . Bear in mind that JSFiddle.net will get the data (so don't send anything too serious/incriminating ;-) ) and that their server refuses anything bigger than 100kb (so send something small). The idea is there, though. I have left the IFRAME visible so you can see what happens.

It's not a pretty solution by far, but it works until IE catches up with HTML5.

Edit: I forgot to mention - this needs a hack to work in IE7. change() is not triggered properly in this specific browser. The solution:

if (!$.browser.msie) {
  nItem.change(function() { ... });
}
else {
   nItem.click(function() { 
      setTimeout(function() {
          (function() { ... });
      },0);
   });
}                                   

Upvotes: 1

Chris Van Opstal
Chris Van Opstal

Reputation: 37547

Do you need to support older browsers?

Traditionally there was no way to upload files using pure javascript/ajax. For security reasons javascript access to the <input type="file" /> control was restricted (otherwise you could potentially trick the browser into uploading any file on the user's computer). Third-party upload controls used flash to work around these limitations and this remains the only real solution if need to support older browsers.

HTML5 offers two new features that can help you achieve what you're trying to do:

  • File API: Allows you to natively do a lot of cool things such as select multiple files, list selected files, and display file information (all client-side).
  • Upload files with AJAX. You can now send files or any blob data back to the server purely using the XMLHttpRequest object.

I haven't tried the latter yet myself but I do believe you should be able to access uploaded files using ASP.NET's Request.Files[] object (let us know if you try it!). These features aren't universally supported and most importantly IE 8/9 lack support for most of the above. So if you have need to support these browsers your best bet would be to use one of the third-party upload controls.

Upvotes: 1

Related Questions