65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows Phone 7 的 XML 序列化技巧和窍门

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.43/5 (3投票s)

2011 年 10 月 13 日

CPOL

2分钟阅读

viewsIcon

37219

downloadIcon

505

一些有关如何在 Windows Phone 7 中处理序列化的技巧

引言

最近,我一直在尝试序列化一些复杂的类,以下是我解决 Windows Phone 7 上出现错误的技巧。

Using the Code

在演示代码中,我创建了一个 Settings 类,我们将尝试对其进行序列化。请注意,您需要安装 Windows Phone SDK 7.1 才能运行该项目。

Settings 类有两个方法来简化 保存加载 操作。

public void Save()
    {
        IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
        IsolatedStorageFileStream stream = storage.CreateFile(AppSettingsFileName);

        XmlSerializer xml = new XmlSerializer(GetType());
        xml.Serialize(stream, this);

        stream.Close();
        stream.Dispose();
    }
public static Settings Load()
    {
        IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
        Settings tmpSettings;

        if (storage.FileExists(AppSettingsFileName))
        {
            IsolatedStorageFileStream stream = 
			storage.OpenFile(AppSettingsFileName, FileMode.Open);
            XmlSerializer xml = new XmlSerializer(typeof(Settings));

            tmpSettings = xml.Deserialize(stream) as Settings;

            stream.Close();
            stream.Dispose();
        }
        else
        {
            tmpSettings = new Settings();
        }

        return tmpSettings;
    }

如您所见,我们使用了 .NET Framework 提供的标准 XML 序列化。(您需要在新项目中添加对 System.XML.Serialization 的引用。)

问题 1 - 在保存方法中打开的流

请注意,我们没有为保存代码添加任何异常处理,因此如果序列化失败,流将保持打开状态。让我们尝试向 Settings 类添加新的属性。

public Dictionary<string, int> SomeSettings { get; set; }
public int[] Array { get; set; }
public int[,] Array2D { get; set; }

如果您现在将主窗体添加到按钮以调用 保存加载 函数并运行程序,您应该在 保存 方法期间看到异常。

There was an error reflecting type 'Serialization.Settings'.

内部异常表明它无法序列化 SomeSettings 属性。现在,我们可以使用 [XmlIgnore] 属性对其进行标记并重新运行程序。保存 操作现在应该成功完成。但有时,并且在此处,您会收到一个说

An error occurred while accessing IsolatedStorage. 
Windows phone 7 at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor

这是因为 在模拟器中之前的程序运行中打开并挂起。现在您必须重新启动模拟器才能解决此问题。为了摆脱此错误,您需要修改 保存/加载 函数的代码

public void Save()
        {
            IsolatedStorageFile storage = 
		IsolatedStorageFile.GetUserStoreForApplication();
            IsolatedStorageFileStream stream = null;
            try
            {
                stream = storage.CreateFile(AppSettingsFileName);

                XmlSerializer xml = new XmlSerializer(GetType());
                xml.Serialize(stream, this);
            }
            catch (Exception ex)
            { }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                    stream.Dispose();
                }
            }
        }
        public static Settings Load()
        {
            IsolatedStorageFile storage = 
		IsolatedStorageFile.GetUserStoreForApplication();
            Settings tmpSettings;

            if (storage.FileExists(AppSettingsFileName))
            {
                IsolatedStorageFileStream stream = null;
                try
                {
                    stream = storage.OpenFile(AppSettingsFileName, FileMode.Open);
                    XmlSerializer xml = new XmlSerializer(typeof(Settings));

                    tmpSettings = xml.Deserialize(stream) as Settings;
                }
                catch (Exception ex)
                {
                    tmpSettings = new Settings();
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Close();
                        stream.Dispose();
                    }
                }
            }
            else
            {
                tmpSettings = new Settings();
            }

            return tmpSettings;
        }

问题 2 - 您无法序列化的内容

让我们向设置类添加构造函数

public Settings()
        {
            SomeSettings = new Dictionary<string, int>() 
			{ { "Code", 1 }, { "User", 2 } };
            Array = new int[] { 1, 23, 4 };
            Array2D = new int[,] { { 1, 2 }, { 3, 4 } };
        }

现在序列化将失败,因为我们尝试序列化 二维数组。您可以通过将 2D 数组替换为 List<int[]> 来解决此问题。

您也 无法序列化 Dictionary<P,Q>。解决这个问题有点困难。一种选择是用 List<Pair> 替换 Dictionary,其中 Pair

public class Pair<t,q />
    {
        public T Key { get; set; }
        public Q Value { get; set; }

        public Pair() {}
        public Pair(T x, Q y)
        {
            Key = x;
            Value = y;
        }
    }

类序列化的其他限制

  • 类必须是 public
  • 类必须具有默认构造函数
  • 只有 public 成员将被序列化
  • 属性必须同时具有 get/set public

链接

历史

  • 1.0 - 创建于 2011/12/10
© . All rights reserved.