2013-11-18 3 views
2

У меня снова возникла проблема с работой моего сериализатора. У меня есть BaseClass А и производный класс B:XML-сериализация с производными типами

class Program 
{ 
    static void Main(string[] args) 
    { 
     A foo = new B(); 

     // determine that the class B overrides A 
     XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 
     overrides.Add(typeof(A), new XmlAttributes 
     { 
      XmlElements = { new XmlElementAttribute("B", typeof(B)) } 
     }); 

     XmlSerializer ser = new XmlSerializer(typeof(A), overrides); 
     ser.Serialize(new XmlTextWriter("test.xml", Encoding.Default), foo); 

    } 
} 

public class A { public int a;} 
public class B : A { public int b;} 

Но когда я запускаю эту небольшую программу, я получаю Exception

XmlRoot и XmlType атрибутов не может быть определена для типа ConsoleApplication1.A

, но я никогда не определял корень или атрибут типа для класса A, поэтому я действительно смущен этим сообщением. Есть ли что-нибудь за кулисами, которые я должен указать? Все, что я хочу сделать, это сериализовать экземпляр B, который просто добавляет некоторые свойства в определение A ...

ответ

2

я, наконец, получил два решения для работы:

номер 1:

... 
XmlSerializer ser = new XmlSerializer(typeof(A)); 
ser.Serialize(new XmlTextWriter("test.xml", Encoding.Default), foo); 
...   

[System.Xml.Serialization.XmlRoot("Root", Namespace = "DefaultNS")] 
[System.Xml.Serialization.XmlInclude(typeof(B))] 
public class A { public int a;} 

[System.Xml.Serialization.XmlRoot(Namespace = "CustomNS")] 
public class B : A { public int b;} 

Номер 2 (в дополнение к раствору Ondrejs):

... 
XmlSerializer ser = new XmlSerializer(typeof(A), overrides, new[] { typeof(B) }, new XmlRootAttribute("Root"), "defautlNS"); 
... 

public class A { public int a;} 
public class B : A { public int b;} 

второй в отличие от первое решение имеет тот недостаток, что вы можете не видеть, откуда приходит атрибут в XML-документе (из defaultNS или customNS), поскольку вы не можете указать какой-либо customNS.

+0

Что не так с моим решением? –

+0

Я добавил третий параметр в XmlSerializer, чтобы указать массив возможных типов, которые также могут быть получены из A (в дополнение к B). – HimBromBeere

4

Он находится прямо здесь, в сообщении об ошибке, которое вы получаете.

XmlRoot и XmlType атрибуты не могут быть определены для типа ConsoleApplication1.A

Вы должны указать корневой элемент для вывода XML-документа.

Заменить

overrides.Add(typeof(A), new XmlAttributes 

с

overrides.Add(typeof(A), "node", new XmlAttributes 

И вам придется, вероятно, также заменить

new XmlSerializer(typeof(A), overrides);  

с

new XmlSerializer(typeof(B), overrides); 

Для получения дополнительной информации и примера по переопределению, пожалуйста, посетите MSDN.

+0

Проверьте мой ответ. –

+0

Я также добавил решение для другой ошибки, которая произошла после первого исправления. Пожалуйста, посмотрите пример на MSDN, я также разместил ссылку в своем ответе. –

+0

Я полагаю, что определение серилайзера с 'typeof (B)' не позволит нам сериализовать дальнейшие реализации A, не так ли? С массивом типов в качестве третьего параметра для конструктора он может работать, см. Ответ. – HimBromBeere

Смежные вопросы