我已经按照yahoo在文档中提供的所有步骤完成了誓言来访问yahoo weather API的代码,如下所示: 1)创建Yahoo帐户 2)建立应用程式 3)白名单应用 4)C#代码通过誓言访问yahoo weather API
我在请求API时遇到了未经授权的访问异常。 这是代码:
public class WeatherYdn
{
public static void Main(string[] args)
{
const string appId = "YOUR-WHITELISTED-APPID";
const string consumerKey = "YOUR-CONSUMER-KEY";
const string consumerSecret = "YOUR-SECRET-KEY";
const string url = "https://weather-ydn-yql.media.yahoo.com/forecastrss";
string timestamp = StringHelper.GenerateTimeStamp();
String oauthNonce = StringHelper.GenerateNonce();
IList<string> parameters = new List<string>();
parameters.Add("oauth_consumer_key=" + consumerKey);
parameters.Add("oauth_nonce=" + oauthNonce);
parameters.Add("oauth_signature_method=HMAC-SHA1");
parameters.Add("oauth_timestamp=" + timestamp);
parameters.Add("oauth_version=1.0");
// Make sure value is encoded
parameters.Add("location=" + HttpUtility.UrlEncode("pune,in", Encoding.UTF8));
parameters.Add("format=json");
((List<string>) parameters).Sort();
StringBuilder parametersList = new StringBuilder();
for (int i = 0; i < parameters.Count; i++)
{
parametersList.Append(((i > 0) ? "&" : "") + parameters.ElementAt(i));
}
var signatureString = "GET&" +
HttpUtility.UrlEncode(url,Encoding.UTF8) + "&" +
HttpUtility.UrlEncode(parametersList.ToString(), Encoding.UTF8);
string signature = null;
try
{
string secretAccessKey = consumerSecret;
byte[] secretKey = Encoding.UTF8.GetBytes(secretAccessKey);
HMACSHA1 hmac = new HMACSHA1(secretKey);
hmac.Initialize();
byte[] bytes = Encoding.UTF8.GetBytes(signatureString);
byte[] rawHmac = hmac.ComputeHash(bytes);
signature = Convert.ToBase64String(rawHmac);
}
catch (Exception e)
{
Console.WriteLine("Unable to append signature");
}
string authorizationLine = "OAuth " +
"oauth_consumer_key=\"" + consumerKey + "\", " +
"oauth_nonce=\"" + oauthNonce + "\", " +
"oauth_timestamp=\"" + timestamp + "\", " +
"oauth_signature_method=\"HMAC-SHA1\", " +
"oauth_signature=\"" + signature + "\", " +
"oauth_version=\"1.0\"";
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url + "?location=pune,in&format=json");
request.Headers.Add("Authorization", authorizationLine);
request.Headers.Add("Yahoo-App-Id", appId);
request.ContentType = "application/json; charset=UTF-8";
request.Accept = "application/json";
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
Console.WriteLine(readStream.ReadLine());
}
}
答案 0 :(得分:0)
在哪一行出现错误? GetResponse()返回它吗? 我认为您使用的凭据(appId,consumerKey,consumerSecret)无效!
答案 1 :(得分:0)
public string appId = "Your app-id";
public string consumerKey = "Your-consumer key";
public string consumerSecret = "Your Consumer Secret key";
// GET: api/Random
[HttpGet("{CityName}")]
public async Task<IActionResult> GetAsync([FromUri] string CityName)
{
string urlss = "https://weather-ydn-yql.media.yahoo.com/forecastrss?location=";
string url = urlss + CityName+ "&format=json&u=c";
JObject jresult;
using (var client = new HttpClient())
{
try
{
var webClient = new WebClient();
webClient.Headers.Add(AssembleOAuthHeader());
var d = webClient.DownloadString(url);
jresult = JObject.Parse(d);
var json_jsonstring = Newtonsoft.Json.JsonConvert.SerializeObject(jresult);
return Ok(json_jsonstring);
}
catch (HttpRequestException httpRequestException)
{
return BadRequest($"Error getting weather from Yahoo Weather: {httpRequestException.Message}");
}
}
}
public string AssembleOAuthHeader()
{
return "Authorization: OAuth " +
"realm=\"yahooapis.com\"," +
"oauth_consumer_key=\"" + consumerKey + "\"," +
"oauth_nonce=\"" + Guid.NewGuid() + "\"," +
"oauth_signature_method=\"PLAINTEXT\"," +
"oauth_timestamp=\"" + ((DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1).Ticks) / (1000 * 10000)) +
"\"," +
"oauth_version=\"1.0\"," +
"oauth_signature=\"" + consumerSecret + "%26\"," +
"oauth_callback=\"oob\"";
}
答案 2 :(得分:0)
对于Yahoo Weather新身份验证,您可以使用此python库 yahoo-weather
答案 3 :(得分:0)
我认为您的代码很好。问题出在Yahoo的末端,URL解码的实施不佳。 Java URL Encode编码为大写,而.net HTTPUtility.URLEncode编码为小写。我为字符串创建了扩展方法,该方法将以Yahoo API可以处理的方式纠正问题和URL编码。这样做之后一切正常(我遇到了与您完全相同的问题)。
<Extension>
Public Function UppercaseURLEncode(ByVal sourceString As String) As String
Dim temp As Char() = HttpUtility.UrlEncode(sourceString).ToCharArray()
For i As Integer = 0 To temp.Length - 2
If temp(i).ToString().Equals("%", StringComparison.OrdinalIgnoreCase) Then
temp(i + 1) = Char.ToUpper(temp(i + 1))
temp(i + 2) = Char.ToUpper(temp(i + 2))
End If
Next
Return New String(temp)
End Function
答案 4 :(得分:0)
//Here Is The Working Code :
public class YWSample
{
const string cURL = "https://weather-ydn-yql.media.yahoo.com/forecastrss";
const string cAppID = "Your-App-ID";
const string cConsumerKey = "Your-Consumer-Key";
const string cConsumerSecret = "Your-Consumer-Secret";
const string cOAuthVersion = "1.0";
const string cOAuthSignMethod = "HMAC-SHA1";
const string cWeatherID = "woeid=727232"; // Amsterdam, The Netherlands
const string cUnitID = "u=c"; // Metric units
const string cFormat = "xml";
//Code to get timestamp
static string _get_timestamp()
{
var lTS = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
return Convert.ToInt64(lTS.TotalSeconds).ToString();
}
//Code to get nonce
static string _get_nonce()
{
return Convert.ToBase64String(
new ASCIIEncoding().GetBytes(
DateTime.Now.Ticks.ToString()
)
);
} // end _get_nonce
static string _get_auth()
{
var lNonce = _get_nonce();
var lTimes = _get_timestamp();
var lCKey = string.Concat(cConsumerSecret, "&");
var lSign = $"format={cFormat}&" + $"oauth_consumer_key={cConsumerKey}&" + $"oauth_nonce={lNonce}&" +
$"oauth_signature_method={cOAuthSignMethod}&" + $"oauth_timestamp={lTimes}&" +
$"oauth_version={cOAuthVersion}&" + $"{cUnitID}&{cWeatherID}";
lSign = string.Concat(
"GET&", Uri.EscapeDataString(cURL), "&", Uri.EscapeDataString(lSign)
);
using (var lHasher = new HMACSHA1(Encoding.ASCII.GetBytes(lCKey)))
{
lSign = Convert.ToBase64String(
lHasher.ComputeHash(Encoding.ASCII.GetBytes(lSign))
);
} // end using
return "OAuth " +
"oauth_consumer_key=\"" + cConsumerKey + "\", " +
"oauth_nonce=\"" + lNonce + "\", " +
"oauth_timestamp=\"" + lTimes + "\", " +
"oauth_signature_method=\"" + cOAuthSignMethod + "\", " +
"oauth_signature=\"" + lSign + "\", " +
"oauth_version=\"" + cOAuthVersion + "\"";
} // end _get_auth
public static void Main(string[] args)
{
const string lURL = cURL + "?" + cWeatherID + "&" + cUnitID + "&format=" + cFormat;
var lClt = new WebClient();
lClt.Headers.Set("Content-Type", "application/" + cFormat);
lClt.Headers.Add("Yahoo-App-Id", cAppID);
lClt.Headers.Add("Authorization", _get_auth());
Console.WriteLine("Downloading Yahoo weather report . . .");
var lDataBuffer = lClt.DownloadData(lURL);
var lOut = Encoding.ASCII.GetString(lDataBuffer);
Console.WriteLine(lOut);
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}//end of Main
} // end YWSample