title: Accessing Yelp's OAuth 1.0a API with DotNetOpenAuth
body: <p>Has anyone had success using DotNetOpenAuth to access <a href="http://www.yelp.com/developers/documentation/v2/authentication" rel="nofollow">Yelp's v2 api</a> using DotNetOpenAuth?</p>
  
  <p>After digging through the examples and the source, this is what I came up with:</p>
  
  <pre><code>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&lt;string, string&gt; tokensAndSecrets = new Dictionary&lt;string, string&gt;();
  
          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();
          }           
      }
   }
  </code></pre>
  
  <p>If I pass in the following QueryString <code>limit=5&amp;category_filter=movietheaters,bars,cafe,museums,danceclubs,parks&amp;ll=37.78364455,-122.464104</code>, I get an exception saying "Precondition failed.: value != null" and a stacktrace of:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>Any suggestions?  Am I on the right trail?</p>