Click here to Skip to main content
15,867,568 members
Articles / Web Development / ASP.NET

Use a Generic Util for Easily Testing REST Methods

Rate me:
Please Sign up or sign in to vote.
4.76/5 (10 votes)
30 Jan 2014CPOL5 min read 24.3K   995   31   6
Overview and Usage of a Util for testing REST methods

Applying Lipstick to Frankenstein's Monster

Note: I have written an alternative version of this article and utility here for those who don't want to mix args with their path info in the server routing attributes. 

The client utility that I cobbled together for testing my Web API REST calls was getting out-of-hand/unwieldy or, to put it bluntly, 9X Uglier than a Bag of Butts (or a monster mashup, like Mary Shelley's Adam), as you can see here:

Image 1

So I decided to clean up my act by creating a more generic Windows Forms utility. My aim was to avoid having to add a set of buttons each time I wanted to test a new Controller. All I need to do now is to add the Controller method "decorations" (or routing attributes) to a combobox or a text file. Then, when I run the util, I either load the text file or select the URI I want to test from the combobox. The util determines, based on the URI selected, which args needed to be added, and makes (up to four) textboxes visible in which I can enter the argument values to pass. The util then builds the URI to be sent to the Web API server.

I'm adding the code to this util to this article, but I'm not going to feature it here because I realize that some of it is kind of kludgy and many of you could elegantize it and make it more "performant" - IOW, the code used is not necessarily the best way of accomplishing the ends in all cases - but it works pretty well for me, so that's why I'm sharing it; I'll also add the .exe as a download. The point of this article is to step you through the usage of it.

Speaking of inelegant code, after increasing the count of args from 4 to 10, I replaced the brute force/verbose VisiblizeCandidateArgs() code with the following:

C#
private void VisiblizeCandidateArgs(bool visiblize)
{
    const int CANDIDATE_COUNT = 10;
    for (int i = 1; i <= CANDIDATE_COUNT; i++)
    {
        Control lbl = GetControlByName(string.Format("labelArg{0}", i));
        lbl.Visible = visiblize;
    }
    for (int i = 1; i <= CANDIDATE_COUNT; i++)
    {
        Control txtbx = GetControlByName(string.Format("textBoxArg{0}", i));
        txtbx.Visible = visiblize;
        if (!visiblize)
        {
            txtbx.Text = string.Empty;
        }
    }
}

The Seven Step Method to This Madness

At this point in time and space, I will lead you through the use of the util. And actually, I have placed numbers on the form's controls to indicate the steps in which you should plod (or race) through this util.

First, run it, and you will see something highly provocative (YMMV):

Image 2

Shocking!!! You see here that the base URI for my app is in step 0 (Enter Base URI)! What an egotist! Well, really not so, because it's just there (for you) as a "living" example ("It's Alive!") -- you can (and should) change the URI to whatever is right for the REST service you are going to est.

Mash the "1) Load Routing Attributes From File" button to do so (first, though, you must have such a file or, if you've downloaded the code, you can add the URIs you want to the combobox's Items property).

A conditionally sufficient word (or two): For background information on decorating your Controller methods with explicit attribute routing, see this article.

A text file you load might have contents like this:

  • [Route("api/SQLServerPOC/Count")]
  • [Route("api/SQLServerPOC/GetAll")]
  • [Route("api/SQLServerPOC/{ID:int}")]
  • [Route("api/SQLServerPOC/GetByFullName/{FName}/{MName}/{LName}")]
  • [Route("api/SQLServerPOC/GetByLastName/{LName}")]
  • [Route("api/SQLServerPOC/GetByStateOrProvince/{StateOrProvince}")]
  • [Route("api/SQLServerPOC/GetByZip/{PostalCode}")]
  • [Route("api/SQLServerPOC/GetByCountry/{Country}")]

Now that you've populated the combo box, you can go to step 2 - select one of the items / URIs.

The "3) Discover Attribute Args" button examines the URI and determines any "differentiator" contained in the URI (such as "GetAll" or "GetByLName" or whatever) and also if there are any args and if so, how many. If there are some, it makes the appropriate number of label/textbox pairs visible (up to four) so that you can enter an appropriate value to pass as the argument in the text box (the label indicates the name of the arg and its data type). Here's what you might see after selecting a URI with three args and entering some values into the text boxes:

Image 3

If you then hit the "5) (Re)build URI" button, it will do so, appending to the Base URI the Controller Name, the "Differentiator" if it has one (GetByFullName in this case), and any arg vals. Don't believe me? Czech it out:(

Image 4

The only thing left to do is mash the "6) Test the URI" button. But since I want to show more data, I'm going to change the URI to select by State and then do so. The results are:

Image 5

Anthem for Doomed Singles

Known Issue: The GetRESTData() method (which is called when you mash the "Test the URI" button) blows up if only one json "record" is returned. I guess because it doesn't consider one measly element an array, and it returns a

JArray
. So that is an exercise left to the reader: figure out a fix for that.

I did spin a clever but kludgy way to get around the crashing of GetRESTData() when only one json array element is found. I changed this code:

C#
private JArray GetRESTData(string uri)
{
    var webRequest = (HttpWebRequest)WebRequest.Create(uri);
    var webResponse = (HttpWebResponse)webRequest.GetResponse();
    var reader = new StreamReader(webResponse.GetResponseStream());
    string s = reader.ReadToEnd();
    return JsonConvert.DeserializeObject<jarray>(s);
}

...to this:

C#
private JArray GetRESTData(string uri)
{
    try
    {
        var webRequest = (HttpWebRequest)WebRequest.Create(uri);
        var webResponse = (HttpWebResponse)webRequest.GetResponse();
        var reader = new StreamReader(webResponse.GetResponseStream());
        string s = reader.ReadToEnd();
        return JsonConvert.DeserializeObject<jarray>(s);
    }
    catch // This method crashes if only one json "record" is found
    {
        try
        {
            MessageBox.Show(GetScalarVal(uri));
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    return null;
}

private string GetScalarVal(string uri)
{
    var client = new WebClient();
    return client.DownloadString(uri);
}

UPDATE: I've added another file that can be downloaded; the latest version of my test util (as of 2/7/2014) as a project template. It is the file named "Web_API_GET_REST_Test.zip". Feel free to adapt, adopt, tweak, but do not fold, spindle, mutilate, or otherwise catawamptiously chaw it up.

TANSTaaFL

If you like this article/utility, be kind and rewind ... all the cassette tapes in the known universe - and before teatime, at that! Alternative service: Tiptoe through the Tulips.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder Across Time & Space
United States United States
I am in the process of morphing from a software developer into a portrayer of Mark Twain. My monologue (or one-man play, entitled "The Adventures of Mark Twain: As Told By Himself" and set in 1896) features Twain giving an overview of his life up till then. The performance includes the relating of interesting experiences and humorous anecdotes from Twain's boyhood and youth, his time as a riverboat pilot, his wild and woolly adventures in the Territory of Nevada and California, and experiences as a writer and world traveler, including recollections of meetings with many of the famous and powerful of the 19th century - royalty, business magnates, fellow authors, as well as intimate glimpses into his home life (his parents, siblings, wife, and children).

Peripatetic and picaresque, I have lived in eight states; specifically, besides my native California (where I was born and where I now again reside) in chronological order: New York, Montana, Alaska, Oklahoma, Wisconsin, Idaho, and Missouri.

I am also a writer of both fiction (for which I use a nom de plume, "Blackbird Crow Raven", as a nod to my Native American heritage - I am "½ Cowboy, ½ Indian") and nonfiction, including a two-volume social and cultural history of the U.S. which covers important events from 1620-2006: http://www.lulu.com/spotlight/blackbirdcraven

Comments and Discussions

 
GeneralMy vote of 5 Pin
Farhad Reza17-Nov-16 22:47
Farhad Reza17-Nov-16 22:47 
GeneralMy vote of 5 Pin
D V L23-Aug-15 22:25
professionalD V L23-Aug-15 22:25 
QuestionMy Vote on My Vote of Pin
Roink4-Feb-14 9:06
professionalRoink4-Feb-14 9:06 
AnswerRe: My Vote on My Vote of Pin
B. Clay Shannon4-Feb-14 9:14
professionalB. Clay Shannon4-Feb-14 9:14 
GeneralRe: My Vote on My Vote of Pin
Roink4-Feb-14 9:39
professionalRoink4-Feb-14 9:39 
AnswerRe: My Vote on My Vote of Pin
Paulo Zemek8-Feb-14 7:07
mvaPaulo Zemek8-Feb-14 7:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.