Archive for the 'WCF' Category

RESTful Web Service in WCF

The RPC-based services presented thus far on this blog have used standard SOAP and WS-* encodings over an HTTP transport. This is evidenced by the wsHttpBinding binding in the service configuration. RPC is a traditional client/server architecture whereby the client calls a command or action on the service. The World Wide Web is constructed around a different architecture where clients request resources from a service. Resources are identified by Uniform Resource Identifiers (URI) and often contain links to other resources. This architecture is known as Representational State Transfer or REST. Consult the Wikipedia article on REST for more details.

Web services can also be constructed using the REST architecture. Such services are called RESTful. Resources on the Web are returned to your browser as, for example, HTML documents and JPEG images, are presentation oriented, and are intended to be rendered in human-readable form. RESTful services, on the other hand, return machine-readable resources as XML documents or in JSON format.

RESTful services can be created quite easily in WCF using the .NET framework 3.5. In fact configuration is much easier than with SOAP services. Here I will make the Baroque composer service that I created in my last postRESTful. First declare the service contract.

[ServiceContract(Namespace="https://patconroy.wordpress.com/service")]
public interface IRestBaroque
{
    [OperationContract]
    [WebGet(UriTemplate = "/composers")]
    ComposerCollection GetComposers();

    [OperationContract]
    [WebGet(UriTemplate = "/composers/{composerId}")]
    Composer GetComposer(string composerId);

    [OperationContract]
    [WebGet(UriTemplate = "/composers/{composerId}/compositions")]
    CompositionCollection GetCompositions(string composerId);

    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/json/composers")]
    ComposerCollection GetComposersJson();

    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/json/composers/{composerId}")]
    Composer GetComposerJson(string composerId);

    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/json/composers/{composerId}/compositions")]
    CompositionCollection GetCompositionsJson(string composerId);
}

Notice the additional attribute WebGet attached to each operation. This informs the framework that following operation is to be invoked on when an HTTP GET method is received for a certain resource. The WebGetAttribute.UriTemplate property identifies the URI of the resource that the service operation will respond to. UriTemplate is, as its name implies, a template that may contain runtime replaceable parameters. The framework parses these parameters from the requested URI at runtime and passes them in to the operation implementation as method parameters. The name in the template must match exactly the parameter name in the operation method. Additionally, the method parameter must be of type string. The framework will not convert from string to any other data type such as int. That must be done in the operation implementation, as it is in this example.

public CompositionCollection GetCompositions(string composerId)
{
    CompositionCollection compositions = null;
    int id;
    if (Int32.TryParse(composerId, out id))
    {
        compositions = GetCompositionData(id);
    }

    if (compositions == null || compositions.Count == 0)
    {
        WebOperationContext.Current.OutgoingResponse.SetStatusAsNotFound();
        return null;
    }
    return compositions;
}

Also notice how an error condition is handled. The HTTP status is set to an appropriate value, in this case 404 or “Not Found”, when an invalid composer ID is passed in. A RESTful service should utilize HTTP to its fullest extent in a manner that follows the HTTP protocol standard.

I have already mentioned that configuration of a RESTful service is much easier than a SOAP service in WCF. This is the only bootstrap code needed to self-host this service. There is no <system.serviceModel> section in the application configuration file. WebServiceHost’s default settings take care of most common scenarios. Simplified configuration is also available in IIS hosted scenarios using WebServiceHostFactory.

public static void Main()
{
    Uri uri = new Uri("http://localhost:8000/service/restbaroque");
    using (WebServiceHost serviceHost = new WebServiceHost(typeof(BaroqueService), uri))
    {
        serviceHost.Open();

        // The service can now be accessed.
        Console.WriteLine("The service is ready.");
        Console.WriteLine("Press <ENTER> to terminate service.");
        Console.WriteLine();
        Console.ReadLine();
     }
}

RESTful service GET methods can be tested simply by using a browser. I simply enter the URL http://localhost:8000/service/restbaroque/composers into the IE address bar after starting the service. The result is an XML document listing all of the composers in my test database, just as I expected.
rest_composers

