user2786091 user2786091 - 3 months ago 8
C# Question

Deserialize with Newtonsoft.Json

i'm tester learning C# and Rest service testing both new to me......
I have Json response like this

{ "results" : [
{
"address_components" : [
{
"long_name" : "1600",
"short_name" : "1600",
"types" : [ "street_number" ]
},
{
"long_name" : "Amphitheatre Parkway",
"short_name" : "Amphitheatre Pkwy",
"types" : [ "route" ]
},
{
"long_name" : "Mountain View",
"short_name" : "Mountain View",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Santa Clara County",
"short_name" : "Santa Clara County",
"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.4223434,
"lng" : -122.0843689
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : 37.42369238029149,
"lng" : -122.0830199197085
},
"southwest" : {
"lat" : 37.42099441970849,
"lng" : -122.0857178802915
}
}
},
"place_id" : "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
"types" : [ "street_address" ]
}
],
"status" : "OK"
}


and going to deserialize it to object and only need "lat" and "lng" in geometry / location

My code look like

JObject myMap = JObject.Parse(response.Content);
IList<JToken> mylist = myMap["results"][0]["geometry"].Children().ToList();`

IList<location> spots = new List<location>();
foreach (JToken spot in mylist)
{
Console.WriteLine("\nthe spots are :\t:"+ spot.ToString());
location somesopt = JsonConvert.DeserializeObject<location>(spot.ToString());
Console.WriteLine("\n the lat is :\t" + somesopt.lat.ToString());
Console.WriteLine("\n the lat is :\t" + somesopt.lng.ToString());
}


and my objects are .........

public class location
{
public double lat { get; set; }
public double lng { get; set; }
}

public class geopost
{
public location geometry;
}


The problem is always I get JsonSerializationException at json deseserializobject I try changing many permutation of defining mylist
but could not get it write ....what wrong am I doing..?

when use same structure of code for "Long_name" and "short_name" at address component it works fine. I understand that address component is array and geometry / location are objects. But how do you handle it?

Answer

Why not deserialise to a proper class structure? Something like this:

public class AddressComponent
{
    public string long_name { get; set; }
    public string short_name { get; set; }
    public List<string> types { get; set; }
}

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

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

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

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

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

public class Result
{
    public List<AddressComponent> address_components { get; set; }
    public string formatted_address { get; set; }
    public Geometry geometry { get; set; }
    public string place_id { get; set; }
    public List<string> types { get; set; }
}

public class RootObject
{
    public List<Result> results { get; set; }
    public string status { get; set; }
}

Then deserialise like this:

var data = JsonConvert.DeserializeObject<RootObject>(json);

Now you can operate directly on your object hierarchy:

foreach (var result in data.results)
{
    var lat = result.geometry.location.lat;
}

PS I generated the class hierarchy from json2csharp.com

Comments