ozz ozz - 20 days ago 8
C# Question

How can I serialize and deserialize dynamic as IDictionary<string,object> in Json.Net

I have to use older version of Json.Net (our ESB uses it)

There is a memory leak for DynamicObject based classes.

I'm using Rick's Expando class https://github.com/RickStrahl/Expando

I want to serialize my Expando object as IDictionary and deserialize it as my Expando object

I tried to use CustomJsonConverter as you can see:

public class ExpandoConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Expando).IsAssignableFrom(objectType);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;

JObject jObject = JObject.Load(reader);
// It is easier to write readJson I will implement
throw new NotImplementedException();
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var x = (value as Expando);
writer.WriteStartObject();
foreach (var item in x.GetProperties(true))
{
writer.WritePropertyName(item.Key);

serializer.Serialize(writer,item.Value);

writer.WriteEndObject();
}
writer.WriteEndObject();
}


But I'm getting weird errors every time I try to implement WriteJson, is there any simple way like that (in WriteJson):

var dictionary= ExpandoToDictionary(expando);
serializer.Serialize(writer,dictionary);


`

dbc dbc
Answer

In the absence of an mcve there may be other problems with your code, but you need to remove the inner call to WriteEndObject() from WriteJson():

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    var x = (value as Expando);
    writer.WriteStartObject();
    foreach (var item in x.GetProperties(true))
    {
        writer.WritePropertyName(item.Key);

        serializer.Serialize(writer,item.Value);

        // Do not close the object here also.
    }
    writer.WriteEndObject();
}

Calls to WriteStartObject() and WriteEndObject() should be paired.