I'm new to APIs in general. I'm trying to learn how to use the Google GeoCode API to get the county from a user input zip code. I'm using .NET Core MVC
An example payload can be seen with the following URL: http://maps.googleapis.com/maps/api/geocode/json?address=77379&sensor=true
which produces the payload:
{
"results" : [
{
"address_components" : [
{
"long_name" : "77379",
"short_name" : "77379",
"types" : [ "postal_code" ]
},
{
"long_name" : "Spring",
"short_name" : "Spring",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Harris County",
"short_name" : "Harris County",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Texas",
"short_name" : "TX",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Spring, TX 77379, USA",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 30.088189,
"lng" : -95.47364999999999
},
"southwest" : {
"lat" : 29.9871611,
"lng" : -95.5887879
}
},
"location" : {
"lat" : 30.0314279,
"lng" : -95.5302337
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 30.088189,
"lng" : -95.47364999999999
},
"southwest" : {
"lat" : 29.9871611,
"lng" : -95.5887879
}
}
},
"place_id" : "ChIJtZcGtDLNQIYRtGE9AgmSOPQ",
"postcode_localities" : [ "Klein", "Spring" ],
"types" : [ "postal_code" ]
}
],
"status" : "OK"
}
For example, I would like to get the string "Harris County" from the above's url JSON result.
In my model, I have:
public class GoogleAddress
{
public List<Result> results;
}
[DataContract]
public class Result
{
[DataMember(Name = "long_name")]
public string long_name { get; set; }
[DataMember(Name = "short_name")]
public string short_name { get; set; }
[DataMember(Name = "types")]
public string types { get; set; }
}
In my controller, I have the following within my method:
//zip to be passed as a parameter in my method later, hardcoded here for testing
string zip = "77379";
string county = "";
var serializer = new DataContractJsonSerializer(typeof(GoogleAddress));
//example url: http://maps.googleapis.com/maps/api/geocode/json?address=77379&sensor=true
string url = "http://maps.googleapis.com/maps/api/geocode/json?address=" + zip + "&sensor=true";
var client = new HttpClient();
var streamTask = client.GetStreamAsync(url);
var address = (GoogleAddress)serializer.ReadObject(await streamTask);
var result = address.results;
//how do I get the county from the result?
return View(county);
How should my model be set up to match the payload and how do I get the County name from the payload?
Consider using a framework like Json.Net. Using this you can dynamically parse your json response and get only those parts which are usefull for you:
var jsonResult = "some json from google api";
dynamic jsonObject = JObject.Parse(jsonResult);
var long_name = jsonObject.results[0].address_components[2].long_name;
var short_name = jsonObject.results[0].address_components[2].short_name;
If you want to work with the whole data set returned from google, you can create a suitable class structure (this can be automated by using a tool such as json2csharp or Visual Studios Paste Special functionality) and deserialize your json result regarding:
Class structure
public class AddressComponent
{
public string long_name { get; set; }
public string short_name { get; set; }
public List<string> types { 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 Bounds
{
public Northeast northeast { get; set; }
public Southwest southwest { get; set; }
}
public class Location
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Northeast2
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Southwest2
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Viewport
{
public Northeast2 northeast { get; set; }
public Southwest2 southwest { 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 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> postcode_localities { get; set; }
public List<string> types { get; set; }
}
public class RootObject
{
public List<Result> results { get; set; }
public string status { get; set; }
}
Deserialize json
var data = JsonConvert.DeserializeObject<RootObject>(jsonResult);
var long_name = data.results[0].address_components[2].long_name;
var short_name = data.results[0].address_components[2].short_name;
Edit
Full example:
string zip = "77379";
string url = "http://maps.googleapis.com/maps/api/geocode/json?address=" + zip + "&sensor=true";
var client = new HttpClient();
// 'using' forces proper cleanup after finishing the operation
using(var response = await client.GetAsync(url))
{
if(response.IsSuccessStatusCode)
{
var jsonResult = await response.Content.ReadAsStringAsync();
dynamic jsonObject = JObject.Parse(jsonResult);
// Consider doing some validation first to be sure that 'results' and 'address_components' contains any elements to avoid exceptions
var long_name = jsonObject.results[0].address_components[2].long_name;
var short_name = jsonObject.results[0].address_components[2].short_name;
}
}