0

The problem

I am using JSON.NET to serialize complex model, and i encountered a situation where my Deserialized object Unequal to the Serialized one.

this situation caused by the way JSON.NET handle IEnumerable types,

When JSON.NET encounters a IEnumerable type, it takes it as a simple Array,
leaving out all other Properties aside.
Even when using TypeNameHandling = TypeNameHandling.All the fields are still neglected from the Wrapping JSON object.

Minimal Reproduction Example:

public class MyModel : List<string>
{
  public MyModel(string id) 
  { 
    Id = id; 
    Add("hello");
    Add("world");
  }

  public string Id { get; private set; }
}

Deserialize the following class (with TypeNameHandling = TypeNameHandling.All) produce :

{
  "$type": "...MyModel[], ...",
  "$values": [
    "hello", 
    "world"
  ]
}

Notice Leaving property Id out of the Serialization string.

.

Workaround:

For now, i just translated all my types to NOT be IEnumerable, but instead contain the base class as a member.

e.g.

public class MyModel
{
  public List<string> Values { get; private set; }
  public MyModel(string id) 
  { 
    Values = new List<string>();
    Id = id; 
    Values.Add("hello");
    Values.Add("world");
  }

  public string Id { get; private set; }
}

Though, for my model, this workaround is somewhat acceptable...
This serialization is destined to spread across more models then mine,
and I don't want to "forbid" model features (such as IEnumerable) from the models.

-

Anyone know how to overcome this?

Thanks

Tomer W
  • 3,092
  • 1
  • 22
  • 38
  • You need to specify a public property with `{ get; set; }` for it to be included during serialization. – jegtugado Oct 23 '17 at 06:28
  • 1
    Duplicate of [Newtonsoft deserialize object that extends from Collection](https://stackoverflow.com/a/38665852) (which explains why Json.NET can either serialize collection properties or items, but not both) and [How do I get json.net to serialize members of a class deriving from List?](https://stackoverflow.com/q/21265629). – dbc Oct 23 '17 at 06:31
  • @JohnEphraimTugado thanks for the comment, though, JSON.NET knows it can call a constructor with fields from JSON, therefore it'll call my `public MyModel(string id)` constructor with a valid `id` – Tomer W Oct 23 '17 at 07:02
  • @dbc thanks, i was searching for "IEnumerable" and missed those entries... I'll vote duplicate my question :) – Tomer W Oct 23 '17 at 07:04

0 Answers0