2016-06-07 13 views
2

Ich habe ein Problem mit der Deserialisierung von XML zu einer Objektliste, wobei immer 0 und innerhalb dieser "Rohdaten" DateAndTimeSlot während des Debuggens gezählt wird.Deserialisieren von XML zu verschachteltem Objekt Liste zurückkehrender Zähler 0

Leider kann ich die Namen dieser Elemente nicht ändern.

Wenn ich jedoch die XML-Daten zurück überprüfe, gibt es DateAndTimeslot-Objekte im XML.

Bei anderen Objektlisten scheint mir alles in Ordnung zu sein, ohne Namespaces einzubeziehen.

Was habe ich verpasst?

C# Code:

[XmlRoot("AppointmentAvailabilityStatusResponse")] 
    public class CheckAppointmentAvailabilityContainer 
    { 
     [XmlElement("AppointmentAvailabilityStatusResult")] 
     public AppointmentAvailabilityStatus appointmentAvailabilityStatus { get; set; } 
    } 
    [XmlRoot("AppointmentAvailabilityStatusResult", Namespace = "Appointments")] 
    public class AppointmentAvailabilityStatus 
    { 
     [XmlArray("DateAndTimeSlot", Namespace = "Appointments")] 
     [XmlArrayItem(typeof(DateAndTimeslot))] 
     public DateAndTimeSlots DateAndTimeSlot { get; set; } 
     [XmlElement("RequestedStatus")] 
     public int RequestedStatus { get; set; } 
    } 
    [XmlRoot(ElementName = "DateAndTimeSlot")] 
    [XmlType("a")] 
    public class DateAndTimeSlots : List<DateAndTimeslot> { } 

    [XmlRoot(ElementName = "DateAndTimeslot", Namespace = "Appointments.TO")] 
    [XmlType("b")] // if included this renames the node to "b" for some reason 
    public class DateAndTimeslot 
    { 
     [XmlElement("Date")] 
     public string Date { get; set; } 
     [XmlElement("TimeSlot")] 
     public string TimeSlot { get; set; } 
    } 

Verkürzte XML zurück, dass ich wünschte voll deserialise zu.

<AppointmentAvailabilityStatusResponse> 
    <AppointmentAvailabilityStatusResult xmlns:a="Appointments" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <a:DateAndTimeSlot xmlns:b="Appointments.TO"> 
     <b:DateAndTimeslot> 
     <b:Date>14/07/2016</b:Date> 
     <b:TimeSlot>AM</b:TimeSlot> 
     </b:DateAndTimeslot> 
     <b:DateAndTimeslot> 
     <b:Date>14/07/2016</b:Date> 
     <b:TimeSlot>PM</b:TimeSlot> 
     </b:DateAndTimeslot> 
    </a:DateAndTimeSlot> 
    <a:RequestStatus>0</a:RequestStatus> 
    </AppointmentAvailabilityStatusResult> 
</AppointmentAvailabilityStatusResponse> 

XML, wenn ich ein Dummy-Objekt serialise - einige Unterschiede, die ich versuche zu korrigieren, nicht sicher, ob die Namensräume für Deserialisation notwendig sind, obwohl

<AppointmentAvailabilityStatusResponse> 
<AppointmentAvailabilityStatusResult> 
<DateAndTimeSlot xmlns=\"Appointments\"> 
<DateAndTimeslot> 
<Date xmlns=\"Appointments.TO\">today</Date> 
<TimeSlot xmlns=\"Appointments.TO\">now</TimeSlot> 
</DateAndTimeslot> 
</DateAndTimeSlot> 
<RequestedStatus xmlns=\"Appointments\">0</RequestedStatus> 
</AppointmentAvailabilityStatusResult> 
</AppointmentAvailabilityStatusResponse> 

Deserializer

