Calling ASP.NET Web API end-points for testing purposes

I'll preface this by saying there are almost certainly a bucket load of different tools and twice as many supporting libraries / packages out there that'll give you a solution to this problem but sometimes it's worth doing something from first principles as a means to learn. When I originally composed this it wasn't for that reason, it was because I needed something quick and dirty and I re-purposed a good wodge of existing code in order to achieve what I wanted. Because of this the code is full of "smells" but I'll highlight these as and when I remember to!

Calling your ASP.NET Web API

The first thing that's needed is some code for calling an ASP.NET Web API method, the code I've used is setup to request, and process a returned, JSON blob because that's what I need! To do this I've got a base class that can be inherited from to provide access to its MakeRequest method:

using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Net.Http.Headers;

namespace TestingAspNetWebApiMethods
{
    public abstract class ApiBase
    {
        protected T MakeRequest<T, U>(string url, U content) where T : ResponseBase
        {
            var client = new HttpClient
            {
                BaseAddress = new Uri(url)
            };

            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var response = client.PostAsJsonAsync(url, content).Result;

            if (response.IsSuccessStatusCode)
            {
                var responseBody = response.Content.ReadAsStringAsync();
                responseBody.Wait();

                var result = JsonConvert.DeserializeObject<T>(responseBody.Result);
                result.Success = true;
                return result;
            }

            return default(T);
        }
    }
}

This is the building block upon which everything else is based, but it does have a couple of bits of "yuck" in it, some of these are:

  • We spin up a new instance of HttpClient every time this method is called, there's writing out there that suggests this is a bad thing.
  • HttpClient is a disposable object and we're not disposing of it, for shame!
  • There's no error handling here - that's quite deliberate, I've stripped it out of the class for brevity
  • We call an Async method and then Wait on it rather than making the MakeRequest method async itself. I did say this code was quick and dirty!

NOTE: The PostAsJsonAsync method used on HttpClient is an extension method found in the System.Net.Http.Formatting library

Next up is creating a wrapper/proxy for our API by using this base class. I'm only going to show a single method in the proxy, but yours can have as many as you want. I implement each method on the API as a method on my proxy class, usually with one proxy class per controller. Some times I end up writing a "process driven" proxy class that has calls to methods on multiple controllers, for example to modify the "create user" workflow in its entirety.

So without further ado, here's an example of a proxy class:

namespace TestingAspNetWebApiMethods
{
    public sealed class LoginApi : ApiBase
    {
        public LoginResponse Login(string loginHost, string username, string password)
        {
            var apiUrl = $"https://{loginHost}/api/login/authenticatecredentials";

            var body = new
            {
                password,
                username
            };

            var result = MakeRequest<LoginResponse, object>(apiUrl, body);

            return result;
        }
    }
}

This class inherits from ApiBase and provides a single method that will call an API url, pass the username and password to it and retrieve the response into a LoginResponse object. This is an implementation of ResponseBase which you can see referenced in ApiBase, these two clases look like this:

namespace TestingAspNetWebApiMethods
{
    public abstract class ResponseBase
    {
        public bool Success { get; set; }
    }

    public class LoginResponse : ResponseBase
    {
        public int[] secondFactorLetterPosition { get; set; }
        public string temporaryAuthenticationToken { get; set; }
    }
}

The code in MakeRequest is responsible for calling the ASP.NET Web API method, passing data to it and then (by the wonder of Newtonsoft.Json) decoding it into an instance of LoginResponse. The ResponseBase base class provides a Success property that allows MakeRequest to tell its caller whether the request to the server succeeded, or not.

Actually putting this together and using it looks something like this:

var loginApiClient = new LoginApi();
var loginResult = loginApiClient.Login("localhost:4321", "myUserName", "myPassword")
if (loginResult.Success)
{
    // Handle success here
}
else
{
    // Handle failure here
}

Once you've got this, it's very easy to quickly write little tools (ConsoleApplication137, anyone?) that you can use to test various parts of your API quickly.

About Rob

I've been interested in computing since the day my Dad purchased his first business PC (an Amstrad PC 1640 for anyone interested) which introduced me to MS-DOS batch programming and BASIC.

My skillset has matured somewhat since then, which you'll probably see from the posts here. You can read a bit more about me on the about page of the site, or check out some of the other posts on my areas of interest.

No Comments

Add a Comment