Chunk Upload
The chunk upload of files enables the user to send large files, which are uploaded asynchronously with multiple requests, to the server and to pause and resume the file upload for the time the application is open in the browser.
Important
- The chunk upload functionality is available as of the Kendo UI 2017 R2 release.
- The chunk upload functionality is available only in the asynchronous mode of the Upload.
Getting Started
To enable the chunk upload, set up the ChunkSize
helper method (async.chunkSize
option) of the Upload.
Example
@(Html.Kendo().Upload()
.Name("files")
.Async(a => a
.Save("ChunkSave", "Upload")
.Remove("Remove", "Upload")
.AutoUpload(true)
.ChunkSize(1100) // Will separate the file into chunks of size 1100 bytes.
)
)
[DataContract]
public class ChunkMetaData
{
[DataMember(Name = "uploadUid")]
public string UploadUid { get; set; }
[DataMember(Name = "fileName")]
public string FileName { get; set; }
[DataMember(Name = "contentType")]
public string ContentType { get; set; }
[DataMember(Name = "chunkIndex")]
public long ChunkIndex { get; set; }
[DataMember(Name = "totalChunks")]
public long TotalChunks { get; set; }
[DataMember(Name = "totalFileSize")]
public long TotalFileSize { get; set; }
}
public class FileResult
{
public bool uploaded { get; set; }
public string fileUid { get; set; }
}
public void AppendToFile(string fullPath, Stream content)
{
try
{
using (FileStream stream = new FileStream(fullPath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
{
using (content)
{
content.CopyTo(stream);
}
}
}
catch (IOException ex)
{
throw ex;
}
}
public ActionResult ChunkSave(IEnumerable<HttpPostedFileBase> files, string metaData)
{
if (metaData == null)
{
return Save(files);
}
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(metaData));
var serializer = new DataContractJsonSerializer(typeof(ChunkMetaData));
ChunkMetaData chunkData = serializer.ReadObject(ms) as ChunkMetaData;
string path = String.Empty;
// The Name of the Upload component is "files"
if (files != null)
{
foreach (var file in files)
{
path = Path.Combine(Server.MapPath("~/App_Data"), chunkData.FileName);
//AppendToFile(path, file.InputStream);
}
}
FileResult fileBlob = new FileResult();
fileBlob.uploaded = chunkData.TotalChunks - 1<= chunkData.ChunkIndex;
fileBlob.fileUid = chunkData.UploadUid;
return Json(fileBlob);
}
Fine-Tuning
To modify or fine-tune the chunk upload, use any of the following configuration options:
-
Concurrent
(async.concurrent)—Controls whether the selected files are uploaded simultaneously or one after the other. -
AutoRetryAfter
(async.autoRetryAfter)—The time interval in milliseconds after which the Upload attempts to retry a failed upload. -
MaxAutoRetries
(async.maxAutoRetries)—The number of attempts the Upload makes to retry a failed upload before reporting it.
Example
@(Html.Kendo().Upload()
.Name("files")
.Async(a => a
.Save("ChunkSave", "Upload")
.Remove("Remove", "Upload")
.AutoUpload(true)
.ChunkSize(1100) // Will separate the file into chunks of size 1100 bytes.
.Concurrent(true) // Will upload all files simultaneously.
.AutoRetryAfter(300) // Will attempt a failed chunk upload after 300ms.
.MaxAutoRetries(4) // Will attempt the same failed chunk upload 4 times.
)
)
Transfer of Chunks
The chunk upload functionality separates the selected files chunks or blobs of data. These chunks are automatically sent to the server to the destination that is set up in the saveUrl
option over an AJAX request. Because the chunks are sent in a specific order, the server is expected to send back a response with the meta data of the chunk that is uploaded. This response indicates to the Upload that it can proceed either with the next chunk ("uploaded": false
) or with the next file ("uploaded": true
).
The response has to include the meta data from the following example.
Example
{
"uploaded": true | false,
/* False instructs the Upload to send the next chunk of data.
True indicates that the last chunk is processed, the upload was successful
and the upload of the next file can continue. */
"fileUid": Number
/* The UID of the uploaded chunk, so that the Upload can get the next chunk and send it. */
}
The following example demonstrates a valid server response.
Example
{"uploaded":true,"fileUid":"b95ee9fa-85e8-482c-946d-a12ed6dbefed"}
Server-side Implementation
The server-side implementation entirely depends on the application requirements and logic. The approach that is demonstrated in this article and in the chunk upload demo can serve you as an example on how to handle chunks and merge them into files.
Important
As a client-side solution, the Upload does not handle validation. File validation and security requirements should be handled on the server by using application logic.
See Also
- Overview of the Upload HtmlHelper
- Upload HtmlHelper Modes of Operation
- How to Upload Files from Grid Popup Editors in ASP.NET MVC Applications
- How to Upload Files to Databases in ASP.NET MVC Applications
- Overview of the Kendo UI Upload Widget
- Overview of Telerik UI for ASP.NET MVC
- Fundamentals of Telerik UI for ASP.NET MVC
- Scaffolding in Telerik UI for ASP.NET MVC
- Telerik UI for ASP.NET MVC API Reference Folder
- Telerik UI for ASP.NET MVC HtmlHelpers Folder
- Tutorials on Telerik UI for ASP.NET MVC
- Telerik UI for ASP.NET MVC Troubleshooting
- Upload HtmlHelper Troubleshooting