question initiale
Je veux serialize
un List<IXmlSerializable>
changer le XmlType de la dynamique de classe IXmlSerializable
(donc je ne peux pas utiliser les attributs des balises pour le faire)C# XML sérialisation remplacement Type de IXmlSerializable Classe
J'ai essayé d'utiliser XmlAttributeOverrides pour ce faire sans succès jusqu'à présent.
Voici un exemple de code illustrant la question:
classe IXmlSerializable (de MSDN):
public class Person : IXmlSerializable
{
// Private state
private string personName;
// Constructors
public Person(string name)
{
personName = name;
}
public Person()
{
personName = null;
}
// Xml Serialization Infrastructure
public void WriteXml(XmlWriter writer)
{
writer.WriteString(personName);
}
public void ReadXml(XmlReader reader)
{
personName = reader.ReadString();
}
public XmlSchema GetSchema()
{
return (null);
}
// Print
public override string ToString()
{
return (personName);
}
}
classe de test (en utilisant la console pour la sortie):
class Program
{
static void Main(string[] args)
{
List<Person> lPersonList = new List<Person> {
new Person("First"),
new Person("Second"),
new Person("Third")
};
XmlAttributeOverrides lOverrides = new XmlAttributeOverrides();
XmlAttributes lAttributes = new XmlAttributes { XmlType = new XmlTypeAttribute("Employee") };
lOverrides.Add(typeof(Person), lAttributes);
XmlSerializer lSerialiser = new XmlSerializer(typeof(List<Person>), lOverrides, null, new XmlRootAttribute("Employees"), null);
XmlSerializerNamespaces lNamespaces = new XmlSerializerNamespaces();
lNamespaces.Add("", "");
lSerialiser.Serialize(Console.Out, lPersonList, lNamespaces);
System.Console.WriteLine("Enter any key to close.");
System.Console.ReadKey();
}
}
ici est ce que je veux obtenir:
<Employees>
<Employee>First</Employee>
<Employee>Second</Employee>
<Employee>Third</Employee>
</Employees>
Mais je reçois cette erreur d'exécution:
System.InvalidOperationException: Seul attribut XmlRoot peut être spécifié pour la personne de type. Veuillez utiliser XmlSchemaProviderAttribute pour spécifier le type de schéma.
Remarque Quand ma personne classe n'applique pas IXmlSerializable
, tout fonctionne bien ...
Quelqu'un pourrait-il me aider à ce sujet?
solution choisie (basée sur @dbc answer)
Comme @dbc a souligné, en utilisant une classe "substitution" est la meilleure façon de faire ce que je veux. Mais comme je l'ai dit, j'ai besoin de changer le type de personne dynamiquement, ce qui signifie que je ne peux pas utiliser les balises attributs.
J'utilise encore XmlAttributeOverrides
dans ma conception finale, la voici:
Surrogate List<Person>
classe (comme @dbc sans attributs tags):
public class EmployeesListSurrogate
{
public List<Person> EmployeeList { get; set; }
public static implicit operator List<Person>(EmployeesListSurrogate surrogate)
{
return surrogate == null ? null : surrogate.EmployeeList;
}
public static implicit operator EmployeesListSurrogate(List<Person> employees)
{
return new EmployeesListSurrogate { EmployeeList = employees };
}
}
classe de test à l'aide de substitution:
class Program
{
static void Main(string[] args)
{
List<Person> lPersonList = new List<Person> {
new Person("First"),
new Person("Second"),
new Person("Third")
};
XmlAttributeOverrides lOverrides = new XmlAttributeOverrides();
XmlAttributes lEmployeesListAttributes = new XmlAttributes { XmlRoot = new XmlRootAttribute("Employees") };
lOverrides.Add(typeof(EmployeesListSurrogate), lEmployeesListAttributes);
XmlAttributes lEmployeeAttributes = new XmlAttributes { XmlElements = { new XmlElementAttribute("Employee") } };
lOverrides.Add(typeof(EmployeesListSurrogate), "EmployeeList", lEmployeeAttributes);
XmlSerializer lSerializer = new XmlSerializer(typeof(EmployeesListSurrogate), lOverrides);
XmlSerializerNamespaces lNamespaces = new XmlSerializerNamespaces();
lNamespaces.Add("", "");
lSerializer.Serialize(Console.Out, (EmployeesListSurrogate)lPersonList, lNamespaces);
}
}
Je veux terminer ceci avec un grand merci à @dbc, votre réponse a été très utile et info rmatif, j'ai beaucoup appris. Je ne peux pas vous mettre en colère mais j'espère que la communauté le fera!