Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing a signed Google Maps API Geocoding request from a .NET Command Line Application
    text
    copied!<p>So I'm writing an application to cache geocoding data as I import records. I've got it working fine when I use an unsigned request, however I can't seem to figure out what's wrong when I try to use my company's clientid and signature. I always get a 403 Forbidden.</p> <p>Here's my URL builder:</p> <pre><code> private const string _googleUri = "http://maps.googleapis.com/maps/api/geocode/xml?address="; private const string _googleClientId = "XXXXXXXX"; private const string _googleSignature = "XXXXXXXXXXXXXXXXXXXXXXXX"; //RESOLVED private static String GetGeocodeUri(string address) { ASCIIEncoding encoding = new ASCIIEncoding(); string url = String.Format("{0}{1}&amp;client={2}&amp;sensor=false" , _googleUri , HttpUtility.UrlEncode(address) , _googleClientId); // converting key to bytes will throw an exception, need to replace '-' and '_' characters first. string usablePrivateKey = _googleSignature.Replace("-", "+").Replace("_", "/"); byte[] privateKeyBytes = Convert.FromBase64String(usablePrivateKey); Uri uri = new Uri(url); byte[] encodedPathAndQueryBytes = encoding.GetBytes( uri.LocalPath + uri.Query ); // compute the hash HMACSHA1 algorithm = new HMACSHA1(privateKeyBytes); byte[] hash = algorithm.ComputeHash(encodedPathAndQueryBytes); // convert the bytes to string and make url-safe by replacing '+' and '/' characters string signature = Convert.ToBase64String(hash).Replace("+", "-").Replace("/", "_"); // Add the signature to the existing URI. return uri.Scheme + "://" + uri.Host + uri.LocalPath + uri.Query + "&amp;signature=" + signature; } </code></pre> <p>Here's the Program:</p> <pre><code>public static AddressClass GetResponseAddress(string address) { AddressClass GoogleAddress = new AddressClass(); XmlDocument doc = new XmlDocument(); String myUri = GetGeocodeUri(address); try { doc.Load(myUri); XmlNode root = doc.DocumentElement; if (root.SelectSingleNode("/GeocodeResponse/status").InnerText == "OK") { GoogleAddress.Latitude = Double.Parse(root.SelectSingleNode("/GeocodeResponse/result/geometry/location/lat").InnerText); GoogleAddress.Longitude = Double.Parse(root.SelectSingleNode("/GeocodeResponse/result/geometry/location/lat").InnerText); } } catch (Exception ex) { Console.WriteLine("Exception &lt;" + ex.Message + "&gt;"); } return GoogleAddress; } </code></pre> <p>Now, my initial reaction to it not working was that Google must be missing the referer domain because they must be registered. So I tried it with HttpWebRequest and set the referer to my domain, but still no dice.</p> <pre><code>//Not needed, Just an alternate method public static AddressClass GetResponseAddress(string address) { AddressClass GoogleAddress = new AddressClass(); WebClient client = new WebClient(); XmlDocument doc = new XmlDocument(); Uri myUri = new Uri(GetGeocodeUri(address)); HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(myUri); myRequest.Referer = "http://www.myDomain.com/"; //I've even tried pretending to be Chrome //myRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.75 Safari/535.7"; try { doc.Load(myRequest.GetResponse().GetResponseStream()); XmlNode root = doc.DocumentElement; if (root.SelectSingleNode("/GeocodeResponse/status").InnerText == "OK") { GoogleAddress.Latitude = Double.Parse(root.SelectSingleNode("/GeocodeResponse/result/geometry/location/lat").InnerText); GoogleAddress.Longitude = Double.Parse(root.SelectSingleNode("/GeocodeResponse/result/geometry/location/lat").InnerText); } } catch (Exception ex) { Console.WriteLine("Exception &lt;" + ex.Message + "&gt;"); } return GoogleAddress; } </code></pre> <p>Any help would be much appreciated.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload