ibubi ibubi - 3 months ago 8
JSON Question

Deserializing entity without aware of its type

I came up with this problem in my project, i have a json string from table, it is a serialized entity.


Json

{
"Entity":{
"__type":"Book:#Definition",
"BookId":3,
"BookName":"Meloon Dreams",
"Type":2,
"Price":35
}
}


Book Class

namespace Definition
{
[DataContract]
public class Book : IEntity
{
[DataMember]
public int BookId { get; set; }

[DataMember]
public string BookName { get; set; }

[DataMember]
public BookType Type { get; set; }

[DataMember]
public decimal Price { get; set; }
}
}


Workflow Class

public class Workflow
{
public int WorkflowId { get; set; }

public IEntity Entity { get; set; }
}


So, in a controller class i get the json string from table and i want to deserialize it to its own type. But, only the __type inside the json string helps me with its type. What i mean is

workflow.Entity = Serializer.JsonDeserialize<IEntity>(jsonString);


i need to put Book instead of IEntity

Is that possible without changing the class structures, or is it possible to get the type from json and convert it to type and put it instead IEntity?

Kel Kel
Answer

If I understand the question correctly, you want to instantiate generic classes dynamically specifying generic type. It is possible to do it with reflection:

// Load type name from json - you'll need to implement LoadTypeFromJson() method to load type name string from json
string typeName = LoadTypeFromJson();

// Get .Net Type by type name
Type entityType = Type.GetTypeByName(typeName);

// Get Serializer type
Type serializerType = typeof(Serializer);

// Get MethodInfo for Deserialize method of Serializer class
MethodInfo deserializeMethodInfo = serializerType.GetMethod("Deserialize");

// Construct Serializer.Deserialize<IEntity> method for specific IEntity
MethodInfo constructedDeserializeMethod = deserializeMethodInfo.MakeGenericMethod(entityType);

// Call constructed method
constructedDeserializeMethod.Invoke(null, new object[] { jsonString });

The key part here is MethodInfo.MakeGenericMethod method