I could have gotten the same data in JSON format using the URL http://localhost:8000/service/restbaroque/json/composers. This would be useful if I was creating an AJAX client that consumed this service. The WebGetAttribute applied to the service operation GetComposersJson specifies an UriTemplate of “/json/composers” and sets the ResponseFormat property to WebMessageFormat.Json.

In the future I will enhance the service with add, update and delete methods. I will also create a WPF client to consume this service. Stay tuned.

Advertisements

Asynchronous Web Service Implementation

In my last post I demonstrated different ways to invoke a web service asynchronously in a WPF smart client application. It’s also possible to implement the service itself using the asynchronous pattern.

For this example I will create a Baroque service. The contract for this service contains two operations: GetComposers and GetCompositions. GetComposers returns a list of Baroque era music composers via an array of Composer types. Composer is declared as a data contract that contains members for a unique numeric id, first, middle and last names.

GetCompositions returns a collection of well known compositions of a given composer. It takes the composer’s numeric id as a parameter and returns an array of string. The service contract would normally be declared as follows for a synchronous implementation.

[ServiceContract(Namespace = "https://patconroy.wordpress.com/service")]
public interface IBaroque
{
    [OperationContract]
    Composer[] GetComposers();

    [OperationContract]
    string[] GetCompositions(int composerId);
}

I’ll demonstrate later that this is how the client will see the service contract, but it must be declared differently on the back-end for asynchronous operation.

[ServiceContract(Namespace="https://patconroy.wordpress.com/service")]
public interface IBaroque
{
    [OperationContract(AsyncPattern=true)]
    IAsyncResult BeginGetComposers(AsyncCallback callback, object asyncState);
    Composer[] EndGetComposers(IAsyncResult result);

    [OperationContract(AsyncPattern=true)]
    IAsyncResult BeginGetCompositions(int composerId, AsyncCallback callback, object asyncState);
    string[] EndGetCompositions(IAsyncResult result);
}

First of all each operation is now implemented as a pair of Begin/End methods and some additional parameters were introduced. This follows the standard .NET asynchronous pattern, so it should look familiar. Additionally the AsyncPattern property of the OperationContract attribute must be set to true.

Since I’m implementing the async pattern rather than just using it I created a helper class that implements the IAsyncResult interface. This will be returned by the two Begin methods and will subsequently be passed back to the End methods. This class can hold and application state data that’s needed between the Begin and End calls. The class also includes a ManualResetEvent that gets set when the asynchronous operation completes

public class AsyncResult : IAsyncResult
{
    private object _state;
    private AsyncCallback _callback;
    private ManualResetEvent _event;

    public AsyncResult(AsyncCallback callback, object state)
    {
        _callback = callback;
        _state = state;
        _event = new ManualResetEvent(false);
    }

    #region IAsyncResult Members
    public object AsyncState
    {
        get { return _state; }
    }

    public WaitHandle AsyncWaitHandle
    {
        get { return _event; }
    }

    public bool CompletedSynchronously
    {
        get { return false; }
    }

    public bool IsCompleted
    {
        get { return _event.WaitOne(0, false); }
    }
    #endregion

    public void Complete()
    {
        _event.Set();
        if (_callback != null)
            _callback(this);
    }
}

To implement this solution I created and Access database named baroque.mdb that has two tables: Composer and Composition. Composer has a unique id column as well as the first, middle and last name text columns. Composition has the composer id and composition name columns. As you might guess there is a one-to-many relationship between composer and composition. This example used the OLE-DB data provider to read the table.

public IAsyncResult BeginGetComposers(AsyncCallback callback, object asyncState)
{
    TypedAsyncResult<Composer&#91;&#93;> result = new TypedAsyncResult<Composer&#91;&#93;>(callback, asyncState);
    ThreadPool.QueueUserWorkItem(new WaitCallback(GetComposers), result);
    return result;
}

