There is a very basic need to cache some data at clientside in Silverlight, when we get data using WCF service and want that data to reside at the client side so that the system will not fetch the data every time from the server. This will make sense when we know that the data is kind of static and will not change frequently.
To make use of
IsolatedStorage, a developer has to create a file stream and save the data. Ideally in the real world, all data will be kept in memory as an object of some type. Now to store this object in
IsolatedStorage, one has to first deserialize it and store it in files and define file names for them. Later this data will be read from the files and will be kept in memory again in the form of an object.
To simplify the above task, I have combined the functionality of
DataContractSerializer and created the
ClientStorage class which helps the user to store any object directly in the
IsolatedStorage, i.e. making object persistent, an interesting feature of OOPs. To achieve a feature of OOPs, one must follow the OOPs approach rather than writing the same code again and again for different objects. This piece of code can be clubbed together and I have named it as
Silverlight provides two classes, one is
IsolatedStorage and another is
IsolatedStorage class to store data at the client machine. With isolated storage, data is isolated by user and by assembly. Credentials such as the origin or the strong name of the assembly determine assembly identity. Data can also be isolated by application domain, using similar credentials.
DataContractSerializer class is used to serialize and deserialize instances of a type into an XML
stream or document. For example, you can create a type named
Person with properties that contain essential data, such as a name and address. You can then create and manipulate an instance of the
Person class and write all of its property values in an XML document for later retrieval, or in an XML stream for immediate transport. Most important, the
DataContractSerializer is used to serialize and deserialize data sent in Silverlight version 2 messages. Apply the
DataContractAttribute attribute to classes, and the
DataMemberAttribute attribute to class members to specify properties and fields that are serialized.
ClientStorage is a singleton class that is basically a indexed collection which helps in fetching the objects on the basis of key. It automatically serializes the object and also stores the type of the object, so that it can be de-serialized later. It gives Index based object fetching mechanism which makes life easier.
It contains a
Dictionary of key and object. It writes all the keys to keyNames.txt and each object in a separate file. Key names are unique so all the objects will be stored in the file name as <key_name>object.xml.
An indexer is written to fetch the value via providing the key in the index. As soon as any new key is added to the
ClientStorage, it adds it to the
Dictionary and serializes the
Dictionary and stores it in keynames.txt file. Then the newly added object is serialized and stored in a separate file. When object is retrieved from
ClientStorage, it first looks for the key existence and then if the object is
null, reads the object's XML file, deserializes the object, updates in
Dictionary and then returns the object.
private object Retreive(string key)
if (CheckForFileExistence(key + KEY_OBJECT_FILE) &&
if (keysNTypes[key].StoredObject == null)
using (IsolatedStorageFileStream iStream =
new IsolatedStorageFileStream(key + KEY_OBJECT_FILE,
if (iStream != null)
DataContractSerializer serializer =
value = serializer.ReadObject(iStream);
keysNTypes[key].StoredObject = value;
throw new KeyNotFoundException();
value = keysNTypes[key].StoredObject;
While instantiating the
ClientStorage object, it reads the keys file and creates the
Dictionary without their objects. When retrieval request comes for any object, then only it fetches the object from the XML file. This way I am minimizing the effort of loading/instantiating the
private void ReadKeys(IsolatedStorageFile isoStore)
IsolatedStorageFileStream iStream =
DataContractSerializer serializer =
keysNTypes = serializer.ReadObject(iStream) as Dictionary<string>;
Using the Code
The approach is simple and following the habit of using
ViewState. When we use
Session to store any object in ASP.NET, the developer does not bother where this information will be kept. She/he keeps her/his objects in
session when she wanted them to be available throughout the life time of user's session. The same applies to
IsolatedStorage, when developer wants to store something per user/application wide data on client machine that would be available cross browser to the application independent of
session like persistent for always until user deletes them manually. Then why to complicate things, why not something like
ClientStorage[keyname] = object; and it's all done.
ClientStorage[keyname] = object;
object = ClientStorage[keyname];
Next, it can be improved/enhanced further to provide versioning support for the objects stored in
ClientStorage so that it helps in identifying the stale objects in the
ClientStorage and allows to re-fetch/re-creation of that object.
I know this can be improved further, any suggestions or feedback will be highly appreciated.
- 28th June, 2009: Initial post