在IsolatedStorageSettings中存储对象
我有一个对象我想存储在IsolatedStorageSettings中,我不想在应用程序重启时重用它。
我的问题在于,由于某种原因我编写的代码在重新启动时尝试访问密钥时不记得该对象。
namespace MyNameSpace { public class WindowsPhoneSettings { private const string SelectedSiteKey = "SelectedSite"; private IsolatedStorageSettings isolatedStore = IsolatedStorageSettings.ApplicationSettings; private T RetrieveSetting(string settingKey) { object settingValue; if (isolatedStore.TryGetValue(settingKey, out settingValue)) { return (T)settingValue; } return default(T); } public bool AddOrUpdateValue(string Key, Object value) { bool valueChanged = false; if (isolatedStore.Contains(Key)) { if (isolatedStore[Key] != value) { isolatedStore[Key] = value; valueChanged = true; } } else { isolatedStore.Add(Key, value); valueChanged = true; } return valueChanged; } public MobileSiteDataModel SelectedSite { get { return RetrieveSetting(SelectedSiteKey); } set { AddOrUpdateValue(SelectedSiteKey, value); isolatedStore.Save(); } } } }
然后我在App.xaml.cs中实例化WindowsPhoneSettings并为它创建一个公共getter和setter。 能够在整个应用程序中访问它。 调试这表明正确的对象存储在隔离的存储中,但是当关闭应用程序并重新打开它时,隔离存储似乎是空的。 我在模拟器和真实设备上都试过这个。 如您所见,我在设置对象时调用了save方法。
我在这做错了什么?
我最终将设置保存到隔离存储中的文件,因为IsolatedStorageSettings似乎永远不起作用。
所以我的代码最终是这样的:
public class PhoneSettings { private const string SettingsDir = "settingsDir"; private const string SettingsFile = "settings.xml"; public void SetSettings(Settings settings) { SaveSettingToFile(SettingsDir, SettingsFile, settings); } public Settings GetSettings() { return RetrieveSettingFromFile (SettingsDir, SettingsFile); } private T RetrieveSettingFromFile(string dir, string file) where T : class { IsolatedStorageFile isolatedFileStore = IsolatedStorageFile.GetUserStoreForApplication(); if (isolatedFileStore.DirectoryExists(dir)) { try { using (var stream = new IsolatedStorageFileStream(System.IO.Path.Combine(dir, file), FileMode.Open, isolatedFileStore)) { return (T)SerializationHelper.DeserializeData (stream); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Could not retrieve file " + dir + "\\" + file + ". With Exception: " + ex.Message); } } return null; } private void SaveSettingToFile (string dir, string file, T data) { IsolatedStorageFile isolatedFileStore = IsolatedStorageFile.GetUserStoreForApplication(); if (!isolatedFileStore.DirectoryExists(dir)) isolatedFileStore.CreateDirectory(dir); try { string fn = System.IO.Path.Combine(dir, file); if (isolatedFileStore.FileExists(fn)) isolatedFileStore.DeleteFile(fn); //mostly harmless, used because isolatedFileStore is stupid :D using (var stream = new IsolatedStorageFileStream(fn, FileMode.CreateNew, FileAccess.ReadWrite, isolatedFileStore)) { SerializationHelper.SerializeData (data, stream); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Could not save file " + dir + "\\" + file + ". With Exception: " + ex.Message); } } }
还有一个设置类,只包含我想要保存的东西。 这可能是:
class Settings { private string name; private int id; public string Name { get { return name; } set { name = value; } } public int Id { get { return id; } set { id = value; } } }
编辑:如何实现SerializationHelper
示例
public static class SerializationHelper { public static void SerializeData(this T obj, Stream streamObject) { if (obj == null || streamObject == null) return; var ser = new DataContractJsonSerializer(typeof(T)); ser.WriteObject(streamObject, obj); } public static T DeserializeData (Stream streamObject) { if (streamObject == null) return default(T); var ser = new DataContractJsonSerializer(typeof(T)); return (T)ser.ReadObject(streamObject); } }
存储在IsolatedStorageSettings中的对象使用DataContractSerializer进行序列化,因此必须是可序列化的。 在添加到ISS之前(以及从ISS中删除之后),确保它们可以自己或序列化(并反序列化)它们。
如果在尝试检索时项目不存在,则可能是因为序列化问题而无法首先添加它们。
这是我用来将对象保存到独立存储并从独立存储加载对象的代码 –
private void saveToIsolatedStorage(string keyname, object value) { IsolatedStorageSettings isolatedStore = IsolatedStorageSettings.ApplicationSettings; isolatedStore.Remove(keyname); isolatedStore.Add(keyname, value); isolatedStore.Save(); } private bool loadObject(string keyname, out object result) { IsolatedStorageSettings isolatedStore = IsolatedStorageSettings.ApplicationSettings; result = null; try { result = isolatedStore[keyname]; } catch { return false; } return true; }
这是我用来调用上面的代码 –
private void SaveToIsolatedStorage() { saveToIsolatedStorage("GameData", GameData); } private void LoadFromIsolatedStorage() { Object temp; if (loadObject("GameData", out temp)) { GameData = (CGameData)temp; } else { GameData.Reset(); } }
请注意,我保存和恢复的对象很小且可序列化。 如果我的对象包含一个二维数组或其他一些不可序列化的对象,那么在使用iso存储之前,我会执行自己的序列化和反序列化。
如果您将RetrieveSetting
更改为:
private T RetrieveSetting(string settingKey) { T settingValue; if(isolatedStore.TryGetValue(settingKey, out settingValue)) { return (T)settingValue; } return default(T); }
请注意,正在提取的对象被声明为类型T
而不是object
。