【问题标题】:How can I deserialize an XML, when I only know the type of an ancestor class?当我只知道祖先类的类型时,如何反序列化 XML?
【发布时间】:2011-07-03 18:43:55
【问题描述】:

假设我想反序列化它(我已经删除了命名空间以使事情变得更简单):

<TextField>
  <Caption>Location</Caption>
  <Name>Location</Name>
</TextField>

TextField 继承自 FormField,所以在我的 FormField 类定义中看起来像这样:

[KnownType(typeof(TextField))]
[DataContract(Name = "FormField"]
public abstract class FormField
{
    [DataMember]
    public string Name { get; set; }
}

TextField 类如下所示:

[DataContract(Name = "TextField")]
public class TextField : FormField
{
    [DataMember]
    public string Caption { get; set; }
}

我尝试使用这个进行反序列化:

internal static FormField Deserialize(string xml)
{
    var serializer = new DataContractSerializer(typeof(FormField)});
    using (var backing = new StringReader(xml))
    {
        using (var reader = new XmlTextReader(backing))
        {
            return serializer.ReadObject(reader) as FormField;
        }
    }
}

我得到一个 SerializationException:“期望元素 'FormField'...”

【问题讨论】:

  • TextField是XML文件的根,还是FormField是根?
  • TextField 是根。 TextField继承自FormField,所以TextField是FormField的一种。

标签: c# .net datacontractserializer xml-deserialization


【解决方案1】:

为了解决我的问题,我在 XML 中添加了一个容器节点,使其看起来像这样:

<FormFieldContainer>
    <TextField>   
        <Caption>Location</Caption>
        <Name>Location</Name>
    </TextField>
</FormFieldContainer>

我创建了这个类:

[DataContract(Name = "FormFieldContainer")]
internal class FormFieldContainer
{
    [DataMember]
    internal FormField FormField { get; set; }
}

而我的反序列化方法是这样的:

    internal static FormField Deserialize(string xml)
    {
        var serializer = new DataContractSerializer(typeof(FormFieldContainer));
        using (var backing = new StringReader(xml))
        {
            using (var reader = new XmlTextReader(backing))
            {
                return ((FormFieldContainer)serializer.ReadObject(reader)).FormField;
            }
        }
    }

如果有人有更好的解决方案,请分享:)

【讨论】:

    【解决方案2】:

    那你的模型不应该是这样的吗?

    public abstract class TextField: FormField
    {
        [DataMember]
        public string Name { get; set; }
    }
    

    只是一个小插曲,我实际上刚刚开始深入研究 DataContractSerializer 的东西列表,很奇怪。

    【讨论】:

    • 我在上面添加了我的 TextField 类,所以你可以看到它的样子。
    猜你喜欢
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 2011-06-22
    • 2012-02-29
    相关资源
    最近更新 更多