views:

1656

answers:

3

It's been stated that one of the new features of Silverlight 4 RC is that it now supports upload progress.

I'm assuming this means it's possible to make an upload file progress bar without "chunking" but I can't figure out how to do this, so how do we do this? Source code examples would be great.

Thanks!

A: 

Hi Steve,

I'd suggest to take a look at this nice article. I'm not sure if this is the best way to do this, but I'd really suggest using MVVM in Silverlight 4 anyway. In the article, you can see that a "BusyIndicator" is used to display silverlight's asynchronous file upload status.

Maybe this will help you, I can't actually tell if it has a "chunking" behaviour or works as you would expect. Good luck!

Best regards
Thomas

moonground.de
this is a good start, but doesn't actually provide update progress - the code has a bug in it as it was probably done before Silverlight 4 RC
steve
Ok, thanks for the clarification and for posting the final code!
moonground.de
A: 

Ok, after lots of playing I've got it figured out:

   private void UploadFile(string url, CustomPostDataInfo pdi)
    {

        // Use the client http stack!

        //HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
        HttpWebRequest webRequest = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(new Uri(url));

        webRequest.AllowWriteStreamBuffering = false; // <-- this enables upload progress reporting!

        webRequest.Method = "POST";
        webRequest.ContentType = "multipart/form-data; boundary=" + pdi.Boundary; // Boundary only needed for multipart form ada

        // Calculate our response length
        webRequest.ContentLength = pdi.FormDataHeader.Length + pdi.File2Upload.Length + pdi.FormDataFooter.Length; // Calculate the length of your entire message here, required

        pdi.request = webRequest;

        webRequest.BeginGetRequestStream(new AsyncCallback(WriteToStreamCallback), pdi);
    }

    private void WriteToStreamCallback(IAsyncResult asynchronousResult)
    {
        CustomPostDataInfo pdi = (AmazonS3PostDataInfo)asynchronousResult.AsyncState;
        HttpWebRequest webRequest = pdi.request;
        Stream requestStream = webRequest.EndGetRequestStream(asynchronousResult);
        UTF8Encoding encoding = new UTF8Encoding();

        UpdateShowProgress(false, "Uploading file..."); // Your custom update event - make sure to use a Dispatcher to update on the UI thread as this is running on a separate thread.

        // Write any pre file data if needed
        // ...

        // Write our file data
        {
            // Read chunks of this file
            byte[] buffer = new Byte[1024 * 32];
            Stream fileStream = pdi.File2Upload.OpenRead();
            int bytesRead = 0;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                requestStream.Write(buffer, 0, bytesRead);
                requestStream.Flush(); // Will block until data is sent

                bytesUploaded += bytesRead;

                //Show the progress change
                UpdateShowProgress(false, "Uploading file...");
            }
        }

        // Write any post file data
        // ...

        UpdateShowProgress(false, "Uploaded, waiting for response...");

        requestStream.Close();

        // Get the response from the HttpHandler
        webRequest.BeginGetResponse(new AsyncCallback(ReadHttpResponseCallback), webRequest);

    }

    private void ReadHttpResponseCallback(IAsyncResult asynchronousResult)
    {
        HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
        HttpWebResponse webResponse = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);
        StreamReader reader = new StreamReader(webResponse.GetResponseStream());

        string response = reader.ReadToEnd(); // Get the result

        reader.Close();

        UpdateShowProgress(true, response);
    }
steve
A: 

Can you post a VB version of this? Your code above is incomplete.

Eric