WebAuthorizer comes back authorized, but throws 401 when trying to parse users object

May 5, 2014 at 11:01 PM
I'm using LinqToTwitter to authorize a user to tweet in a ASP.NET C# Web Forms app. The process appears to work until the return from Twitter. Weirdly, the WebAuthorizer object (TwitterAuth) shows as authorized, but then when I call <code>users.SingleOrDefault</code>, an exception is thrown.

Here are the contents of the <code>users</code> object at the time <code>users.SingleOrDefault()</code> is called:
[0] = {value(LinqToTwitter.TwitterQueryable`1[LinqToTwitter.User])}
[1] = {tweet => ((Convert(tweet.Type) == 2) AndAlso (tweet.UserID == value(MyApp.TwitterConnect+<>c__DisplayClass4).twitterAuth.UserId))}
Here is the exception thrown:
Message = "Error while querying Twitter."
StackTrace = "  at LinqToTwitter.TwitterQueryProvider.Execute[TResult](Expression expression)\r\n   at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source)\r\n   at MyApp.TwitterConnect.ReturnFromTwitter() in c:\\_code\\MyApp\\WebApps\\MyApp\\TwitterConnect.aspx.cs:line 115"
Here's the full InnerException of that, which I assume is more helpful:
{"The remote server returned an error: (401) Unauthorized."}
[System.Net.WebException]: {"The remote server returned an error: (401) Unauthorized."}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
HResult: -2146233079
InnerException: null
Message: "The remote server returned an error: (401) Unauthorized."
Source: "LinqToTwitter"
StackTrace: "   at LinqToTwitter.TwitterExecute.QueryTwitter[T](Request request, IRequestProcessor`1 reqProc)"
TargetSite: {System.String QueryTwitter[T](LinqToTwitter.Request, LinqToTwitter.IRequestProcessor`1[T])}
Here is the (condensed and anonymized) relevant snippet of code:
private void ReturnFromTwitter()
{
    LinqToTwitter.TwitterContext twitterCtx;

    LinqToTwitter.IOAuthCredentials credentials = new LinqToTwitter.InMemoryCredentials();
    credentials.ConsumerKey = System.Configuration.ConfigurationManager.AppSettings["twitterConsumerKey"];
    credentials.ConsumerSecret = System.Configuration.ConfigurationManager.AppSettings["twitterConsumerSecret"];

    LinqToTwitter.WebAuthorizer twitterAuth = new LinqToTwitter.WebAuthorizer
    {
        Credentials = credentials,
        PerformRedirect = authUrl => Response.Redirect(authUrl)
    };

    try
    {
        System.Threading.Thread.Sleep(3000);
        twitterAuth.CompleteAuthorization(Request.Url);
        string creds = twitterAuth.Credentials.ToString();

        if (twitterAuth.IsAuthorized)
        {
            twitterCtx = new LinqToTwitter.TwitterContext(twitterAuth);

            var users =
                from tweet in twitterCtx.User
                where tweet.Type == LinqToTwitter.UserType.Show && tweet.UserID == twitterAuth.UserId
                select tweet;

            var user = users.SingleOrDefault(); //Exception is thrown here

            TwitterUID = long.Parse(user.UserID);
            TwitterOauthToken = twitterAuth.OAuthTwitter.OAuthToken;
            TwitterAccessToken = twitterAuth.Credentials.AccessToken;
            TwitterProfileImage = user.ProfileImageUrl;
            TwitterUserName = user.Name;
        }
        else
        {
            IsConnected = false;
            Message = "Twitter is not properly connected...try again later.";
            //Log error
            return;
        }
    }
    catch (System.Exception ex)
    {
        IsConnected = false;
        Message = "Unable to connect to Twitter...try again later.";
        //Log error
        return;
    }
}
I have read this help document and confirmed that I am using the right consumer and secret keys. When I was in the portal, I didn't see any messages that our account was not in good standing. This code was working fine a couple of months ago, but then suddenly broke.

We are having a similar issue in the backend of our mobile apps (meaning the LinqToTwitter work is actually being done inside of web services). I know you recently modernized the library, but I've seen that updating necessitates significant code changes. I tried to implement these for the backend web services, but I wasn't able to (asynchronousness inside of APIs looks difficult or impossible, but that's beyond the scope here). Is the fact that we're using an outdated version (2.0.23.0) of LinqToTwitter maybe responsible? Or does this sound like a different issue we could resolve without all those code changes?
Coordinator
May 6, 2014 at 2:58 PM
Hi,

LINQ to Twitter v2.12, the last non-async version, is available as a download from this site. The FAQ, that I see you found, is currently the most accurate reference on how to resolve a 401 problem. As you can see, there could be many causes.

@JoeMayo