3

Problem: In my data models I want to define a class with a property that is an abstract base class.

public class MyDataContract
{
    [JsonProperty("myFoo")]
    public Foo MyFoo { get; set; }

    [JsonProperty("correlationId")]
    public Guid Correlationid { get; set; }
}

public abstract class Foo
{
    [JsonProperty("id")]
    public int Id { get; set; }
}

public class Bar : Foo
{
    [JsonProperty("name")]
    public string Name { get; set; }
}

public class Baz : Foo
{
    [JsonProperty("time")]
    public DateTime Time { get; set; }
}

In particular, I want to deserialize these data contracts from a message queue. But JsonConcert.DeserializeObject<MyDataContract>(json) will fail because MyFoo is an abstract class. It cannot figure out something like

{ 
    myFoo: {
       id: 1293,
       name: 'Tom'
   },
   correlationId: 'f70edc04-9465-4edd-9582-f066f62dab02'
}

Is there a solution that doesn't involve rolling my own JSON converter for my data contract?

Or doing something like

public class MyDataContract<T>
    where T : Foo
{
    [JsonProperty("myFoo")]
    public T MyFoo { get; set; }

    [JsonProperty("correlationId")]
    public Guid Correlationid { get; set; }
}

and then trying like

Foo foo = JsonConvert.DeserializeObject<MyDataContract<Foo>>(json);
if (foo != null)
{
    return foo;
}


Bar bar = JsonConvert.DeserializeObject<MyDataContract<Bar>>(json);
if (bar != null)
{
    return bar;
}

throw new InvalidOperationException("Uh-oh");
Hiram Katz
  • 383
  • 1
  • 2
  • 7

1 Answers1

0

If you don't know what specific type is coming across the wire (or other system boundry), I think you should add all of the properties to the base class and map to the more specific type afterward (based on the availability / non-null state of relevant properties). You could manage access via namespaces and access modifiers; depends on the requirements of your system and how clear the names of types are.

If you DO know what type you're receiving, you should deserialize directly to that type.

Regardless, you should think about your object type hierarchy and if it needs to be structured the way that it is.

ryanwebjackson
  • 1,017
  • 6
  • 22
  • 36