public Composer[] EndGetComposers(IAsyncResult result)
{
    TypedAsyncResult<Composer&#91;&#93;> asyncResult = result as TypedAsyncResult<Composer&#91;&#93;>;
    if (result != null)
    {
        asyncResult.AsyncWaitHandle.WaitOne();
        return asyncResult.Result;
    }
    return null;
}

As you can, see the Begin operation sends the work to a background thread. GetComposers isn’t listed here but it’s in the code download. The framework calls the End method. You don’t do that at all. TypedAsyncResult is a specialization of AsyncResult that stores a generic operation result. It’s in the code download. BeginGetCompositions and EndGetCompositions are implemented similarly.

What is the benefit of the extra coding that was done here? For this example there really isn’t one. The OLE-DB data provider only supports synchronous database operations, so I had to create my own background thread. The SQL Server data provider, on the other hand, does support asynchronous operations. Had I used SQL Server instead of Access then I would have used SqlCommand.BeginExecuteReader and SqlCommand.EndExecuteReader. Background threading is handled in the framework rather than in the application.

WCF hides all of these implementation details from the client. The client only sees GetComposers and GetCompositions methods as if they were synchronous implementations. Of course the WCF client proxy can optionally contain the methods needed to call the service asynchronously. I described these in my last post. These are, however, independent of the server implementation. The client can choose to call the service synchronously or asynchronously regardless of how the service was coded. The code download contains a WPF client application that uses the event based asynchronous pattern to call the service.

composerclient

All of the source code from this post can be downloaded here.

Asynchronous Web Service Invocation

In my last post I described various ways to perform work on a background thread in a WPF smart client application. Performing long running operations on the main application thread will freeze the user interface and yield a poor user experience. On the other hand any GUI elements must be manipulated on the main application thread and only on that thread. In this post I describe three different ways to make web service calls on a background thread using WCF client components.

First I created a simple, self-hosted WCF service implementing a simple calculator interface. The Windows SDK has several example implementations of this interface. Each of the implementation methods in my service sleeps for 10 seconds to simulate a long running process.

[ServiceContract(Namespace="https://patconroy.wordpress.com/service")]
public interface ICalculator
{
    [OperationContract]
    double Add(double n1, double n2);
    [OperationContract]
    double Subtract(double n1, double n2);
    [OperationContract]
    double Multiply(double n1, double n2);
    [OperationContract]
    double Divide(double n1, double n2);
}

Those of you running Vista will need to execute the following command as administrator to update the system URL ACL, substituting your own Windows domain and userid in the appropriate place.

netsh http add urlacl url=http://+:8000/ user=domain\userid

The client application example presents four different ways of calling the web service. The main windows has four radio buttons to select from amongst them.

  1. Synchronously on the GUI thread
  2. Asynchronously using BackgroundWorker
  3. Using the Asynchronous Programming Model
  4. Using a new .NET 3.5 event based model

The first of these is certainly the easiest to code. All work occurs on the main application thread, but herein lies a problem. The user interface is frozen while the application waits for the web service to return.

Using BackgroundWorker

The second technique is certainly an improvement. BackgroundWorker is used to launch a background thread that makes the web service call. The background thread waits for the web service to return then sets DoWorkEventArgs.Result. This Result is handed to the RunWorkerCompleted delegate on the GUI thread.

private static void CallServiceBackgroundWorker(Window1 win, double n1, double n2)
{
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += BackgroundWorker_DoWork;
    bw.RunWorkerCompleted += win.BackgroundWorker_RunWorkerCompleted;
    bw.RunWorkerAsync(win);
}
// BackgroundWorker callbacks
static void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    Window1 win = (e.Argument) as Window1;
    e.Result = _calcClient.Add(win._data.Number1, win._data.Number2);
}
void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // This callback is made on the GUI thread
    UpdateResult((double)e.Result);
}

Do you see a problem here? Earlier I stated that “The background thread waits for the web service.” The application consumes a background thread while waiting for the web service to finish. This background thread could be utilized for something else while the web service call is outstanding. This isn’t a problem in a small example but could be a scalability killer in a larger real-world application.

