.NET DataContractJsonSerializer, Nested collections throwing me for a loop
I'm working on a class to get the Latitude and Longitude of an address by 3 different providers (just for comparison sake).
Note, this might look like a lot to look at, but some info is just there for reference if you want. Data below the <hr>
is not necessary to look at.
My Google Maps DataContract works like a champ. But my Bing and MapQuest DataContracts aren't playing so nice. I think the issue has to deal with the Nested collections of the JSON for Bing and MapQuest, and I just don't know how to deal with them.
Here is the Function that processes the Data.
''# Because the JSON Response from Google, MapQuest, and Bing are drastically
''# different, we need to consume the response a little differently
''# for each API.
''# ##################################
''# BING IS BROKEN
''# ##################################
''# Here we're handling the Bing Provider
If Provider = apiProvider.Bing Then
Dim res = DirectCast(serializer.ReadObject(request.GetResponse().GetResponseStream()), BingResponse)
Dim resources As BingResponse.ResourceSet.Resource = res.resourceSets(0).resources(0)
Dim point = resources.point
With coordinates
.latitude = point.coordinates(0)
.longitude = point.coordinates(1)
End With
''# ##################################
''# GOOGLE WORKS LIKE A CHAMP
''# ##################################
''# Here we're handling the Google Provider
ElseIf Provider = apiProvider.Google Then
Dim res = DirectCast(serializer.ReadObject(request.GetResponse().GetResponseStream()), GoogleResponse)
Dim resources As GoogleResponse.Result = res.results(0)
Dim point = resources.geometry.location
With coordinates
.latitude = point.lat
.longitude = point.lng
End With
''# ##################################
''# MAPQUEST IS BROKEN
''# ##################################
''# Here we're handling the MapQuest Provider
ElseIf Provider = apiProvider.MapQuest Then
Dim res = DirectCast(serializer.ReadObject(request.GetResponse().GetResponseStream()), MapQuestResponse)
Dim resources As MapQuestResponse.Result = res.results(0)
Dim point = resources.locations.latLng
With coordinates
.latitude = point.lat
.longitude = point.lng
End With
End If
And here are the three DataContracts
''# A comment to fix SO Code Coloring
<DataContract()>
Public Class BingResponse
<DataMember()>
Public Property resourceSets() As ResourceSet()
<DataContract()>
Public Class ResourceSet
<DataMember()>
Public Property resources() As Resource()
<DataContract([Namespace]:="http://schemas.microsoft.com/search/local/ws/rest/v1", name:="Location")>
Public Class Resource
<DataMember()>
Public Property point() As m_Point
<DataContract()>
Public Class m_Point
<DataMember()>
Public Property coordinates() As String()
End Class
End Class
End Class
End Class
<DataContract()>
Public Class GoogleResponse
<DataMember()>
Public Property results() As Result()
<DataContract()>
Public Class Result
<DataMember()>
Public Property geometry As m_Geometry
<DataContract()>
Public Class m_Geometry
<DataMember()>
Public Property location As m_location
<DataContract()>
Public Class m_location
<DataMember()>
Public Property lat As String
<DataMember()>
Public Property lng As String
End Class
End Class
End Class
End Class
<DataContract()>
Public Class MapQuestResponse
<DataMember()>
Public Property results() As Result()
<DataContract()>
Public Class Result
<DataMember()>
Public Property locations As m_Locations
<DataContract()>开发者_运维百科;
Public Class m_Locations
<DataMember()>
Public Property latLng As m_latLng
<DataContract()>
Public Class m_latLng
<DataMember()>
Public Property lat As String
<DataMember()>
Public Property lng As String
End Class
End Class
End Class
End Class
When testing MapQuest I get this error
System.NullReferenceException: Object reference not set to an instance of an object. on line
.latitude = point.lat
When testing Bing I get this error
System.IndexOutOfRangeException: Index was outside the bounds of the array. on line
Dim resources As BingResponse.ResourceSet.Resource = res.resourceSets(0).resources(0)
FYI, I'll also post what the JSON Response for each looks like.
Google Maps
{
"status": "OK",
"results": [ {
"types": [ "bus_station", "transit_station" ],
"formatted_address": "Microsoft Way & Microsoft ACS, Redmond, WA 98052, USA",
"address_components": [ {
"long_name": "Microsoft Way & Microsoft ACS",
"short_name": "Microsoft Way & Microsoft ACS",
"types": [ "bus_station", "transit_station" ]
}, {
"long_name": "Redmond",
"short_name": "Redmond",
"types": [ "locality", "political" ]
}, {
"long_name": "East Seattle",
"short_name": "East Seattle",
"types": [ "administrative_area_level_3", "political" ]
}, {
"long_name": "King",
"short_name": "King",
"types": [ "administrative_area_level_2", "political" ]
}, {
"long_name": "Washington",
"short_name": "WA",
"types": [ "administrative_area_level_1", "political" ]
}, {
"long_name": "United States",
"short_name": "US",
"types": [ "country", "political" ]
}, {
"long_name": "98052",
"short_name": "98052",
"types": [ "postal_code" ]
} ],
"geometry": {
"location": {
"lat": 47.6397018,
"lng": -122.1305080
},
"location_type": "APPROXIMATE",
"viewport": {
"southwest": {
"lat": 47.6365542,
"lng": -122.1336556
},
"northeast": {
"lat": 47.6428494,
"lng": -122.1273604
}
}
},
"partial_match": true
}, {
"types": [ "bus_station", "transit_station" ],
"formatted_address": "Microsoft Way & NE 36th St, Redmond, WA 98052, USA",
"address_components": [ {
"long_name": "Microsoft Way & NE 36th St",
"short_name": "Microsoft Way & NE 36th St",
"types": [ "bus_station", "transit_station" ]
}, {
"long_name": "Redmond",
"short_name": "Redmond",
"types": [ "locality", "political" ]
}, {
"long_name": "East Seattle",
"short_name": "East Seattle",
"types": [ "administrative_area_level_3", "political" ]
}, {
"long_name": "King",
"short_name": "King",
"types": [ "administrative_area_level_2", "political" ]
}, {
"long_name": "Washington",
"short_name": "WA",
"types": [ "administrative_area_level_1", "political" ]
}, {
"long_name": "United States",
"short_name": "US",
"types": [ "country", "political" ]
}, {
"long_name": "98052",
"short_name": "98052",
"types": [ "postal_code" ]
} ],
"geometry": {
"location": {
"lat": 47.6420593,
"lng": -122.1306990
},
"location_type": "APPROXIMATE",
"viewport": {
"southwest": {
"lat": 47.6389117,
"lng": -122.1338466
},
"northeast": {
"lat": 47.6452069,
"lng": -122.1275514
}
}
},
"partial_match": true
}, {
"types": [ "bus_station", "transit_station" ],
"formatted_address": "Microsoft Way & NE 31ST St, Redmond, WA 98052, USA",
"address_components": [ {
"long_name": "Microsoft Way & NE 31ST St",
"short_name": "Microsoft Way & NE 31ST St",
"types": [ "bus_station", "transit_station" ]
}, {
"long_name": "Redmond",
"short_name": "Redmond",
"types": [ "locality", "political" ]
}, {
"long_name": "East Seattle",
"short_name": "East Seattle",
"types": [ "administrative_area_level_3", "political" ]
}, {
"long_name": "King",
"short_name": "King",
"types": [ "administrative_area_level_2", "political" ]
}, {
"long_name": "Washington",
"short_name": "WA",
"types": [ "administrative_area_level_1", "political" ]
}, {
"long_name": "United States",
"short_name": "US",
"types": [ "country", "political" ]
}, {
"long_name": "98052",
"short_name": "98052",
"types": [ "postal_code" ]
} ],
"geometry": {
"location": {
"lat": 47.6380959,
"lng": -122.1318050
},
"location_type": "APPROXIMATE",
"viewport": {
"southwest": {
"lat": 47.6349483,
"lng": -122.1349526
},
"northeast": {
"lat": 47.6412435,
"lng": -122.1286574
}
}
},
"partial_match": true
}, {
"types": [ "route" ],
"formatted_address": "Microsoft w Campus Acrd, Redmond, WA, USA",
"address_components": [ {
"long_name": "Microsoft w Campus Acrd",
"short_name": "Microsoft w Campus Acrd",
"types": [ "route" ]
}, {
"long_name": "Redmond",
"short_name": "Redmond",
"types": [ "locality", "political" ]
}, {
"long_name": "East Seattle",
"short_name": "East Seattle",
"types": [ "administrative_area_level_3", "political" ]
}, {
"long_name": "King",
"short_name": "King",
"types": [ "administrative_area_level_2", "political" ]
}, {
"long_name": "Washington",
"short_name": "WA",
"types": [ "administrative_area_level_1", "political" ]
}, {
"long_name": "United States",
"short_name": "US",
"types": [ "country", "political" ]
} ],
"geometry": {
"location": {
"lat": 47.6582970,
"lng": -122.1414390
},
"location_type": "GEOMETRIC_CENTER",
"viewport": {
"southwest": {
"lat": 47.6559394,
"lng": -122.1435435
},
"northeast": {
"lat": 47.6622346,
"lng": -122.1372482
}
},
"bounds": {
"southwest": {
"lat": 47.6577719,
"lng": -122.1433446
},
"northeast": {
"lat": 47.6604021,
"lng": -122.1374471
}
}
},
"partial_match": true
} ]
}
Bing Maps
{ "authenticationResultCode" : "ValidCredentials",
"brandLogoUri" : "http://dev.virtualearth.net/Branding/logo_powered_by.png",
"copyright" : "Copyright © 2011 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.",
"resourceSets" : [ { "estimatedTotal" : 1,
"resources" : [ { "__type" : "Location:http://schemas.microsoft.com/search/local/ws/rest/v1",
"address" : { "addressLine" : "1 Microsoft Way",
"adminDistrict" : "WA",
"countryRegion" : "United States",
"formattedAddress" : "1 Microsoft Way, Redmond, WA 98052",
"locality" : "Redmond",
"postalCode" : "98052"
},
"bbox" : [ 47.636682837606166,
-122.13698544771381,
47.644408272747519,
-122.12169881991093
],
"confidence" : "High",
"entityType" : "Address",
"name" : "1 Microsoft Way, Redmond, WA 98052",
"point" : { "coordinates" : [ 47.640545555176843,
-122.12934213381237
],
"type" : "Point"
}
} ]
} ],
"statusCode" : 200,
"statusDescription" : "OK",
"traceId" : "3d0dd6c4ea1f4c4ba6f9c7211a5abf75|BAYM001222|02.00.82.2800|BY2MSNVM001058"
}
MapQuest
{ "info" : { "copyright" : { "imageAltText" : "© 2011 MapQuest, Inc.",
"imageUrl" : "http://tile21.mqcdn.com/res/mqlogo.gif",
"text" : "© 2011 MapQuest, Inc."
},
"messages" : [ ],
"statuscode" : 0
},
"options" : { "ignoreLatLngInput" : false,
"maxResults" : -1,
"thumbMaps" : true
},
"results" : [ { "locations" : [ { "adminArea1" : "US",
"adminArea1Type" : "Country",
"adminArea3" : "WA",
"adminArea3Type" : "State",
"adminArea4" : "King County",
"adminArea4Type" : "County",
"adminArea5" : "Redmond",
"adminArea5Type" : "City",
"displayLatLng" : { "lat" : 47.674197999999997,
"lng" : -122.1203
},
"dragPoint" : false,
"geocodeQuality" : "CITY",
"geocodeQualityCode" : "A5XCX",
"latLng" : { "lat" : 47.674197999999997,
"lng" : -122.1203
},
"linkId" : 0,
"mapUrl" : "http://www.mapquestapi.com/staticmap/v3/getmap?type=map&size=225,160&pois=purple-1,47.674198,-122.1203,0,0|¢er=47.674198,-122.1203&zoom=9&key=Fmjtd|luu22q01ng,2n=o5-h6rnq&rand=-47567557",
"postalCode" : "",
"sideOfStreet" : "N",
"street" : "",
"type" : "s"
} ],
"providedLocation" : { "location" : "1 Microsoft Way, Redmon WA" }
} ]
}
Addition
For map quest:
Shouldn't Public Property locations As m_Locations
be Public Property locations() As m_Locations()
? I assume this is array notation in VB. It would seem you're taking the latLng from the Array object and not the instance of the location in the array.
Found a similar question with a data contract (accepted answer) for the same response. Looking for differences but not spotting them yet...
精彩评论