Calling WebAPI service from Windows Phone 8 using HttpClient – Addendum

I’ve noticed that allot of people have visited here to view the entry on Calling WebAPI service from Windows Phone 8 using HttpClient. Since writing it I’ve significantly extended the BaseService class that I wrote for it and thought I should share it online.

So here is a further example of an implementation showing how to call a WebAPI service from Windows Phone (or really any other location).

public abstract class BaseService
{
    private readonly string _BaseAddress;

    //Provide the address however you want
    public BaseService()
        : this("http://192.168.1.4:69/")
    {
            
    }

    public BaseService(string BaseAddress)
    {
        this._BaseAddress = BaseAddress;
    }

    /// <summary>
    /// Create an instance of the HttpClient class and return it.
    /// </summary>
    /// <param name="BaseAddress">The base address of a location to call i.e. http://192.168.1.1:69/ (The service path is provided later)</param>
    /// <returns>System.Net.Http.HttpClient with base address and timeout set</returns>
    private static HttpClient GetHttpClient(string BaseAddress)
    {
        HttpClient client = new HttpClient();
        client.BaseAddress = new Uri(BaseAddress);
        client.Timeout = new TimeSpan(10000000 * 20); //seconds
        return client;
    }

    /// <summary>
    /// Invoke get request with path and parameter and return result.
    /// </summary>
    /// <typeparam name="T">Type to be returned</typeparam>
    /// <param name="Path">Service Path i.e. /Services/Service</param>
    /// <param name="Parameter">Any object that implements ToString() correctly</param>
    /// <returns>Task Of T</returns>
    protected async Task<T> GetServiceAsync<T>(string Path, object Parameter)
    {
        return await BaseService.GetServiceAsync<T>(this._BaseAddress, Path, Parameter);
    }

    /// <summary>
    /// Invoke get request with path and parameter array and return result.
    /// </summary>
    /// <typeparam name="T">Type to be returned</typeparam>
    /// <param name="Path">Service Path i.e. /Services/Service</param>
    /// <param name="ParamArray">Any parameter array that implements ToString() correctly</param>
    /// <returns>Task Of T</returns>
    protected async Task<T> GetServiceAsync<T>(string Path, params object[] ParamArray)
    {
        return await BaseService.GetServiceAsync<T>(this._BaseAddress, Path, ParamArray);
    }

    /// <summary>
    /// Invoke get request with path and parameter array and return result.
    /// </summary>
    /// <typeparam name="T">Type to be returned</typeparam>
    /// <param name="BaseAddress">Base address path to be called</param>
    /// <param name="Path">Service Path i.e. /Services/Service</param>
    /// <param name="ParamArray">Any parameter array that implements ToString() correctly</param>
    /// <returns>Task Of T</returns>
    protected async static Task<T> GetServiceAsync<T>(string BaseAddress, string Path, params object[] ParamArray)
    {
        using (HttpClient client = BaseService.GetHttpClient(BaseAddress))
        {
            string actionUrl = string.Format("{0}{1}", Path, MvcUtilities.BuildWebApiRequest(ParamArray));
            HttpResponseMessage response = await client.GetAsync(actionUrl);
            response.EnsureSuccessStatusCode();
            T result = await response.Content.ReadAsAsync<T>();
            return result;
        }
    }
        
    /// <summary>
    /// Invoke put request with path and parameter and return result.
    /// </summary>
    /// <typeparam name="T">Type to be returned</typeparam>
    /// <param name="Path">Service Path i.e. /Services/Service</param>
    /// <param name="Obj">Any object that implements ToString() correctly</param>
    /// <returns>Task Of T</returns>
    protected async Task<T> PutServiceAsync<T>(string Path, object Obj)
    {
        return await BaseService.PutServiceAsync<T>(this._BaseAddress, Path, Obj);
    }

    /// <summary>
    /// Invoke put request with basepath, path and parameter and return result.
    /// </summary>
    /// <typeparam name="T">Type to be returned</typeparam>
    /// <param name="BaseAddress">Base address path to be called</param>
    /// <param name="Path">Service Path i.e. /Services/Service</param>
    /// <param name="Obj">Any object that implements ToString() correctly</param>
    /// <returns>Task Of T</returns>
    protected async static Task<T> PutServiceAsync<T>(string BaseAddress, string Path, object Obj)
    {
        using (HttpClient client = BaseService.GetHttpClient(BaseAddress))
        {
            HttpResponseMessage response = await client.PutAsJsonAsync(Path, Obj);
            response.EnsureSuccessStatusCode();
            T result = await response.Content.ReadAsAsync<T>();
            return result;
        }
    }

    /// <summary>
    /// Invoke post request with basepath and path return result.
    /// </summary>
    /// <typeparam name="T">Type to be returned</typeparam>
    /// <param name="Path">Service Path i.e. /Services/Service</param>
    /// <param name="Obj">Any object that implements ToString() correctly</param>
    /// <returns>Task Of T</returns>
    protected async Task<T> PostServiceAsync<T>(string Path, object Obj)
    {
        return await BaseService.PostServiceAsync<T>(this._BaseAddress, Path, Obj);
    }

    /// <summary>
    /// Invoke post request with basepath, path and parameter and return result.
    /// </summary>
    /// <typeparam name="T">Type to be returned</typeparam>
    /// <param name="BaseAddress">Base address path to be called</param>
    /// <param name="Path">Service Path i.e. /Services/Service</param>
    /// <param name="Obj">Any object that implements ToString() correctly</param>
    /// <returns>Task Of T</returns>
    protected async static Task<T> PostServiceAsync<T>(string BaseAddress, string Path, object Obj)
    {
        using (HttpClient client = BaseService.GetHttpClient(BaseAddress))
        {
            HttpResponseMessage response = await client.PostAsJsonAsync(Path, Obj);
            response.EnsureSuccessStatusCode();
            T result = await response.Content.ReadAsAsync<T>();
            return result;
        }
    }

}

public class BaseServiceException : Exception
{
    public BaseServiceException() { }
    public BaseServiceException(string Message) : base(Message) { }
    public BaseServiceException(string Message, Exception InnerException) : base(Message, InnerException) { }

}

Calling WebAPI service from Windows Phone 8 using HttpClient

I had to solve what I figure must be a typical problem for a windows phone developer today, invoking a WebAPI service from the Mobile side. I found documentation on this process rather scarce, so here’s how you do it.

NuGet is your friend in this regard.

Step 1.

PM>  Install-Package Microsoft.AspNet.WebApi.Client -Pre

Step 2.
Confirm references

References

Step 3.

Now you can use  the HttpClient Async API to invoke your WebAPI service and return data. Here’s an example.

code

Which can then be used like this

StockService

To download the source click here.