0

I am trying to find an elegant way deserialize a complex class with an interface property whose type I want to pass at runtime.

The scenario is that I have a Web API 2 service that is consumed by a separate application using HttpClient. The service controllers produce a number of different responses that wrap a payload in a response class. The payload can be any number of separate objects that implement IPayload, and when I deserialize I need to tell the deserializer what concrete class to deserialize IPayload to.

The class looks like this:

public class Response
{
    public bool Success bit {get; set;}

    public IEnumerable<IPayload> Payload {get; set;}
}

And the code that attempts to deserialize

...

Response response = await hr.Content.ReadAsAsync<Response>();

...

It's almost as if I would have to pass two types to the deserializer.

I've tried to do this using TypeNameHandling, and while I can get the service to include a $type property, that won't work because the code that generates the response also utilizes a generic. I wind up with "$type": "System.Collections.Generic.List`1[[Interfaces.IPayload, ClassLibrary1]], mscorlib" which I similarly can't deserialize to a concrete class.

Is there a way to do this out of the box, or would I have to create a custom deserializer?

christok
  • 1,087
  • 2
  • 12
  • 29
  • 1
    Something like this? https://stackoverflow.com/a/18490583/3608792 I like the `JsonConverter` approach becuase there's no need to maintain a constructor. Just throw an attribute on the property. – Dan Wilson Jun 14 '18 at 13:34
  • Possible duplicate of [Casting interfaces for deserialization in JSON.NET](https://stackoverflow.com/questions/5780888/casting-interfaces-for-deserialization-in-json-net) – user1672994 Jun 14 '18 at 13:34
  • You can create the constructor with actual concrete type so that JSON.net inject with appropriate type while deserializing. Check the link I've mentioned in previous comment. – user1672994 Jun 14 '18 at 13:36
  • @user1672994 I like this approach, but in my case it's not really the elegant solution I was hoping for, since the would require me to create a separate Response constructor for every possible IPayload, right? – christok Jun 14 '18 at 13:49
  • @DanWilson - not sure if this completely gets to what I'm looking for as it does not seem that there's an opportunity to specify the type at the time of deserialization. But perhaps I'm reading it wrong and will look at this a bit more. – christok Jun 14 '18 at 14:00

0 Answers0