Aug 022012
 

Introduction

Recently, I started building up a WCF Service Application from scratch to implement a specific set of operations from an existing WSDL.

This was a little cumbersome, but gave me an excellent opportunity to extend and play around with a concept I’ve been trying to perfect for a couple of years now.  In a nutshell, what I wanted was the ability to just focus on implementing the specific functionality of a Web Service operation, yet reuse common validation, logging and exception handling.

This required each web service to inherit from a common base class.  Each request is a class which inherits from a base class also (containing properties which are required for every request).

Class Object View

Let’s take a look at my web service:

image

As you can see, the FormsManager class derives from the obviously named ServiceBase.  Now, as I stated previously, my intention was to move as much “common functionality” into the base as possible.  To do this, let’s take a look at one of the operations:

A Sample Web Service Operation

/// 
/// Submit a form (i.e. lodge a form)
/// 
/// 
/// 
public SubmitFormResponse SubmitForm(SubmitFormRequest request)
{
    return base.ExecuteRequest<SubmitFormRequest, SubmitFormResponse>
	(request, delegate
    {
        AuthoriseAccountId(request.AccountId, request.FormType, 
				FormTypeAuthorisationEnum.Submit);

        if (!String.IsNullOrEmpty(request.ReferenceId))
        {
            AuthoriseAccountId(request.AccountId, 
				request.ReferenceId, 
				FormAuthorisationEnum.Manage);
        }
     
        FormsProvider.SubmitForm(request);

        SubmitFormResponse response = new SubmitFormResponse();
        response.Reference = request.ReferenceId;
        return response;
    });
}

In this scenario, SubmitFormRequest inherits from RequestBase and SubmitFormResponse inherits from ResponseBase.  This will make more sense in the next block of code.

As you can see, this operation only has to worry about implementing functionality specific to it’s requirements – common validation, exception handling and logging can be moved into the ‘ExecuteRequest’ function in the base class like so:

The Base Class

        
/// 
/// Execute a Request where the delegate returns a value
/// 
/// 
protected Z ExecuteRequest<T, Z>(T request, Func<Z> operation)
    where T : RequestBase
    where Z : ResponseBase 
{
    try
    {
        TraceLogger.Log.Trace(
		String.Format("Execute Request: {0}", 
				TraceHelper.GetPreviousMethod()));

        if (request == null)
        {
            throw new 
	    ArgumentNullException("Specified Request Parameter was NULL");
        }
        if (String.IsNullOrEmpty(request.AccountId))
        {
            throw new 
            RequiredArgumentException("Account ID was not specified");
        }

        // Validate the identity of the request
        ValidateAccountId(request);

        return operation();
    }
    catch (Exception ex)
    {
         //Log the exception
        if (ex is ICustomException)
        {
            throw ex;
        }
        throw ex; //TODO: Sanitise the Exception
    }
}

This is still a work in progress, but what it does demonstrate is how to embed a consistent and reusable set of functionality into a base class (reducing code duplication) and allowing you to add code to each web service operation which is specific to the nature of the operation; without the need to explicitly add try/catch or logging.

How does this work?

We’re making use of the Func<> (and in other base functions where no return value is required, Action<>) delegate functionality.  In this instance, Func<Z> defines a delegate which returns a value of type Z.  In the example here, Z is defined as SubmitFormResponse.

Therefore, the pseudo code for executing a SubmitForm request is as follows:

  • Call base class
  • Try
    • Trace (calling function name)
    • Is Request NULL?
    • Is AccountId Null or Empty?
    • Is AccountId Valid?
    • return Call delegate()
      • Is AccountId Authorised?
      • Is ReferenceId Null or Empty?
      • Is AccountId Authorised to Manage this Reference?
      • SubmitForm
      • Create new SubmitFormResponse
      • return response
  • Catch
  • Log exception
  • Is Custom Exception? (throw)
  • Sanitise Exception (throw)

The try/catch block in the ExecuteRequest implementation will also catch any unhandled exceptions thrown by the delegate.  This gives you the potential for automatic exception management – no more uncaught exceptions thrown back to the caller.  You can also make use of standardised logging as well.

Note that the type restriction on the base class function could easily have been defined as the following:

        
/// 
/// Execute a Request where the delegate returns a value
/// 
/// 
protected Z ExecuteRequest<T, Z>(T request, Func<Z> operation)
    where T : RequestBase
    where Z : class
{

Which would allow the delegate to return any class.  Alternatively, you could remove the restriction altogether if you wanted to return value types as well, for example:

/// 
/// Execute a Request where the delegate returns a value
/// 
/// 
protected Z ExecuteRequest<T, Z>(T request, Func<Z> operation)
    where T : RequestBase

//-------------------------------------------------------------------------

return base.ExecuteRequest<SaveDraftFormRequest, int>(request, delegate
{
    return -1;
});

Should your base class be required to handle a delegate which does not return a value, simply replace Func<> with Action<>.

Summary

What I’ve covered off here is just some simple usages of generics and delegates which may help to improve the maintainability and consistency of your WCF web service operations. 

There are limitations (such as the granularity of properties you would be compelled to put into a base class), but the wins are (IMHO) worth the time to implement.

Perhaps you have designed or implemented something similar? 

Please leave a comment.

Oct 122011
 

Hi All.

Engineering FlowchartI’m debating a new article.

I’m currently debating whether to spend some time documenting an interesting solution to a fairly esoteric scenario.  I’m not sure if it is worth the investment (in my time), so I’m going to throw it open to the community. 

Give me feedback – if you have an interest in seeing this solution, please leave a comment.  The only reason I mention this is because the solution is really quite interesting, and a good lesson in the rarer binding types (and message & transport security) in Windows Communication Foundation (WCF).

Here’s the premise:

We have a .NET 2.0 client (which can not be upgraded to 3.5 or 4.0) which must consume a web service by providing a Web Service Extension (WSE) 3 policy file – which stipulates a separate set of credentials (username/password/domain) for authentication in a downstream legacy system.

Presently, this client calls a series of legacy ASMX services (also .NET 2.0).  However, there is a desire to upgrade these services to WCF (for more widespread use) and so we can take advantages of .NET 4.0 in the service implementation and beyond.  The challenge is to provide the same functionality (policy file attached to the transport) for later authentication. 

The information would be transmitted by HTTPs or via HTTP under a VPN (so, ultimately, encrypted).  This is obviously a fairly intriguing paradigm, made more interesting by the prospect of actually not using the WSE3 policy information for handshake authentication.

The original design, from my understanding, was to make the passing of credentials transparent to the service calls themselves (hence, not passing username, password and domain per service call explicitly).  I could be wrong about that, but in any case this is the scenario we have today.

Here’s where you fit in:

So, I repeat – who’d be interested in seeing the solution?  Please leave a comment to indicate an interest.  Depending on how much interest there is, I’ll put together both a long article and a sample, demonstrative, solution.

Cheers, R