Page view counter

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.

Published Monday, September 29, 2008 1:06 PM by jesseliberty

Comments

# re: Isolated Storage – Might Be Easier Than You Think

Dude, that is one sweet article.

Very well done.

Please keep it comming.

Monday, September 29, 2008 4:17 PM by caperaven

# re: Isolated Storage – Might Be Easier Than You Think

Wouldn't it be more accurate to say that you can store anything in site/app settings that the DataContractSerializer can serialize?  I believe this is going to preclude a number of advanced scenarios.  That's way it worked in Beta 2 at least.

Monday, September 29, 2008 11:44 PM by rob.eisenberg

# Silverlight Cream for September 29, 2008 -- #382

Boyan Mihaylov on SL/Amazon, David Hyde with SL Stock Portfolio, Chris Anderson with SL LOB app, Jesse

Tuesday, September 30, 2008 2:00 AM by Community Blogs

# 2008 September 30 - Links for today « My (almost) Daily Links

Pingback from  2008 September 30 - Links for today « My (almost) Daily Links

# re: Isolated Storage – Might Be Easier Than You Think

Great article, but that's the first time I've seen "Ulysis" spelt like that!

Tuesday, September 30, 2008 8:38 AM by jasonbsteele

# Silverlight news for September 30, 2008

Pingback from  Silverlight news for September 30, 2008

Tuesday, September 30, 2008 9:45 AM by Silverlight news for September 30, 2008

# re: Isolated Storage – Might Be Easier Than You Think

Rob.eisenberg: I want to check further, but I don't see any implication that you must use the DataContractSerializer with IsolatedStorage -- it seems to me that you are writing bytes. But let me look further, perhaps I'm missing something fundamental (wouldn't be the first time).

Jasonbsteele: oops. Gotta fix that!

Tuesday, September 30, 2008 4:12 PM by jesseliberty

# Dew Drop – September 30, 2008 (Evening Edition) | Alvin Ashcraft's Morning Dew

Pingback from  Dew Drop – September 30, 2008 (Evening Edition) | Alvin Ashcraft's Morning Dew

# re: Isolated Storage – Might Be Easier Than You Think

@jesse

Actually I think we are talking about two different things.  I believe I misinterpreted your post.  Isolated storage can store anything.  But, the VS built in Settings class uses the DataContractSerializer to serialize any of its custom settings to iso storage.  So the restriction is in the build-in Settings class, not in iso storage.

Friday, October 03, 2008 12:12 PM by rob.eisenberg

# So Much Technology – So Little Time

We have, I think, officially passed the point where anyone can keep up with the new technology available

Thursday, October 23, 2008 11:21 AM by Jesse Liberty - Silverlight Geek

# So Much Technology – So Little Time

We have, I think, officially passed the point where anyone can keep up with the new technology available

Thursday, October 23, 2008 11:51 AM by Microsoft Weblogs

# Silverlight Tipps vom Insider

Pingback from  Silverlight Tipps vom Insider

Friday, October 24, 2008 5:08 AM by Silverlight Tipps vom Insider

# My Silverlight talk at Montreal .NET User Group

This week I gave a Silverlight presentation at the Montreal .NET Community ( www.dotnetmontreal.com

Tuesday, April 07, 2009 8:31 AM by Laurent Duveau

# My Silverlight talk at Montreal .NET User Group

This week I gave a Silverlight presentation at the Montreal .NET Community ( www.dotnetmontreal.com

Tuesday, April 07, 2009 11:09 AM by Laurent Duveau

# Canadian MVP Rocks Silverlight in Montreal!

MVP Laurent Duveau recently delivered a Silverlight talk at the Montreal .NET Community . During his

Friday, May 01, 2009 4:55 AM by The Microsoft MVP Award Program Blog

# silverlight所有

用反射来动态加载XAML

2009年04月23日星期四23:25 2008年10月,写了一篇《动态加载XAML文件》,其中按照SilverlightMSDN的

Tuesday, June 16, 2009 5:27 AM by 冰云