Krystalware

SlickUpload Demos

» Overview Demonstrates the basics of SlickUpload. Selecting files, maximum file limit, file type validation, require files to be selected.
» FileNameGenerator How to control and generate server filenames for files as they are uploaded.
» Additional Fields How to add additional input fields for each selected file.
» Custom Progress Display custom progress information during a postprocessing step after files are uploaded.
» Localization How to localize the SlickUpload control.
» Modal Progress Show the progress display in a modal.
» Skinned Skin the file list and progress display.
» Upload to Amazon S3 How to upload to Amazon's Simple Storage Service with progress display.
» Upload to SQL Server Upload directly to a SQL Server, streaming with no memory usage.
Clustered» Use a StatusManager configuration to allow uploads with progress to a cluster/web farm/web garden.
» Custom UploadStreamProvider How to develop your own upload stream provider – this example shows how to zip files as they are uploaded.
» SimpleThe bare metal SlickUpload control, drag-dropped onto the page.

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:

  1. Set the awsAccessKeyId element's value attribute to the Amazon S3 access key for your account
  2. Set the awsSecretAccessKey element's value attribute to the Amazon S3 secret key for your account
  3. 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);