2

So I'm using json.net to deserialize some data from the interwebs. And the bumblebrains providing the data are making it hard for me. The data type of one of the properties of the object I'm trying to deserialize varies depending on the contents of another property in the object, like so:

{ "typeindicator": "A", "object_I_Need": { ...formatted for object type A ... } }

Or

{ "typeindicator": "B", "object_I_Need": { ...formatted for object type B ... } }

I need the "object_I_Need" regardless of whether it's type A or B and I have the schema for both types.

I don't need to solve this completely in the deserializer. I just JsonExtensionDataAttribute to check for unknown fields so I was wondering if I could just let the object_I_Need fall into that and then deserialize that seperately... is there a way to do that?

What are my options here? I guess I could deserialize the whole thing into a dynamic object, decide what type the object_I_Need is and serialize it again? I hope there's a better way, though. Suggestions appreciated.

Thanks, Crash

Crash Gordon
  • 151
  • 1
  • 9
  • According to the [spec](http://json.org/), a JSON object is an *unordered set of name/value pairs.*. So assuming that the `typeindicator` comes before the object itself may be a bad idea. Can you store it in a `JObject` and post-process it? Or maybe see here for a possible solution: https://stackoverflow.com/questions/31927365/passing-additional-information-to-a-jsonconverter#comment51768777_31927365 – dbc Aug 24 '15 at 22:50
  • Thanks dbc.. I think using JObject will work.. who knew that was there? :) Thanks! – Crash Gordon Aug 24 '15 at 23:00
  • See also: [Deserializing polymorphic json classes without type information using json.net](http://stackoverflow.com/q/19307752/10263) – Brian Rogers Aug 27 '15 at 07:05

2 Answers2

1

You can use Newtonsoft to deserialize into a dynamic object and then build you object from there.

var dyn = JsonConvert.DeserializeObject<dynamic>(rawJson);

var myObject = new O();
if (dyn.typeindicator.Value == "A") {
    myObject.PropA = dyn.object_I_Need.AAAA.Value;
}
else
{
    myObject.PropA = dyn.object_I_Need.anotherA.Value;
}
deramko
  • 2,807
  • 1
  • 18
  • 27
1

Here's what works for me here:

public class DeCrash
{
    [JsonProperty("object_I_Need")]
    protected JObject ObjectINeed;

    [JSonProperty("typeindicator")]
    public String TypeIndicator { get; set; }

    [JsonIgnore]
    public TypeA ObjectA 
    { 
        get 
        { 
           return TypeIndicator == "A" ? ObjectINeed.ToObject<TypeA> : null;
        }
    }

    [JsonIgnore]
    public TypeB ObjectB
    { 
        get 
        { 
           return TypeIndicator == "B" ? ObjectINeed.ToObject<TypeB> : null;
        }
    }
}
Crash Gordon
  • 151
  • 1
  • 9