反序列化时跳过无效值

时间:2015-02-28 14:23:13

标签: c# .net xml

问题

是否可以在反序列化时跳过无效值?例如,如果用户在xml文件中插入了无效值。

类定义

using Relink.Data.Enum;
using System;
using System.IO;
using System.Xml.Serialization;
using System.ComponentModel; 

namespace Relink {

    [Serializable]
    public class Settings {

        internal static XmlSerializer Serializer = new XmlSerializer(typeof(Settings));

        public Difficulty Difficulty {
            get;
            set;
        }

        public Boolean CaptureMouse {
            get;
            set;
        }

        internal void loadDefaults() {
            this.Difficulty = Difficulty.Normal;
            this.CaptureMouse = false;
        }

    }

}

序列化方法

// ...
if(!File.Exists(GameDir + SettingsFile)) {
    Settings = new Settings();
    Settings.loadDefaults();
    TextWriter writer = new StreamWriter(GameDir + SettingsFile);
    Settings.Serializer.Serialize(writer, Settings);
    writer.Close();
    writer.Dispose();
} else {
    TextReader reader = new StreamReader(GameDir + SettingsFile);
    Settings = (Settings)Settings.Serializer.Deserialize(reader);
}
// ...

XML内容(有效)

<?xml version="1.0" encoding="utf-8"?>
<Settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Difficulty>Normal</Difficulty>
  <CaptureMouse>false</CaptureMouse>
</Settings>

XML内容(无效)

<?xml version="1.0" encoding="utf-8"?>
<Settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Difficulty>Moo</Difficulty>
  <CaptureMouse>false</CaptureMouse>
</Settings>

说明

我不想“重置”用户设置,我只想跳过无效的内容并使用默认值。否则,我会尝试一个try / catch构造,只需重新生成xml文件。

1 个答案:

答案 0 :(得分:2)

不幸的是,当遇到未知的XmlSerializer值时,无法在enum内抑制异常。相反,您需要为此目的创建一个string - 值的属性,并序列化该属性而不是enum - 值的属性:

[Serializable]
public class Settings
{
    internal static XmlSerializer Serializer = new XmlSerializer(typeof(Settings));

    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    [XmlElement("Difficulty")]
    public string XmlDifficulty
    {
        get
        {
            return Difficulty.ToString();
        }
        set
        {
            try
            {
                Difficulty = (Difficulty)Enum.Parse(typeof(Difficulty), value);
            }
            catch
            {
                Debug.WriteLine("Invalid difficulty found: " + value);
                Difficulty = Difficulty.Normal;
            }
        }
    }

    [XmlIgnore]
    public Difficulty Difficulty { get; set; }

    public Boolean CaptureMouse { get; set; }

    internal void loadDefaults()
    {
        this.Difficulty = Difficulty.Normal;
        this.CaptureMouse = false;
    }
}