JavaScript/jQuery FileUploader - Server-Side Implementation in ASP.NET
Depending on whether the FileUploader sends Ajax requests or uses an HTML form to upload files, the server must be configured differently. Ready-to-use implementations for both these cases are given below.
See Also
Ajax Upload
C#
VB
[HttpPost] // "file" is the value of the FileUploader's "name" property public ActionResult AsyncUpload(HttpPostedFileBase file) { // Specifies the target location for the uploaded files string targetLocation = Server.MapPath("~/Files/"); // Specifies the maximum size allowed for the uploaded files (700 kb) int maxFileSize = 1024 * 700; // Checks whether or not the request contains a file and if this file is empty or not if (file == null || file.ContentLength <= 0) { throw new HttpException("File is not specified"); } // Checks that the file size does not exceed the allowed size if (file.ContentLength > maxFileSize) { throw new HttpException("File is too big"); } // Checks that the file is an image if (!file.ContentType.Contains("image")) { throw new HttpException("Invalid file type"); } try { string path = System.IO.Path.Combine(targetLocation, file.FileName); // Here, make sure that the file will be saved to the required directory. // Also, ensure that the client has not uploaded files with malicious content. // If all checks are passed, save the file. file.SaveAs(path); } catch (Exception e) { throw new HttpException("Invalid file name"); } return new EmptyResult(); }
<HttpPost> Function AsyncUpload(file As HttpPostedFileBase) As ActionResult ' Specifies the target location for the uploaded files' Dim targetLocation As String = Server.MapPath("~/Files/") ' Specifies the maximum size allowed for the uploaded files (700 kb)' Dim maxFileSize As Integer = 1024 * 700 ' Checks whether or not the request contains a file and if this file is empty or not' If (IsNothing(file) Or file.ContentLength <= 0) Then Throw New HttpException("File is not specified") End If ' Checks that the file size does not exceed the allowed size' If (file.ContentLength > maxFileSize) Then Throw New HttpException("File is too big") End If ' Checks that the file is an image' If (Not file.ContentType.Contains("image")) Then Throw New HttpException("Invalid file type") End If Try Dim path As String = System.IO.Path.Combine(targetLocation, file.FileName) ' Here, make sure that the file will be saved to the required directory.' ' Also, ensure that the client has not uploaded files with malicious content.' ' If all checks are passed, save the file.' file.SaveAs(path) Catch ex As Exception Throw New HttpException("Invalid file name") End Try Return New EmptyResult() End Function
You can pass the exception messages to the client using a custom action filter:
C#
VB
[NonAction] protected override void OnActionExecuted(ActionExecutedContext filter) { var exception = filter.Exception; if (exception != null) { filter.HttpContext.Response.StatusCode = 500; filter.Result = new JsonResult { Data = exception.Message }; filter.ExceptionHandled = true; } }
<NonAction()> Protected Overrides Sub OnActionExecuted(ByVal filter As ActionExecutedContext) Dim exception As Exception = filter.Exception If exception IsNot Nothing Then filter.HttpContext.Response.StatusCode = 500 filter.Result = New JsonResult With {.Data = exception.Message} filter.ExceptionHandled = True End If End Sub
See Also
HTML Form Upload
C#
VB
public ActionResult SyncUpload() { // Specifies the target location for the uploaded files string targetLocation = Server.MapPath("~/Files/"); // Specifies the maximum size allowed for the uploaded files (700 kb) int maxFileSize = 1024 * 700; // Checks whether the request contains any files if(Request.Files.Count == 0) return View("Index"); HttpFileCollectionBase files = Request.Files; for (int index = 0; index < files.Count; index++ ) { HttpPostedFileBase file = files[index]; // Checks that the file is not empty if (file.ContentLength <= 0) continue; string fileName = file.FileName; // Checks that the file size does not exceed the allowed size if (file.ContentLength > maxFileSize) continue; // Checks that the file is an image if (!file.ContentType.Contains("image")) continue; try { string path = System.IO.Path.Combine(targetLocation, file.FileName); // Here, make sure that the file will be saved to the required directory. // Also, ensure that the client has not uploaded files with malicious content. // If all checks are passed, save the file. file.SaveAs(path); } catch (Exception e) { continue; } } return View("Index"); }
Function SyncUpload() As ActionResult ' Specifies the target location for the uploaded files' Dim targetLocation As String = Server.MapPath("~/Files/") ' Specifies the maximum size allowed for the uploaded files (700 kb)' Dim maxFileSize As Integer = 1024 * 700 Dim files As HttpFileCollectionBase = Request.Files ' Checks whether the request contains any files' If files.Count = 0 Then Return View("Index") End If For i = 0 To files.Count - 1 Dim file As HttpPostedFileBase = files(i) ' Checks that the file is not empty' If (file.ContentLength <= 0) Then Continue For End If Dim fileName As String = file.FileName ' Checks that the file size does not exceed the allowed size' If (file.ContentLength > maxFileSize) Then Continue For End If ' Checks that the file is an image' If (Not file.ContentType.Contains("image")) Then Continue For End If Try Dim path As String = System.IO.Path.Combine(targetLocation, file.FileName) ' Here, make sure that the file will be saved to the required directory.' ' Also, ensure that the client has not uploaded files with malicious content.' ' If all checks are passed, save the file.' file.SaveAs(path) Catch ex As Exception Continue For End Try Next i Return View("Index") End Function
See Also
Chunk Upload
C#
VB
// The structure that represents chunk details public class ChunkMetadata { public int Index { get; set; } public int TotalCount { get; set; } public int FileSize { get; set; } public string FileName { get; set; } public string FileType { get; set; } public string FileGuid { get; set; } } [HttpPost] // "file" is the value of the FileUploader's "name" property public ActionResult ChunkUpload(HttpPostedFileBase file, string chunkMetadata) { // Specifies the location for temporary files string tempFileLocation = Server.MapPath("~/Files/Temp/"); // Specifies the target location for uploaded files var targetLocation = Server.MapPath("~/Files/"); try { if (!string.IsNullOrEmpty(chunkMetadata)) { // Gets chunk details ChunkMetadata metaDataObject = JsonConvert.DeserializeObject<ChunkMetadata>(chunkMetadata); // ... // Perform security checks here // ... // Creates a directory for temporary files if it does not exist if (!Directory.Exists(tempFileLocation)) Directory.CreateDirectory(tempFileLocation); var tempFilePath = Path.Combine(tempFileLocation, metaDataObject.FileGuid + ".tmp"); // Appends the chunk to the file AppendContentToFile(tempFilePath, file); // Saves the file if all chunks are received if (metaDataObject.Index == (metaDataObject.TotalCount - 1)) System.IO.File.Copy(tempFilePath, Path.Combine(targetLocation, metaDataObject.FileName)); } } catch { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } return new EmptyResult(); } void CheckMaxSize(FileStream stream) { if (stream.Length > 1024*400000) throw new Exception("File is too large"); } void AppendContentToFile(string path, HttpPostedFileBase content) { using (FileStream stream = new FileStream(path, FileMode.Append, FileAccess.Write)) { content.InputStream.CopyTo(stream); CheckMaxSize(stream); } }
' The structure that represents chunk details Public Class ChunkMetadata Public Property Index As Integer Public Property TotalCount As Integer Public Property FileSize As Integer Public Property FileName As String Public Property FileType As String Public Property FileGuid As String End Class <HttpPost> Function ChunkUpload(file As HttpPostedFileBase, chunkMetadata As String) As ActionResult ' Specifies the location for temporary files Dim tempFileLocation As String = Server.MapPath("~/Files/Temp") ' Specifies the target location for uploaded files Dim targetLocation = Server.MapPath("~/Files/") Try If (Not String.IsNullOrEmpty(chunkMetadata)) Then ' Gets chunk details Dim metaDataObject As ChunkMetadata = JsonConvert.DeserializeObject(Of ChunkMetadata)(chunkMetadata) ' ... ' Perform security checks here ' ... ' Creates a directory for temporary files if it does not exist If (Not Directory.Exists(tempFileLocation)) Then Directory.CreateDirectory(tempFileLocation) End If Dim tempFilePath = Path.Combine(tempFileLocation, metaDataObject.FileGuid + ".tmp") ' Appends the chunk to the file AppendContentToFile(tempFilePath, file) ' Saves the file if all chunks are received If (metaDataObject.Index = (metaDataObject.TotalCount - 1)) Then System.IO.File.Copy(tempFilePath, Path.Combine(targetLocation, metaDataObject.FileName)) End If End If Catch ex As Exception Throw New HttpException("Bad request") End Try Return New EmptyResult() End Function Function AppendContentToFile(path As String, content As HttpPostedFileBase) Using stream As New FileStream(path, FileMode.Append, FileAccess.Write) content.InputStream.CopyTo(stream) CheckMaxSize(stream) End Using End Function Function CheckMaxSize(stream As FileStream) If (stream.Length > 1024*400000) Then Throw New Exception("File is too large") End If End Function
See Also
Feedback