A 2023 solution using jQuery3 and .Net
HTML:
<form>
<input type=file /> <button class=upload>Upload</button>
</form>
JS:
$('button.upload').closest('form').on('submit', ev => {
ev.preventDefault();
const form = $(ev.target);
const files = form.find('input[type=file]')[0].files;
const formData = new FormData();
formData.append('upload', files[0]);
$.ajax({
url: '/manage/upload',
type: 'POST',
data: formData,
encType: 'multipart/form-data',
contentType: false,
processData: false
})
.done(r => {
debugger;
});
return false;
});
Asp.Net MVC Controller:
[HttpPost]
public async Task<JsonResult> Upload(HttpPostedFileBase upload)
{
string s = null;
using (upload.InputStream)
using (var reader = new StreamReader(stream, true))
s = await reader.ReadToEndAsync();
// Do something with the uploaded contents of the file
return Json(true);
}
Notes about this code:
formData.upload('<name goes here>',...
- in this case, 'upload'
- must match the parameter name in your .Net Controller Action (HttpPostedFileBase upload
), So if you change the key in the AJAX call from 'upload' to 'file'
, you need to change the Action parameter like HttpPostedFileBase file
if you want this to be easy. It can be done without matching these form body keys, but, it's a bunch of extra work.
This code assumes you have only 1 file upload control in your form. You can use more upload inputs in a form but it's more complicated - but it's very easy to use this code with 1 input type=file per form, and multiple such form/input pairs. The form lacking any attributes at all is intentional and totally fine, given it's never meant to submit anywhere on its own.
The url
property of the options passed in js to the ajax call should be the path to the upload action on your Controller, wherever that is. There's nothing special here, just a plain web path.
The Controller Action here happens to consume the file on the premise that it's a text document, but, you don't need to do this. I'm just including how to read it in a small number of lines of code as one thing you might conveniently do with it.
I've left out any error handling to cut to the chase, and present the least possible code to get this to work.
The arrow function in the submit handler does not offer a this object, so if you were thinking of using $(this)
or this.files
... in that handler instead of $(ev.target)
, don't do it.