2010-07-16 3 views
7

Question: J'utilise une classe de dictionnaire sérialisable, trouvée à http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx , pour sérialiser un dictionnaire. Ce qui fonctionne bien, mais je rencontre un problème ennuyeux.Dictionnaire sérialisable, comment définir le nom de la clé?

 <System.Xml.Serialization.XmlRoot("DataBase")> _ 
    Public Class cDataBase 
     <System.Xml.Serialization.XmlNamespaceDeclarations()> _ 
     Public ns As New System.Xml.Serialization.XmlSerializerNamespaces() 


     <System.Xml.Serialization.XmlElement("Tables")> _ 
     Public Tables1 As New SerializableDictionary(Of String, cTable) 


    End Class ' cDataBase 

Quand je sérialiser instances de la classe ci-dessus, celle-ci, le xml créé ressemble à ceci:

<Tables> 
<item> 
    <key> 
    <string>MyTable</string> 
    </key> 
    <value> 
    <Table CreationDate="0001-01-01T00:00:00" LastModified="0001-01-01T00:00:00"> 
     <Columns> 
     <Column Name="PrimaryKeyName"> 
      <DataType>Uniqueidentifier</DataType> 
      <Length>36</Length> 
     </Column> 
     </Columns> 
     <Rows> 
     <Row> 
      <Item>Reihe1</Item> 
      <Item>Reihe2</Item> 
      <Item>Reihe3</Item> 
     </Row> 
     <Row> 
      <Item>Reihe1</Item> 
      <Item>Reihe2</Item> 
      <Item>Reihe3</Item> 
     </Row> 

Ce qui serait bien si je pouvais comprendre comment renommer la clé < chaîne > à quelque chose défini dans un attribut

<key> 
    <string>MyTable</string> 
    </key> 

Fondamentalement, quelque chose comme le XmlArrayItem attribut, comme ci-dessous, si (seulement) le dictionnaire est un tableau ...

 <System.Xml.Serialization.XmlArray("Tables")> _ 
     <System.Xml.Serialization.XmlArrayItem("Table")> _ 
     Public Tables As New List(Of cTable) 

Je voulais essayer de changer de chaîne à une classe personnalisée héritée de la chaîne, que je pouvais équiper avec un nom, mais le problème est, on ne peut pas hériter de la chaîne ...

Répondre

0

Vous pouvez spécialiser le modèle de dictionnaire ou dériver d'une spécialisation pour sérialiser comme vous voulez.

1

Si je lis bien votre question, vous voulez changer votre sortie sérialisée de ceci:

<Tables> 
    <item> 
    <key> 
     <string>MyTable</string> 
    </key> 
    <value> 
     <!-- snip --> 
    </value> 
    </item> 
</Tables> 

à quelque chose comme ceci:

<Tables> 
    <item> 
    <key> 
     <TableId>MyTable</TableId> 
    </key> 
    <value> 
     <!-- snip --> 
    </value> 
    </item> 
</Tables> 

Vous mentionnez également que d'une manière que vous pourriez réaliser ceci serait de créer votre propre type qui a hérité de System.String, ce qui - comme vous le mentionnez aussi - n'est évidemment pas possible parce que c'est sealed.

Vous pouvez atteindre cependant le même résultat en encapsulant la valeur de clé dans votre propre type, puis contrôler la sortie XmlSerializer en utilisant un XmlTextAttribute (voir MSDN):

Par défaut, les XmlSerializer sérialisés un membre de classe en tant qu'élément XML . Toutefois, si vous appliquez le XmlTextAttribute à un membre, le XmlSerializer convertit sa valeur en texte XML. Cela signifie que la valeur est codée dans le contenu de un élément XML.

Dans votre cas, vous devriez utiliser l'attribut comme suit:

public class TableId 
{ 
    [XmlText] 
    public string Name 
    { 
     get; 
     set; 
    } 
} 

Et puis utiliser ce type comme la clé (s) à votre Dictionary. Ce qui devrait atteindre ce que vous voulez.

0

Bien que ce soit probablement un peu hors sujet, je dois demander pourquoi utiliser XML pour le sérialiser? Si vous voulez juste enregistrer l'état de l'objet pour le futur, je suggérerais JSON au lieu de XML.Un grand avantage est que vous pouvez facilement sauvegarder une classe Dictionary normale sans avoir à écrire de code spécial. La charge utile est également beaucoup plus petite que JSON, donc c'est un bon format pour envoyer à travers le fil si nécessaire.

Scott Gu a un peu d'infos sur l'utilisation du JavascriptSerializer here. Je suggère d'en faire une méthode d'extension sur l'objet. Ensuite, vous pouvez le faire:

Dictionary<int, string> myDict = new Dictionary<int,string>(); 
myDict.Add(10,"something"); 
string jsonData = myDict.ToJSON(); 

Si cela est quelque chose que votre intéressé par moi savoir et je peux poster le code pour les méthodes d'extension que j'utilise. (sry pas au travail et je ne les ai pas avec moi ici.)

+0

D'abord, je suis limité à .NET 2.0, et le second, le principal problème est que le dictionnaire est un type générique et non sérialisable (pas JSON non plus). Je suis en série au format XML parce que XML est plus large utilisé, et mieux à lire, si sérialisé à partir de .NET 2.0. –

0

Puisque vous avez la source, vous pouvez le modifier afin qu'il recherche les attributs XML s'ils sont présents. Il n'y a rien de sacré au sujet de la famille d'attributions XML - ils sont comme n'importe quel autre attribut qui peut être recherché par réflexion. Une fois que vous avez ce que vous pouvez mettre de nouveaux noms dans le code où dans creater et/ou lit des balises XML. Vous pouvez également ajouter 2 paramètres pour remplacer explicitement les noms de tag, comme ReadXml (myReader, "Tables", "Table") et changer le code pour suivre ces noms au lieu des valeurs par défaut. Vous devez passer en C# :-)

0

Envisagez de remplacer Dictionary par KeyedCollection. Il est sérialisé en tant que liste, par conséquent il est plus petit et les noms de noeud XML sont les noms des propriétés/champs de cTable.

[Serializable] 
[CollectionDataContract] 
public class TablesCollection : KeyedCollection<string, cTable> 
{ 
    protected override string GetKeyForItem(cTable item) 
    { 
     return item == null ? String.Empty : item.TableName; 
    } 
} 
0

ne peut pas dire que je l'ai utilisé que la mise en œuvre du dictionnaire serializeable, mais si vous êtes prêt à essayer de nouvelles choses, il y a une petite classe abstraite connue appelée KeyedCollection qui est entièrement serializeable, soutient clé accès basé, et peut être facilement mis en œuvre en tant que dictionnaire.

.Net 2.0 Keyed Collection

Questions connexes