Click here to Skip to main content
Click here to Skip to main content

Use a Generic Util for Easily Testing REST Methods

, 30 Jan 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
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:

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:

        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):

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:

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:(

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:

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:

        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:

        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)

Share

About the Author

B. Clay Shannon
Publisher "Found in the Translation"
United States United States
I am the entire team at "Found in the Translation," which produces multilingual books (paperback and Kindle versions) such as "Don Quixote: In Spanish and English, Paragraph-by-Paragraph" among many others (English paired with not only Spanish, but also French and even Finnish). You can see all those books here: http://jsfiddle.net/clayshannon/pRgQL/75/
 
Personal web sites that I have created can be seen at http://usamaporama.azurewebsites.net and http://bigsurgarrapata.azurewebsites.net/
 
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: http://www.lulu.com/spotlight/blackbirdcraven
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
QuestionMy Vote on My Vote of [modified] PinmemberRoink4-Feb-14 9:06 
AnswerRe: My Vote on My Vote of PinprofessionalB. Clay Shannon4-Feb-14 9:14 
GeneralRe: My Vote on My Vote of PinmemberRoink4-Feb-14 9:39 
AnswerRe: My Vote on My Vote of PinprofessionalPaulo Zemek8-Feb-14 7:07 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.141022.2 | Last Updated 30 Jan 2014
Article Copyright 2014 by B. Clay Shannon
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid