Friday, 25 April 2014

Accessing ASP.Net MVC Web APIs from Windows Application

Here I am sharing a piece of code that can be used to consume Web API from a windows application such as a WPF application. The class here is a generic class that can be used with actually any application consuming Web API services. In order to use these methods along with the reference library, we need to add the library Microsoft.AspNet.WebApi.Client.5.1.2. Below is the class:
Required namespaces :
 
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
 
---------------------------------------------------------------------------------------------------------------------  
public class ApiClient<Stype, Rtype> where Stype : class where Rtype : class
{
        private Uri apiUrl;
        HttpClient httpClient = new HttpClient();
        public ApiClient(Uri apiUrl)
        {
            this.apiUrl = apiUrl;
            Initialize();
        }
        public void Initialize()
        {
            httpClient.BaseAddress = apiUrl;
            httpClient.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));
        }
        public async Task<WebApiResult<Rtype>> GetRequest(string apiMethod)
        {
            Rtype resultObject = null;
            HttpResponseMessage response;
            WebApiResult<Rtype> result = new WebApiResult<Rtype>();
            result.ErrorMessages = new List<string>();
            try
            {
                response = await httpClient.GetAsync(apiMethod).ConfigureAwait(false);
                response.EnsureSuccessStatusCode();
                if (response.IsSuccessStatusCode)
                {
                    await response.Content.ReadAsAsync<Rtype>().ContinueWith(x =>
                    {
                        if (!x.IsFaulted)
                        {
                            resultObject = x.Result;
                            result.Data = resultObject;
                        }
                        else
                        {
                            result.ErrorMessages.Add(x.Exception.InnerException.Message);
                            result.HasError = true;
                        }
                    });
                }
                else
                {
                    result.ErrorMessages.Add(string.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase));
                    result.HasError = true;
                }
            }
            catch (Newtonsoft.Json.JsonException jsonEx)
            {
                result.ErrorMessages.Add(jsonEx.Message);
                result.HasError = true;
            }
            catch (HttpRequestException httpEx)
            {
                result.ErrorMessages.Add(httpEx.Message);
                result.HasError = true;
            }
            catch (Exception ex)
            {
                result.ErrorMessages.Add(ex.Message);
                result.HasError = true;
            }
            return result;
        }
        public async Task<WebApiResult<Rtype>> PostRequest(string apiPostMethod, Stype postObject)
        {
            Rtype resultObject = null;
            HttpResponseMessage response;
            WebApiResult<Rtype> result = new WebApiResult<Rtype>();
            result.ErrorMessages = new List<string>();
            try
            {
                response = await httpClient.PostAsJsonAsync(apiPostMethod, postObject).ConfigureAwait(false);
                if (!response.IsSuccessStatusCode)
                {
                    result.ErrorMessages.Add(string.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase));
                    result.HasError = true;
                }
                await response.Content.ReadAsAsync<Rtype>().ContinueWith(x =>
                {
                    if (!x.IsFaulted)
                    {
                        resultObject = x.Result;
                        result.Data = resultObject;
                    }
                    else
                    {
                        result.ErrorMessages.Add(x.Exception.InnerException.Message);
                        result.HasError = true;
                    }
                });
            }
            catch (Exception ex)
            {
                result.ErrorMessages.Add(ex.Message);
                result.HasError = true;
            }
            return result;
        }
        public async Task<WebApiResult<Rtype>> UpdateRequest(string apiUpdateMethod, Stype putObject)
        {
            Rtype resultObject = null;
            HttpResponseMessage response;
            WebApiResult<Rtype> result = new WebApiResult<Rtype>();
            result.ErrorMessages = new List<string>();
            try
            {
                response = await httpClient.PutAsJsonAsync(apiUpdateMethod, putObject).ConfigureAwait(false);
                response.EnsureSuccessStatusCode();
                if (response.IsSuccessStatusCode)
                {
                    await response.Content.ReadAsAsync<Rtype>().ContinueWith(x =>
                    {
                        if (!x.IsFaulted)
                        {
                            resultObject = x.Result;
                            result.Data = resultObject;
                        }
                        else
                        {
                            result.ErrorMessages.Add(x.Exception.InnerException.Message);
                            result.HasError = true;
                        }
                    });
                }
                else
                {
                    result.ErrorMessages.Add(string.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase));
                    result.HasError = true;
                }
            }
            catch (Newtonsoft.Json.JsonException jsonEx)
            {
                result.ErrorMessages.Add(jsonEx.Message);
                result.HasError = true;
            }
            catch (HttpRequestException httpEx)
            {
                result.ErrorMessages.Add(httpEx.Message);
                result.HasError = true;
            }
            catch (Exception ex)
            {
                result.ErrorMessages.Add(ex.Message);
                result.HasError = true;
            }
            return result;
        }
        public async Task<WebApiResult<Rtype>> DeleteRequest(string apiDeleteMethod)
        {
            Rtype resultObject = null;
            HttpResponseMessage response;
            WebApiResult<Rtype> result = new WebApiResult<Rtype>();
            result.ErrorMessages = new List<string>();
            try
            {
                response = await httpClient.DeleteAsync(apiDeleteMethod).ConfigureAwait(false);
                response.EnsureSuccessStatusCode();
                if (response.IsSuccessStatusCode)
                {
                    await response.Content.ReadAsAsync<Rtype>().ContinueWith(x =>
                    {
                        if (!x.IsFaulted)
                        {
                            resultObject = x.Result;
                            result.Data = resultObject;
                        }
                        else
                        {
                            result.ErrorMessages.Add(x.Exception.InnerException.Message);
                            result.HasError = true;
                        }
                    });
                }
                else
                {
                    result.ErrorMessages.Add(string.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase));
                    result.HasError = true;
                }
            }
            catch (Newtonsoft.Json.JsonException jsonEx)
            {
                result.ErrorMessages.Add(jsonEx.Message);
                result.HasError = true;
            }
            catch (HttpRequestException httpEx)
            {
                result.ErrorMessages.Add(httpEx.Message);
                result.HasError = true;
            }
            catch (Exception ex)
            {
                result.ErrorMessages.Add(ex.Message);
                result.HasError = true;
            }
            return result;
        }
    }
 ---------------------------------------------------------------------------------------------------------------------  
In the above class the SType is the type of object we are posting and RType is the type of the object we are expecting in the response. Below is the  result class that will help us handling error on the api call.
---------------------------------------------------------------------------------------------------------------------  
public class WebApiResult<T> where T : class
{
        #region fileds
        private bool hasError;
        private T data;
        private List<string> errorMessages;
        #endregion

        #region Memebers
        public T Data
        {
            get{return data;}
            set{data = value;}
        }
        public List<string> ErrorMessages
        {
            get{ return errorMessages;}
            set{errorMessages = value;}
        }
        public bool HasError
        {
            get{return hasError;}
            set{hasError = value;}
        }
        #endregion
    }

---------------------------------------------------------------------------------------------------------------------  
 The code sample is available under github here
 

No comments:

Post a Comment