C# WebApiHelper

Date: 2017-09-11
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Http;
using Newtonsoft.Json;

namespace Helpers.WebApi
{
    public class WebApiResponse<T>
    {
        public WebApiResponse(string url, HttpResponseMessage response, string content, T result)
        {
            Url = url;
            Response = response;
            Content = content;
            Result = result;
        }
        public readonly string Url;
        public readonly HttpResponseMessage Response;
        public HttpStatusCode Status { get { return Response.StatusCode; } }
        public readonly string Content;
        public readonly T Result;
    }

    public static class WebApiHelper
    {
        private const string AuthorizationHeader = "Authorization";

        public class WebApiClient : IDisposable
        {
            public WebApiClient(string apiAddress, NetworkCredential credentials)
            {
                this.apiAddress = apiAddress;
                this.credentials = credentials;
            }
            private readonly string apiAddress;
            private readonly NetworkCredential credentials;
            private HttpClient httpClient;

            private void Prepare()
            {
                if (httpClient == null)
                {
                    HttpClientHandler httpClientHandler = new HttpClientHandler() { };
                    httpClient = new HttpClient(httpClientHandler);
                }
            }

            private string GetUrl(params string[] parts)
            {
                var partList = new List<string> { apiAddress.TrimEnd('/') };
                partList.AddRange(parts.Where(part => !string.IsNullOrEmpty(part)));
                return string.Join("/", partList);
            }

            public async Task<WebApiResponse<T>> Request<T>(HttpMethod method, HttpStatusCode expectStatus, string content, params string[] parts)
            {
                Prepare();
                var uri = GetUrl(parts);
                HttpRequestMessage requestMessage = new HttpRequestMessage(method, uri);

                if (credentials != null && !String.IsNullOrEmpty(credentials.UserName))
                {
                    var headerValue = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(String.Format("{0}:{1}", credentials.UserName, credentials.Password)));
                    requestMessage.Headers.Add(AuthorizationHeader, headerValue);
                }

                if (!string.IsNullOrEmpty(content))
                {
                    requestMessage.Content = new StringContent(content, Encoding.UTF8, "application/json");
                }

                DateTime startTime = DateTime.Now;
                var responseMessage = await httpClient.SendAsync(requestMessage).ConfigureAwait(continueOnCapturedContext: false);
                var responseContent = await responseMessage.Content.ReadAsStringAsync();
                var endTime = DateTime.Now;

                if (responseMessage.StatusCode == HttpStatusCode.Unauthorized)
                {
                    throw new UnauthorizedAccessException(string.Format("Unauthorized; Url: {0}", uri));
                }
                else if (responseMessage.StatusCode != expectStatus && expectStatus != HttpStatusCode.Unused)
                {
                    throw new Exception(string.Format("[{0}]\r\n[Error, status not expected: {1}]\r\n{2}", uri, responseMessage.StatusCode, responseContent));
                }

                if (typeof(T) != typeof(string))
                {
                    return new WebApiResponse<T>(uri, responseMessage, responseContent, JsonConvert.DeserializeObject<T>(responseContent));
                }
                // Return the request content as string
                return new WebApiResponse<T>(uri, responseMessage, responseContent, (T)Convert.ChangeType(responseContent, typeof(T)));
            }

            public async Task<WebApiResponse<T>> Get<T>(params string[] parts)
            {
                return await Request<T>(HttpMethod.Get, HttpStatusCode.OK, null, parts);
            }

            public async Task<WebApiResponse<T>> Get<T>(HttpStatusCode expectStatus, params string[] parts)
            {
                return await Request<T>(HttpMethod.Get, expectStatus, null, parts);
            }

            public async Task<WebApiResponse<T>> Post<T>(object content, params string[] parts)
            {
                return await Request<T>(HttpMethod.Post, HttpStatusCode.Created, JsonConvert.SerializeObject(content), parts);
            }

            public async Task<WebApiResponse<T>> Post<T>(object content, HttpStatusCode expectStatus, params string[] parts)
            {
                return await Request<T>(HttpMethod.Post, expectStatus, JsonConvert.SerializeObject(content), parts);
            }

            public async Task<WebApiResponse<T>> Put<T>(object content, params string[] parts)
            {
                return await Request<T>(HttpMethod.Put, HttpStatusCode.OK, JsonConvert.SerializeObject(content), parts);
            }

            public async Task<WebApiResponse<T>> Put<T>(object content, HttpStatusCode expectStatus, params string[] parts)
            {
                return await Request<T>(HttpMethod.Put, expectStatus, JsonConvert.SerializeObject(content), parts);
            }

            public async Task<WebApiResponse<T>> Delete<T>(params string[] parts)
            {
                return await Request<T>(HttpMethod.Delete, HttpStatusCode.OK, null, parts);
            }

            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }

            public virtual void Dispose(bool disposing)
            {
                if (disposing)
                {
                    if (httpClient != null)
                        httpClient.Dispose();
                }
            }
        }
    }
}
// Usage:
using (var client = new WebApiClient("http://server.com:3000/", new NetworkCredential("User", "Password")))
{
    var response = await client.Get<User>("api/users/12");
    if (response.Status == System.Net.HttpStatusCode.OK)
    {
        var userName = response.Result.Name;
    }
}
8710cookie-checkC# WebApiHelper