예제 #1
0
        /// <summary>
        /// Asynchronously invokes a method on the Tumblr API without expecting a response.
        /// </summary>
        /// <param name="method">
        /// The <see cref="ApiMethod"/> to invoke.
        /// </param>
        /// <param name="cancellationToken">
        /// A <see cref="CancellationToken"/> that can be used to cancel the operation.
        /// </param>
        /// <returns>
        ///  A <see cref="Task"/> that can be used to track the operation. If the task fails, <see cref="Task.Exception"/>
        ///  will carry a <see cref="TumblrException"/> representing the error occurred during the call.
        /// </returns>
        /// <exception cref="ObjectDisposedException">
        /// The object has been disposed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="method"/> is <b>null</b>.
        /// </exception>
        public Task CallApiMethodNoResultAsync(ApiMethod method, CancellationToken cancellationToken)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("TumblrClient");
            }

            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            return(CallApiMethodAsync <object>(method, cancellationToken));
        }
예제 #2
0
        /// <summary>
        /// Asynchronously invokes a method on the Tumblr API, and performs a projection on the
        /// response before returning the result.
        /// </summary>
        /// <typeparam name="TResponse">
        /// The type of the response received from the API. This must be a type that can be deserialized
        /// from the response JSON.
        /// </typeparam>
        /// <typeparam name="TResult">
        /// The actual type that is the result of the method.
        /// </typeparam>
        /// <param name="method">
        /// The <see cref="ApiMethod"/> to invoke.
        /// </param>
        /// <param name="projection">
        /// The projection function that transforms <typeparamref name="TResponse"/> into <typeparamref name="TResult"/>.
        /// </param>
        /// <param name="cancellationToken">
        /// A <see cref="CancellationToken"/> that can be used to cancel the operation.
        /// </param>
        /// <param name="converters">
        /// An optional list of JSON converters that will be used while deserializing the response from the Tumblr API.
        /// </param>
        /// <returns>
        /// A <see cref="Task{T}"/> that can be used to track the operation. If the task succeeds, the <see cref="Task{T}.Result"/> will
        /// carry a <typeparamref name="TResult"/> instance. Otherwise <see cref="Task.Exception"/> will carry a <see cref="TumblrException"/>
        /// representing the error occurred during the call.
        /// </returns>
        /// <exception cref="ObjectDisposedException">
        /// The object has been disposed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <list type="bullet">
        /// <item>
        ///		<description>
        ///			<paramref name="method"/> is <b>null</b>.
        ///		</description>
        ///	</item>
        ///	<item>
        ///		<description>
        ///			<paramref name="projection"/> is <b>null</b>.
        ///		</description>
        ///	</item>
        /// </list>
        /// </exception>
        public async Task <TResult> CallApiMethodAsync <TResponse, TResult>(ApiMethod method, Func <TResponse, TResult> projection, CancellationToken cancellationToken, IEnumerable <JsonConverter> converters = null)
            where TResult : class
            where TResponse : class
        {
            if (disposed)
            {
                throw new ObjectDisposedException("TumblrClient");
            }

            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            if (projection == null)
            {
                throw new ArgumentNullException("projection");
            }

            var response = await CallApiMethodAsync <TResponse>(method, cancellationToken, converters).ConfigureAwait(false);

            return(projection(response));
        }
