2

So I'm trying to deserialize an object that has properties: $ref and $id. I have tried going between Dictionary as well as an object where I have specified namingconventions via JsonPropertyAttribute. Serialization works, but deserialization doesn't. The error I keep getting is:

Additional text found in JSON string after finishing deserializing object.

Sample code where all three samples, fail.

[Serializable]
public class Ref
{
    [JsonProperty(PropertyName = "$ref")]
    public virtual string RefName { get; set; }
    [JsonProperty(PropertyName = "$id")]
    public virtual int Id { get; set; }
}

[Serializable]
public class Child
{
    public virtual string Name { get; set; }
    [JsonProperty(IsReference = true)]
    public virtual Ref Father { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        //Additional text found in JSON string after finishing deserializing object.
        //Test 1
        var reference = new Dictionary<string, object>();
        reference.Add("$ref", "Persons");
        reference.Add("$id", 1);

        var child = new Dictionary<string, object>();
        child.Add("_id", 2);
        child.Add("Name", "Isabell");
        child.Add("Father", reference);

        var json = JsonConvert.SerializeObject(child);
        var obj = JsonConvert.DeserializeObject<Dictionary<string, object>>(json); //Exception

        //Test 2
        var refOrg = new Ref {RefName = "Parents", Id = 1};
        var refSer = JsonConvert.SerializeObject(refOrg);
        var refDeser = JsonConvert.DeserializeObject<Ref>(refSer); //Exception

        //Test 3
        var childOrg = new Child {Father = refOrg, Name = "Isabell"};
        var childSer = JsonConvert.SerializeObject(childOrg);
        var childDeser = JsonConvert.DeserializeObject<Child>(refSer); //Exception
    }
}
svick
  • 236,525
  • 50
  • 385
  • 514
Daniel
  • 8,133
  • 5
  • 36
  • 51

3 Answers3

4

I have the same issue when trying to deserialize a swagger/json schema document. The solution is:

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;
Hongye Sun
  • 3,868
  • 1
  • 25
  • 18
2

You'll find that $ref & $id are special properties used by Json.NET to manage multiple instances of objects in a single object graph.

By putting these keys into your dictionary the deserialize process is trying to parse these as references to objects that don't exist.

Try altering the keys.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
0

This answer worked for me: Json.Net adding $id to EF objects despite setting PreserveReferencesHandling to "None"

In your implementation of DefaultContractResolver/IContractResolver, add this;

public override JsonContract ResolveContract(Type type) {
    var contract = base.ResolveContract(type);
    contract.IsReference = false;
    return contract;
}
Community
  • 1
  • 1
Howie
  • 2,760
  • 6
  • 32
  • 60