1

I am new to Newtonsoft.Json so please excuse my ignorance - however I am coming up against this issue when trying to Deserialize the following Json to either a c# object or indeed manually.

The Json is

{
  "travellerInfo": [
    {
      "passengerData": {
        "travellerInformation": {
          "passenger": [
            {
              "type": "ADT",
              "firstName": "MARY MRS"
            },
            {
              "type": "INF",
              "firstName": "JOSHUA"
            }
          ],
          "traveller": {
            "surname": "SMITH",
            "quantity": "2"
          }
        }
      }
    },
    {
      "passengerData": {
        "travellerInformation": {
          "passenger": {
            "type": "ADT",
            "firstName": "JOHN MR"
          },
          "traveller": {
            "surname": "SMITH",
            "quantity": "1"
          }
        }
      }
    }
  ]
}

So as you can see, on the first 'passenger' item, this returns as an Array, however on the second 'passenger' item, it doesn't return as an array, just a single block. I am not in control of the Json being sent to me - it comes from an external system. My C# classes are

public class Passenger
{
    public string type { get; set; }
    public string firstName { get; set; }
}

public class Traveller
{
    public string surname { get; set; }
    public string quantity { get; set; }
}

public class TravellerInformation
{
    public List<Passenger> passenger { get; set; }
    public Traveller traveller { get; set; }
}

public class PassengerData
{
    public TravellerInformation travellerInformation { get; set; }
}

public class TravellerInfo
{
   public PassengerData passengerData { get; set; }
}

and I call

var example = JsonConvert.DeserializeObject<TravellerInfo>(jsonString);

I am getting the error

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Script1.TravellerInfo' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path 'travellerInfo', line 57, position 20. 

I tried putting a [JsonArray] attribute on the Passenger class to force it to deserialise as an array/list, but same error occured as I think the underlying item is a JProperty instead of a JObject.

So how can I get this to work when the ["passenger"] can come back as both an Array and Single object ?

Cheers in Advance

Paul T
  • 131
  • 6
  • 1
    I'd advise you to use [Json 2 C#](http://json2csharp.com/) web to generate your classes, or paste special in Visual Studio – Pikoh Feb 14 '17 at 15:31
  • 1
    Clearly it's impossible for the travellerInformation object to have both a passenger property as a single instance **and** and array. What I think I would do in this case is try to modify the Json (it's a string, after all) so that the passenger property is **always** an array. So find a way to add the square brackets if needed? Here's an answer in Java: http://stackoverflow.com/questions/21063367/jackson-mapping-object-or-list-of-object-depending-on-json-input – Oxonhammer Feb 14 '17 at 15:32
  • `Passenger` has nothing to do with the error you are showing as that has to do with the `TraverInfo` array you are trying to pass into a `TraverInfo` Object - Aside from that if you are in control of creating the data, change passenger to always be an array with either 1 or more entries. If not, you could write a mapper on the script side to "fix" that, wrapping the single object into an array before sending it up? – Nope Feb 14 '17 at 15:32
  • @Fran - ah yes, I see that now, I was concentrating on the Passenger element as I knew that repeated - and can now see that the TravellerInfo can also be either an array or a single item - this Json is a little, um, confused :) – Paul T Feb 14 '17 at 16:15

2 Answers2

0

Try this. Replace List<Passenger> with object passenger in TravellerInformation:

public class Traveller
{
    public string surname { get; set; }
    public string quantity { get; set; }
}

public class TravellerInformation
{
    public object passenger { get; set; }
    public Traveller traveller { get; set; }
}

public class PassengerData
{
    public TravellerInformation travellerInformation { get; set; }
}

public class TravellerInfo
{
    public PassengerData passengerData { get; set; }
}

And call this by passing List<TravellerInfo> instead of TravellerInfo:

var example = JsonConvert.DeserializeObject<List<TravellerInfo>>(jsonString);

Also for these cases you can use this service which automatically creates C# classes from JSON objects, so you don't have to worry about correctness.

Just Shadow
  • 10,860
  • 6
  • 57
  • 75
  • I did use Json 2 C# to create the classes - however to raise this question I only showed the particular section that was causing the problem. There is a single ["response"] element at the top of the Json - sorry if this caused some confusion – Paul T Feb 14 '17 at 15:42
  • Thanks for picking up the List - I didn't realise that this could also be an array or single item in the Json. So I changed it to List in the class for Response - and that seems to have fixed that but now the error is specific to the List still - I did try to change that just object, but same error occured – Paul T Feb 14 '17 at 16:34
  • Sorry, couldn't understand the last sentence. Is the remaining problem to detect if type of `object` is `List` or `Passenger` for converting to it? If yes, then I think I have a solution – Just Shadow Feb 14 '17 at 18:00
0

You can try deserialize it as dynamic and then do some checks to types. Check if it is IEnumerable.

That should do the job.

Gh61
  • 9,222
  • 4
  • 28
  • 39