Reputation: 9360
I was wondering if I have an object that contains a field which has its deserialization process dependant on another field, how can I deserialize the parent object?
Container
class Container
{
public int Id { get; set; }
public object Data { get; set; } //deserialization depends on first field
}
Hierarchy
class FieldType1
{
public string Value { get; set; }
}
class FieldType2
{
public int Numbers { get; set; }
}
Given the example above if I have a Dictionary<int,Type>
how can I deserialize an object that comes as a string like the one below?:
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
As you can see in my example above I always have the same container
type.but one property differs.
Update
After some answers here could it be possible to keep only one type of parent object and instead have a base type for the second field ?
[JsonSubTypes.KnownSubType(typeof(Child1),1)]
[JsonSubTypes.KnownSubType(typeof(Child2),2)]
public abstract Child
{
}
public class Parent{
public int Id;
public Child child;
}
Can i decorate somehow the parent to know how to deserialize its second field (similar to JsonSubTypes
)?
Summing it up i do not want to have P,P1,P2..Pn
types for parent.
I want to have one type P
for parent with F1,F2...Fn
types for its second field.So that when i deserialize i would just say JsonConvert.DeserializeObject<P>
while the converter takes care of which concrete type is the second field:
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);
Upvotes: 3
Views: 1140
Reputation: 12163
At a first glance, I'd simply use a simple function that you could put into a SomeNameParser/Converter class.
Pesudo C# code, something like the following:
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)
}
Improvements
You could make the parsing of the firstField do a lookup to return a System.Type
, then pass the type to JsonConvert.Deserialize(obj.Data, type)
which would save the repetitive JsonConvert.
Hopefully you can see the general pattern.
Upvotes: 2