无法反序列化的XML字符串

问题描述:

我有以下XML这我想反序列化如下,但我得到的错误:无法反序列化的XML字符串

There was an error reflecting type 'System.Collections.Generic.List`1[MyApp.Models.Field]

下面是我的代码

public class FieldList 
{ 
    [XmlArray("fields")] 
    [XmlArrayItem("field")] 
    List<Field> Fields { get; set; } 
} 

public class Field 
{ 
    [XmlAttribute("type")] 
    public string Type { get; set; } 

    [XmlAttribute("required")] 
    public bool Required { get; set; } 

    [XmlAttribute("label")] 
    public string Label { get; set; } 

    [XmlAttribute("name")] 
    public string Name { get; set; } 

    [XmlElement("option")] 
    [JsonProperty("values")] 
    public List<Option> Options { get; set; } 
} 

public class Option 
{ 
    [XmlAttribute("label")] 
    public string Label { get; set; } 

    [XmlAttribute("value")] 
    public string Value { get; set; } 

    [XmlAttribute("selected")] 
    public bool Selected { get; set; } 

    /// <remarks/> 
    [XmlIgnore()] 
    public bool SelectedSpecified { get; set; } 

    [XmlText] 
    public string Text { get; set; } 
} 

var xml = @"<?xml version=""1.0"" ?> 
    <form-template> 
    <fields> 
     <field type=""select"" required=""true"" label=""Cars"" name=""cars"" > 
      <option label=""Toyota"" value=""Toyota"" selected=""true"">Toyota</option> 
      <option label=""Nisan"" value=""Nisan"" >Nisan</option> 
     </field> 
    </fields> 
    </form-template>"; 


var serializer = new XmlSerializer(typeof(FieldList), new XmlRootAttribute("form-template")); 
var stringReader = new StringReader(xml); 
var xmlFields = (FieldList)serializer.Deserialize(stringReader); 

我在做什么错误?

* UPDATE *

按照下面的意见改变

public IEnumerable<Option> Options { get; set; } 

public List<Option> Options { get; set; } 

修正错误,但现在没有什么是反序列化 - 变量xmlFields是空???我需要从特定的节点读取还是不重要?

+0

的'InnerException'应该包含一个线索。 –

+0

@ManfredRadlwimmer将IEnumerable

+0

我最好的猜测是,因为以下属性是一个接口 public IEnumerable

让我们来看看你的代码。

new XmlRootAttribute("form-template")映射到<form-template>节点。

public class Field映射到<field节点。

但没有映射到<fields>节点。

添加下面的类:

public class FieldList 
{ 
    [XmlArray("fields")] 
    [XmlArrayItem("field")] 
    public List<Field> Fields { get; set; } 
} 

它应该工作:

var serializer = new XmlSerializer(typeof(FieldList), new XmlRootAttribute("form-template")); 
var stringReader = new StringReader(xml); 
var xmlFields = (FieldList)serializer.Deserialize(stringReader); 

此外,你应该将属性添加到Option类:

[XmlText] 
public string Text { get; set; } 

更新。

你可以摆脱FieldList类。但是,您必须手动跳过部分xml节点。

List<Field> xmlFields; 
var serializer = new XmlSerializer(typeof(List<Field>), new XmlRootAttribute("fields")); 

// You can read from a stream or from a StringReader instead of a file 
using (var xmlReader = XmlReader.Create("test.xml")) 
{ 
    // Skip <form-template> node 
    xmlReader.ReadToFollowing("fields"); 

    xmlFields = (List<Field>)serializer.Deserialize(xmlReader); 
} 

添加XmlType属性类:

[XmlType("field")] 
public class Field 
+0

我已根据您的解决方案进行了修改,但'xmlFields'仍为空? – adam78

+0

有什么办法可以从''节点开始读取xml,这样我就可以摆脱FieldList'类而不修改现有的xml了? – adam78

+0

@ adam78 - 请参阅更新。 –

的XmlSerializer无法序列抽象属性,请更改的IEnumerable列出像下面,

public IEnumerable<Option> Options { get; set; } 

public List<Option> Options { get; set; } 

您根元素不与你有XML的结构匹配。我已经编辑XML像下面,

var xml = "<?xml version=\"1.0\" ?>" + 
        " " + 
        " <Fields>" + 
        "  <Field Type=\"select\" Required=\"true\" Label=\"Cars\" Name=\"cars\" >" + 
        "   <option label=\"Toyota\" lalue=\"Toyota\" selected=\"true\">Toyota</option>" + 
        "   <option label=\"Nisan\" value=\"Nisan\" >Nisan</option>" + 
        "  </Field>" + 
        " </Fields>"; 

和反序列化的代码作为,

XmlSerializer serializer = new XmlSerializer(typeof(List<Field>), new XmlRootAttribute("Fields")); 

    var stringReader = new StringReader(xml); 
     List<Field> xmlFields = (List<Field>)serializer.Deserialize(stringReader); 

现在它被反序列化的罚款。请参阅输出,

enter image description here

+0

更改为'列表

+0

“Option”类是否标有'[Serializable]'属性?它有无参数CTOR吗? – Moerwald

+0

@Moerwald - “XmlSerializer”类不使用“Serializable'属性。 –

您需要正确生成类要序列化的XML。将不含双“双引号”的正确XML复制到剪贴板中,转到Visual Studio解决方案中的任何cs文件。点击编辑 - >选择性粘贴 - >将XML粘贴为类。这将正确地生成您的cs文件中的转换类。然后,将这些更改为自动实现的属性,而不是使用私有变量来减少屏幕上的混乱。

与所述一组以下类,反序列化作为

XmlSerializer serializer = new XmlSerializer(typeof(FormTemplate)); 
      var xml = @"<?xml version=""1.0"" ?> 
    <form-template> 
    <fields> 
     <field type=""select"" required=""true"" label=""Cars"" name=""cars"" > 
      <option label=""Toyota"" value=""Toyota"" selected=""true"">Toyota</option> 
      <option label=""Nisan"" value=""Nisan"" >Nisan</option> 
     </field> 
    </fields> 
    </form-template>"; 
      var stringReader = new StringReader(xml); 
      var xmlFields = serializer.Deserialize(stringReader); 

自动生成的一组的修改,以改变 属性来自动实现的属性的类。

/// <remarks/> 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
[System.Xml.Serialization.XmlRootAttribute("form-template", Namespace = "", IsNullable = false)] 
public partial class FormTemplate 
{ 
    /// <remarks/> 
    public Fields fields { get; set; } 
} 

/// <remarks/> 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
public partial class Fields 
{ 
    /// <remarks/> 
    public SingleField field { get; set; } 
} 

/// <remarks/> 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
public partial class SingleField 
{ 
    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute("option")] 
    public Option[] option { get; set; } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public string type { get; set; } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public bool required { get; set; } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public string label { get; set; } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public string name { get; set; } 
    } 

/// <remarks/> 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
public partial class Option 
{ 
    /// <remarks/> 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public string label { get; set; } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public string value { get; set; } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public bool selected { get; set; } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlIgnoreAttribute()] 
    public bool selectedSpecified { get; set; } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlTextAttribute()] 
    public string Value { get; set; } 

}