0

Я взял пример с this SO question и создал собственный объект Google Maps, используемый для десериализации объекта json.Как работают DataContracts? - Deserialize Json

Теперь код работает как чемпион, но мне просто нужно объяснение, почему и как оно работает. Сериализатор «пытается» сопоставить имена или что-то еще происходит.

Что именно это делается?

Вот рабочий код.

Imports System.Net 
Imports System.Web 
Imports System.Runtime.Serialization 
Imports System.Runtime.Serialization.Json 
Imports System.Web.Script.Serialization 

Namespace Utilities.Apis 
    Public NotInheritable Class GoogleGeolocate 


     Private Const googleUrl As String = "http://maps.googleapis.com/maps/api/geocode/json?address={0}&sensor=false" 
     Private Sub New() 
     End Sub 

     Public Shared Function GetLatLon(ByVal address As String) As String 
      ''# This is just here to prevent "placeholder" data from being submitted. 
      If address = "6789 university drive" Then 
       Return Nothing 
      End If 

      address = HttpUtility.UrlEncode(address) 

      Dim url = String.Format(googleUrl, address) 

      Dim request = DirectCast(HttpWebRequest.Create(url), HttpWebRequest) 
      request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate") 
      request.AutomaticDecompression = DecompressionMethods.GZip Or DecompressionMethods.Deflate 
      Dim serializer As New DataContractJsonSerializer(GetType(GoogleResponse)) 
      Dim res = DirectCast(serializer.ReadObject(request.GetResponse().GetResponseStream()), GoogleResponse) 

      Dim resources As GoogleResponse.Result = res.results(0) 
      Dim point = resources.geometry.location.lat 
      Dim latlon As New GeolocationLatLon 
      With latlon 
       .latitude = resources.geometry.location.lat 
       .longitude = resources.geometry.location.lng 
      End With 

      Dim jsonSerializer = New JavaScriptSerializer 

      Return jsonSerializer.Serialize(latlon) 
     End Function 
    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 
End Namespace 

И вот GeolocationLatLon Poco

Public Class GeolocationLatLon 
    Public latitude As String 
    Public longitude As String 
End Class 

Когда я вызываю код, это действительно очень просто.
нота, это контроллер MVC, который не имеет ничего общего «на самом деле» с вопросом, кроме как показать то, что я делаю

Function GeoLocation(ByVal address As String) As ContentResult 
     Return New ContentResult With {.Content = GoogleGeolocate.GetLatLon(address), 
             .ContentType = "application/json"} 
    End Function 

И конечный результат

{ "широта": "50.124300", "долгота": "- 114.4979990"}

ответ

1

Внутренне имя DataContractJsonSerializer карты в формате JSON/значение пары к XML Infoset. Фактически DataContractJsonSerializer построен поверх XML-DataContractSerializer и обрабатывает каждый вход JSON и вывод JSON, как если бы он имел дело с XML. Существует уровень абстракции более высокого уровня (писатель JSON и считыватель JSON, как показано через JsonReaderWriterFactory), который фактически переводит этот XML в JSON и JSON обратно во внутренний XML.

Посмотрите на это excellent overview (Mapping Between JSON and XML), чтобы узнать, что происходит с DataContractJsonSerializer, и как оно тянет все это.