Windows 8 Snippet: Proper Serialization
This week's Windows 8 snippet covers one of the most widely used tasks, especially when it comes to local data storage and retrieval - serialization. I got tired of re-writing the same routine over and over again, so here are the code fragments for my and your record.
Serialization:
public static async Task<bool> SerializeToFile<T>(string fileName, T serializationSource)
{
try
{
StorageFile file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(
fileName, CreationCollisionOption.ReplaceExisting);
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(stream.AsStreamForWrite(), serializationSource);
}
return true;
}
catch
{
return false;
}
}
Notice that I am making this as flexible as possible. The normal approach for a lot of developers would be passing a defined type as the serialization source. Which is a viable solution for small applications, but is bound to be too cumbersome for larger solutions where you will have to serialize multiple types to multiple destinations. Hence, I am also requiring the developer to specify the file name that I will be using as the destination.
Also, notice that I am using Windows.Storage.ApplicationData.Current.LocalFolder as the root. That way, I do not need to declare any custom capabilities in order for this function to work, as it will push the data in the application-designated space. This can be customized by requesting the StorageFolder instance to be written to.
Also pay close attention to what the function is returning. Do not, I repeat, DO NOT use async void. If the task is successful, it will signal this via a bool value. Same applies to case where it might fail (e.g. not enough storage space).
Deserialization:
public static async Task<T> DeserializeFromFile<T>(string fileName)
{
T returnable;
try
{
StorageFile file = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))
{
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
returnable = (T)serializer.ReadObject(stream.AsStream());
}
return returnable;
}
catch
{
return default(T);
}
}
Here I am taking a similar approach when it comes to getting the type-based data back. There are no pre-defined types - everything is inferred from the generic T. If the data is correctly serialized, I am returning the instance that I managed to obtain. Otherwise the default value is returned for the type passed, which could be null for reference types and appropriate values for value types (e.g. 0 for int, false for bool).





