I have been trying to solve this stupid problem in a few days and it makes my head. I would be very pleased that someone has a working example, because the ones I found so far have not worked: (I can serialize basic types, but not objects. And I am very confused regarding DataContractAttribute, etc. . The error I get is:
{"Type" SerializeListWinRT.DataModel.LocalStorage + Cat 'with data contract name' LocalStorage.Cat:http://schemas.datacontract.org/2004/07/SerializeListWinRT.DataModel 'is not expected. Consider using a DataContractResolver or add types that are not statically unknown to the list of known types — for example, using the KnownTypeAttribute attribute or adding them to the list of known types passed to the DataContractSerializer. "}
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.Storage; using System.IO; using System.Runtime.Serialization; using Windows.Storage.Streams; namespace SerializeListWinRT.DataModel { class LocalStorage { [DataContractAttribute] public class Cat { [DataMember()] public String Name { get; set; } } static private Dictionary<string, object> _data = new Dictionary<string, object>(); private const string filename = "items.xml"; static public Dictionary<string, object> Data { get { return _data; } } static public T GetItem<T>(string key) { T result = default(T); if (_data.ContainsKey(key)) { result = (T)_data[key]; } return result; } static public bool ContainsItem(string key) { return _data.ContainsKey(key); } static async public Task Save() { await Windows.System.Threading.ThreadPool.RunAsync((sender) => { LocalStorage.SaveAsync().Wait(); }, Windows.System.Threading.WorkItemPriority.Normal); } static async public Task Restore() { await Windows.System.Threading.ThreadPool.RunAsync((sender) => { LocalStorage.RestoreAsync().Wait(); }, Windows.System.Threading.WorkItemPriority.Normal); } static async private Task SaveAsync() { _data.Add("cat", new Cat { Name = "Myname is" }); _data.Add("dog", new Cat { Name = "Myname is" }); StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting); IRandomAccessStream sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite); IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0); DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(Dictionary<string, object>)); sessionSerializer.WriteObject(sessionOutputStream.AsStreamForWrite(), _data); await sessionOutputStream.FlushAsync(); } static async private Task RestoreAsync() { StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists); if (sessionFile == null) { return; } IInputStream sessionInputStream = await sessionFile.OpenReadAsync(); DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(Dictionary<string, object>)); _data = (Dictionary<string, object>)sessionSerializer.ReadObject(sessionInputStream.AsStreamForRead()); } } }
How I solved the problem:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.Storage; using System.IO; using System.Runtime.Serialization; using Windows.Storage.Streams; namespace SerializeListWinRT.DataModel { class LocalStorage { [KnownType(typeof(SerializeListWinRT.Cat))] [DataContractAttribute] public class Cat { [DataMember()] public String Name { get; set; } } static private Dictionary<string, object> _data = new Dictionary<string, object>(); private const string filename = "ngt.xml"; static public Dictionary<string, object> Data { get { return _data; } } static public T GetItem<T>(string key) { T result = default(T); if (_data.ContainsKey(key)) { result = (T)_data[key]; } return result; } static public bool ContainsItem(string key) { return _data.ContainsKey(key); } static async public Task Save<T>() { await Windows.System.Threading.ThreadPool.RunAsync((sender) => { LocalStorage.SaveAsync<T>().Wait(); }, Windows.System.Threading.WorkItemPriority.Normal); } static async public Task Restore<T>() { await Windows.System.Threading.ThreadPool.RunAsync((sender) => { LocalStorage.RestoreAsync<T>().Wait(); }, Windows.System.Threading.WorkItemPriority.Normal); } static async private Task SaveAsync<T>() { _data.Add("cat", new Cat { Name = "Myname is" }); _data.Add("dog", new Cat { Name = "Myname is" }); StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting); IRandomAccessStream sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite); IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0); DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(Dictionary<string, object>), new Type[] { typeof(T) }); sessionSerializer.WriteObject(sessionOutputStream.AsStreamForWrite(), _data); await sessionOutputStream.FlushAsync(); } static async private Task RestoreAsync<T>() { StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists); if (sessionFile == null) { return; } IInputStream sessionInputStream = await sessionFile.OpenReadAsync(); DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(Dictionary<string, object>), new Type[] { typeof(T) }); _data = (Dictionary<string, object>)sessionSerializer.ReadObject(sessionInputStream.AsStreamForRead()); } }
}