S3 Upload Sample
To see this sample in action, download the SlickUpload package and configure it for your environment.
NOTE: the maximum allowed request size for this sample is 1000 MB. If you attempt to upload files larger than this,
you will recieve a oversized upload error which SlickUpload will handle gracefully. This is controlled by the maxRequestLength attribute of the
httpRuntime key in the web.config file.
Configuration
Configuration for the S3 example involves configuring the appSettings in the web.config to point at the correct Amazon S3 account.
To do this, perform the following steps:
- Set the awsAccessKeyId element's value attribute to the Amazon S3 access key for your account
- Set the awsSecretAccessKey element's value attribute to the Amazon S3 secret key for your account
- Set the awsBucket element's value attribute to the name of an existing bucket to upload into. This sample will not create the bucket, so this must be an existing bucket your account can write to.
Description
This sample builds on the Custom Progress sample and demonstrates how to upload to S3 with progress through the entire process – during the upload to the server as well as the upload to S3.
It uses the excellent Affirma ThreeSharp library to communicate with S3.
First, we create a ThreeSharpConfig and ThreeSharpQuery based on the Amazon AccessKeyID and SecretAccessKey stored in the web.config.
ThreeSharpQuery is the core of ThreeSharp and manages all other object interactions.
ThreeSharpConfig cfg = new ThreeSharpConfig();
cfg.AwsAccessKeyID = ConfigurationManager.AppSettings["awsAccessKeyId"];
cfg.AwsSecretAccessKey = ConfigurationManager.AppSettings["awsSecretAccessKey"];
_q = new ThreeSharpQuery(cfg);
In the UploadComplete event, we do a little calculation and setup to get ready to upload:
Dictionary<string, string> status = new Dictionary<string, string>();
status["percentComplete"] = "0";
status["percentCompleteText"] = "0%";
// Update the progress context
e.Status.UpdatePostProcessStatus(status);
string bucket = ConfigurationManager.AppSettings["awsBucket"];
long totalLength = 0;
long transferredLength = 0;
// Calculate total length
foreach (UploadedFile uFile in e.UploadedFiles)
totalLength += uFile.ContentLength;
Then, we get right down to business. For each file that was uploaded, we create an ObjectAddRequest to post it to S3. We load the request with the file to be sent, and then fire up a thread to do the actual sending:
// Upload each file
foreach (UploadedFile uFile in e.UploadedFiles)
{
string fileName = uFile.LocationInfo[FileUploadStreamProvider.FileNameKey];
using (ObjectAddRequest req = new ObjectAddRequest(bucket, Server.UrlEncode(uFile.ClientName)))
{
req.LoadStreamWithFile(fileName);
// Create and fire up a new thread to do the actual upload
Thread t = new Thread(UploadThread);
t.Start(req);
The thread is very simple. It executes the add request and waits for a response:
void UploadThread(object data)
{
ObjectAddRequest req = (ObjectAddRequest)data;
using (ObjectAddResponse resp = _q.ObjectAdd(req))
{ }
}
While the thread is doing the actual uploading to S3, we watch the progress and continuously update it to the client:
while (t.IsAlive && req.BytesTransferred < req.BytesTotal)
{
float percentComplete = ((transferredLength + req.BytesTransferred) / (float)totalLength);
status["percentComplete"] = (percentComplete * 100).ToString("f2");
status["percentCompleteText"] = percentComplete.ToString("p2");
// Update the progress context
e.Status.UpdatePostProcessStatus(status);
// wait 500ms
Thread.Sleep(500);
}
Once the file is complete, we tally up the data that was sent and remove the local copy of the file:
transferredLength += uFile.ContentLength;
File.Delete(fileName);
Finally, after all files are uploaded, we signal that postprocessing is complete:
status["percentComplete"] = "100";
status["percentCompleteText"] = "100 %";
// Update the progress context
e.Status.UpdatePostProcessStatus(status, true);
|