Estoy escribiendo una aplicación para guardar en caché los datos de geocodificación mientras importo los registros. Funciono bien cuando utilizo una solicitud sin firmar, sin embargo, parece que no puedo entender qué sucede cuando trato de usar el cliente y la firma de mi empresa. Siempre obtengo un 403 Forbidden.Uso de una solicitud de geocodificación de la API de Google Maps firmada desde una aplicación de línea de comandos .NET
Aquí es mi URL constructor:
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}&client={2}&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 + "&signature=" + signature;
}
aquí está el programa:
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 <" + ex.Message + ">");
}
return GoogleAddress;
}
Ahora, mi reacción inicial a que no funcione es que Google debe faltar el dominio árbitro, ya que deben ser registrados . Así que lo intenté con HttpWebRequest y configuré el referer en mi dominio, pero aún no había dado.
//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 <" + ex.Message + ">");
}
return GoogleAddress;
}
Cualquier ayuda sería muy apreciada.
Estoy casi seguro de que esto va más allá de los términos de servicio para la API en cuestión. La razón por la que tiene un problema es porque no está diseñado para usarse en una aplicación tradicional solo como una aplicación web. No olvide que no hay un límite de transacción a menos que pague a Google. –
Google permite el almacenamiento en caché antes de generar informes para grandes conjuntos de datos, siempre que se realice correctamente .--- (b) Sin captura previa, almacenamiento en caché o almacenamiento de contenido.No debe precapturar, almacenar en caché o almacenar ningún Contenido, excepto que puede almacenar: (i) cantidades limitadas de Contenido con el fin de mejorar el rendimiento de su Implementación de la API de Maps si lo hace de forma temporal, segura y en un manera que no permita el uso del Contenido fuera del Servicio; y (ii) cualquier identificador de contenido o clave que la Documentación de las API de Maps le permita específicamente almacenar. – copjon
@Ramhound Además, sí hay un límite de consultas de 2.500/día sin pagar y 100.000 si paga. – copjon