Я пытаюсь реализовать новейший API погоды yahoo в приложении .NET (используемое нами было прекращено в пользу этого нового): https://developer.yahoo.com/weather/documentation.html#commercial
Их единственные примеры на PHPи Java.Я приложил все усилия, чтобы преобразовать пример Java в .NET, но я все еще получаю ответ «401 - Несанкционированный».Я просмотрел свой код несколько раз и не могу найти никаких проблем, поэтому я надеюсь, что кто-то еще сможет увидеть, где я ошибся.Код ниже.
Private Sub _WeatherLoader_DoWork(sender As Object, e As DoWorkEventArgs)
Try
Dim oauth As New OAuth.OAuthBase
Dim forecastRssResponse As query
Dim appId As String = My.Settings.YahooAppID
Dim consumerKey As String = My.Settings.YahooAPIConsumerKey
Dim yahooUri As String = String.Format("{0}?location=billings,mt&format=xml", YAHOO_WEATHER_API_BASE_ENDPOINT)
Dim oAuthTimestamp As Integer = oauth.GenerateTimeStamp()
Dim oAuthNonce As String = oauth.GenerateNonce()
Dim parameters As New List(Of String)
Try
parameters.Add(String.Format("oauth_consumer_key={0}", consumerKey))
parameters.Add(String.Format("oauth_nonce={0}", oAuthNonce))
parameters.Add("oauth_signature_method=HMAC-SHA1")
parameters.Add(String.Format("oauth_timestamp={0}", oAuthTimestamp.ToString()))
parameters.Add("oauth_version=1.0")
' Encode the location
parameters.Add(String.Format("location={0}", HttpUtility.UrlEncode("billings,mt", Encoding.UTF8)))
parameters.Add("format=xml")
' Sort parameters ascending
parameters = parameters.OrderBy(Function(item) item).ToList()
Dim i As Integer = 0
Dim builder As New StringBuilder()
Do While (i < parameters.Count())
builder.Append(String.Format("{0}{1}", If(i > 0, "&", String.Empty), parameters(i)))
i += 1
Loop
Dim signatureString As String = String.Format("GET&{0}&{1}", HttpUtility.UrlEncode(YAHOO_WEATHER_API_BASE_ENDPOINT, Encoding.UTF8), HttpUtility.UrlEncode(builder.ToString(), Encoding.UTF8))
Dim oAuthSignature As String = _CreateOauthSignature(signatureString)
Dim authorizationLine As String = String.Format("OAuth oauth_consumer_key={0}, oauth_nonce={1}, oauth_timestamp={2}, oauth_signature_method=HMAC-SHA1, oauth_signature={3}, oauth_version=1.0", consumerKey, oAuthNonce, oAuthTimestamp, oAuthSignature)
Dim forecastRequest As WebRequest = WebRequest.Create(yahooUri)
forecastRequest.Headers.Add("Authorization", authorizationLine)
forecastRequest.Headers.Add("Yahoo-App-Id", appId)
' Cast to HttpWebRequest to set ContentType through property
CType(forecastRequest, HttpWebRequest).ContentType = "text/xml"
Dim forecastResponse As WebResponse = forecastRequest.GetResponse()
If forecastResponse IsNot Nothing Then
Using responseStream As Stream = forecastResponse.GetResponseStream()
Dim rssDoc As New XmlDocument()
rssDoc.Load(responseStream)
forecastRssResponse = rssDoc.OuterXml().FromXml(Of query)()
End Using
e.Result = forecastRssResponse
End If
Catch ex As Exception
e.Result = Nothing
LoadingManually = False
End Try
Catch ex As Exception
modMain.SendDevErrorEmail(ex, "_WeatherLoader_DoWork in WeatherWidget", "Catch around dowork code in fired from refresh timer event in wether widget")
e.Result = Nothing
LoadingManually = False
End Try
End Sub
Private Function _CreateOauthSignature(baseInfo As String) As String
Dim secretKey As String = String.Format("{0}&", My.Settings.YahooAPIConsumerSecretKey)
Dim encoding As New System.Text.ASCIIEncoding()
Dim keyBytes As Byte() = encoding.GetBytes(secretKey)
Dim messageBytes As Byte() = encoding.GetBytes(baseInfo)
Dim hashMessage As Byte()
Using hmac As New HMACSHA1(keyBytes)
hashMessage = hmac.ComputeHash(messageBytes)
End Using
Return Convert.ToBase64String(hashMessage)
End Function