Day #29: Using Isolated Storage in Silverlight

Today is day #29 in my 31 Days of Silverlight series. We’re going to cover how to utilize the isolated storage available on the user’s machine today. We can use isolated storage when we are in out-of-browser mode, and I recently dedicated 3 entire posts (Days #23 – #25) to getting your application ready for out-of-browser. We will be starting with that codebase, and you can download my Silverlight Out of Browser application here.

1. Adding some using statements

First things first, we’re going to need some way to write files, and the way we do that is with the System.IO namespace family. We’re going to add two different using statements to our MainPage.xaml.cs file:

using System.IO;
using System.IO.IsolatedStorage;

These allow us to read and write files, as well as access the Isolated Storage on the user’s machine.

2. Adding to our XAML file

For this tutorial, I am going to be adding a textbox to our page that will contain the lyrics to the song “Big Bang Theory,” by the Barenaked Ladies. We’re making this box editable, however, so that a user can write in their own lyrics, or fix typos they may find. They will be saving these changes locally to their isolated storage. Here’s what our new XAML file looks like…the only real additions are a TextBox and a Button (for saving):

<UserControl x:Class="SilverlightOutOfBrowser.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
<
Canvas x:Name="LayoutRoot">
<
Canvas.Background>
<
LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<
GradientStop Color="#FF2A2A2A" Offset="1"/>
<
GradientStop Color="#FF9D9D9D"/>
</
LinearGradientBrush>
</
Canvas.Background>
<
Image x:Name="networkimage" Height="48" Width="48" Canvas.Left="532" Canvas.Top="10" Source="network_unknown.png" Stretch="Fill" ToolTipService.ToolTip="Network Connectivity"/>
<
MediaElement x:Name="videobox" Height="384" Width="512" Source="/BigBangTheory.wmv" Stretch="Fill" Canvas.Left="12" Canvas.Top="10"/>
<
Image x:Name="outofbrowserimage" Height="48" Width="48" Canvas.Left="585" Canvas.Top="10" Source="outofbrowser_unknown.png" Stretch="Fill" ToolTipService.ToolTip="Install This Application"/>
<
TextBox x:Name="lyrics" Canvas.Top="400" Canvas.Left="12" Width="512" Height="80" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto"/>
<
Button x:Name="LyricSave" Click="LyricSave_Click" Width="100" Height="80" Content="Save Lyrics" Canvas.Top="400" Canvas.Left="530" />
</
Canvas>
</
UserControl>

3. Saving a file in isolated storage

Before we can retrieve our data from a file, we should probably write it, right? I am going to create a saveLyricsFile method that takes a string for the lyrics we want to save. All it really does is open a pathway to the isolated storage, creates a file (in our case, a .txt file), and then uses a StreamWriter to write the lyrics to the file. Here’s what my method looks like:

        string lyricsfile = "BigBangTheoryLyrics.txt";

private void saveLyricsFile(string lyricsToSave)
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream isfs = isf.OpenFile(lyricsfile, FileMode.Create, FileAccess.Write))
{
using (StreamWriter sw = new StreamWriter(isfs))
{
sw.WriteLine(string.Format("{0}", lyricsToSave));
sw.Close();
}
}
}
getLyrics();
}

You’ll notice that I also call a new method called getLyrics() at the end of this method. Once I’ve saved the file to the user’s machine, I want a different method to retrieve the contents of that file, and write them to the TextBox on my page. That way, each time that the page loads, the lyrics box will have the most up-to-date version of the user’s lyrics file.

4. Retrieving the info in the file

