gabrigabra
gabrigabra

Reputation: 13

Deserialize List<T> with type from runtime

I am trying to deserialize a response from an API and the type is retrieved at runtime:

var modelType = Type.GetType($"Namespace.{itemname}").GetType();

Then I call a generic method passing the type in (with refrection). After the API call i try to deserialize it form the response:

var obj= await response.Content.ReadAs<List<T>>();

but it gives this error:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.RuntimeType' because the type requires a JSON string value to deserialize correctly.

I also tryied reading it as string and then using the JsonConvert

var str = await response.Content.ReadAsStringAsync();
var obj = JsonConvert.DeserializeObject<List<T>>(str);

Also same error. Anybody got any idea how to do it? thanks!

Upvotes: 1

Views: 789

Answers (2)

Alberto Chiesa
Alberto Chiesa

Reputation: 7360

The problem lies in the line var modelType = Type.GetType($"Namespace.{itemname}").GetType();.

This code resolves a type by name (Type.GetType($"Namespace.{itemname}")) but then calls on this Type instance the method GetType. This gives you the type of the instance, which is, confusingly, System.Type or System.RuntimeType, depending upon the framework version.

Removing the extra GetType() should fix the problem.

Upvotes: 1

David L
David L

Reputation: 33853

You cannot use generics with a runtime type. That said, there are serialize/deserialize overloads that takes a type argument.

In your case, since you have a List where T is a runtime type, you'd need reflection to dynamically create your generic type at runtime and then pass it into the second argument:

var listType = typeof(List<>);
var modelType = Type.GetType($"Namespace.{itemname}");
var str = await response.Content.ReadAsStringAsync();
var obj = JsonConvert.DeserializeObject(str, listType.MakeGenericType(modelType));

Upvotes: 0

Related Questions