예제 #3
0
        /// <summary>
        /// Asynchronously invokes a method on the Tumblr API.
        /// </summary>
        /// <typeparam name="TResult">
        /// The type of the response received from the API. This must be a type that can be deserialized
        /// from the response JSON.
        /// </typeparam>
        /// <param name="method">
        /// The <see cref="ApiMethod"/> to invoke.
        /// </param>
        /// <param name="cancellationToken">
        /// A <see cref="CancellationToken"/> that can be used to cancel the operation.
        /// </param>
        /// <param name="converters">
        /// An optional list of JSON converters that will be used while deserializing the response from the Tumblr API.
        /// </param>
        /// <returns>
        /// A <see cref="Task{T}"/> that can be used to track the operation. If the task succeeds, the <see cref="Task{T}.Result"/> will
        /// carry a <typeparamref name="TResult"/> instance. Otherwise <see cref="Task.Exception"/> will carry a <see cref="TumblrException"/>
        /// representing the error occurred during the call.
        /// </returns>
        /// <exception cref="ObjectDisposedException">
        /// The object has been disposed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="method"/> is <b>null</b>.
        /// </exception>
        public async Task <TResult> CallApiMethodAsync <TResult>(ApiMethod method, CancellationToken cancellationToken, IEnumerable <JsonConverter> converters = null)
            where TResult : class
        {
            if (disposed)
            {
                throw new ObjectDisposedException("TumblrClient");
            }

            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            //build the api call URL
            StringBuilder apiRequestUrl = new StringBuilder(method.Url);

            if (method.HttpMethod == HttpMethod.Get && method.Parameters.Count > 0)
            {
                //we are in a HTTP GET: add the request parameters to the query string
                apiRequestUrl.Append("?");
                apiRequestUrl.Append(method.Parameters.ToFormUrlEncoded());
            }

            using (var request = new HttpRequestMessage(method.HttpMethod, apiRequestUrl.ToString()))
            {
                if (method.OAuthToken != null)
                {
                    method.Parameters.Add("oauth_token", method.OAuthToken.Key);
                }

                if (method.Parameters.Any(c => c is BinaryMethodParameter))
                {
                    //if there is binary content we submit a multipart form request
                    var content = new MultipartFormDataContent();
                    foreach (var p in method.Parameters)
                    {
                        content.Add(p.AsHttpContent());
                    }

                    request.Content = content;
                }
                else
                {
                    //otherwise just a form url encoded request
                    var content = new FormUrlEncodedContent(method.Parameters.Select(c => new KeyValuePair <string, string>(c.Name, ((StringMethodParameter)c).Value)));
                    request.Content = content;
                }

                using (var response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false))
                {
                    var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

                    using (var reader = new JsonTextReader(new StreamReader(stream)))
                    {
                        var serializer = CreateSerializer(converters);
                        if (response.IsSuccessStatusCode)
                        {
                            return(serializer.Deserialize <TumblrRawResponse <TResult> >(reader).Response);
                        }
                        else
                        {
                            var errorResponse =
                                (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                                                                        ? new TumblrErrors()
                            {
                                Errors = new String[0]
                            }
                                                                        : serializer.Deserialize <TumblrErrorResponse>(reader).Response;

                            throw new TumblrException(response.StatusCode, response.ReasonPhrase, errorResponse.Errors);
                        }
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Asynchronously invokes a method on the Tumblr API.
        /// </summary>
        /// <typeparam name="TResult">
        /// The type of the response received from the API. This must be a type that can be deserialized
        /// from the response JSON.
        /// </typeparam>
        /// <param name="method">
        /// The <see cref="ApiMethod"/> to invoke.
        /// </param>
        /// <param name="cancellationToken">
        /// A <see cref="CancellationToken"/> that can be used to cancel the operation.
        /// </param>
        /// <param name="converters">
        /// An optional list of JSON converters that will be used while deserializing the response from the Tumblr API.
        /// </param>
        /// <returns>
        /// A <see cref="Task{TResult}"/> that can be used to track the operation. If the task succeeds, the <see cref="Task{TResult}.Result"/> will
        /// carry a <typeparamref name="TResult"/> instance. Otherwise <see cref="Task.Exception"/> will carry a <see cref="TumblrException"/>
        /// representing the error occurred during the call.
        /// </returns>
        /// <exception cref="ObjectDisposedException">
        /// The object has been disposed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="method"/> is <b>null</b>.
        /// </exception>
        public async Task <TResult> CallApiMethodAsync <TResult>(ApiMethod method, CancellationToken cancellationToken, IEnumerable <JsonConverter> converters = null)
            where TResult : class
        {
            if (disposed)
            {
                throw new ObjectDisposedException("TumblrClient");
            }

            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            //build the api call URL
            StringBuilder apiRequestUrl = new StringBuilder(method.Url);

            if (method.HttpMethod == HttpMethod.Get && method.Parameters.Count > 0)
            {
                //we are in a HTTP GET: add the request parameters to the query string
                apiRequestUrl.Append("?");
                apiRequestUrl.Append(method.Parameters.ToFormUrlEncoded());
            }

            using (var request = new HttpRequestMessage(method.HttpMethod, apiRequestUrl.ToString()))
            {
                if (method.OAuthToken != null)
                {
                    method.Parameters.Add("oauth_token", method.OAuthToken.Key);
                }

                if (method.Parameters.Any(c => c is BinaryMethodParameter))
                {
                    //if there is binary content we submit a multipart form request
                    var content = new MultipartFormDataContent();
                    foreach (var p in method.Parameters)
                    {
                        content.Add(p.AsHttpContent());
                    }

                    request.Content = content;
                }
                else
                {
                    //otherwise just a form url encoded request
                    var content = new FormUrlEncodedContent(method.Parameters.Select(c => new KeyValuePair <string, string>(c.Name, ((StringMethodParameter)c).Value)));
                    request.Content = content;
                }

                await request.PreparationForTumblrClient(_hashProvider, _consumerKey, _consumerSecret, oAuthToken);

                using (var response = await httpClient.SendAsync(request, cancellationToken).ConfigureAwait(false))
                {
                    var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

                    using (var reader = new JsonTextReader(new StreamReader(stream)))
                    {
                        var serializer = CreateSerializer(converters);
                        if (response.IsSuccessStatusCode)
                        {
                            return(serializer.Deserialize <TumblrRawResponse <TResult> >(reader).Response);
                        }
                        else
                        {
                            TumblrError[] errorResponse;

#if (NETSTANDARD1_3 || NETSTANDARD2_0 || NETCOREAPP2_2)
                            errorResponse = Array.Empty <TumblrError>();
#else
                            errorResponse = new TumblrError[0];
#endif

                            switch (response.StatusCode)
                            {
                            case System.Net.HttpStatusCode.Unauthorized:
                            {
                                break;
                            }

                            default:
                            {
                                if (response.Content.Headers.ContentType.MediaType == "application/json")
                                {
                                    errorResponse = serializer.Deserialize <TumblrErrorResponse>(reader).Errors;
                                }
                                break;
                            }
                            }

                            throw new TumblrException(response.StatusCode, response.ReasonPhrase, errorResponse.ToList());
                        }
                    }
                }
            }
        }