When I was doing SivlerLight 2 development and using SP2007, I was wishing for a cleaner way of downloading a file. It just seemed so browser like to stream a file via the response stream and force the browser to pop open two dialogs like below. I had worked so hard on making the Silverlight application not to look like a traditional browser based application, it just seemed to be a shame.
Well when I was doing Silverlight 4 and SP2010 development I came across the SilverLight System.Windows.Controls.SaveFileDialog class. This is just like using the Windows.Forms.FileDialog class of old days except for Silverlight. Very nice, because you just get the save file dialog without all the extra windows, making it behave more like a desktop application.
So I needed some code to get a file from SharePoint and then prompt the user with the SaveFileDialog. Remember everything must be called asynchronously in Silverlight. The code below uses the Sivlerlight client object model File.OpenBinaryDirect along with an “in-line” anonymous delegate allowing the callback code to be executed in the same method. Works out very well.
private void DownloadFile(string path) { string filterTemplate = "!@Ext Files (*.!@Ext) | *.!@Ext"; SaveFileDialog dialog = new SaveFileDialog(); dialog.DefaultExt = Path.GetExtension(path).Substring(1); dialog.Filter = filterTemplate.Replace("!@Ext", dialog.DefaultExt); bool? result = dialog.ShowDialog(); if (result.HasValue && result == true) { this.Busy = true; Stream sourceStream = null; Uri fileUrl = new Uri(path); ClientContext clientContext = new ClientContext(fileUrl.GetComponents( UriComponents.SchemeAndServer, UriFormat.UriEscaped)); Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, fileUrl.AbsolutePath, (object eventSender, OpenBinarySucceededEventArgs eventArgs) => { if (eventArgs.Stream != null) sourceStream = eventArgs.Stream; Deployment.Current.Dispatcher.BeginInvoke(() => { using (Stream destStream = dialog.OpenFile()) { byte[] bytes = new byte[sourceStream.Length]; sourceStream.Read(bytes, 0, (int)sourceStream.Length); destStream.Write(bytes, 0, bytes.Length); destStream.Flush(); } this.Busy = false; }); }, null); } } |