2014-12-15 2 views
7

Я пытаюсь десериализации XML-строку в мой класс, который является производным от другого класса, но у меня возникли проблемы в этом, я получаю следующее сообщение об ошибке:Deserialize Строка XML в класс

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

Я предполагаю, что мне не хватает атрибута декоратора, который сообщит сериализатору, как десериализовать этот xml в классе?

Вот мой код:

//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:

ОК на основе ответов здесь. Я обновил код, теперь у меня есть класс Display, который происходит из DeviceRequest. Теперь я получаю следующее сообщение об ошибке:

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

Как говорит ошибка, вы не можете deserialise абстрактный класс, потому что вы не можете создать экземпляр абстрактного класс. Либо сделайте его конкретным классом или десериализацией для конкретного класса, который наследуется от него. –

+1

Обратите внимание, что '[XmlInclude]' может использоваться для разрешения подтипов, но он все равно должен быть конкретным –

+0

Спасибо, ребята, я обновил исходный вопрос на основе ваших ответов, получив другую ошибку: {«Там это ошибка в документе XML (2, 2). "}, {" не ожидалось. "} –

ответ

2

ОК, я решил эту проблему сейчас. Спасибо за введение, ребята.

мне нужно добавить:

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

к классу дисплея

[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

Как DeviceRequest является абстрактным типом, он не может быть реализован напрямую. Невозможно напрямую десериализовать в случаях Device-Request. Тем не менее, если есть некоторые не абстрактные классы, полученные из него, пожалуйста, покажите некоторые из них.

+0

Спасибо, я обновил исходный вопрос с не-абстрактным классом, полученным из DeviceRequest. Ошибки теперь с {«В документе XML есть ошибка (2, 2).»}, {«Не ожидалось».} –