Friday, January 7, 2011

Using Isolated Storage

Once again, first we have to understand what it is and how it works.

In my own words:
It is a folder in Windows' File System where you can securely store data for your applications. You would, for example, want to store data in Isolated Storage for a small application which you don't want to have to use a Database, or a .config file. In addition to that, the user won't see the data being stored, it won't ask for any permission or anything like that. Another great thing is that Isolated Storage can be divided by machine's users, which means that each user will have their own configuration for your application. It can also be divided by users and applications, or by users and assemblies.

In MSDN's words:
Isolated storage is a data storage mechanism that provides isolation and safety by defining standardized ways of associating code with saved data. Standardization provides other benefits as well. Administrators can use tools designed to manipulate isolated storage to configure file storage space, set security policies, and delete unused data. With isolated storage, your code no longer needs unique paths to specify safe locations in the file system, and data is protected from other applications that only have isolated storage access. Hard-coded information that indicates where an application's storage area is located is unnecessary.

That pretty much covers it. Following what I said, let us declare a configuration class and serialize it to the Isolated Storage. Here's our configuration class:

[Serializable] // This is not really needed for XML Serialization: it will serialize without it
public class Config
    public string InitialDirectory { get; set; }
    public bool StartActivated { get; set; }
    public string WarningMessage { get; set; }
    public int ExpireTime { get; set; }

I am assuming we will serialize all of its members.

Working with Isolated Storage is pretty straight-forward. The two key classes are IsolatedStorageFile which represents the Isolated Storage and IsolatedStorageFileStream, which is literally a stream.
Using both of them, with the following code we can serialize our Config class to Isolated Storage, as a XML:

using System.IO;
using System.IO.IsolatedStorage;
using System.Xml.Serialization;

// First we fill our config fields:
Config config = new Config();
config.InitialDirectory = @"C:\Temp";
config.StartActivated = true;
config.WarningMessage = "Don't do that again!";
config.ExpireTime = 90;

// Now let's get a reference to the Isolated Storage:
IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication(); // You may get an exception here, I'll talk about it below
isolatedStorageFile.CreateDirectory("MyDir"); // If you will

// Our Stream to Isolated Storage:
IsolatedStorageFileStream isolatedStream = new IsolatedStorageFileStream(@"MyDir\config.xml", FileMode.OpenOrCreate, isolatedStorageFile); // Pass FileMode as OpenOrCreate so you won't get an exception if the file already exists, nor will you have to check for it

// Serializing it:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Config));

xmlSerializer.Serialize(isolatedStream, config);

// Now flush our Isolated Stream:

So you have your Application's Configurations serialized to Isolated Storage, divided by user.
This way you can deserialize it and apply it to your application, like this:

using System.IO;
using System.IO.IsolatedStorage;
using System.Xml.Serialization;

IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream isolatedStreamOpen = new IsolatedStorageFileStream(@"MyDir\config.xml", FileMode.Open, isolatedStorageFile); // Here FileMode has to be Open
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Config));

Config config = (Config)xmlSerializer.Deserialize(isolatedStreamOpen);

// Then you can distribute your configurations across  your application

About that exception I said you might get, exception of type IsolatedStorageException, with message "Unable to determine application identity of the caller.". This means that your application is not enabled for ClickOnce security settings. This allows your application to use Isolated Storage, and some other stuff.

Editing: If you plan on running your application as a simple .exe file, without having to install it, the method GetUserStoreForApplication() won't be good. It only 'lets' you access Isolated Storage after the application is deployed, installed, and not as a single .exe file. It WILL work if you run it through Visual Studio though. So be careful here. As an alternative, use method GetUserStoreForDomain().

To activate ClickOnce Security Settings, do this:
  • Right click your project, and select Properties
  • Go to the security tab
  • Check the option "Enable ClickOnce Security Settings"

Doing this prevents the exception from happening.

Again, hope it helps.

No comments:

Post a Comment