Link2Twitter oAuth MVC documentation out of date - invalid Auth tokens?

Dec 12, 2013 at 6:22 AM
I've been attempting to follow the code sample found here, and I've run into some issues:

https://linqtotwitter.codeplex.com/wikipage?title=Implementing%20OAuth%20for%20ASP.NET%20MVC&referringTitle=Learning%20to%20use%20OAuth

It seems as though this documentation is out of date, as I've downloaded the latest version of Linq to Twitter (dated 2013-11-26), and some of the class names and return types in the LinqToTwitter DLL seem to have changed. The sample will not run as-is, and my attempts to make it work with the latest version so far have failed.

What I'm trying to produce is a simple test app to log into twitter, and post an image on behalf of a user. My code consists of three parts:
  • Login() : Sends my consumer key and secret to twitter, with LoginCallback passed in as the callback.
  • LoginCallback() : Gets a the auth key and "verifier" (I'm assuming this is the auth secret?) response from twitter, creates a new MVCAuthorizer object using these details, and passes it to PostImage.
  • PostImage() : Uses the authentication details from LoginCallback to post an image to twitter.
All three pieces seem to work fine in isolation; I've been able to redirect to twitter's authentication page using Login(), I've been able to get an auth token back from twitter using LoginCallback(), and I've been able to post an image to twitter using PostImage(), but only if I use the auth tokens provided on my app's dev page. If try to put all three together and use the tokens I get back from twitter to post an image, I get the error "Invalid or expired token".

What I've noticed is that the (working) key from my app page consists of my UserID, a hyphen, and then 39 alphanumeric characters, but the token and secret I'm getting back from LoginCallback() in the query string are 41 and 42 characters long respectively. This doesn't seem right. I'm also confused as to why instead of an "oAuth_token" and "AccessToken" I'm getting an "oAuth_token" and an "oAuth_Verifier".

For reference, here is my code (consumer key and secret omitted):

Login():
public ActionResult Login()
        {
          var auth = new MvcAuthorizer
          {
            Credentials = new SessionStateCredentials
            {
              ConsumerKey = "*********",
              ConsumerSecret = "*********"
            },
            AuthAccessType = AuthAccessType.Write
          };

          string twitterCallbackUrl = Request.Url.ToString() + "Callback";

          return auth.BeginAuthorization(new Uri(twitterCallbackUrl));

        }
LoginCallback():
public ActionResult LoginCallback()
        {
          string oAuthToken = Request.Params["oauth_token"].ToString();
          string oAuthVerifier = Request.Params["oauth_verifier"].ToString();

          var auth = new MvcAuthorizer
          {
            Credentials = new SessionStateCredentials
            {
              ConsumerKey = "*********",
              ConsumerSecret = "*********",
              OAuthToken = oAuthToken,
              AccessToken = oAuthVerifier 
            }
          };

          bool authorized = auth.CompleteAuthorization(new Uri("http://localhost:58342/Home/FinishedCallback"));

          if(authorized)
            PostImage(auth);

          //Now post the image
          PostImage(auth);

          return View();
        }
PostImage():
private void PostImage(MvcAuthorizer auth)
        {

          TwitterContext twitterCtx = new TwitterContext(auth);

          string statusMessage = "Status message!";

          List<Media> mediaItems = new List<Media>
          {
              new Media
              {
                Data = Utilities.GetFileBytes("C:\\Users\\Public\\Pictures\\image01.jpg"),
                FileName = "File name",
                ContentType = MediaContentType.Jpeg
              }
          };

          Status tweet = twitterCtx.TweetWithMedia(statusMessage,false,StatusExtensions.NoCoordinate,StatusExtensions.NoCoordinate,null,false,mediaItems,null);

        }
When I run all three functions together in sequence, its the last line of PostImage() that throws the "Invalid or expired token" error message.

My questions are as follows:
  1. Is there a more up-to-date code sample I can look at, or is it the code I'm using that's out-of-date?
  2. Why is twitter sending me back auth tokens in a different (wrong?) format from the ones on the app page?
Coordinator
Dec 12, 2013 at 5:20 PM
That documentation is updated for the newest version of LINQ to Twitter v3.0 Beta. There are demos in the downloadable source code. The L2T 2.1 demo is in LinqToTwitterMvcDemo.
Dec 12, 2013 at 10:55 PM
Hi Joe,

Thank you for your response, my mistake. I was able to get my code to work using the 2.1 sample provided. If anyone else is curious, I was calling auth.CompleteAuthorization with my login callback's Uri rather than the Uri passed back by twitter. So while my problem is now resolved, the first thing I tried was the beta version, and I wasn't able to get that working at all. The reason is that doesn't seem to be a class named MvcAuthorizer in the latest LinkToTwitterPcl.dll.

Thanks for your help!
Coordinator
Dec 13, 2013 at 3:58 AM
The MvcAuthorizer is in the LinqToTwitter.AspNet.dll assembly. I had to separate the ASP.NET and Windows Store authorizers from the core LinqToTwitterPcl.dll assembly to support PCL.