I have a three classes
public class A<T>
{
public bool Success {get; set;}
public string Reason {get; set;}
public T Data {get; set;}
}
public class B
{
public string Token {get; set;}
}
public class C
{
public int SomeInt {get; set;}
public string SomeString {get; set;}
public double SomeDouble {get; set;}
}
I call my web service and pass in A or A to deserialise into like this
async Task<T> MyTask<T>(...) (where T is A<B> or A<C>)
The service works fine and returns some JSON which if I try and to deserialise into a var, I'm getting nothing deserialised
To deserialise, I'm using
var foo = JsonConvert.DeserializeObject<T>(response.Content);
Is there a limitation to how I can deserialise the object so I can only use a base class rather than this form of class?
Yes, you can not just pass A because A is not base class, it is generic class and does not exists on its own.
C# generates generic classes during compile time, which means if you use A<B> in your code, C# will generate something like:
public class generated_A_B
{
public bool Success { get; set; }
public string Reason { get; set; }
public B Data { get; set; }
}
Nothing will be generated for A<C>, if not explicitly used. Reason is obvious, if you generate classes for every single combination of the A, you will bloat your code.
In your current situation it is better to just call them explicitly
void Main()
{
CallAB();
CallAC();
}
A<B> CallAB()
{
return ServiceCall<A<B>>("/api/ab");
}
A<C> CallAC()
{
return ServiceCall<A<C>>("/api/ac");
}
If you really want to get "generic" A, you should make A an actual base class and have your API to return the type of Data. In my example I just use Name of the type, but you probably should use FullName that includes namespace, to avoid name conflicts.
void Main()
{
var json = @"
{
""success"": true,
""reason"": ""All good"",
""type"": ""B"",
""data"": {
""token"": ""1234-5678""
}
}";
var foo = JsonConvert.DeserializeObject<A>(json);
var type = Assembly.GetExecutingAssembly().GetTypes().Where(i => i.IsClass && i.Name == foo.Type).FirstOrDefault();
if (type == null)
{
throw new InvalidOperationException(string.Format("Type {0} not found", foo.Type));
}
var data = foo.Data.ToObject(type);
}
public class A
{
public bool Success { get; set; }
public string Reason { get; set; }
public string Type { get; set; }
public JToken Data { get; set; }
}
public class B
{
public string Token { get; set; }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With