download file from absolute uri to stream to SaveFileDialog
Asked Answered
E

2

5

I've gotten as far as putting a file into a stream from a url. However puttin savefiledialog inside the event OpenReadCompleted gives an exception because the savefiledialog needs to be fired from an user iniated event. Putting the savefiledialog NOT inside OpenReadCompleted gives an error because the bytes array is empty, not yet processed. Is there another way to save a file to stream from a uri without using an event?

public void SaveAs()
{
WebClient webClient = new WebClient(); //Provides common methods for sending data to and receiving data from a resource identified by a URI.
        webClient.OpenReadCompleted += (s, e) =>
                                           {
                                               Stream stream = e.Result; //put the data in a stream
                                               MemoryStream ms = new MemoryStream();
                                               stream.CopyTo(ms);
                                               bytes = ms.ToArray();
                                           };  //Occurs when an asynchronous resource-read operation is completed.
        webClient.OpenReadAsync(new Uri("http://testurl/test.docx"), UriKind.Absolute);  //Returns the data from a resource asynchronously, without blocking the calling thread.

        try
        {
        SaveFileDialog dialog = new SaveFileDialog();
        dialog.Filter = "All Files|*.*";

        //Show the dialog
        bool? dialogResult = dialog.ShowDialog();

        if (dialogResult != true) return;

        //Get the file stream
        using (Stream fs = (Stream)dialog.OpenFile())
        {
            fs.Write(bytes, 0, bytes.Length);
            fs.Close();

            //File successfully saved
        }
        }
        catch (Exception ex)
        {
            //inspect ex.Message
            MessageBox.Show(ex.ToString());
        }

}
Evonevonne answered 22/11, 2011 at 16:46 Comment(0)
U
7

The approach to take is to first open the SaveFileDialog as a result of some user interaction like a Button click. Having had the user determine where to save the download and the SaveDialog method has returned you keep that instance of SaveFileDialog on hand.

You then invoke the download and in the OpenReadCompleted you can use the the SaveFileDialog OpenFile method to get a stream to which you can pump the result.

public void SaveAs() 
{
    SaveFileDialog dialog = new SaveFileDialog(); 
    dialog.Filter = "All Files|*.*"; 

    bool? dialogResult = dialog.ShowDialog(); 

    if (dialogResult != true) return;

    WebClient webClient = new WebClient();
    webClient.OpenReadCompleted += (s, e) => 
    { 
        try 
        {      
            using (Stream fs = (Stream)dialog.OpenFile()) 
            {
                e.Result.CopyTo(fs); 
                fs.Flush(); 
                fs.Close(); 
            }

         } 
         catch (Exception ex) 
         { 
             MessageBox.Show(ex.ToString()); 
         } 
    }; 
    webClient.OpenReadAsync(new Uri("http://testurl/test.docx"), UriKind.Absolute); 
} 

You'll note that not only is the code cleaner and simpler but if the user ends up cancelling the SaveFileDialog you haven't wasted their time or bandwidth downloading a file.

Unreserve answered 22/11, 2011 at 19:57 Comment(1)
It works perfectly! Why didn't I think of that. Probably because I'm a newbie. Thanks a lot.Evonevonne
S
0

i found simple way to download file from silverlight application. use HyperLinkButton control.

you can specify target also using "TargetName" propery.

Subsistence answered 20/5, 2016 at 6:19 Comment(1)
This is more suitable as a comment.Dosage

© 2022 - 2024 — McMap. All rights reserved.