Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serializable dictionary, how to set key name?

Question: I use a serializable dictionary class, found at http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx , to serialize a dictionary. Which works fine, but I run into an annoying problem.

      <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

When I serialize instances of the above class, as this, the created xml looks like this:

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

Which would be good if only I could figure out how to rename the key from <string> to something defined in an attribute

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

Basically something like the XmlArrayItem attribute, such as below, if (only) the dictionary were an array...

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

I wanted to try to change Of String to a custom class inherited from string, which I could equip with a name, but the problem is, one cannot inherit from string...

like image 290
Stefan Steiger Avatar asked Jul 16 '10 11:07

Stefan Steiger


People also ask

Can you serialize a dictionary C#?

NET objects is made easy by using the various serializer classes that it provides. But serialization of a Dictionary object is not that easy. For this, you have to create a special Dictionary class which is able to serialize itself. The serialization technique might be different in different business cases.

Can I serialize a dictionary?

Serializing Dictionaries With UnityBy making a new class that inherits both Dictionary and Unity's ISerializationCallbackReceiver interface, we can convert the Dictionary data to a format that Unity can serialize. And, with that, we have Dictionaries that can be used in Unity.

Can dictionary be serialized unity?

Unity cannot serialize standard dictionaries. This means that they won't show or be edited in the inspector and they won't be instantiated at startup. A classic workaround is to store the keys and values in separate arrays and construct the dictionary at startup.


1 Answers

If I'm reading your question correctly, you want to change your serialized output from this:

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

To something like this:

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

You also mention that one way you could achieve this would be to create your own type which inherited from System.String, which - as you also mention - obviously isn't possible because it's sealed.

You can however achieve the same result by encapsulating the key value in your own type, and then controlling the XmlSerializer output using an XmlTextAttribute (see MSDN):

By default, the XmlSerializer serializes a class member as an XML element. However, if you apply the XmlTextAttribute to a member, the XmlSerializer translates its value into XML text. This means that the value is encoded into the content of an XML element.

In your case you'd use the attribute as follows:

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

And then use this type as the key(s) to your Dictionary. Which should achieve what you want.

like image 135
Dougc Avatar answered Sep 18 '22 07:09

Dougc