反序列化未知类型

时间:2012-01-16 22:34:06

标签: c# .net xml serialization

我有以下XML:

<property name="someName" value="someValue" />

或者,这可能是:

<property name="someName" value="5" />

或者:

<property name="someName" value="true" />

等等......

[Serializable]
[XmlType("property")]
public class Property
{
    [XmlAttribute("name")]
    public string Name { get; set; }
    [XmlAttribute("value")]
    public object Value { get; set; }

    public Property()
    {

    }
}

上述代码不起作用。我可以使用字符串或任何特定的东西,只要它始终是特定类型。我希望对象允许任何已知的类型工作。

2 个答案:

答案 0 :(得分:5)

除非使用IXmlSerializable接口实现自定义序列化并手动处理情况,否则无法将对象用作XmlSerializer属性的数据类型。如果您没有将Value属性序列化为属性,则可以使用XmlInclude指定可能的已知类型(例如int,bool,string,...),并且序列化程序将在XML上发出其他属性指定确切的类型,以便它知道如何反序列化。但所有这些都不适用于您的场景,因为您正在使用属性。不幸的是,您必须重新考虑XML结构或使用自定义序列化。 XmlSerializer根本无法处理这种情况。

另一种可能性是将此属性定义为String并执行后序列化处理。甚至可能在模型上定义另一个只有getter的属性,并且基于此字符串的值可能会尝试将其解析为某个基础类型。

答案 1 :(得分:1)

那么,xml序列化程序如何知道您是否要存储字符串“5”或实际数字5?您需要实现IXmlSerializable接口,或者您可以应用解决方法:

[Serializable]
[XmlType("property")]
public class Property
{
    [XmlAttribute("name")]
    public string Name { get; set; }
    [XmlAttribute("value")]
    public string StringValue { get; set; }

    private object _Value;
    [XmlIgnore]
    public object Value
    {
        get
        {
            if (_Value == null)
            {
                 _Value = CreateFromStringValue();
            }
            return _Value;
        }
    }

    public Property()
    {
    }

    private object CreateFromStringValue()
    {
       // parse StringValue in here as you see fit (e.g. first try bool, then int, float, etc.)
    }
}

不太好,但可能就是你所需要的一切。