John O'Grady
John O'Grady

Reputation: 245

How to deserialise JSON output into C# Struct (based on return from calling Google Maps API)

First time posting here as a total newb so apologies if I'm not going about posting this question in the right way

I have a struct to hold Geo coordinates in a .NET MVC5 project

   public struct GeoCoordinate
    {
        private readonly double latitude;
        private readonly double longitude;

        public double Latitude { get { return latitude; } }
        public double Longitude { get { return longitude; } }

        public GeoCoordinate(double latitude, double longitude)
        {
            this.latitude = latitude;
            this.longitude = longitude;
        }

        public override string ToString()
        {
            return string.Format("{0},{1}", Latitude, Longitude);
        }
    }

I am attempting to call a method on the Post Create method to fill the coordinate values with location coordinates provided by the Google Maps API- which provides a JSON formatted datastream back.

public GeoCoordinate GEOCodeAddress(String Address)
    {
        var address = String.Format("https://maps.googleapis.com/maps/api/geocode/json?address={0}&sensor=false", Address.Replace(" ", "+"));
        var result = new System.Net.WebClient().DownloadString(address);
        JavaScriptSerializer jss = new JavaScriptSerializer();

        return jss.Deserialize<dynamic>(result);


    }

I can "see" the result contains JSON which has in it (among lots of other attributes) the location coordinates that I'm looking to return, I'm just having issues with the syntax to "parse" out these location attributes and return them to my create method.

In the JSON visualiser the coordinates are in JSON[0].geometry.location.lat and JSON[0].geometry.location.lng and I'm guessing (?!) that the JSON[0].geometry.location contains an object that should be compatible (ish) with my struct. Am happy to amend the struct to make it compatible if necessary!

Thanks in advance for any help/insight you can give!

Upvotes: 4

Views: 951

Answers (2)

John O&#39;Grady
John O&#39;Grady

Reputation: 245

Hi after some experimentation, I eventually figured out that I can parse it out using the following syntax. There's most likely a less verbose version but this works!

     public GeoCoordinate GEOCodeAddress(String Address)
    {
        var address = String.Format("https://maps.googleapis.com/maps/api/geocode/json?address={0}&sensor=false", Address.Replace(" ", "+"));
        var result = new System.Net.WebClient().DownloadString(address);
        JavaScriptSerializer jss = new JavaScriptSerializer();
        RootObject googleData = JsonConvert.DeserializeObject<RootObject>(result);
        GeoCoordinate coordinates = new GeoCoordinate();
        coordinates.Latitude= googleData.results[0].geometry.location.lat;
        coordinates.Longitude= googleData.results[0].geometry.location.lng;
        return coordinates;

Upvotes: 0

DavidG
DavidG

Reputation: 118947

Looking at the JSON returned by that URL, the classes you need to deserialise into object look like this (The easiest way to get to this code is to copy the JSON to clipboard, then in Visual Studio, Edit menu, Paste Special and select Paste as JSON Classes):

public class RootObject
{
    public Result[] results { get; set; }
    public string status { get; set; }
}

public class Result
{
    public Address_Components[] address_components { get; set; }
    public string formatted_address { get; set; }
    public Geometry geometry { get; set; }
    public string place_id { get; set; }
    public string[] types { get; set; }
    public bool partial_match { get; set; }
}

public class Geometry
{
    public Bounds bounds { get; set; }
    public Location location { get; set; }
    public string location_type { get; set; }
    public Viewport viewport { get; set; }
}

public class Bounds
{
    public Northeast northeast { get; set; }
    public Southwest southwest { get; set; }
}

public class Northeast
{
    public float lat { get; set; }
    public float lng { get; set; }
}

public class Southwest
{
    public float lat { get; set; }
    public float lng { get; set; }
}

public class Location
{
    public float lat { get; set; }
    public float lng { get; set; }
}

public class Viewport
{
    public Northeast1 northeast { get; set; }
    public Southwest1 southwest { get; set; }
}

public class Northeast1
{
    public float lat { get; set; }
    public float lng { get; set; }
}

public class Southwest1
{
    public float lat { get; set; }
    public float lng { get; set; }
}

public class Address_Components
{
    public string long_name { get; set; }
    public string short_name { get; set; }
    public string[] types { get; set; }
}

And to get that data into one of those object, just do this (using Json.Net):

RootObject googleData = JsonConvert.DeserializeObject<RootObject>(result);

Upvotes: 3

Related Questions