Click here to Skip to main content
15,886,788 members
Articles / Web Development / ASP.NET / ASP.NETvNext
Technical Blog

Ajax file upload with ASP.NET5

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
2 Nov 2015MIT1 min read 19.9K   9   4
This post is about uploading files to ASP.NET 5 web application using HTML5 file API.

This post is about uploading files to ASP.NET 5 web application using HTML5 file API. Most of the HTML5 File upload examples are using the “HttpContext.Current.Request.Files” which is not implemented in the ASP.NET5. The alternative is to use IFormFile, it is working fine, if you are using the normal Form - File upload combination. But in case of Ajax file upload it is not working. Later I found a SO post, which talks about File upload in ASP.NET5. It is mentioned like you need to read the body contents and save it using file stream. But when I did that, it was also not working. Later I found that the body contains the filename and content type information as well like this.

Image 1

Since I have the content type and file name, saving the file stream as file won’t create a valid image file. You need a parser to parse the contents. Initially I thought of implementing one, but later I found one which is already available in codeplex - Multipart Form Data Parser. Using this you can parse the body and get the file name, content type and file contents.

Here is the complete code.

HTML Form

HTML
1 <form id="UploadForm" asp-action="upload" asp-controller="home">
2     <input class="form-control" type="file" name="UploadFile" id="UploadFile" accept="image/*" />
3     <input type="submit" value="Submit" class="btn btn-default" />   
4 </form>

And here is script, which handles the Ajax file upload.

JavaScript
 1 $("#UploadForm").submit(function (e) {
 2 	var data = new FormData();
 3 	var selectedFiles = $("#UploadFile")[0].files;
 4 	data.append(selectedFiles[0].name, selectedFiles[0]);
 5 
 6 	$.ajax({
 7 		type: "POST",
 8 		url: "/home/Upload",
 9 		contentType: false,
10 		processData: false,
11 		data: data,
12 		success: function (result) {
13 			alert(result);
14 		},
15 		error: function () {
16 			alert("There was error uploading files!");
17 		}
18 	});
19 
20 	e.preventDefault();
21 });

And here is the controller code.

C#
 1 [HttpPost]
 2 public IActionResult Upload()
 3 {
 4     MultipartParser multipartParser = 
 5         new MultipartParser(new StreamReader(Request.Body).BaseStream);
 6     if(multipartParser.Success)
 7     {
 8         var bytes = multipartParser.FileContents;
 9     }
10     
11     return Json("Uploaded");
12 }

Hope it helps. Happy Programming

This article was originally posted at http://dotnetthoughts.net/feed.xml

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Technical Lead
India India
Working as Tech. Lead

My blog : dotnetthoughts.net.
You can follow me in twitter : @anuraj

Comments and Discussions

 
QuestionIs it incomplete code Pin
Tridip Bhattacharjee2-Nov-15 20:37
professionalTridip Bhattacharjee2-Nov-15 20:37 
AnswerRe: Is it incomplete code Pin
GerVenson3-Nov-15 2:49
professionalGerVenson3-Nov-15 2:49 
GeneralRe: Is it incomplete code Pin
Tridip Bhattacharjee3-Nov-15 20:58
professionalTridip Bhattacharjee3-Nov-15 20:58 
GeneralRe: Is it incomplete code Pin
GerVenson3-Nov-15 22:04
professionalGerVenson3-Nov-15 22:04 
Not every possible variable of an Request is proposed to the Action. That would be a hell of parameters. You can define on your own what you would like to handle directly by declaring Parameters to your methods but you can still access the Request in its whole.

You can do the following:
C#
public IActionResult Upload(FormCollection form);

or
C#
public IActionResult Upload(FileViewModel form);

or
C#
public IActionResult Upload()
{
    var filea = base.Request["fileA"];
    //or
    var fileb = base.Request.Form["fileA"];
}

This is absolutely valid. This is what you expect right? If fits your need in most cases when not using an custom ViewModel. In this case we expect the FormCollections entry's to contain binary data ( the file ). MVC is receiving the form as a Stream over the network, so when you define the FormCollection in our controller mvc is Forced to Serialize the Stream and then give it to your method that can handle it. This has a 2 mayor disadvantages.

1 we are holding a lot of data in RAM.
Just imagine 100 users are calling this method to store files on the Server. This is a Bunch of memory that will be allocated.
2 what are we expect to do with the FileBlob? Save it to the FileSystem to Persist it of course.
This will be the case in 80% of all scenarios. So let it ASP do. As soon as the Stream will be arrive in your Host it will be persisted on your HDD. Then you can access it thats no problem but the Memory will be stay free of it.

Some more infos about MVC Controller Params:
Getting Data From View to Controller in MVC[^]

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.