I'm getting a Json-response containing travel information between to public transport destinations.
If there is no direct transfer, the Json-element containing the information ("Leg") will be an object. However, if there is no direct transfer the ("Leg") element will turn into an array containing two or more objects with different attributes.
When I try to deserialise the Json-response using the autogenerated classes from the API schema (Paste as special JSON), the deserialisation returns only null-values.
Generating C# classes using the actual Json-response sets the ("Leg") element to an public object, with no getters or setters for the attributes. This way the deserialisation will work, but I'm not able to convert the ("Leg") element with it's attributes. Or it's probably possible but I don't know how.
Here is the Json-response
{
"TripList": {
"noNamespaceSchemaLocation": "http://api.xsd",
"servertime": "03:10",
"serverdate": "2017-04-11",
"Trip": [
{
"Leg": {
"name": "Spårvagn 6",
"sname": "6",
"type": "TRAM",
"id": "xxx5014500604002",
"direction": "Länsmansgården",
"fgColor": "#fa8719",
"bgColor": "#00394d",
"stroke": "Solid",
"Origin": {
"name": "Centralstationen, Göteborg",
"type": "ST",
"id": "xxx2014001950004",
"routeIdx": "1",
"time": "04:05",
"date": "2017-04-11",
"track": "D",
"rtTime": "04:05",
"rtDate": "2017-04-11",
"$": "\n"
},
"Destination": {
"name": "Vågmästareplatsen, Göteborg",
"type": "ST",
"id": "xxx2014007520002",
"routeIdx": "5",
"time": "04:11",
"date": "2017-04-11",
"track": "B",
"rtTime": "04:11",
"rtDate": "2017-04-11",
"$": "\n"
},
"JourneyDetailRef": { "ref": "xx}
}
},
{
"Leg": [
{
"name": "Gå",
"type": "WALK",
"Origin": {
"name": "Göteborg C, Göteborg",
"type": "ST",
"id": "xxx2014008000015",
"time": "04:42",
"date": "2017-04-11",
"$": "\n"
},
"Destination": {
"name": "Nordstan, Göteborg",
"type": "ST",
"id": "xxx2014004945002",
"time": "04:47",
"date": "2017-04-11",
"track": "B",
"$": "\n"
}
},
{
"name": "Spårvagn 6",
"sname": "6",
"type": "TRAM",
"id": "xxx5014500604012",
"direction": "Länsmansgården",
"fgColor": "#fa8719",
"bgColor": "#00394d",
"stroke": "Solid",
"Origin": {
"name": "Nordstan, Göteborg",
"type": "ST",
"id": "xxx2014004945002",
"routeIdx": "11",
"time": "04:47",
"date": "2017-04-11",
"track": "B",
"rtTime": "04:47",
"rtDate": "2017-04-11",
"$": "\n"
},
"Destination": {
"name": "Vågmästareplatsen, Göteborg",
"type": "ST",
"id": "xxx2014007520002",
"routeIdx": "14",
"time": "04:52",
"date": "2017-04-11",
"track": "B",
"rtTime": "04:52",
"rtDate": "2017-04-11",
"$": "\n"
},
"JourneyDetailRef": { "ref": "xx" }
}
]
},
{
"Leg": [
{
"name": "Gå",
"type": "WALK",
"Origin": {
"name": "Göteborg C, Göteborg",
"type": "ST",
"id": "xxx2014008000015",
"time": "04:58",
"date": "2017-04-11",
"$": "\n"
},
"Destination": {
"name": "Nordstan, Göteborg",
"type": "ST",
"id": "xxx2014004945002",
"time": "05:03",
"date": "2017-04-11",
"track": "B",
"$": "\n"
}
},
{
"name": "Spårvagn 6",
"sname": "6",
"type": "TRAM",
"id": "xxx5014500604024",
"direction": "Länsmansgården",
"fgColor": "#fa8719",
"bgColor": "#00394d",
"stroke": "Solid",
"Origin": {
"name": "Nordstan, Göteborg",
"type": "ST",
"id": "xxx2014004945002",
"routeIdx": "11",
"time": "05:03",
"date": "2017-04-11",
"track": "B",
"rtTime": "05:03",
"rtDate": "2017-04-11",
"$": "\n"
},
"Destination": {
"name": "Vågmästareplatsen, Göteborg",
"type": "ST",
"id": "xxx2014007520002",
"routeIdx": "14",
"time": "05:08",
"date": "2017-04-11",
"track": "B",
"rtTime": "05:08",
"rtDate": "2017-04-11",
"$": "\n"
},
"JourneyDetailRef": { "ref": "xx" }
}
]
}
]
}
}
As show in the Json-response above, the "Leg" element varies. Sometimes it's an array and sometimes not. In this response the first occurrence of Leg seems to be an object, the following two Leg occurrences seem to be arrays of objects, where the objects properties differ whether it's a "walking route" or a "Tram route". This changes with every response. Now these are the classes generated using the acutal Json-response
public class Rootobject
{
public Triplist TripList { get; set; }
}
public class Triplist
{
public string noNamespaceSchemaLocation { get; set; }
public string servertime { get; set; }
public string serverdate { get; set; }
public Trip[] Trip { get; set; }
}
public class Trip
{
public object Leg { get; set; }
}
My wish is to deserialise the response in a way where I can harvest the data from "Leg", put in in C# objects and pass them into a view.
I'm not sure if I was able to explain the problem in a proper way, but I don't know how to deal with this.
I would really need some guidance!
EDIT
I came up with a solution, perhaps an ugly solution buy at least it works the way I want. I created a separate model called "Leg", then I simply for-looped the Leg-part of the Json-response, checking if the object is an array or not.
The additional model class:
public class Leg
{
public string name { get; set; }
public string sname { get; set; }
public string type { get; set; }
public string id { get; set; }
public string direction { get; set; }
public string fgColor { get; set; }
public string bgColor { get; set; }
public string stroke { get; set; }
public string accessibility { get; set; }
public Origin Origin { get; set; }
public Destination Destination { get; set; }
public Journeydetailref JourneyDetailRef { get; set; }
}
public class Origin
{
public string name { get; set; }
public string type { get; set; }
public string id { get; set; }
public string routeIdx { get; set; }
public string time { get; set; }
public string date { get; set; }
public string track { get; set; }
public string rtTime { get; set; }
public string rtDate { get; set; }
public string _ { get; set; }
}
public class Destination
{
public string name { get; set; }
public string type { get; set; }
public string id { get; set; }
public string routeIdx { get; set; }
public string time { get; set; }
public string date { get; set; }
public string track { get; set; }
public string rtTime { get; set; }
public string rtDate { get; set; }
public string _ { get; set; }
}
public class Journeydetailref
{
public string _ref { get; set; }
}
The method
// Deserialising the full Json-response.
var json = JsonConvert.DeserializeObject<TripModel>(jsonString);
result = json;
// Nested list of "Leg". Will be populated with both direct-routes and routes with connections.
List<List<Leg>> completeLegList = new List<List<Leg>>();
List<Leg> root = new List<Leg>();
// Just to make a variable easier to work with
string legTrimmed;
for (int i = 0; i < json.TripList.Trip.Length; i++)
{
// Assigning the variable
legTrimmed = json.TripList.Trip[i].Leg.ToString();
// Sorting out the trips containing 1 or more transerfs (looking for the opening array character.)
if (legTrimmed.Contains("["))
{
// Replacing whitespace and linebreaks
legTrimmed.Replace(" ", string.Empty);
legTrimmed.Replace("\r\n", string.Empty);
// Deserializing just the Leg-data from the master Json-response. Putting the results in an list.
var legObjectMultiple = JsonConvert.DeserializeObject<List<Leg>>(legTrimmed);
// Adding the list (with multiple connections) to the main Leg-list.
completeLegList.Add(legObjectMultiple);
}
// Trips with direct connection below.
else
{
legTrimmed = json.TripList.Trip[i].Leg.ToString();
legTrimmed.Replace(" ", string.Empty);
legTrimmed.Replace("\r\n", string.Empty);
Leg legObjectSingle = JsonConvert.DeserializeObject<Leg>(legTrimmed);
var legListSingle = new List<Leg>();
legListSingle.Add(legObjectSingle);
completeLegList.Add(legListSingle);
}
}
return completeLegList;
Thanks Best J