使用DotNetOpenAuth访问Yelp的OAuth 1.0a API

问题描述:

有没有人使用DotNetOpenAuth使用DotNetOpenAuth访问Yelp's v2 api使用DotNetOpenAuth访问Yelp的OAuth 1.0a 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<string, string> tokensAndSecrets = new Dictionary<string, string>(); 

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

如果我通过下面的查询字符串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) 

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

+1

我知道我很末到本方,但我写了一个这个库:https://github.com/JustinBeckwith/YelpSharp。它在NuGet上。我从Twitterizer开始,但它无法正确处理OAuth的某些高级查询字符串。 这是 – 2012-02-15 18:32:20

在放弃dotnetopenauth之前,我在这个问题上挣扎了整整1天。我发现了一种使用http://www.twitterizer.net/的oauth库搜索yelp的非常简单的方法。只需下载twitter版本的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(); 
    } 
+1

这并不包括'AccessToken'来自哪里,这在webapp和桌面应用程序上截然不同...... – 2011-08-15 06:46:15

+0

@Chirag你知道还有一个更小的Twitterizer库仅仅是OAuth ? – 2011-12-02 19:53:56

+0

@JeffAtwood您的用户需要授权您的应用程序。授权导致访问令牌。过于简化,其:1)获取访问令牌。 2)将用户重定向到授权URL。 3)该服务将用户重定向到回调URL(在您的网站)。 4)获取访问令牌。 – 2011-12-02 19:55:38

您可以使用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<string, string> 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); 
}