如何使用相关属性反序列化JSON?

时间:2019-02-28 21:40:11

标签: c# .net-core json.net deserialization

我想知道是否有一个对象包含一个其反序列化过程依赖于另一个字段的字段,我该如何反序列化父对象?

容器

class Container
{ 
    public int Id { get; set; }
    public object Data { get; set; } //deserialization depends on first field
}

层次结构

class FieldType1
{
    public string Value { get; set; }
}

class FieldType2
{
    public int Numbers { get; set; }
}

给出上面的示例,如果我有一个Dictionary<int,Type>,我该如何反序列化像下面这样的字符串形式的对象?

var container = new Container { Data = new FieldType1 { Value = "sata" }};
var str = JsonConvert.SerializeObject(container);
var clone = JsonConvert.DeserializeObject<Container>(str);//has dependant field on another field

如您在上面的示例中所见,我总是具有相同的container类型。但是一个属性不同。

更新

在这里给出一些答案之后,是否可以仅保留一种父对象类型,而对第二个字段使用基类型呢?

  [JsonSubTypes.KnownSubType(typeof(Child1),1)]
  [JsonSubTypes.KnownSubType(typeof(Child2),2)]
  public abstract Child
  {
  }


 public class Parent{
 public int Id;
 public Child child;

 }

我可以以某种方式修饰父级以知道如何反序列化其第二个字段(类似于JsonSubTypes)吗?


总结一下,我不想为父级添加P,P1,P2..Pn类型。 我想为父级设置一个P类型,第二个字段为F1,F2...Fn类型。这样,当我反序列化时,我只会说JsonConvert.DeserializeObject<P>,而转换器会处理哪个具体类型是第二个字段:

 Parent c1=new P{ id=1,child=new Child1()};
 Parent c2=new P{ id=2,child=newChild2()};
 List<Parent> items=new List<Parent>{c1,c2};
 var str=JsonConvert.SerializeObject(items);

 var clone=JsonConvert.DeserializeObject<List<Parent>>(str);

1 个答案:

答案 0 :(得分:2)

乍一看,我只是使用一个简单的函数,您可以将其放入 SomeNameParser / Converter 类。

伪C#代码,如下所示:

var jObject = JObject.Parse(obj.Data);
switch (jObject["firstField"])
{
   case "fieldType1":
     return JsonConvert.DeserializeObject<string>(str);

   case "fieldType2":
     return JsonConvert.DeserializeObject<int>(str);

   default:
     Throw new Exception( make this meaningful)
}

改进
您可以对 firstField 进行解析以进行查找以返回System.Type,然后将类型传递给JsonConvert.Deserialize(obj.Data, type),这将节省重复的JsonConvert。

希望您能看到常规模式。