rhk98
rhk98

Reputation: 117

ISet<T> serialization to JSON using DataContractJsonSerializer

I am doing some tests to check/understand JSON serialization to/from .Net types in C#. I am trying to use the DataContractJsonSerializer.

Here is a sample type that I am trying to serialize:

[DataContract]
[KnownType(typeof(HashSet<int>))]
public class TestModel
{
    [DataMember]
    public string StreetName { get; private set; }
    [DataMember]
    public int StreetId { get; private set; }
    [DataMember]
    public int NumberOfCars { get; set; }
    [DataMember]
    public IDictionary<string, string> HouseDetails { get; set; }
    [DataMember]
    public IDictionary<int, string> People { get; set; }
    [DataMember]
    public ISet<int> LampPosts { get; set; }

    public TestModel(int StreetId, string StreetName)
    {
        this.StreetName = StreetName;
        this.StreetId = StreetId;

        HouseDetails = new Dictionary<string, string>();
        People = new Dictionary<int, string>();
        LampPosts = new HashSet<int>();
    }

    public void AddHouse(string HouseNumber, string HouseName)
    {
        HouseDetails.Add(HouseNumber, HouseName);
    }

    public void AddPeople(int PersonNumber, string PersonName)
    {
        People.Add(PersonNumber, PersonName);
    }

    public void AddLampPost(int LampPostName)
    {
        LampPosts.Add(LampPostName);
    }
}

When I then try to serialize an object of this type using DataContractJsonSerializer, I get the following error:

{"'System.Collections.Generic.HashSet`1[System.Int32]' is a collection type and cannot be serialized when assigned to an interface type that does not implement IEnumerable ('System.Collections.Generic.ISet`1[System.Int32]'.)"}

This msg does not sound right to me. ISet<T> does implement IEnumerable<T>( and also IEnumerable). If in my TestModel class, I replace

public ISet<int> LampPosts { get; set; }

with

public ICollection<int> LampPosts { get; set; }...

then it all sails through.

I am new to JSON so any help would be greatly appreciated

Upvotes: 3

Views: 1272

Answers (1)

Alexander
Alexander

Reputation: 4173

Looks like this is a known microsoft bug. List of supported interfaces is hardcoded in framework, and ISet is not one of them:

CollectionDataContract.CollectionDataContractCriticalHelper._knownInterfaces = new Type[]
{
  Globals.TypeOfIDictionaryGeneric,
  Globals.TypeOfIDictionary,
  Globals.TypeOfIListGeneric,
  Globals.TypeOfICollectionGeneric,
  Globals.TypeOfIList,
  Globals.TypeOfIEnumerableGeneric,
  Globals.TypeOfICollection,
  Globals.TypeOfIEnumerable
};

And yes, error message is incorrect. So, DataContractJsonSerializer cannot serialize ISet interface, it should be either replaced with one of supported interfaces, or with concrete ISet implementation.

Upvotes: 2

Related Questions