使用DotNetOpenAuth访问Yelp的OAuth 1.0a API

本文关键字:0a API OAuth DotNetOpenAuth 访问 Yelp 使用 | 更新日期: 2023-09-27 17:57:00

有没有人成功地使用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<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();
        }           
    }
 }

如果我传入以下 QueryString limit=5&category_filter=movietheaters,bars,cafe,museums,danceclubs,parks&ll=37.78364455,-122.464104,我会收到一个异常,说"前提条件失败.: 值 != null"和堆栈跟踪:

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访问Yelp的OAuth 1.0a API

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

下载链接已 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类方法使请求具有以下功能:

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