2017-10-17 3 views
4

Ich habe die folgende XML deserialisieren, die ich wie folgt deserialisieren ich versucht, aber ich Fehler:Es konnte keine XML-String

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

Unten ist mein Code

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); 

Was soll ich tun falsch?

* UPDATE *

Wie pro Kommentare unter wechselnden

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

Um

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

behebt den Fehler, aber jetzt ist nichts deserialisiert - die Variable xmlFields ist leer ??? Muss ich von einem bestimmten Knoten lesen oder ist das egal?

+0

Die 'InnerException' einen Hinweis enthalten sollte. –

+0

@ManfreedRadlwimmer 'IEnumerable ändern ' zu 'Liste ' behebt den Fehler, aber nichts wird deserialisiert - 'xmlFields' ist leer? – adam78

+0

Meine beste Vermutung ist, dass, weil folgende Eigenschaft eine Schnittstelle ist öffentliche IEnumerable Optionen {get; einstellen; } und Deserializer weiß nicht, wie die Instanz zu erstellen, die es funktionieren sollte, wenn Sie List verwenden Optionen {get; set;} – Gurpreet

Antwort

2

Schauen wir uns Ihren Code an.

new XmlRootAttribute("form-template") Karten zu <form-template> Knoten.

public class Field Karten zu <field Knoten.

Aber nichts entspricht <fields> Knoten.

In folgenden Klasse:

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

sollte es funktionieren:

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

Außerdem sollten Sie eine Eigenschaft auf die Option Klasse hinzufügen:

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

Aktualisierung.

Sie können die Klasse FieldList loswerden. Aber dann müssen Sie einen Teil der XML-Knoten manuell überspringen.

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); 
} 

Add XmlType Attribut Klasse:

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

Ich habe die Änderungen gemäß Ihrer Lösung vorgenommen, aber "xmlFields" ist immer noch null? – adam78

+0

gibt es eine Möglichkeit, die XML von '' Knoten zu lesen, so dass ich die 'FieldList' Klasse loswerden kann, ohne die bestehende XML zu ändern? – adam78

+0

@ adam78 - siehe Update. –

3

XmlSerializer kann nicht serialisiert abstrakte Eigenschaften, so wenden Sie sich bitte IEnumerable ändern wie unten zur Liste,

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

zu

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

Sie Root-Element ist nicht mit der XML-Struktur passend Sie haben. Ich habe XML bearbeitet wie unten,

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>"; 

und Deserialisieren Codes,

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

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

Jetzt wird Deserialisieren in Ordnung. Bitte beachten Sie die Ausgabe,

enter image description here

+0

Änderung an 'List Options' behebt den Fehler, aber' xmlFields 'Variable ist leer? – adam78

+0

Ist die Klasse 'Option' mit dem Attribut '[Serializable]' gekennzeichnet? Hat es einen parameterlosen CTOR? – Moerwald

+0

@Moerwald - Die Klasse 'XmlSerializer' verwendet nicht das Attribut 'Serializable'. –

1

Sie müssen die Klassen erzeugen, richtig, zu dem Sie die XML serialisieren. Kopieren Sie Ihr korrektes XML ohne doppelte Anführungszeichen in die Zwischenablage, gehen Sie in der Lösung in Visual Studio zu einer CS-Datei. Klicken Sie auf Bearbeiten-> Inhalte einfügen-> XML als Klassen einfügen. Dadurch werden Klassen korrekt für die Konvertierung in Ihrer CS-Datei generiert. Ändern Sie diese dann in automatisch implementierte Eigenschaften, anstatt private Variablen zu verwenden, um das Durcheinander auf dem Bildschirm zu reduzieren.

Mit dem Satz von Klassen unter, deserialisieren als

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); 

Auto generierte Satz von Klassen zu ändern Eigenschaften automatisch implementierte Eigenschaften modifizieren.

/// <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; } 

} 
Verwandte Themen