Anatomy of a simple REST client

In Anatomy of a simple REST service we created a service using WFC Web HTTP services. The service has a single resource that supports the GET and POST verbs. Let’s create a client for this REST service.

Creating a client application

Start with the previous solution (see the download at the end) open in Visual Studio, and create a new Console Application: in the Solution Explorer, right-click on the solution node and select Add | New Project | Visual C# | Windows | Console Application and name it AcmePaintClient.

Creating a client DTO

The Colors service from the previous solution has the Color resource’s GET send, and POST receive Color objects. However, they are JSON object on the wire, so on the client side we are free to create any DTO we want so long as it’s compatible.with the JSON object. Compatibility include having properties whose names match the names of the fields in the JSON object. Compatibility does not include having the same class name as was using in the server DTO or preserving the order of the properties..

Add a class named AcmeColor and add properties whose names match the names of the Color DTO defined in the previous solution, like this.

public class AcmeColor
{
  public byte Green { get; set; }
  public byte Blue { get; set; }
  public byte Red { get; set; }
}

Creating a client

First, let’s change the service URL to be a fixed value. In Solution Explorer | AcmePaint double-click on the Properties item. On the AcmePaint Properties window, select the Web tab. Under Servers, verify that Use Visual Studio Development Server is selected, and select Specific port. Note the value of the port, we’ll be using that shortly. My value is 42524.

Next, we’ll add a reference to an assembly we’ll be using. In Solution Explorer, right-click on the AcmePaintClient project and select Add Reference. On the .NET tab, select System.Runtime.Serialization.

In the Program.cs file, add the following using declarations and the GetColor method.

using System;
using System.Net;
using System.Runtime.Serialization.Json;

private static AcmeColor GetColor( int id )
{
  using ( var client = new WebClient() )
  {
    var uri = new Uri(
      string.Format( "http://localhost:42524/Colors.svc/Color/{0}", id ) );

    using ( var stream = client.OpenRead( uri ) )
    {
      var serializer = new DataContractJsonSerializer( typeof( AcmeColor ) );
      return (AcmeColor)serializer.ReadObject( stream );
    }
  }
}

Quite simply, this is using the WebClient.OpenRead method (== open then read) to perform the GET operation, which returns a Stream that contains the returned JSON. Then the DataContractJsonSerialicer.ReadObject method reads the JSON stream into an AcmeColor type.

Also in the Program.cs file, add the following PostColor method.

private static void PostColor( AcmeColor color )
{
  using ( var client = new WebClient() )
  {
    client.Headers[ HttpRequestHeader.ContentType ] = "application/json";

    var uri = new Uri( "http://localhost:42524/Colors.svc/Color" );
    using ( var stream = client.OpenWrite( uri, "POST" ) )
    {
      var serializer = new DataContractJsonSerializer( typeof( AcmeColor ) );
      serializer.WriteObject( stream, color );
      stream.Close();
    }
  }
}

This time we’re using the WebClient.OpenWrite method (== open then write) to perform the POST operation. This method also returns a Stream, but this time it is a stream for us to write the JSON from an AcmeColor type. That task is performed by DataContractJsonSerializer.WriteObject.

Also note that we’ve set the HTTP Content-Type header so that the service knows what it is receiving.

Finally, modify the Main method to call both of our methods.

static void Main( string[] args )
{
  var color = GetColor( 3 );

  Console.WriteLine( "Color: Red={0}, Green={1}, Blue={2}",
    color.Red, color.Green, color.Blue );

  PostColor( new AcmeColor { Red = 0x80, Green = 0xff, Blue = 0x80 } );

  Console.WriteLine( "Press any key to exit..." );
  Console.ReadKey();
}

Running the client

In the Solution Explorer, right-click on the AcmePaintClient project and select Set as StartUp Project. Then press F5 to start with debugging. The following output is displayed:

Color: Red=255, Green=128, Blue=0
Press any key to exit...

Debugging the service

So far you have no real evidence that the PostColor method actually communicated with the Colors.svc service. I did that expressly so that we can also explore how to debug the service, which a very handy thing to know.

Here’s a simple technique based on the following observation. An instance of Visual Studio can only debug a single program at a time; however it can start as many programs as you like without debugging.

Let’s add a pause at the very top of the Program.Main method so that we can control when it starts making service calls.

Console.WriteLine( "Press any key to start..." );
Console.ReadKey();

Next, in the AcmePaint project, open Color.svc.cs (double-click on the Color.svc item) and set a breakpoint on the close curly-brace for the PostColor method, e.g., by clicking in the left column next to that line in the source code, or by setting the cursor on that line and pressing F9.

Now, with AcmePaintClient still set as the start-up project, press Ctrl+F5 to start running the client without debugging.

Return to Visual Studio, and in Solution Explorer, right-click on AcmePaint project and select Set as StartUp Project. Then press F5 to start the service with debugging.

Return to the console window running the AcmePaintClient and press any key so that it starts making calls to the service.

Visual Studio should hit the breakpoint at the end of the PostColor method. View the value of the requestedColor variable in the Locals window (if the Locals window is not displayed select Debug | Windows | Locals.) You can verify that it is the requestedColor value is the same value that was sent by the client.

Cleaning up

In Visual Studio, press F5 to let the service invocation run to completion. In the AcmePaintClient console window, press any key to exit. In Visual Studio, press Shift+F5 to stop debugging the AcmePaint service.

Review

We created a minimal REST service client using the WebClient class to perform HTTP requests for both the GET and POST verbs. We also learned a technique for debugging and stepping into the service.

Resources

Download the completed code

Additional Posts in this series

Anatomy of a simple REST service

Comments are closed.