.NET DataContractJsonSerializer, вложенные коллекции бросают меня в тупик - PullRequest
2 голосов
/ 30 апреля 2011

Я работаю над классом, чтобы получить широту и долготу адреса от 3 разных провайдеров (просто для сравнения).

Обратите внимание, на это может показаться много, но некоторая информация просто для справки, если хотите. Данные ниже <hr> смотреть не обязательно.

Мой Google Maps DataContract работает как чемпион. Но мои Bing и MapQuest DataContracts не так хороши. Я думаю, что проблема связана с вложенными коллекциями JSON для Bing и MapQuest, и я просто не знаю, как с ними справиться.

Вот функция, обрабатывающая данные.

        ''# 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

А вот и три 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

При тестировании MapQuest Я получаю эту ошибку

System.NullReferenceException: ссылка на объект не установлена ​​для экземпляра объекта. на линии

.latitude = point.lat

При тестировании Bing я получаю эту ошибку

System.IndexOutOfRangeException: индекс находился за пределами массива. на линии

Dim resources As BingResponse.ResourceSet.Resource = res.resourceSets(0).resources(0)

К вашему сведению, я также опубликую, как выглядит ответ JSON для каждого из них.

Карты Google

{
  "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

{ "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|&center=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" }
      } ]
}

Добавление

screenshot

1 Ответ

1 голос
/ 30 апреля 2011

За карту квеста:

Не должно ли Public Property locations As m_Locations быть Public Property locations() As m_Locations()? Я предполагаю, что это обозначение массива в VB. Казалось бы, вы берете latLng из объекта Array, а не экземпляр местоположения в массиве.

Найден аналогичный вопрос с контрактом данных (принятый ответ) для того же ответа. Ищете различия, но пока не замечаете их ...

...