Now that we have a file on the user’s machine, we need a way to get that information back, and use it. Using many of the same mechanisms from step #3, we are going to find our file in isolated storage, open it, and use a StreamReader to read the contents of the file into a string variable. Finally, we write that string to our TextBox. Here’s the method:

        string lyricstext = "Our whole universe was in a hot dense state,nThen nearly fourteen billion years ago expansion started. Wait...nThe Earth began to cool,nThe autotrophs began to drool,nNeanderthals developed tools,nWe built a wall (we built the pyramids),nMath, science, history, unraveling the mysteries,nThat all started with the big bang!nnSince the dawn of man is really not that long,nAs every galaxy was formed in less time than it takes to sing this song.nA fraction of a second and the elements were made.nThe bipeds stood up straight,nThe dinosaurs all met their fate,nThey tried to leap but they were latenAnd they all died (they froze their asses off)nThe oceans and pangeanSee ya, wouldn't wanna be yanSet in motion by the same big bang!nnIt all started with the big BANG!nnIt's expanding ever outward but one daynIt will cause the stars to go the other way,nCollapsing ever inward, we won't be here, it wont be hurtnOur best and brightest figure that it'll make an even bigger bang!nnAustralopithecus would really have been sick of usnDebating out while here they're catching deer (we're catching viruses)nReligion or astronomy, Encarta, DeuteronomynIt all started with the big bang!nnMusic and mythology, Einstein and astrologynIt all started with the big bang!nIt all started with the big BANG!";

private void getLyrics()
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isf.FileExists(lyricsfile))
{
using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(lyricsfile, FileMode.Open, isf))
{
using (StreamReader sr = new StreamReader(isfs))
{
string lyricsdata = sr.ReadToEnd();
lyrics.Text = lyricsdata;
}
}
}
else
{
saveLyricsFile(lyricstext);
}
}
}

Notice that I set up an external string variable that is my original lyrics text. If the file doesn’t exist yet (a distinct possibility, since the user can delete it, or this may be their first time to the site), we need to populate it when we create it. So in my “else” statement, I call the saveLyricsFile method, passing those original lyrics in. Otherwise, if the file exists, we just read the contents of the file, and set those contents to the TextBox.Text value.

5. Calling the getLyrics() method when we load

We already have a Loaded event handler method, so let’s use that to call our getLyrics() method. This way, when the page loads, we’ll retrieve the contents of the file (and if the file doesn’t exist, we’ll create it.)

6. Making the button commit the “save”

The last step we need to take is to get our button to actually save the contents of the TextBox to the isolated storage file. The XAML I gave you earlier already had an event handler defined, so “navigate to event handler,” and add this line:

saveLyricsFile(lyrics.Text);

This will take the contents of our TextBox, and save it to the user’s local file. If you hit refresh in your browser, you should see that the new version of your text appears now. Because I embedded audio in my application, I am providing a link to see my Silverlight Isolated Storage application running. Normally I would just embed it here, but I don’t want to embarrass you at the office. 🙂

You can download my solution for Silverlight Isolated Storage here.

7. Summary

Isolated Storage in Silverlight works both in and outside the browser, but there are different storage requirements depending on how you use it. Out of browser applications have access to 25 MB of storage, while in-brower applications only have 1 MB. The reason for this makes sense, though. When we’re running out of browser, we could be running disconnected, which would require us to store all of the user’s changes locally until we reconnect to the network.

In short, using isolated storage is not very different from writing to the file system in WPF, but we don’t get to specify paths on the user’s machine. All of our data and files reside inside a sandboxed area, that has no access to other parts of the user’s machine. This keeps them safe from malicious attacks that could occur under other circumstances. Here’s a look at where these files are stored:

Windows Vista/7
Users\AppDataLocalLowMicrosoftSilverlightis

Windows XP
Documents and Settings\Local SettingsApplication DataMicrosoftSilverlightis

Mac OS X
/Users//Library/Application Support/Microsoft/Silverlight/is

Only a few more days left in the 31 Days of Silverlight, and then a fun little Silverlight game for you on January 1st. I hope you are enjoying this series!

2 thoughts on “Day #29: Using Isolated Storage in Silverlight

  1. Laughing is the sensation of feeling good all over and showing it principally in one spot.

  2. There are no secrets better kept than the secrets that everybody guesses.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s