Sample Project: SilverlightFileAccess.zip (489.06 kb)
In a previous article, I mentioned that reading and writing to the user's local file system was not allowed. This wasn't 100% true.
In reality, you can read a file from the user's local file system as long as you present a "File Open" dialog to the user. The user can then select the file to open and your Silverlight application can open the selected files and only those files.
This is done for security reasons. With today's shady characters on the internet writing viruses and phishing tools, Silverlight was built with security in mind. This means (a) that it's more secure for the end user, and (b) as developers, we're limited in what we can do. So a Silverlight application cannot open a file for reading unless the user specifically selected that file for the purposes of being read.
Here is some Xaml for my test application.
<Grid x:Name="LayoutRoot" Background="Black">
<Button Content="Open..."
Width="75"
Height="25"
Click="Button_Click"
VerticalAlignment="Top"
HorizontalAlignment="Left"/>
<TextBlock x:Name="Status"
Margin="0,25,0,0"
Foreground="White"/>
<Image x:Name="Image"
MinWidth="100"
MinHeight="100"
Margin="0,50,0,0"/>
</Grid>
In order to read a file, you need to create a FileOpenDialog object and present that to the user.
OpenFileDialog dlg = new OpenFileDialog();
dlg.Multiselect = false;
dlg.Filter = "JPEG Files (*.jpg)|*.jpg";
bool bResult = (bool)dlg.ShowDialog();
if (!bResult)
return;
Here, I am showing the dialog to the user and asking for a JPEG file. I am also limiting the open to a single file. You can have the user select multiple files as well as provide more choices to the user as to the type of file to open.
Once the user has selected the file, you access the file information from the OpenFileDialog.SelectedFile member. This member is of type FileDialogFileInfo. From this class, you can get the name of the file (but not the full path) as well as open a Stream to the file. The stream is a standard System.IO.Stream class which you can read normally.
Here, I am opening the stream, but then funnelling it into an Image object to be displayed on my form.
FileDialogFileInfo info = dlg.SelectedFile;
Status.Text = info.Name;
Stream s = info.OpenRead();
BitmapImage bi = new BitmapImage();
bi.SetSource(s);
Image.Source = bi;
s.Close();
In this example, once I open the file, the selected image should appear on the page.
However, your application can read from the file however it wants: as a text file, Xml, or other binary format.
But what about writing to a file. Unfortunately, at this time, there is not an equivalent SaveFileDailog class. However, there is a workaround. To Save a file, you need to trigger a web browser file download (ie. a normal file download via the web browser). So data would need to be sent to the server, and your hosting web application would need to trigger the download. This will be the topic for a future article.