问题
I grabbed an example off of this SO question, and built my own custom Google Maps object used for deserializing the json object.
Now the code works like a champ, but I just need an explanation on why/how it works. Does the serializer "try" to match up names, or is something else going on.
What exactly is this doing?
Here's the working code.
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
And here's the GeolocationLatLon Poco
Public Class GeolocationLatLon
Public latitude As String
Public longitude As String
End Class
When I call the code, it's really quite simple.
note, this is an MVC controller, that has nothing to do "really" with the question other than to show what I'm doing
Function GeoLocation(ByVal address As String) As ContentResult
Return New ContentResult With {.Content = GoogleGeolocate.GetLatLon(address),
.ContentType = "application/json"}
End Function
And the final result is
{"latitude":"50.124300","longitude":"-114.4979990"}
回答1:
Internally, DataContractJsonSerializer maps JSON name/value pairs to an XML infoset. In fact, DataContractJsonSerializer is built on top of the XML-based DataContractSerializer and processes every JSON input and JSON output as if it were dealing with XML. There is a higher-level abstraction layer (a JSON writer and a JSON reader, as exposed via JsonReaderWriterFactory) that actually translates this XML to JSON and JSON back to internal XML.
See this excellent overview (Mapping Between JSON and XML) to see what happens to DataContractJsonSerializer internally and how it pulls all this off.
来源:https://stackoverflow.com/questions/4289073/how-do-datacontracts-work-deserialize-json