mirror of
https://github.com/jcreek/CityFinder.git
synced 2026-07-12 18:33:44 +00:00
feat(*): Add functionality to request city from Google API
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace CityFinder.Models
|
||||
{
|
||||
public partial class GeocodeApiErrorResponse
|
||||
{
|
||||
[JsonProperty("error_message")]
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
[JsonProperty("results")]
|
||||
public List<object> Results { get; set; }
|
||||
|
||||
[JsonProperty("status")]
|
||||
public string Status { get; set; }
|
||||
}
|
||||
|
||||
public partial class GeocodeApiErrorResponse
|
||||
{
|
||||
public static GeocodeApiErrorResponse FromJson(string json) => JsonConvert.DeserializeObject<GeocodeApiErrorResponse>(json, JsonConverter.Settings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace CityFinder.Models
|
||||
{
|
||||
public partial class GeocodeApiResponse
|
||||
{
|
||||
[JsonProperty("results")]
|
||||
public List<Result> Results { get; set; }
|
||||
|
||||
[JsonProperty("status")]
|
||||
public string Status { get; set; }
|
||||
}
|
||||
|
||||
public partial class Result
|
||||
{
|
||||
[JsonProperty("address_components")]
|
||||
public List<AddressComponent> AddressComponents { get; set; }
|
||||
|
||||
[JsonProperty("formatted_address")]
|
||||
public string FormattedAddress { get; set; }
|
||||
|
||||
[JsonProperty("place_id")]
|
||||
public string PlaceId { get; set; }
|
||||
|
||||
[JsonProperty("types")]
|
||||
public List<string> Types { get; set; }
|
||||
}
|
||||
|
||||
public partial class AddressComponent
|
||||
{
|
||||
[JsonProperty("long_name")]
|
||||
public string LongName { get; set; }
|
||||
|
||||
[JsonProperty("short_name")]
|
||||
public string ShortName { get; set; }
|
||||
|
||||
[JsonProperty("types")]
|
||||
public List<string> Types { get; set; }
|
||||
}
|
||||
|
||||
public partial class GeocodeApiResponse
|
||||
{
|
||||
public static GeocodeApiResponse FromJson(string json) => JsonConvert.DeserializeObject<GeocodeApiResponse>(json, JsonConverter.Settings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace CityFinder.Models
|
||||
{
|
||||
internal static class JsonConverter
|
||||
{
|
||||
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
|
||||
{
|
||||
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
|
||||
DateParseHandling = DateParseHandling.None,
|
||||
Converters =
|
||||
{
|
||||
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,9 @@ namespace CityFinder
|
||||
|
||||
Console.WriteLine("Enter a zip/postal code:");
|
||||
string postalCodeInput = Console.ReadLine();
|
||||
|
||||
// Get the city using an API call
|
||||
await GetCity(countryInput, postalCodeInput);
|
||||
/// <summary>
|
||||
/// This method sets up the json config file and sets the user-agent header on the HttpClient.
|
||||
/// </summary>
|
||||
@@ -99,6 +102,43 @@ namespace CityFinder
|
||||
return countryInput;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method queries the Google Geocode API to get a city name from a country and postal code.
|
||||
/// </summary>
|
||||
/// <param name="countryCode">The country code to search for.</param>
|
||||
/// <param name="postalCode">The postal code to search for.</param>
|
||||
/// <returns>Returns nothing, but it needs awaiting as it's calling an external API.</returns>
|
||||
private static async Task GetCity(string countryCode, string postalCode)
|
||||
{
|
||||
string apiKey = config["GoogleMapsGeocodeApiKey"];
|
||||
string requestUri = $"https://maps.googleapis.com/maps/api/geocode/json?key={apiKey}&address={postalCode}®ion={countryCode}";
|
||||
string responseBody = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
HttpResponseMessage response = await client.GetAsync(requestUri);
|
||||
responseBody = await response.Content.ReadAsStringAsync();
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
GeocodeApiResponse geocodeApiResponse = GeocodeApiResponse.FromJson(responseBody);
|
||||
string cityName = geocodeApiResponse.Results.FirstOrDefault().AddressComponents.FirstOrDefault(a => a.Types.Contains("postal_town")).LongName;
|
||||
|
||||
Console.WriteLine($"The city is called {cityName}");
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
GeocodeApiErrorResponse geocodeApiErrorResponse = GeocodeApiErrorResponse.FromJson(responseBody);
|
||||
|
||||
Console.WriteLine($"Exception caught - Message :{ex.Message}");
|
||||
Console.WriteLine($"Google API request failed with status {geocodeApiErrorResponse.Status}");
|
||||
Console.WriteLine(geocodeApiErrorResponse.ErrorMessage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Exception caught - Message :{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method displays a table of valid country codes.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user