2

I've found similar questions from people about properties of objects within a collection, but my question is about a property of the collection itself. In the example below, the Something property of the Collection doesn't make the trip back from serialization.

How can I make DataContractSerializer serialize the Something property of the collection? I am aware of the workaround of making a property outside the collection object, but this negates the reason for even using custom collections (the ability to add properties to it in the future).

This happens with NetDataContractSerializer and XmlSerializer as well.

Objects

[DataContract]
public class TempClass
{
    [DataMember]
    public TempStuffCollection Collection { get; set; }
}

[CollectionDataContract]
public class TempStuffCollection : List<TempStuff>
{
    [DataMember]
    public string Something { get; set; }
}

[DataContract]
public class TempStuff
{
    [DataMember]
    public string Foo { get; set; } = "Bar";
}

Serialization Helpers

public TempClass Deserialize(byte[] serializedBytes)
{
    using (Stream memoryStream = new MemoryStream(serializedBytes))
    {
        DataContractSerializer deserializer = new DataContractSerializer(typeof(TempClass));
        TempClass storeMessage = (TempClass)deserializer.ReadObject(memoryStream);
        return storeMessage;
    }
}

public byte[] Serialize(TempClass storeMessage)
{
    using (MemoryStream memoryStream = new MemoryStream())
    {
        DataContractSerializer serializer = new DataContractSerializer(typeof(TempClass));
        serializer.WriteObject(memoryStream, storeMessage);

        return memoryStream.ToArray();
    }
}

Example Program

void Main()
{
    var o = new TempClass
    {
        Collection = new TempStuffCollection
        {
            new TempStuff(),
            new TempStuff(),
            new TempStuff(),
        }
    };

    o.Collection.Something = "this should still be here";

    var serialized = Serialize(o);
    var deserialized = Deserialize(serialized);

    // Outputs: 3
    Console.WriteLine(deserialized.Collection.Count);
    // Outputs: null
    Console.WriteLine(deserialized.Collection.Something ?? "null");
}

Output

3
null
Community
  • 1
  • 1
Chris Benard
  • 3,167
  • 2
  • 29
  • 35
  • 4
    Because `CollectionDataContract` provides [Interchangeable Collections](https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/collection-types-in-data-contracts#interchangeable-collections). For example, an array has a `Length` property and a list has a `Count` property. If they were saved, it would be impossible to ensure interchangeability. – Alexander Petrov Nov 13 '19 at 19:45
  • Doesn't that make `CollectionDataContractAttribute` and custom collections pointless, since they can't have anything differentiating them from a `List`? – Chris Benard Nov 13 '19 at 19:50
  • It's not pointless because it allows you to customize the data contract name and namespace, and item name and namespace, e.g. as shown in [How to customize dictionary serialization with DataContractSerializer?](https://stackoverflow.com/q/51915801/3744182) or [need to have child by using DataContractSerializer to populate XML](https://stackoverflow.com/a/26896141/3744182). – dbc Nov 13 '19 at 19:56
  • 1
    [Advanced collections rules](https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/collection-types-in-data-contracts#advanced-collection-rules) has a table with methods for serialization/deserialization – Pavel Anikhouski Nov 13 '19 at 19:57
  • Actually, there are two thread [here](https://stackoverflow.com/questions/17091313/datacontract-not-able-to-serialize-collection-members) and [here](https://stackoverflow.com/questions/7501526/collectiondatacontract-serialization-not-adding-custom-properties-datamember) which says that's not possible with DCS – Pavel Anikhouski Nov 13 '19 at 20:34
  • @ChrisBenard - As explained in the comment thread, applying `[DataContract]` means you get the collection's properties; applying `[CollectionDataContract]` (or not doing anything) means you get the collection's items; but there's no option to get both. Does the thread fully answer your question? Or do you need a workaround? – dbc Nov 13 '19 at 23:05
  • 1
    @dbc already applied a workaround for now. Encapsulated the collection inside the "collection". Fully answered via comments. – Chris Benard Nov 14 '19 at 01:16

0 Answers0