.NET DataContractJsonSerializer, Nested collections throwing me for a loop - asp.net
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...
Related
Google geocoding & place details incomplete in Kosovo
I've got multiple existing and reasonably specific addresses in Kosovo (e.g. https://goo.gl/maps/fryFyLm1Eg3M6jfB7) which google geocodes as partial matches: // https://maps.googleapis.com/maps/api/geocode/json?address=Rr.D%C3%ABshmor%C3%ABt%20e%20Kombit,%20ferizaj+kosovo&key=... { "results": [ { "address_components": [ { "long_name": "Dëshmorët e Kombit", "short_name": "Dëshmorët e Kombit", "types": [ "route" ] }, { "long_name": "Ferizaj", "short_name": "Ferizaj", "types": [ "locality", "political" ] } ], "formatted_address": "Dëshmorët e Kombit, Ferizaj", "geometry": { ... }, "partial_match": true, "place_id": "ChIJxflVGlh-VBMRe2iYrxbiSzY", "types": [ "route" ] } ], "status": "OK" } Lots of address components seem to be missing though (administrative_area_level_1, country_political =ISO country code, etc). Fetching place details doesn't help: // https://maps.googleapis.com/maps/api/place/details/json?fields=place_id,name,formatted_address,geometry,address_components&place_id=ChIJxflVGlh-VBMRe2iYrxbiSzY&key=... { "result": { "address_components": [ { "long_name": "Dëshmorët e Kombit", "short_name": "Dëshmorët e Kombit", "types": [ "route" ] }, { "long_name": "Ferizaj", "short_name": "Ferizaj", "types": [ "locality", "political" ] } ], "formatted_address": "Dëshmorët e Kombit, Ferizaj", "geometry": { ... }, "name": "Dëshmorët e Kombit", "place_id": "ChIJxflVGlh-VBMRe2iYrxbiSzY" }, "status": "OK" } I suppose it's related to this google group thread on disputed territories from 2016 but do the limitations still apply? Other geocoding providers (e.g. https://geocode.xyz/42.36566,21.15629?json=1) yield much more detailed results. What are the latest recommendations on geocoding disputed terriotiries like Kosovo with google?
CyberSource payout unsucessfull when we put businessApplicationId = "CP"
We are trying to pay a client's credit card bills, for that we have to choose "businessApplicationId": "CP" in payout api, Am i right? Request format is : { "clientReferenceInformation": { "code": "111111113" }, "orderInformation": { "amountDetails": { "totalAmount": "111.00", "currency": "USD" } }, "merchantInformation": { "merchantDescriptor": { "name": "Sending Company Name", "locality": "FC", "country": "US", "administrativeArea": "CA", "postalCode": "94440" } }, "recipientInformation": { "firstName": "John", "lastName": "Doe", "address1": "Paseo Padre Boulevard", "locality": "Foster City", "administrativeArea": "CA", "country": "US", "postalCode": "94400", "phoneNumber": "6504320556" }, "senderInformation": { "referenceNumber": "1234567890", "account": { "fundsSource": "05", "number": "1234567890123456789012345678901234" }, "name": "Company Name", "address1": "900 Metro Center Blvd.900", "locality": "Foster City", "administrativeArea": "CA", "countryCode": "US" }, "processingInformation": { "businessApplicationId": "CP", "networkRoutingOrder": "V8", "commerceIndicator": "internet" }, "paymentInformation": { "customer": { "customerId": "C99A860705336053E053AF598E0A0D43" } } } we get the following response: { "id": "6290386260456808404006", "submitTimeUtc": "2021-08-15T14:43:46Z", "status": "SERVER_ERROR", "reason": "SYSTEM_ERROR", "message": "Error - General system failure." } Our configuration is : Authentication type: HTTP Signature Sample Request : Payout(Token) Payment Processor Type : Chase Paymentech (Default) Sandbox Credentials : Merchant ID : Priya1234 Previously cybersource team had enabled tokenization and payout in our Merchant Id : Priya1234, Currently we are in a test environment, Is there anything that we have missed here? Also Please let us know if there are any other options available to pay client's credit card bills.
Some Reverse GeoCode queries return null
We are attempting to retrieve district information for a number of locations. However the Here API returns no values. These locations are in the state of Arunachal Pradesh and Jammu & Kashmir in India. I tested with a number of latitude/longitudes for these states. None of them return any data. https://reverse.geocoder.ls.hereapi.com/6.2/reversegeocode.json?prox=28.2180,94.7278&mode=retrieveAreas&apiKey=XXXXXXXXXXXXXXXXXXXXXXXXXXX Response: { "Response": { "MetaInfo": { "Timestamp": "2020-08-05T15:11:46.711+0000" }, "View": [] } } Even when I choose a location from Google Maps and use that in the API call, it still returns null. https://reverse.geocoder.ls.hereapi.com/6.2/reversegeocode.json?prox=27.083227, 93.605954&mode=retrieveAreas&apiKey=XXXXXXXXXXXXXXXXXXXXXXXXXXX Response: { "Response": { "MetaInfo": { "Timestamp": "2020-08-05T15:11:46.711+0000" }, "View": [] } }
The Geocoding and Search API v7 is recommended. https://revgeocode.search.hereapi.com/v1/revgeocode?at=28.2180%2C94.7278&lang=en-US { "items": [ { "title": "Jomlo Mobuk, Arunachal Pradesh, India", "id": "here:cm:namedplace:22803761", "resultType": "locality", "localityType": "city", "address": { "label": "Jomlo Mobuk, Arunachal Pradesh, India", "countryCode": "IND", "countryName": "India", "state": "Arunachal Pradesh", "county": "Siang", "city": "Jomlo Mobuk", "postalCode": "791001" }, "position": { "lat": 28.22394, "lng": 94.85208 }, "distance": 0, "mapView": { "west": 94.72013, "south": 28.17345, "east": 94.9472, "north": 28.29374 } } ] }
How to Get County Information for the given address when we use Rest API
I am using below code to get the address information and i am getting entire address. But i only need county for the given city and zip of USA. Please help function getCounty() { $.ajax({ url: 'https://geocoder.api.here.com/6.2/geocode.json', type: 'GET', dataType: 'jsonp', jsonp: 'jsoncallback', data: { city: 'Farmington', postalcode: '48335', country: 'usa', app_id: '**************************', app_code: '************************', gen: '9' }, success: function (data) { alert(JSON.stringify(data)); } }); }
Please try below code to access County attribute of the response. Hope this help. alert(data.Response.View[0].Result[0].Location.Address.County); And please check below full JSON response for the request. { "Response": { "MetaInfo": { "Timestamp": "2019-01-09T07:08:18.912+0000" }, "View": [ { "_type": "SearchResultsViewType", "ViewId": 0, "Result": [ { "Relevance": 1, "MatchLevel": "postalCode", "MatchQuality": { "City": 1, "PostalCode": 1 }, "Location": { "LocationId": "NT_9usvaftBv-o9T6WyVpnWRC", "LocationType": "area", "DisplayPosition": { "Latitude": 42.47427, "Longitude": -83.40889 }, "NavigationPosition": [ { "Latitude": 42.47427, "Longitude": -83.40889 } ], "MapView": { "TopLeft": { "Latitude": 42.48732, "Longitude": -83.4355 }, "BottomRight": { "Latitude": 42.43954, "Longitude": -83.37537 } }, "Address": { "Label": "48335, Farmington, MI, United States", "Country": "USA", "State": "MI", "County": "Oakland", "City": "Farmington", "PostalCode": "48335", "AdditionalData": [ { "value": "United States", "key": "CountryName" }, { "value": "Michigan", "key": "StateName" }, { "value": "Oakland", "key": "CountyName" }, { "value": "N", "key": "PostalCodeType" } ] } } } ] } ] } }
Finding a large database of locations around the world?
I am creating a sample application for a client using mapbox and I need to huge dataset of locations that span accross the whole world in lt lng format. E.g. var addressPoints = [ [-37.8210922667, 175.2209316333, "2"], [-37.8210819833, 175.2213903167, "3"], [-37.8210881833, 175.2215004833, "3A"], ]; I was thinking of a list of hotels around the world or something? Or an extremely cleaver way of creating locations on the fly in Javascript that do not end up in the sea? Any help would be great appreciated! Thanks.
This is a fun question - I don't know of a huge data set but some ideas I had for generating one are: Strava API If you have a free API key, you can query Strava's segments end point and give it a lat/lng boundary, so you will get start and end points within those bounds (but limited to 10 results so you'd have to loop to get enough data and may exceed your API call limit, however if you just create it once it might not be so bad). You could also get a lot of points from a specific bike ride/run, but they'd all be close together which I don't think you want. http://strava.github.io/api/v3/segments/#explore e.g. Throttling The default rate limit allows 600 requests every 15 minutes, with up to 30,000 requests per day. API call curl -G https://www.strava.com/api/v3/segments/explore \ -H "Authorization: Bearer YOUR_TOKEN" \ -d bounds=37.821362,-122.505373,37.842038,-122.465977 \ Response { "segments": [ { "id": 229781, "name": "Hawk Hill", "climb_category": 1, "climb_category_desc": "4", "avg_grade": 5.7, "start_latlng": [ 37.8331119, -122.4834356 ], "end_latlng": [ 37.8280722, -122.4981393 ], "elev_difference": 152.8, "distance": 2684.8, "points": "}g|eFnm#n#Op#VJr#" }, { "id": 632535, "name": "Hawk Hill Upper Conzelman to Summit", "climb_category": 0, "climb_category_desc": "NC", "avg_grade": 8.10913, "start_latlng": [ 37.8334451, -122.4941994 ], "end_latlng": [ 37.8281297, -122.4980005 ], "elev_difference": 67.29200000000003, "distance": 829.834, "points": "_j|eFvc#p#SbAu#h#Qn#?RTDH" } ] } Google Geocoding API This API will accept an address and give you a lat/lng (and more) but is throttled. You'd just need a list of addresses which would be pretty easy to get. API https://developers.google.com/maps/documentation/geocoding/ Throttling Users of the free API: 2,500 requests per 24 hour period. 5 requests per second. API call https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA Response { "results" : [ { "address_components" : [ { "long_name" : "1600", "short_name" : "1600", "types" : [ "street_number" ] }, { "long_name" : "Amphitheatre Pkwy", "short_name" : "Amphitheatre Pkwy", "types" : [ "route" ] }, { "long_name" : "Mountain View", "short_name" : "Mountain View", "types" : [ "locality", "political" ] }, { "long_name" : "Santa Clara", "short_name" : "Santa Clara", "types" : [ "administrative_area_level_2", "political" ] }, { "long_name" : "California", "short_name" : "CA", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "United States", "short_name" : "US", "types" : [ "country", "political" ] }, { "long_name" : "94043", "short_name" : "94043", "types" : [ "postal_code" ] } ], "formatted_address" : "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA", "geometry" : { "location" : { "lat" : 37.42291810, "lng" : -122.08542120 }, "location_type" : "ROOFTOP", "viewport" : { "northeast" : { "lat" : 37.42426708029149, "lng" : -122.0840722197085 }, "southwest" : { "lat" : 37.42156911970850, "lng" : -122.0867701802915 } } }, "types" : [ "street_address" ] } ], "status" : "OK" }