Ejemplo n.º 1
0
        /// <summary>
        /// Executes the command.
        /// </summary>
        /// <returns>The results of the command.</returns>
        public TwitterResponse <T> ExecuteCommand()
        {
            TwitterResponse <T> twitterResponse = new TwitterResponse <T>();

            if (this.OptionalProperties.UseSSL)
            {
                this.Uri = new Uri(this.Uri.AbsoluteUri.Replace("http://", "https://"));
            }

            // Loop through all of the custom attributes assigned to the command class
            foreach (Attribute attribute in this.GetType().GetCustomAttributes(false))
            {
                if (attribute is AuthorizedCommandAttribute)
                {
                    if (this.Tokens == null)
                    {
                        throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Tokens are required for the \"{0}\" command.", this.GetType()));
                    }

                    if (string.IsNullOrEmpty(this.Tokens.ConsumerKey) ||
                        string.IsNullOrEmpty(this.Tokens.ConsumerSecret) ||
                        string.IsNullOrEmpty(this.Tokens.AccessToken) ||
                        string.IsNullOrEmpty(this.Tokens.AccessTokenSecret))
                    {
                        throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Token values cannot be null when executing the \"{0}\" command.", this.GetType()));
                    }
                }
                else if (attribute is RateLimitedAttribute)
                {
                    // Get the rate limiting status
                    if (TwitterRateLimitStatus.GetStatus(this.Tokens).ResponseObject.RemainingHits == 0)
                    {
                        throw new TwitterizerException("You are being rate limited.");
                    }
                }
            }

            // Prepare the query parameters
            Dictionary <string, object> queryParameters = new Dictionary <string, object>();

            foreach (KeyValuePair <string, object> item in this.RequestParameters)
            {
                queryParameters.Add(item.Key, item.Value);
            }

            // Declare the variable to be returned
            twitterResponse.ResponseObject = default(T);
            twitterResponse.RequestUrl     = this.Uri.AbsoluteUri;
            RateLimiting rateLimiting;
            AccessLevel  accessLevel;

            byte[] responseData;

            try
            {
                WebRequestBuilder requestBuilder = new WebRequestBuilder(this.Uri, this.Verb, this.Tokens)
                {
                    Multipart = this.Multipart
                };

#if !SILVERLIGHT
                if (this.OptionalProperties != null)
                {
                    requestBuilder.Proxy = this.OptionalProperties.Proxy;
                }
#endif

                foreach (var item in queryParameters)
                {
                    requestBuilder.Parameters.Add(item.Key, item.Value);
                }

                HttpWebResponse response = requestBuilder.ExecuteRequest();

                if (response == null)
                {
                    twitterResponse.Result = RequestResult.Unknown;
                    return(twitterResponse);
                }

                responseData            = ConversionUtility.ReadStream(response.GetResponseStream());
                twitterResponse.Content = Encoding.UTF8.GetString(responseData, 0, responseData.Length);

                twitterResponse.RequestUrl = requestBuilder.RequestUri.AbsoluteUri;

#if !SILVERLIGHT
                // Parse the rate limiting HTTP Headers
                rateLimiting = ParseRateLimitHeaders(response.Headers);

                // Parse Access Level
                accessLevel = ParseAccessLevel(response.Headers);
#else
                rateLimiting = null;
                accessLevel  = AccessLevel.Unknown;
#endif

                // Lookup the status code and set the status accordingly
                SetStatusCode(twitterResponse, response.StatusCode, rateLimiting);

                twitterResponse.RateLimiting = rateLimiting;
                twitterResponse.AccessLevel  = accessLevel;
            }
            catch (WebException wex)
            {
                if (new[]
                {
#if !SILVERLIGHT
                    WebExceptionStatus.Timeout,
                    WebExceptionStatus.ConnectionClosed,
#endif
                    WebExceptionStatus.ConnectFailure
                }.Contains(wex.Status))
                {
                    twitterResponse.Result       = RequestResult.ConnectionFailure;
                    twitterResponse.ErrorMessage = wex.Message;
                    return(twitterResponse);
                }

                // The exception response should always be an HttpWebResponse, but we check for good measure.
                HttpWebResponse exceptionResponse = wex.Response as HttpWebResponse;

                if (exceptionResponse == null)
                {
                    throw;
                }

                responseData            = ConversionUtility.ReadStream(exceptionResponse.GetResponseStream());
                twitterResponse.Content = Encoding.UTF8.GetString(responseData, 0, responseData.Length);

#if !SILVERLIGHT
                rateLimiting = ParseRateLimitHeaders(exceptionResponse.Headers);

                // Parse Access Level
                accessLevel = ParseAccessLevel(exceptionResponse.Headers);
#else
                rateLimiting = null;
                accessLevel  = AccessLevel.Unknown;
#endif

                // Try to read the error message, if there is one.
                try
                {
                    TwitterErrorDetails errorDetails = SerializationHelper <TwitterErrorDetails> .Deserialize(responseData);

                    twitterResponse.ErrorMessage = errorDetails.ErrorMessage;
                }
                catch (Exception)
                {
                    // Occasionally, Twitter responds with XML error data even though we asked for json.
                    // This is that scenario. We will deal with it by doing nothing. It's up to the developer to deal with it.
                }

                // Lookup the status code and set the status accordingly
                SetStatusCode(twitterResponse, exceptionResponse.StatusCode, rateLimiting);

                twitterResponse.RateLimiting = rateLimiting;
                twitterResponse.AccessLevel  = accessLevel;

                if (wex.Status == WebExceptionStatus.UnknownError)
                {
                    throw;
                }

                return(twitterResponse);
            }

            try
            {
                twitterResponse.ResponseObject = SerializationHelper <T> .Deserialize(responseData, this.DeserializationHandler);
            }
            catch (Newtonsoft.Json.JsonReaderException)
            {
                twitterResponse.ErrorMessage = "Unable to parse JSON";
                twitterResponse.Result       = RequestResult.Unknown;
                return(twitterResponse);
            }
            catch (Newtonsoft.Json.JsonSerializationException)
            {
                twitterResponse.ErrorMessage = "Unable to parse JSON";
                twitterResponse.Result       = RequestResult.Unknown;
                return(twitterResponse);
            }

            // Pass the current oauth tokens into the new object, so method calls from there will keep the authentication.
            twitterResponse.Tokens = this.Tokens;

            return(twitterResponse);
        }