public static T DeserializeThis<T>(string cleanXml) 
     { 
      //string cleanXml = RemoveBom(dirtyXml); 
      bool check = cleanXml.TrimStart().StartsWith("<"); 
      if (!string.IsNullOrEmpty(cleanXml) && cleanXml.TrimStart().StartsWith("<")) 
      { 
       try 
       { 
        XmlSerializer xs = new XmlSerializer(typeof(T)); 
        MatchCollection mc = Regex.Matches(cleanXml, @"</?(\d\w+)"); 
        List<string> elements = new List<string>(); 

        foreach (Match m in mc) 
        { 
         string cpval = m.Groups[1].Value; 
         if (!elements.Contains(cpval)) { elements.Add(cpval); } 
        } 

        foreach (string e in elements) 
        { 
         cleanXml = cleanXml.Replace(e, "d_" + e); 
        } 

        using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(cleanXml))) 
        { 
         using (StringReader sr = new StringReader(cleanXml)) 
         { 
          return (T)xs.Deserialize(sr); 
         } 
        } 
       } 
       catch(XmlException x) 
       { 
        var obj = (T)Activator.CreateInstance(typeof(T)); 
        Type type = obj.GetType(); 
        return (T)obj; 
       } 
      } 
      else 
      { 
       var obj = (T)Activator.CreateInstance(typeof(T)); 
       Type type = obj.GetType(); 
       // add in the generic derived class property search and assign 
       return (T)obj; 
      } 
     } 
+1

Fügen Sie den Code in dem Sie versuchen tatsächlich die XML in das Objektdiagramm deserialisiert vorgesehen - meine erste Vermutung ist, Ihnen fehlt die richtige 'NamespaceManager' – Jamiec

+0

Könnte es sein (habe den verwendeten Deserialisierer enthalten), aber ich dachte nicht, dass ich beim Deserialisieren Namespaces verwenden müsste? Dachte, das war nur für das Serialisieren beim Senden von XML, das nicht empfangen wurde. – PurpleSmurph

+1

parsen Sie Ihre 'xml' durch' http: // xmltocsharp.azurewebsites.net', um das stark typisierte C# -Objekt zu erhalten. –

Antwort

0

Danke an diejenigen, die oben kommentiert haben - ich habe es endlich funktioniert. Das Entfernen der XmlArray und nicht einschließlich Anonymous und IsNullable Attribute schien das Problem zu sein, obwohl ich nicht sicher bin, warum, wie es mit allen anderen Funktionen funktioniert, die ich habe, serializable möglicherweise auch nicht vorhanden sein muss.

Arbeitsstruktur Klasse minus der Behälter als dass nicht ändern:

[Serializable()] 
    [XmlType(AnonymousType = true, Namespace = "")] 
    public class AppointmentAvailabilityStatusResult : WebserviceMessage 
    { 
     [XmlElement("DateAndTimeSlot", Namespace = "Appointments")] 
     public DateAndTimeSlot DateAndTimeSlot { get; set; } 

     [XmlElement("RequestedStatus")] 
     public int RequestedStatus { get; set; } 
    } 
    [Serializable()] 
    [XmlType(AnonymousType = true, Namespace = "Appointments")] 
    [XmlRoot(ElementName = "DateAndTimeSlot",Namespace = "Appointments", IsNullable = false)] 
    public class DateAndTimeSlot 
    { 
     [XmlElement(ElementName = "DateAndTimeslot", Namespace = "Appointments.TO")] 
     public List<DateAndTimeslot> DateAndTimeslot { get; set; } 
    } 

    [Serializable()] 
    [XmlType(AnonymousType = true, Namespace = "Appointments.TO")] 
    [XmlRoot(Namespace = "Appointments.TO", IsNullable = false)] 
    public class DateAndTimeslot 
    { 
     [XmlElement("Date")] 
     public string Date { get; set; } 
     [XmlElement("TimeSlot")] 
     public string TimeSlot { get; set; } 
    } 
Verwandte Themen