Isolated Storage – Might Be Easier Than You Think

 

Tim Heuer did an excellent video on IsolatedStoarge, but I'd like to quickly review the the fundamentals as they are quite a bit simpler than many fear.  The idea of IsolatedStorage is to provide your Silverlight Application with access to the user's disk, so that you may store… well, whatever you like when your application is not running. Whether or not you have access, and how much space is allocated is entirely under the control of the user.

In many ways, IsolatedStorage is the next generation of cookies: you can store more, more robustly, with greater precision and control. A full blown usage of IsolatedStorage might involve the creation of files within a directory structure (all of which is obfuscated on the user's hard drive), quota allocation and the storage of binary data. You might use this to store far more than window positions or the user's current "state" within your application; you could conceivably store parts of your application or other binary data to speed up or otherwise enhance the user's experience.

At its simplest though, using IsolatedStorage can be as simple as writing to one of two pre-defined dictionaries: IsolatedStorageSettings.ApplicationSettings or IsolatedStorageSettings.SiteSettings. 

In both cases, the key is defined to be a string, the value to be an object. You grab a reference to the dictionary and the IsolatedStorage system ensures that your application's dictionary is isolated from the dictionaries of other applications. SiteSettings are, as you might expect, shared among all applications on a site.

To be more exact, Applications settings are per-application, per-computer and per-user while SiteSettings are  per-domain, per-computer and per-user.

If I have IE open to two sites, http://microsoft.com/redmond/example1.xap and http://microsoft.com/redmond/example2.xap, these applications will share site settings since they share the same domain, but different application settings.

This can get tricky, though. If my browser is open to http://microsoft.com/redmond/example1.xap and http://microsoft.com/boston/example1.xap it turns out they share the same site (microsoft.com) but not the same application as these are independent .xap files as determined by the full path.

But now we're deep in the mud, and at a high level, getting started with IsolatedStorage is easy, which is the point of this posting.

The application I built (total development time 10 minutes) looks like this,

IsoAdd

Clicking the Add button adds three key/value pairs to IsolatedStorageSettings.ApplicationSettings  and 9 key/value pair to IsolatedStorageSettings.SiteSettings.

   1: void Add_Click( object sender, RoutedEventArgs e )
   2: {
   3:    try
   4:    {
   5:       appSettings.Add( "Ulysses", "Stephen Dedalus" );
   6:       appSettings.Add( "The Catcher in the Rye", "Holden Caulfield" );
   7:       appSettings.Add( "Tom Sawyer", "Huckleberry Finn" );
   8:       siteSettings.Add( "Connection", "Fios" );
   9:       siteSettings.Add( "SpeedUp", "20" );
  10:       siteSettings.Add( "SpeedDown", "5" );
  11:       siteSettings.Add( "Browser1", "IE7" );
  12:       siteSettings.Add( "Browser2", "FireFox" );
  13:       siteSettings.Add( "Browser3", "IE8" );
  14:       siteSettings.Add( "Browser4", "Safari" );
  15:       siteSettings.Add( "OS1", "Vista" );
  16:       siteSettings.Add( "OS2", "Leopard" );
  17:       Display( "Added 3 to app settings, 9 to app settings." );
  18:    }
  19:    catch ( ArgumentException ex )
  20:    {
  21:       Display( ex.Message );
  22:    }
  23: }

Retrieve is hardwired to return the value where the key is Ulysses,

   1: void Retrieve_Click( object sender, RoutedEventArgs e )
   2: {
   3:  
   4:    try
   5:    {
   6:       Display("If the user asked for the main character  in Ulysses, we'd return " + 
   7:          appSettings["Ulysses"].ToString());
   8:    }
   9:    catch ( System.Collections.Generic.KeyNotFoundException ex )
  10:    {
  11:       Display( ex.Message );
  12:    }
  13: }

 

 

 

 

 

IsoRetrieve

Finally, to demonstrate that these are normal collections, with the normal keys and values collection, I provide buttons that iterate through the collections.

IsoValues

Once again, the code is just C# iterating through a dictionary's value collection…

   1: void Values_Click( object sender, RoutedEventArgs e )
   2: {
   3:    string header = "Values: ";
   4:    string msg = header;
   5:    foreach ( object o in appSettings.Values )
   6:    {
   7:        if ( msg.Length > header.Length )
   8:             msg += ", ";
   9:          msg += o.ToString();
  10:       
  11:    }
  12:  
  13:    foreach ( object o in siteSettings.Values )
  14:    {
  15:        if ( msg.Length > header.Length )
  16:             msg += ", ";
  17:          msg += o.ToString();
  18:    }
  19:    Display( msg );
  20: }

 

 

 

 

Not Just Strings

Of course, you don't have to add just strings. The value is an object and can be anything. Let's make an incredibly simple GeekObject and substitute that for the applicationSettings.  We'll start by adding a GeekClass,

   1: namespace SimpleIsolatedStorage
   2: {
   3:    public class Geek
   4:    {
   5:       public string Name { get; set; }
   6:       public int GeekScore { get; set; }
   7:       public string FavoriteGeekBook { get; set; }
   8:       public bool PassTheBestSceneInApollo13Test { get; set; }
   9:  
  10:       public Geek( string name, int score, string book, bool passed )
  11:       {
  12:          Name = name;
  13:          GeekScore = score;
  14:          FavoriteGeekBook = book;
  15:          PassTheBestSceneInApollo13Test = passed;
  16:       }
  17:    }
  18: }

 

Notes: The GeekScore is your results on the Computer Geek test. The PassTheBestSceneInApollo13Test is very simple: what's your favorite scene in the movie Apollo 13?   The value true indicates you answered with some variation of the following:[Several technicians dump boxes containing the same equipment and tools that the astronauts have with them onto a table] Technician: We've got to find a way to make this
[square CSM LiOH canister]  fit into the hole for this [round LEM canister]  … using nothing but that.

The changes to the code are in Add, Retrieve and Values as follows:

   1: void Add_Click( object sender, RoutedEventArgs e )
   2: {
   3:    try
   4:    {
   5:       appSettings.Add( "Jesse", new Geek("Jesse Liberty", 62, "Dragon Book", true));
   6:       appSettings.Add( "Chris", new Geek("Chris ???",30.96647,"Programming WPF",true));
   7:       appSettings.Add( "Dan", new Geek("Dan Hurwitz", 0, "Programming ASP.NET", true));

Adding the appSettings, we make sure we add Geek objects.

Retrieving, we retrieve a hardwired value again, but this time we have to parse out the Geek values,

void Retrieve_Click( object sender, RoutedEventArgs e )
{

   try
   {
      object o = appSettings["Jesse"];  // hard wired retrieve
      Geek g = o as Geek;
      string notString = g.PassTheBestSceneInApollo13Test ? String.Empty : "not ";
      Display("Retrieving Geekiness for Jesse. Score:  " + g.GeekScore.ToString() +
         " and " + g.Name + " did " + notString + "pass the Apollo 13 movie test. ");
   }
   catch ( System.Collections.Generic.KeyNotFoundException ex )
   {
      Display( ex.Message );
   }
}

IsoGeekRetrieve

 

 

 

Finally, when we tick through the values collection, we want again to make sure we're dealing with the Geek object and not just the object per se,

   1: void Values_Click( object sender, RoutedEventArgs e )
   2: {
   3:    string header = "Values: ";
   4:    string msg = header;
   5:    foreach ( object o in appSettings.Values )
   6:    {
   7:        if ( msg.Length > header.Length )
   8:             msg += ", ";
   9:  
  10:        Geek g = o as Geek;
  11:        msg += g.Name + "(" + g.FavoriteGeekBook + ")";
  12:       
  13:    }

IsoGeekValues

Full Source Code SimpleIsolatedStorage.zip 

 

Thanks.

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in z Silverlight Archives. Bookmark the permalink.

One Response to Isolated Storage – Might Be Easier Than You Think

Comments are closed.