Silverlight 4 RC文件上传和上传进度:如何实现?

3

据称,Silverlight 4 RC 的一个新功能是支持上传进度。

我猜这意味着可以制作一个上传文件进度条而不需要“分块”,但我不知道如何做到这一点,请问我们该如何实现?提供源代码示例会很好。

谢谢!


+1,这是一个非常好的问题。 - AnthonyWJones
2个回答

4

好的,在大量尝试后,我已经弄清楚了:

   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);
    }

线程同步逻辑怎么样?或者在这种情况下你不需要一个吗? - jayarjo
对我来说,它会将所有内容都存储在内存中,因此100MB的文件只需要一秒钟就可以准备好了。然后当调用BeginGetResponse时,它才真正开始上传。 - Léon Pelletier
不幸的是,requestStream.Flush() 立即返回,因此此代码在 WP7.x 上无法工作。 - EvZ

0

我建议看一下这篇不错的文章。虽然我不确定这是否是最好的方法,但我真的建议在Silverlight 4中使用MVVM。在这篇文章中,你可以看到“BusyIndicator”用于显示Silverlight异步文件上传状态。

也许这会对你有所帮助,但我无法确定它是否具有“分块”行为或按预期工作。祝你好运!

最好的问候
Thomas


这是一个不错的开始,但实际上并没有提供更新进度 - 代码中存在一个错误,因为它可能是在 Silverlight 4 RC 之前完成的。 - steve
好的,感谢您的澄清和发布最终代码! - thmshd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接