Question

J'ai un graphe d'objet assez volumineux que j'ai sérialisé dans un fichier via le DataContractSerializer. Je souhaite maintenant présenter une liste de ces fichiers à l'utilisateur. Dans cette liste, je souhaite afficher certains détails concernant le fichier, qui sont des propriétés de l'objet racine. Je ne veux pas charger le graphique entier dans la mémoire car je ne souhaite afficher que les propriétés du nœud racine.

Est-ce que quelqu'un connaît un moyen de contrôler la " profondeur " de la désérialisation afin que je puisse simplement extraire l'objet racine du fichier et ignorer les enfants? Je préfère éviter de traiter le fichier en tant que fichier XML brut, car je ne fais aucune manipulation XML brut ailleurs, ce qui constituerait une branche de code supplémentaire à synchroniser.

Ma seule idée pour le moment est de créer un "résumé" compatible. objet ne contenant que les propriétés qui m'intéressent, et aucun des enfants, et désérialise le fichier dans celui-là. Cela devrait ignorer les enfants car ils ne sont pas pertinents pour l'objet de résumé.

Existe-t-il un meilleur moyen d'y parvenir?

Mise à jour / clarification : les attributs ne sont pas la réponse que je recherche. D'une part, ils empêcheront le "extra" " les propriétés de se retrouver dans le fichier lorsque l'objet a été sérialisé pour la première fois.

Deuxièmement, ils sont plus permanents que ce que j'essaie de faire. Finalement, je veux désérialiser le fichier entier, mais pas pour le moment. J'essaie d'afficher une liste récapitulative des fichiers que l'utilisateur choisira pour l'importation. Pendant l'importation, je vais avoir besoin de tous les enfants et petits-enfants. C’est exagéré à l’étape 1. Ce sont des fichiers potentiellement volumineux, alors désérialiser complètement plusieurs d’entre eux pour que je puisse afficher leurs informations d’en-tête ne fonctionnera pas.

J'espère que cela dissipe toute confusion concernant la question initiale.

Était-ce utile?

La solution

C'est à peu près la façon dont vous voulez le faire. DataContractSerializer est conçu pour gérer cette situation, dans laquelle vous devez utiliser des types conceptuellement identiques, mais différents types du point de vue du CLR que vous souhaitez sérialiser entre eux.

Dans ce cas, créez simplement l'objet avec le sous-ensemble similaire de propriétés que vous souhaitez sérialiser et transmettez ce type à DataContractSerializer.

Assurez-vous que sur le "résumé" tapez que vous définissez les propriétés de l'attribut DataContract (ainsi que tous les attributs DataMember ou DataContract sur les enfants que vous exposez), en particulier les propriétés Name et Namespace pour refléter le nom et l'espace de nom du type non récapitulatif (car ils doivent correspondre) .

Autres conseils

Ma première recommandation serait de faire la manipulation XML si vous voulez simplement extraire quelques détails du nœud racine. Une autre possibilité, bien que je ne connaisse pas les conséquences sur les performances, consiste à utiliser les fonctionnalités de contrôle de version de DataContractSerializer pour résoudre ce problème. Sur votre contrat de données, marquez chaque champ sauf ceux dont vous aurez besoin dans le résumé comme facultatif. Copiez ensuite le contrat de données en tant que classe différente, en laissant de côté les champs facultatifs. Désérialiser vers le nouveau contrat de données plus petit.

class Program
{
    static void Main(string[] args)
    {
        Person a = new Person();
        Person b = new Person();
        a.Name = "Mike";
        b.Name = "Joe";
        b.Parent = a;

        DataContractSerializer dtc = new DataContractSerializer(typeof(Person));

        StringBuilder sb = new StringBuilder();
        using (XmlWriter xr = XmlWriter.Create(sb))
        {
            dtc.WriteObject(xr, b);
        }

        object n;

        DataContractSerializer dtc2 = new DataContractSerializer(typeof(TinyPerson));

        using (XmlReader xr = XmlReader.Create(new StringReader(sb.ToString())))
        {
            n = dtc2.ReadObject(xr);
        }

    }
}

[DataContract(Name="Person")]
public class Person
{
    [DataMember]
    public string Name;

    [DataMember(IsRequired=false)]
    public Person Parent; 
}


[DataContract(Name = "Person")]
public class TinyPerson
{
    [DataMember]
    public string Name;

}

vous pouvez contrôler votre sérialisation en utilisant des attributs. en savoir plus ici

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top