Kotan Code 枯淡コード

In search of simple, elegant code

Menu Close

Storing Local Data on Windows Phone 7 Series with Isolated Storage

As I mentioned in my last blog post, one of the things that’s missing on the Windows Phone 7 series is a local database. I was originally quite surprised at the decision not to include a SQL Express edition because the .NET Compact Framework comes with an insane amount of support for talking to local and remotely synchronized SQL databases.

In lieu of having a database, the next best thing that we can do is basically write a data model using simple POCOs (Plain Old CLR Objects) and decorate them with the DataContract and DataMember attributes. This will allow us to use WCF’s DataContractSerializer class to read and write this object graph from a stream. The stream we’re going to use is going to be one that we initialize out of Isolated Storage.

The sample application I’m going to build is really simple: it’s going to keep a local, isolated storage-based log of all the start times for the application. This isn’t really all that practical, but it will show you that the data is being persisted to disk between executions of the application and between debug sessions as well.

To start, let’s create the DataModel class that will be serialized and de-serialized from Iso storage:

[DataContract]
public class DataModel
{
 public DataModel() { }
 [DataMember]
 public int StartupCount { get; set; }

 [DataMember]
 public List<DateTime> StartupTimes { get; set; }

 public static DataModel FromFile()
 {
   DataModel dm = null;
   using (IsolatedStorageFile isf =
   IsolatedStorageFile.GetUserStoreForApplication())
   {
     using (IsolatedStorageFileStream stream =
       new IsolatedStorageFileStream("datamodel.dat",
     System.IO.FileMode.OpenOrCreate, isf))
     {
       if (stream.Length > 0)
       {
         DataContractSerializer dcs =
            new DataContractSerializer(typeof(DataModel));
         dm = dcs.ReadObject(stream) as DataModel;
       }
     }
   }

   if (dm == null)
   {
     dm = new DataModel();
     dm.StartupTimes = new List<DateTime>();
   }
   return dm;
 }

 public void SaveToFile()
 {
    using (IsolatedStorageFile isf =
     IsolatedStorageFile.GetUserStoreForApplication())
   {
     using (IsolatedStorageFileStream stream =
       new IsolatedStorageFileStream("datamodel.dat", FileMode.Create, isf))
    {
      DataContractSerializer dcs =
        new DataContractSerializer(typeof(DataModel));
      dcs.WriteObject(stream, this);
    }
   }
  }
  }

Now that we’ve got a serializable and de-serializable data model that gets and stores its data in an Iso store file, we can put a little code in our application’s home page to prove that we’re actually persisting data between runs of the application:


DataModel dm = DataModel.FromFile();
dm.StartupCount++;
dm.StartupTimes.Add(DateTime.Now);
dm.SaveToFile();

MessageBox.Show(string.Format("{0} start count, {1} startup times length",
 dm.StartupCount, dm.StartupTimes.Count), "Data Model", MessageBoxButton.OK);

With this in place, our application looks like this after a couple of runs:

WP7 Data Serialization Test

WP7 Data Serialization Test

While this is certainly not the only option you have for storing local data, it’s definitely one of the easiest because it only takes a few lines of code to go from disk file to fully functional object graph.