• behance
  • gitHub
  • google
  • linkedin
  • twitter
Wrapping HttpClient

Wrapping HttpClient

I’ve been recently revisiting a WebAPI client implementation that uses DotNetOpenAuth for authorising calls to an OAuth 2.0 protected WebAPI.  So I thought I’d share the generic methods I wrote to perform the actual calls.

The call to CreateAuthorizingHandler(AuthorizationState) is the part of the implementation that appends the required access tokens using some of the internals of DotNetOpenAuth so your own implementation of this bit will be different as will the exception that gets thrown (you may not even want to throw anything at all.  Anyway, here’s the methods:

Post Json

        /// <summary>
        /// Posts the json asynchronous.
        /// </summary>
        /// <typeparam name="TReturn">The type of the return.</typeparam>
        /// <typeparam name="TData">The type of the data.</typeparam>
        /// <param name="url">The URL.</param>
        /// <param name="payload">The payload <see><cref>{TData}</cref></see></param>
        /// <returns>an instance of <see><cref>{TReturn}</cref></see>
        /// </returns>
        /// <exception cref="MoodApiClientException">thrown if object fails validation or the request fails</exception>
        private async Task<TReturn> ExecutePostJsonAsync<TReturn, TData>(string url, TData payload) where TData : class
        {
            ICollection<ValidationResult> validationResults;
            if (!payload.IsValid(out validationResults))
            {
                var validationErrorMessage = ObjectValidationExtensions.BuildValidationErrorMessage(validationResults);
                var typeName = payload.GetType().ToString();
                throw new MyClientException(HttpStatusCode.BadRequest, string.Format("payload type: {0} Failed validation: {1}", typeName, validationErrorMessage));
            }

            using (var httpClient = new HttpClient(CreateAuthorizingHandler(AuthorizationState)))
            {
                var response = await httpClient.PostAsJsonAsync(ApiRootUrl.WellFormedUri(url), payload);

                if (response.IsSuccessStatusCode)
                {
                    var data = await response.Content.ReadAsAsync<TReturn>();
                    return data;
                }

                throw new MyClientException(response.StatusCode, response.ReasonPhrase);
            }
        }

Post Async

        /// <summary>
        /// Executes the post asynchronous.
        /// </summary>
        /// <typeparam name="TReturn">The type of the return.</typeparam>
        /// <param name="url">The URL.</param>
        /// <returns>an instance of type TReturn</returns>
        /// <exception cref="MoodApiClientException">thrown if not successful</exception>
        private async Task<TReturn> ExecutePostAsync<TReturn>(string url)
        {
            using (var httpClient = new HttpClient(CreateAuthorizingHandler(AuthorizationState)))
            {
                using (var response = await httpClient.PostAsync(ApiRootUrl.WellFormedUri(url), null))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        return await response.Content.ReadAsAsync<TReturn>();
                    }

                    throw new MyClientException(response.StatusCode, response.ReasonPhrase);
                }
            }
        }

Get Async

        /// <summary>
        /// Executes the get asynchronously.
        /// </summary>
        /// <typeparam name="T">The Type to attempt to deserialise from the response</typeparam>
        /// <param name="url">The URL.</param>
        /// <returns>an instance of type T</returns>
        /// <exception cref="MoodApiClientException">throw if not successful</exception>
        private async Task<T> ExecuteGetAsync<T>(string url)
        {
            using (var httpClient = new HttpClient(CreateAuthorizingHandler(AuthorizationState)))
            {
                using (var response = await httpClient.GetAsync(ApiRootUrl.WellFormedUri(url)))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        return await response.Content.ReadAsAsync<T>();
                    }

                    throw new MyClientException(response.StatusCode, response.ReasonPhrase);
                }
            }
        }

Delete Async

        /// <summary>
        /// Executes the delete asynchronous.
        /// </summary>
        /// <typeparam name="T">The expected type to deserialise from the response</typeparam>
        /// <param name="url">The URL.</param>
        /// <returns>an instance of type T</returns>
        /// <exception cref="MoodApiClientException">thrown if not successful</exception>
        private async Task<T> ExecuteDeleteAsync<T>(string url)
        {
            using (var httpClient = new HttpClient(CreateAuthorizingHandler(AuthorizationState)))
            {
                using (var response = await httpClient.DeleteAsync(ApiRootUrl.WellFormedUri(url)))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        return await response.Content.ReadAsAsync<T>();
                    }

                    throw new MyClientException(response.StatusCode, response.ReasonPhrase);
                }
            }
        }

Leave a reply

*