2014-12-15 17 views
7

Próbuję deserializowania ciąg XML do mojej klasy, która wywodzi się z innej klasy, ale mam problem w ten sposób, ja otrzymuję następujący błąd:Cofnięcie XML String w klasie

{"The specified type is abstract: name='DeviceRequest', namespace='', at <DeviceRequest xmlns=''>."}

Zakładam, że brakuje mi jakiegoś atrybutu dekoratora, który poinformuje serializera o deserializacji tego xml'a na klasę?

Oto mój kod:

//Usage 
DeviceRequest dreq = DeviceRequest.ParseRequest(e.XML); 


//Base Class 
public abstract class IFSFRequestBase 
{ 
    private string m_ApplicationSender = ""; 
    private int m_WorkStationID = 0; 
    private string m_RequestID = ""; 

    [XmlAttribute()] 
    public abstract string RequestType { get; set; } 

    public abstract byte[] Message(); 

    [XmlAttribute()] 
    public string ApplicationSender 
    { 
     get 
     { 
      return m_ApplicationSender; 
     } 
     set 
     { 
      m_ApplicationSender = value; 
     } 
    } 

    [XmlAttribute()] 
    public int WorkStationID 
    { 
     get 
     { 
      return m_WorkStationID; 
     } 
     set 
     { 
      m_WorkStationID = value; 
     } 
    } 

    [XmlAttribute()] 
    public string RequestID 
    { 
     get 
     { 
      return m_RequestID; 
     } 
     set 
     { 
      m_RequestID = value; 
     } 
    } 

} 


//Derived Class 
public abstract class DeviceRequest : IFSFRequestBase 
{ 
    private string m_TerminalID = ""; 
    private string m_SequenceID = ""; 
    private Output m_OutputField = null; 

    [XmlAttribute(), DefaultValue("")] 
    public string TerminalID 
    { 
     get 
     { 
      return m_TerminalID; 
     } 
     set 
     { 
      m_TerminalID = value; 
     } 
    } 

    [XmlAttribute(), DefaultValue("")] 
    public string SequenceID 
    { 
     get 
     { 
      return m_SequenceID; 
     } 
     set 
     { 
      m_SequenceID = value; 
     } 
    } 

    [XmlElement("Output")] 
    public Output OutputField 
    { 
     get 
     { 
      return m_OutputField; 
     } 
     set 
     { 
      m_OutputField = value; 
     } 
    } 

    public static DeviceRequest ParseRequest(string sXML) 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(DeviceRequest)); 

     StringReader sr = new StringReader(sXML); 

     NamespaceIgnorantXmlTextReader XMLWithoutNamespace = new NamespaceIgnorantXmlTextReader(sr); 

     return (DeviceRequest)serializer.Deserialize(XMLWithoutNamespace); 
    } 
} 


// helper class to ignore namespaces when de-serializing 
public class NamespaceIgnorantXmlTextReader : XmlTextReader 
{ 
    public NamespaceIgnorantXmlTextReader(System.IO.TextReader reader) : base(reader) { } 

    public override string NamespaceURI 
    { 
     get { return ""; } 
    } 
} 

UPDATE:

OK na podstawie odpowiedzi tutaj. Zaktualizowałem kod, mam teraz wyświetlacz klasy wywodzący się z DeviceRequest. I teraz pojawia się następujący błąd:

{"There is an error in XML document (2, 2)."}, {"<DeviceRequest xmlns=''> was not expected."} 


public class Display : DeviceRequest 
{ 
    public static Display ParseRequest(string sXML) 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(Display)); 

     StringReader sr = new StringReader(sXML); 

     NamespaceIgnorantXmlTextReader XMLWithoutNamespace = new NamespaceIgnorantXmlTextReader(sr); 

     return (Display)serializer.Deserialize(XMLWithoutNamespace); 
    } 

    [XmlAttribute()] 
    public override string RequestType 
    { 
     get { return "Output"; } set { } 
    } 

    public override byte[] Message() 
    { 
     throw new NotImplementedException(); 
    } 
} 

DeviceRequest dreq = Display.ParseRequest(e.XML); 
+4

Jak mówi błąd, nie można deserialise klasy abstrakcyjnej, ponieważ nie można utworzyć instancję streszczenie klasa. Albo uczyń go konkretną klasą, albo deserializacją do konkretnej klasy, która z niej odziedziczy. –

+1

Zauważ, że '[XmlInclude]' może być używany do rozwiązywania podtypów, ale nadal będzie musiał być konkretny –

+0

Dzięki chłopaki, zaktualizowałem oryginalne pytanie na podstawie twoich odpowiedzi, teraz otrzymuję inny błąd: {"Nie jest błędem w dokumencie XML (2, 2). "}, {" nie było oczekiwane. "} –

Odpowiedz

2

OK, rozwiązałem ten problem teraz. Dzięki za wejście.

Musiałem dodać:

[System.Xml.Serialization.XmlRootAttribute(ElementName = "DeviceRequest")] 

Klasy reklamowej

[System.Xml.Serialization.XmlRootAttribute(ElementName = "DeviceRequest")] 
public class Display : DeviceRequest 
{ 
    public static Display ParseRequest(string sXML) 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(Display)); 

     StringReader sr = new StringReader(sXML); 

     NamespaceIgnorantXmlTextReader XMLWithoutNamespace = new NamespaceIgnorantXmlTextReader(sr); 

     return (Display)serializer.Deserialize(XMLWithoutNamespace); 
    } 

    [XmlAttribute()] 
    public override string RequestType 
    { 
     get { return "O"; } set { } 
    } 

    public override byte[] Message() 
    { 
     throw new NotImplementedException(); 
    } 
} 
3

Jak DeviceRequest jest abstrakcyjny typ, nie może być instancja bezpośrednio. Nie można bezpośrednio przekształcić z postaci szeregowej w instancje Device-Request. To powiedziawszy, jeśli istnieją pewne nie abstrakcyjne klasy wywodzące się z niego, proszę pokazać niektóre z nich.

+0

Dzięki, zaktualizowałem oryginalne pytanie z nie abstrakcyjną klasą pochodną od DeviceRequest. Błędy teraz z {"Wystąpił błąd w dokumencie XML (2, 2)."}, {"Nie oczekiwano."} –

Powiązane problemy