Here is a working solution for the latest Amazon SDK (as of today: v.1.5.37.0 )
Amazon S3 Multipart Upload works like:
- Initialize the request using
client.InitiateMultipartUpload(initRequest) - Send pieces of the file (loop to the end) using
client.UploadPart(request) - Fill out the request using
client.CompleteMultipartUpload(compRequest) - If something goes wrong, be sure to delete the client and request, and also run the abort command using
client.AbortMultipartUpload(abortMultipartUploadRequest)
I keep the client in Session as we need it, for each channel load, save the ETags tag, which is now used to complete the process.
You can see an example and an easy way to do this in Amazon Docs , I got a class to do everything, plus, I integrated with the beautiful jQuery File Upload (handler code below also).
S3MultipartUpload as follows
public class S3MultipartUpload : IDisposable { string accessKey = System.Configuration.ConfigurationManager.AppSettings.Get("AWSAccessKey"); string secretAccessKey = System.Configuration.ConfigurationManager.AppSettings.Get("AWSSecretKey"); AmazonS3 client; public string OriginalFilename { get; set; } public string DestinationFilename { get; set; } public string DestinationBucket { get; set; } public InitiateMultipartUploadResponse initResponse; public List<PartETag> uploadPartETags; public string UploadId { get; private set; } public S3MultipartUpload(string destinationFilename, string destinationBucket) { if (client == null) { System.Net.WebRequest.DefaultWebProxy = null;
I use DestinationFilename as the destination file, so I can avoid the same name, but I keep the OriginalFilename as needed.
Using jQuery File Upload Plugin, everything works inside the Generic Handler, and the process looks something like this:
// Upload partial file private void UploadPartialFile(string fileName, HttpContext context, List<FilesStatus> statuses) { if (context.Request.Files.Count != 1) throw new HttpRequestValidationException("Attempt to upload chunked file containing more than one fragment per request"); var inputStream = context.Request.Files[0].InputStream; string contentRange = context.Request.Headers["Content-Range"]; // "bytes 0-6291455/14130271" int fileSize = int.Parse(contentRange.Split('/')[1]);, maxChunkSize = int.Parse(context.Request.Headers["X-Max-Chunk-Size"]), uploadedBytes = int.Parse(contentRange.Replace("bytes ", "").Split('-')[0]); iView.Utilities.AWS.S3MultipartUpload s3Upload = null; try { //
Keep in mind that to create a Session object inside a common handler, you need to implement IRequiresSessionState so that your handler looks like this:
public class UploadHandlerSimple : IHttpHandler, IRequiresSessionState
Inside fileupload.js (under _initXHRData ) I added an extra header called X-Max-Chunk-Size , so I can pass this to Amazon and calculate if this is the last part of the downloaded file.
Comment freely and make smart changes for everyone.