反序列化$ ref和$ id

时间:2010-03-07 19:03:07

标签: json serialization json.net

所以我试图反序列化具有属性的对象:$ ref和$ id。我试过在Dictionary之间以及通过JsonPropertyAttribute指定了命名约定的对象。 序列化工作,但反序列化不。我一直得到的错误是:

  

JSON字符串中的其他文字   完成反序列化后的对象。

示例代码,其中所有三个样本都失败。

[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
    }
}

3 个答案:

答案 0 :(得分:3)

我在尝试反序列化swagger / json架构文档时遇到了同样的问题。解决方案是:

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;

答案 1 :(得分:2)

你会发现$ref&amp; $id是Json.NET用于管理单个对象图中的多个对象实例的特殊属性。

通过将这些键放入字典中,反序列化过程会尝试将这些键解析为对不存在的对象的引用。

尝试更改密钥。

答案 2 :(得分:0)

这个答案对我有用:Json.Net adding $id to EF objects despite setting PreserveReferencesHandling to "None"

在DefaultContractResolver / IContractResolver的实现中,添加此内容;

public override JsonContract ResolveContract(Type type) {
    var contract = base.ResolveContract(type);
    contract.IsReference = false;
    return contract;
}