使用DotNetOpenAuth访问Yelp的OAuth 1.0a API

有没有人使用DotNetOpenAuth成功使用DotNetOpenAuth访问Yelp的v2 api ?

在深入了解示例和源代码之后,我就提出了这个问题:

public class YelpConnector { private static readonly string YelpConsumerKey = ConfigurationManager.AppSettings["YelpConsumerKey"]; private static readonly string YelpConsumerSecret = ConfigurationManager.AppSettings["YelpConsumerSecret"]; private static readonly string YelpToken = ConfigurationManager.AppSettings["YelpToken"]; private static readonly string YelpTokenSecret = ConfigurationManager.AppSettings["YelpTokenSecret"]; private static readonly InMemoryTokenManager tokenManager = new InMemoryTokenManager(YelpConsumerKey, YelpConsumerSecret, YelpToken, YelpTokenSecret); private static readonly Uri YelpURLBase = new Uri("http://api.yelp.com/v2/"); private static readonly ServiceProviderDescription YelpServiceDescription = new ServiceProviderDescription { RequestTokenEndpoint = null, UserAuthorizationEndpoint = null, AccessTokenEndpoint = null, TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() }, }; private static dynamic SearchBase(string queryString) { if (string.IsNullOrEmpty(queryString)) throw new ArgumentNullException(); var searchEndpoint = new MessageReceivingEndpoint(new Uri(YelpURLBase, "search?" + queryString), HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest); var consumer = new WebConsumer(YelpServiceDescription, tokenManager); try { using (IncomingWebResponse response = consumer.PrepareAuthorizedRequestAndSend(searchEndpoint, YelpToken)) { string rs = response.GetResponseReader().ReadToEnd(); dynamic js = SimpleJson.SimpleJson.DeserializeObject(rs); return js; } } catch (Exception e) { ErrorSignal.FromCurrentContext().Raise(e); return null; } } internal class InMemoryTokenManager : IConsumerTokenManager { private Dictionary tokensAndSecrets = new Dictionary(); public InMemoryTokenManager(string consumerKey, string consumerSecret, string token, string secret) { if (String.IsNullOrEmpty(consumerKey)) { throw new ArgumentNullException("consumerKey"); } this.tokensAndSecrets[token] = secret; this.ConsumerKey = consumerKey; this.ConsumerSecret = consumerSecret; } public string ConsumerKey { get; private set; } public string ConsumerSecret { get; private set; } public string GetTokenSecret(string token) { return this.tokensAndSecrets[token]; } public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response) { this.tokensAndSecrets[response.Token] = response.TokenSecret; } public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) { this.tokensAndSecrets.Remove(requestToken); this.tokensAndSecrets[accessToken] = accessTokenSecret; } public TokenType GetTokenType(string token) { throw new NotImplementedException(); } } } 

如果我传入以下QueryString limit=5&category_filter=movietheaters,bars,cafe,museums,danceclubs,parks&ll=37.78364455,-122.464104 ,我得到一个例外,说“Precondition failed:value!= null”和一个limit=5&category_filter=movietheaters,bars,cafe,museums,danceclubs,parks&ll=37.78364455,-122.464104

 at System.Diagnostics.Contracts.__ContractsRuntime.Requires[TException](Boolean condition, String message, String conditionText) at DotNetOpenAuth.Messaging.MessagingUtilities.EscapeUriDataStringRfc3986(String value) at DotNetOpenAuth.OAuth.ChannelElements.SigningBindingElementBase.ConstructSignatureBaseString(ITamperResistantOAuthMessage message, MessageDictionary messageDictionary) at DotNetOpenAuth.OAuth.ChannelElements.HmacSha1SigningBindingElement.GetSignature(ITamperResistantOAuthMessage message) at DotNetOpenAuth.OAuth.ChannelElements.SigningBindingElementBase.ProcessOutgoingMessage(IProtocolMessage message) at DotNetOpenAuth.OAuth.ChannelElements.SigningBindingElementChain.ProcessOutgoingMessage(IProtocolMessage message) at DotNetOpenAuth.Messaging.Channel.ProcessOutgoingMessage(IProtocolMessage message) at DotNetOpenAuth.OAuth.ChannelElements.OAuthChannel.InitializeRequest(IDirectedProtocolMessage request) at DotNetOpenAuth.OAuth.ConsumerBase.PrepareAuthorizedRequestAndSend(MessageReceivingEndpoint endpoint, String accessToken) at MeetPpl.Helpers.SocialConnectors.YelpConnector.SearchBase(String queryString) 

