2015-09-18 3 views
2

Я закодировал класс для вычисления расстояния между двумя координатами. Но как только я запускаю проект, он дает ошибку:403 запрещено. WebException был необработанным. NET

WebException was unhandled.

An unhandled exception of type 'System.Net.WebException' occurred in System.Xml.dll

Additional information: The remote server returned an error: (403) Forbidden.

Мой код:

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); 

Возможно, это легко исправить, но я пробовал много чего. Мойправильный, также ключ, который является секретным ключом на console.developer.google.com, если я не ошибаюсь.

Я пробовал тестовый адрес «1600», «Амфитеатр + Парквей», «Гора + Вид», «CA».

Как решить эту ошибку?

+0

может быть ваша строка здания. предположите, что вы используете кодировку url или аналогичную https://msdn.microsoft.com/en-us/library/system.net.webutility.urlencode(v=vs.110).aspx – Ewan

+4

Вы взяли сгенерированную строку и вставили ее в браузер? –

+0

@RonBeyer да, я сделал, и он не работал. –

ответ

0

Похоже, что ваша подпись может быть неверной. В частности, отсутствует часть URL-адреса. Ниже приведена отредактированная версия вашего кода с использованием кода, предоставленного Google для подписания URL-адреса. Код можно найти 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; 
} 
+0

Все еще не работает, предоставляя такая же ошибка в doc.Load (знак (https://maps.googleapis.com/maps/api/geocode/xml?address= "+ адрес +" & client = "+ clientId, ключ)); –

+0

Вы помещаете 'gme-' перед своим идентификатором клиента? –

+0

@ amura.csg нет, мой клиент начинается с цифр, продолжает буквы и заканчивается на .apps.googleusercontent.com –