我编写了一个类来计算两个坐标之间的距离。但是一旦我运行该项目,它就会出错:
WebException未处理。
System.Xml.dll中发生未处理的“System.Net.WebException”类型异常
其他信息:远程服务器返回错误:(403)禁止。
我的代码是:
public Tuple<double, double> GetCoords(string Streetnumber, string Streetname, string Cityname, string Country)
{
XmlDocument doc = new XmlDocument();
string clientId = "///"; =
string key = "//";
string address = Streetnumber + "+" + Streetname + ",+" + Cityname + ",+" + Country;
var urlRequest = "/maps/api/geocode/xml?address=" + address + "&client=" + clientId;
System.Security.Cryptography.HMACSHA1 myhmacsha1 = new System.Security.Cryptography.HMACSHA1();
myhmacsha1.Key = Convert.FromBase64String(key);
var hash = myhmacsha1.ComputeHash(System.Text.Encoding.ASCII.GetBytes(urlRequest));
string signature = Convert.ToBase64String(hash).Replace("+", "-").Replace("/", "_");
WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultNetworkCredentials;
doc.Load("https://maps.googleapis.com/maps/api/geocode/xml?address=" + address + "&client=" + clientId + "&signature=" + signature);
string longitude = doc.SelectSingleNode("//GeocodeResponse/result/geometry/location/lng").InnerText;
double lng = LongitudePlace(longitude);
string latitude = doc.SelectSingleNode("//GeocodeResponse/result/geometry/location/lat").InnerText;
double lat = LatitudePlace(latitude);
return Tuple.Create(lng, lat);
}
我还有一些其他方法,但它们与此问题无关。错误发生在:
doc.Load("https://maps.googleapis.com/maps/api/geocode/xml?address=" + address + "&client=" + clientId + "&signature=" + signature);
也许这很容易解决,但我尝试了很多东西。我的clientID
是正确的,如果我没有误会,也是console.developer.google.com上的密钥。
我尝试了“1600”,“Amphitheatre + Parkway”,“Mountain + View”,“CA”的测试地址。
如何解决错误?
答案 0 :(得分:0)
看起来您的签名可能无法正确形成。具体来说,它缺少URL的一部分。以下是使用Google提供的代码对代码进行编辑的代码的编辑版本。代码可以找到here
<强>代码强>
public Tuple<double, double> GetCoords(string streetNumber, string streetName, string cityName, string country)
{
XmlDocument doc = new XmlDocument();
string clientId = "gme-" + "///";
string key = "//"; //Note this is NOT your API key, it's the Client Secret
string address = streetNumber + "+" + streetName + ",+" + cityName + ",+" + country;
WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultNetworkCredentials;
doc.Load(Sign("https://maps.googleapis.com/maps/api/geocode/xml?address=" + address + "&client=" + clientId, key));
string longitude = doc.SelectSingleNode("//GeocodeResponse/result/geometry/location/lng").InnerText;
double lng = LongitudePlace(longitude);
string latitude = doc.SelectSingleNode("//GeocodeResponse/result/geometry/location/lat").InnerText;
double lat = LatitudePlace(latitude);
return Tuple.Create(lng, lat);
}
//From the Google
public static string Sign(string url, string keyString)
{
ASCIIEncoding encoding = new ASCIIEncoding();
// converting key to bytes will throw an exception, need to replace '-' and '_' characters first.
string usablePrivateKey = keyString.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;
}