Using the Asynchronous Programming Model

This last problem is solved by the Asynchronous Programming Model. The APM pervades the .NET framework. One can, for example, read a FileStream using this method. It works roughly like this.

void CallServiceAsyncPattern(Window1 win, double n1, double n2)
{
    IAsyncResult ar = obj.BeginXyz(param, new AsyncCallback(MyCallback), state);
}
void MyCallback(IAsyncResult ar)
{
    var result = obj.EndXyz(ar);
}

The names of the Begin and End methods will of course differ from class to class. The main application thread initiates the asynchronous operation by calling BeginXyz(). The framework itself then performs the operation on a background thread or better yet by using overlapped I/O. Overlapped I/O is a Windows OS feature that completes the I/O operation in the Windows kernel. An application callback is called when the operation completes. The callback occurs on a background thread.

The .NET web service proxy generator creates a Begin and End method for each of the service interface methods when the /async command line option is specified.

svcutil http://localhost:8000/service/calculator/mex /async

Or just check “Generate asynchronous operations” when creating a service reference in Visual Studio. This example client uses BeginAdd and EndAdd. AsyncCallback is called on a background thread when the web service operation completes. AsyncCallback cannot access the GUI directly, so it dispatches the result to the GUI thread.

private delegate void UpdateResultDelegate(double n);
private static void AsyncCallback(IAsyncResult ar)
{
    double result = _calcClient.EndAdd(ar);
    Window1 win = (ar.AsyncState as Window1);
    // Result must be dispatched to the GUI thread
    win.Dispatcher.Invoke(new UpdateResultDelegate(win.UpdateResult), result);
}
private static void CallServiceAsyncPattern(Window1 win, double n1, double n2)
{
    IAsyncResult ar = _calcClient.BeginAdd(n1, n2, AsyncCallback, win);
}

Using an event based model

A new event based asynchronous model was introduced in the framework version 3.5. The service proxy generator creates all the necessary delegate declarations and event argument classes. It also adds a completed event and an XyzAsync() method to the proxy class for each of the web service methods. Specify /tcv:version35 in addition to /async on the svcutil command line to generate this additional code. This is also done automatically in Visual Studio when “Generate asynchronous operations” is checked.

The event model is an improvement over APM because the completed event is called on the same thread that initially made the asynchronous service request. In the example here AddAsync() is called on the GUI thread, so the AddCompleted event handler is called on the GUI thread after the web service returns. The need to dispatch the result to the GUI thread has been eliminated. GUI state can be manipulated within the event handler, so coding is much easier than with APM.

Event handlers must be set on the service proxy instance prior to making any service requests. This example only uses the Add service method, so only an AddCompleted event handler is set. CalculatorClient also includes SubtractCompleted, MultiplyCompleted and DivideCompleted event handlers.

private static CalculatorClient _calcClient;
static Window1()
{
    _calcClient = new CalculatorClient();
    _calcClient.AddCompleted +=new EventHandler<AddCompletedEventArgs>(CalcClient_AddCompleted);
}
private static void CalcClient_AddCompleted(object sender, AddCompletedEventArgs e)
{
    // This callback is made on the GUI thread
    (e.UserState as Window1).UpdateResult(e.Result);
}

Initiating an asynchronous call to Add is simply a matter of calling CalculatorClient.AddAsync(). Note that the code generator also created SubtractAsync, MultiplyAsync and DivideAsync methods.

private static void CallServiceNewAsync(Window1 win, double n1, double n2)
{
   _calcClient.AddAsync(n1, n2, win);
}

All source code for this example is located here.


December 2017
M T W T F S S
« Apr    
 123
45678910
11121314151617
18192021222324
25262728293031
I am a part of all that I have met;
Yet all exprience is an arch whitherthro'
Gleams that untravell'd world, whose margin fades
For ever and for ever when I move.
How dull it is to pause, to make an end,
To rust unburnish'd, not to shine in use!
Alfred, Lord Tennyson