有什么建议? 我在正确的路上吗?

在放弃dotnetopenauth之前,我在这个问题上挣扎了整整一天。 我找到了一种使用http://www.twitterizer.net/的oauth库搜索yelp的简单方法。 只需下载精简版的twitterizer并使用下面的示例代码。

下载链接是http://www.twitterizer.net/files/Twitterizer2lite-2.3.2.zip

  public static string search() { string yelpSearchURL = "http://api.yelp.com/v2/search?term=food&location=San+Francisco"; string yelpConsumerKey = "your key"; string yelpConsumerSecret = "your secret"; string yelpRequestToken = "your token"; string yelpRequestTokenSecret = "your token secret"; Twitterizer.OAuthTokens ot = new Twitterizer.OAuthTokens(); ot.AccessToken = yelpRequestToken; ot.AccessTokenSecret = yelpRequestTokenSecret; ot.ConsumerKey = yelpConsumerKey; ot.ConsumerSecret = yelpConsumerSecret; string formattedUri = String.Format(CultureInfo.InvariantCulture, yelpSearchURL, ""); Uri url = new Uri(formattedUri); Twitterizer.WebRequestBuilder wb = new Twitterizer.WebRequestBuilder(url, Twitterizer.HTTPVerb.GET, ot); System.Net.HttpWebResponse wr = wb.ExecuteRequest(); StreamReader sr = new StreamReader(wr.GetResponseStream()); return sr.ReadToEnd(); } 

您可以将RestSharp api: https : //github.com/JustinBeckwith/YelpSharp与OAuthBase结合使用: http ://oauth.googlecode.com/svn/code/csharp/OAuthBase.cs。 在YelpSharp实现中,使用以下方法更改Yelp.cs类方法makeRequest

 protected string makeRequest(string area, string id, Dictionary parameters) { // build the url with parameters var url = area; if (!String.IsNullOrEmpty(id)) url += "/" + HttpUtility.UrlEncode(id); if (parameters != null) { bool firstp = true; string[] keys = parameters.Keys.ToArray(); foreach (string _key in keys) { if (firstp) url += "?"; else url += "&"; firstp = false; //Double URL encode "&" to prevent restsharp from treating the second half of the string as a new parameter parameters[_key] = parameters[_key].Replace("&", "%26"); parameters[_key] = parameters[_key].Replace("+", "%2B"); parameters[_key] = parameters[_key].Replace(" ", "%2B"); url += _key + "=" + parameters[_key]; //HttpUtility.UrlEncode(parameters[_key]); } } var client = new RestClient(rootUri); var request = new RestRequest(Method.GET); OAuthBase oAuth = new OAuthBase(); string nonce = oAuth.GenerateNonce(); string timeStamp = oAuth.GenerateTimeStamp(); string normalizedUrl; string normalizedRequestParameters; string sig = oAuth.GenerateSignature(new Uri(string.Format("{0}/{1}", client.BaseUrl, url)), options.ConsumerKey, options.ConsumerSecret, options.AccessToken, options.AccessTokenSecret, "GET", timeStamp, nonce, out normalizedUrl, out normalizedRequestParameters); sig = HttpUtility.UrlEncode(sig); request.Resource = string.Format(area); if (parameters != null) { foreach (var p in parameters) { request.AddParameter(p.Key, p.Value); } } request.AddParameter("oauth_consumer_key", options.ConsumerKey); request.AddParameter("oauth_token", options.AccessToken); request.AddParameter("oauth_nonce", nonce); request.AddParameter("oauth_timestamp", timeStamp); request.AddParameter("oauth_signature_method", "HMAC-SHA1"); request.AddParameter("oauth_version", "1.0"); request.AddParameter("oauth_signature", sig); var response = client.Execute(request); return response.Content; } 

测试如下:

 public void testYelp() { string _term = "food"; string _location = "San Francisco"; var o = Credentials.GetOptions(); var y = new Yelp(o); var searchOptions = new SearchOptions(); searchOptions.GeneralOptions = new GeneralOptions() { term = _term }; searchOptions.LocationOptions = new LocationOptions() { location = _location }; var results = y.Search(searchOptions); }