Tips series: Polymorphic objects with Json and WebApi
- Posted in:
- Web dev
Short intro: my new year resolution, decided in April, is that I will write weekly blog posts. Short, concise, something I worked on last week or whatever… so here is the first one!
This was a small problem I had in the office, one co-worker created two apps, of which one is WebAPI on self-hosted OWIN, other one is a win service. Exposing objects from WebAPI and reading them through HttpClient caused some problems when we refactored them, introduced polymorphism in this case.
Issues were:
- JsonConvert couldn’t de-serialise received string, throwing this exception:
An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dllAdditional information: Could not create an instance of type JsonTypeNameHandling.Vehicle. Type is an interface or abstract class and cannot be instantiated
- We wanted to inspect what WebApi is returning, but XML serializer was kicking in
- We wanted to see full error details
This is common problem with WebApi, since (I guess) default Json settings are not configured to send object type information (recognized by “$type” in Json). Configuration needed for those issues:
- both sides (server and client) needs Json.net settings to use type names:
Client side (using HttpClient):
JsonConvert.DeserializeObject<MyType>(payload, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto })
Server side (WebApi):
configuration.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto; - Serve Json when invoking WebApi with browser:
configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); - Show error information:
configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
The whole example, a small app that creates web server (with OWIN and HttpListener) and calls itself:
Solution can be downloaded from Github