Monthly Archives: August 2007

Using WCF WebHttpBinding and WebGet with nicer Urls

I’ve been playing with the REST support in .NET 3.5.  I’m really enjoying the programming model, but I am not enjoying the .svc file extension in my URLs (I’m not the only person I know who has felt this way for quite some time).

IMO (from what little I know about the REST style) URLs shouldn’t have things like extensions in them (or preferably not).  So with they way WCF endpoint hosting in IIS works (obviously if I am hosting a webHttpBinding in a non-IIS host I can totally control the URLs, but I am writing a REST API to something where I plan to be hosting inside of IIS).  This would end up being my url:

http://host/albumn.svc/instance/

and I want:

http://host/albumn/instance/

The .svc extension in the URL doesn’t seem opaque to me.  I tried modifying the HttpHandler element for the svc file – but that didn’t work for various reasons.  So I ended up writing a simple HttpModule to do URL re-writing (using HttpContext.RewritePath).  I didn’t really want any config relating to URLs – so this module assumes you are serving up only REST based URLs from a web application.  If you were going to use it and serve up other handlers (like aspx files etc) it would need to be modified. Here is the module code:

public class RestModule : IHttpModule
{

public void Dispose()
{ }

public void Init(HttpApplication app)
{
app.BeginRequest += delegate
{
HttpContext ctx = HttpContext.Current;
string path = ctx.Request.AppRelativeCurrentExecutionFilePath;

int i = path.IndexOf(‘/‘, 2);
if(i>0)
{
string svc = path.Substring(0, i) + “.svc”;
string rest = path.Substring(i, path.Length - i);
ctx.RewritePath(svc, rest, ctx.Request.QueryString.ToString(), false);
}
};

}

}

After configuring this in my web.config – I have the ability to type:

http://localhost/RestTest/Service2/Test?id=9999

and the module will translate it to Service2.svc as the handler file – which makes WCF happy.

If you are interested you can download the code here:

RestTest.zip (3.71 KB)

EDIT:  Christian pointed out that this approach alone will not work in IIS6 (my approach is for integrated mode of IIS7).  For IIS you have to add aspnet_isapi.dll to the Wildard Application Maps.  But then he goes on to tell me no one will do that ;-).  So I say – good reason to move to IIS7 and Longhorn/Windows 2008 – since it has a go-live license.

WF Down-under

I’ve had alot of people ask when I am teaching WF next – if you are interested in sitting through me talking about WF for four intense days – come to laid-back Australia.  Pluralsight is teaming up with Readify to offer the course.  I’m super excited since this will be my first trip to Australia.  I can’t wait.  If you are in the area – or just want an excuse to come to Australia – sign up ;-)

Applied Windows Workflow Foundation in Australia Nov 13-17th  

Harry sticks up for the magic method

Here  – I can certainly understand his points.  For me it comes down to two things:

1) The design of ServiceHostBase isn’t as clean as I think it should given its intended purpose (to allow WCF Services to be exposed w/o a .NET Type associated with it).

2) The exception.  I wouldn’t hate the design as much if a) the exception wasn’t a blatant lie, and b) they actually documented that you need to call InitializeDescription from your constructor.

Magic Methods (or the basics of deriving from ServiceHostBase)

Considering my history using ASP and COM – you can imagine I’ve always been a fan of interface-based design.  Of course, I’m not a religious zealot of any sort, so I’ve always been comfortable with the idea of abstract base classes as another perfectly valid way to create pluggable, extensible systems.  This post is about one such pluggable system which utilizes abstract base classes – and how that kind of design can just be stupid (not based on the concept of abstract base classes, but just based on dumb design of such a system).

Harry has been bugging me to post about creating classes that derive from ServiceHostBase, which I have done quite a few times in the past year or so.  The next technical post I make after this one will be about the ins and outs of creating a class that derives from ServiceHostBase (specifically to host workflows as WCF Endpoints), but I’ve had this post on my chest for a while and I just had to let it out (although as I am writing the post I am finding that it is a pretty decent introduction to ServiceHostBase – interspersed with slight vitriol). 

One of the things I strive for whenever I design an abstract base class is to make sure that it is as simple as possible to derive from and implement that base class.  One of the great features in Visual Studio (VS) is that via reflection VS can determine what methods *must* be implemented for a particular base class when you build a derived class.

Let’s take a simple example.  Imagine a base class named “Base” which is marked as abstract and which has one method, named “VirtualMethod”. (I know this is pretty simplistic, but I feel it may be the only way to get the WCF team at MS to understand the issue).

 public abstract class Base

{

    public abstract string VirtualMethod(string param);

}

Now imagine you want to derive from that base class and create a class named “Derived” which implements all the abstract methods of this base class.  Here is an example implementation:

public class Derived : Base

{

 

    public override string VirtualMethod(string param)

    {

Console.WriteLine(“This should work: {0}”,param);

        return “Implemented VirtualMethod”;

    }

}

 

A cool feature related to abstract base classes in Visual Studio 2005 is that once you type “public class Derived : Base”, there is smart tag hovering over the Base keyword.  If you select that smart tag with the mouse (or use the Alt-Shift-F10 keyboard shortcut as I like to do), you get a context menu which states that it will “Implement abstract class ‘Base’” for you.

I personally find the Alt-Shift-F10 shortcut to be super useful (it can also be used to implement an interface).  I also think from a *moral* point-of-view that, when I derive from an abstract base class and use Alt-Shift-F10 (or just manually implement *all* the abstract methods), my derived class should *work* in whatever context the base class is supposed to work (which is really the point of abstract base classes right?).  The whole point of marking methods “virtual” is to force the derived class implementor to provide an override of those methods.   Whatever code uses the base class methods should work with a complete, correct implementation of the base class (of course the C# or VB.NET compiler won’t let you complie an incomplete implementation, but it certainly will let you compile an incorrect one).

So what would you think  if you downloaded some library from some company which was based on some OO language which supported abstract base classes, and you did the above steps (implementing all the abstract methods), and then when you plugged your class into the framework for that class, your class didn’t work?  What would you think if it didn’t work *and* the exception you got was a blatant lie about why your nicely implemented dervied class didn’t work?

In fact, WCF provides such a framework (and has such an exception – you’ll just have to keep reading for that) for creating derived classes that can plug into its framework.  ChannelListeners are the channel manager used to provide service Endpoints – that is Endpoints which listen for incoming messages in WCF. The way you load up ChannelListeners in WCF, in the general case,  is to use a class named ServiceHost.  ServiceHost is a useful class that enables you to associate one or more endpoints with a .NET class which implements one or more contracts, and thus hosts one or more contracts on one or more endpoints.  ServiceHost is a really useful class in WCF (fairly essential actually).

In the ASP.NET/WPAS hosting scenarios, you don’t actually get to create your own ServiceHost type – the ServiceHost is created implicitly based on your .svc file (with help from your web.config file for the binding and potential behaviors). To create the ServiceHost, the WCF HttpHandler actually uses a class called ServiceHostFactory, which is a fairly typical generic Factory pattern implementation (handing out ServiceHost objects to requestors).  This features is a really cool extensibility point of WCF, one that can be used for things ranging from controlling Behaviors on your ServiceHost (i.e. not relying on configuration for features like ServiceMetadataBehavior or ServiceDebugBehavior) to replacing the ServiceHost/.NET Type pairing paradigm with some other paradigm.  Steve Maine has some good info on ServiceHost/ServiceHostFactory  here.

So more than a year ago I ventured to write my first custom ServiceHost/ServiceHostFactory pairing.  Here’s my story of that adventure.  Just to make it a little more interesting, and to see how the plumbing is put together in WCF,  I chose to derive from ServiceHostBase and ServiceHostFactoryBase (see Steve’s article above about the choices between deriving from ServiceHost or ServiceHostBase).  So I fired up Visual Studio and created classes that derived from ServiceHostFactoryBase and ServiceHostBase. Using my Alt-Shift-F10 trick – this is what I end up with (after removing the throw clauses that Alt-Shift-F10 place inside of each overriding method):

public class MyServiceHostFactory : ServiceHostFactoryBase

{

public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)

    {

    }

}

 

public class MyServiceHost : ServiceHostBase

{

protected override ServiceDescription CreateDescription(out IDictionary<string,ContractDescription> implementedContracts)

    {

 

    }

}

Of course at this point the code won’t compile, since I haven’t actually provided implementations.  The implemenation of CreateServiceHost is pretty easy – all I need to do there is create an instance of ServiceHostBase.  In the typical case, your ServiceHostBase implementation will have a constructor that takes both of the arguments passed to CreateServiceHost.  The OOB implementation (ServiceHost) uses the first argument to figure out what .NET Type should be used to implement the service Endpoints around, and uses the second argument as list of base Uris that relative Uri’s can hang off of the base addresses (assuming the Endpoint’s transport channel matches the scheme of the base Uri).  So that’s pretty easy.  I’ll store those two parameters in instance fields on the MyServiceHost Type, as we’ll need them later.

The interesting part here is implementing ServiceHostBase::CreateDescription.  CreateDescription is really the key to making your ServiceHostBase implementation work within the WCF infrastructure.  From the look of the return value (ServiceDescription) you might get the mistaken idea that the ServiceDescription is only used by WCF to publish metadata (assuming metadata publishing is enabled on your Service).  This is really pretty far from the truth.  The instance of ServiceDecription returned from your ServiceHost (as well as the out parameter – the generic dictionary of strings and ContractDescriptions) is used for more than just metadata publishing.   It is used by the WCF dispatching layer to route messages received via the Channel layer down to the Service layer (the piece we are trying to implement).  Creating a valid ServiceDescription and returning the list of implemented contracts is essential for making your ServiceHostBase-derived class work.

So let’s assume I create a valid return value and out parameter for CreateDescription (the next post will get into the necessary detail on how exactly to accomplish that).  Once I do so, notice that there are no more virtual method to implement from ServiceHostBase.

Next, I need to get my custom ServiceHostBase derived class loaded by WCF.  In the typical WCF hosting scenario in IIS there is a .svc file.  The .svc links to the “Service Type” – the .NET Type that WCF will use as the basis for the endpoints exposed via the Uri ending in .svc.  Here is a typical example:

<% @ServiceHost Language=C# Debug=”true” Service=”MyService” CodeBehind=”~/App_Code/Service.cs” %>

In the IIS hosting case, the value of the Service attribute from the ServiceHost directive is passes as the parameter to the ServiceHostFactory:CreateServiceHost and to the typical contstructor of ServiceHost. 

To load your own custom ServiceHostFactory all you need to do is add a Factory attribute to the ServiceHost directive.  Like this:

<% @ServiceHost Service=”MyService” Factory=”MyServiceHostFactory” %>

When I do all this and browse to the URL for the Service, I get this lovely exception in the browser:

 

For search engine purposes – the exception/lie is “InitializeRuntime requires that the Description property be initialized” (this part isn’t a lie) – “Either provider a valid ServiceDescription in the CreateDescription method or override the InitializeRuntime method to provide an alternate implementation”. 

So I begin to scratch my head (this is me retelling the story when I first wrote this code oh-so-long-ago).   I generally always assume that when something like this happens, *I’ve* done something wrong.  So I assume my instance of ServiceDescription must be invalid, since I *definitely* implemented the abstract methods from ServiceHostBase.

Here is where things get ugly. I spent an afternoon looking through Reflector  to figure out where I had gone wrong.  I even went to the trouble to delegate to an instance of ServiceHost to get what I knew to be a valid ServiceDescription.  Once I had done that and I was still getting the same exception, I began to think it wasn’t *my* implementation of CreateDescription, but something else.  This of course (about 4 hours later) led me down another Reflector expedition into what ServiceHost was doing that I wasn’t.

Finally after another hour or so – I stumbled upon it.  In the *constructor* of ServiceHost (not ServiceHostBase mind you – but WCF’s OOB implementation of ServiceHostBase) there is a call to InitializeDescription.  InitializeDescription calls another method, which in turn sets the ServiceHostBase.description field (which is *private* BTW so I couldn’t set the value myself) to the  return value of the call to CreateDescription.

So the *only* way to make a ServiceHostBase derived class work inside of this infrastructure is to call a “magic” method inside of your ServiceHostBase constructor.  Failure to call IntializeDescription will lead to complete failure when implementing a derived class of ServiceHostBase.

So now that I have all my pent-up frustration out – what are the key points here?

1)      This is a stupid design – if I implement all the abstract methods of an abstract base class my class should work.  Period.  Unless there is some super compelling reason – this should also be the case with interfaces (see ISerializable for what I would consider to be a valid exception to this rule where you must implement a special constructor for deserialization purposes).

2)      WCF has no such special reason.  In fact, if you look at the implemenation of InitalizeRuntime, all it does is check to see if the value of the Description property is null or not (the Description property is a public read-only property on top of the ServiceHostBase.description field).  If it is null, the stupid exception I showed above is displayed.   Are you telling me ServiceHostBase:InitializeRuntime couldn’t reasonably add one line of code to call CreateDescription after discovering that the property is null.  And *then* throw this exception after that call returns null?  Or the Description property itself could be responsible for calling InitializeDescription if the field was null (this was Harry’s suggestion).

So basically this means the exception I got is a blatant lie.  I did provide a perfectly valid ServiceDescription from my CreateDescription method.  It’s just that ServiceHostBase never calls CreateDescription.  Instead – in my derived class – in my constructor – I have to call another method (InitializeDescription) which then in turn will cause the description field to be properly filled in with the return value of my totally correct/valid ServiceDescription (which I have to rely on since the description filed on ServiceHostBase is private).  Which, mind you,  I had created 6 hours before I discovered the magic InitializeDescription method.

Please folks (at MS and elsewhere) don’t design abstract base classes that rely on magic methods to work correctly.  It makes me testy.  It’s dumb.  What else can be said about it? How about – IT’S DUMB (ahh – I feel  better already).

Alt-Shift-F10 plus actually implementing all the methods correctly should be enough (barring some real circumstance which might make making a magic method necessary – and if that’s the case – document the hell out of it).

 

Another update to CallWorkflow

So I started this sample  out as an off-the-cuff kind of thing and it seems a number of people are using it.  Lenny Fenster from Microsoft found another bug – when the child workflow would terminate with an exception – the CallWorkflowService was sending the exception to the Queue – but the custom Activity listening for the message wasn’t re-throwing the exception.  Its been fixed – so if you are using this sample – you should download the new code. 

Orginal Post.

My samples page.

Workflows are not java – its not write once run everywhere

Having spoken, taught, and consulted about Windows Workflow Foundation for over two years I’ve run into a number of common misconceptions about WF.

One common misconception is that WF is a write-once run-anywhere technology.  Some people feel like if they write a workflow to run inside of a particular host (let’s take SharePoint) – that those workflows will be able to run inside of another host (let’s imagine the next version of BizTalk which has already been announced will run WF workflows natively as its “Orchestration” engine).  The answer is almost *all* cases is a resounding NO (there are a few small exceptions to this rule but they are hardly worth mentioning).

In  WF a Host has to know how to interact with Workflows,  when to create them, when to use an existing Workflow Instance, and most importantly how to communication with a running workflow (this is probably the #1 reason why workflows are not portable among workflow hosts).

So a workflow you build today for SharePoint is intended only to run in SharePoint.  A workflow you build for a custom Host is likely only to run in that custom Host – it is very very unlikely that you’ll be able to take a workflow built for a custom Host and run it in the next version of BizTalk (and I have no inside knowledge of what workflows inside of the next version of BizTalk will look like – although I think you can probably intuit that from what’s in Orcas in terms of the WCF-WF integration).

This blog post came to me when I was doing a talk about the BizTalk Extensions for WF a few weeks ago and someone asked about running the workflows I show inside of another host (like SharePoint or the next version of BizTalk).  This of course was not the first time I’d gotten that question (or questions like it).  But then this idea came to me,  because of course when I said “No”  the followup question was “Well – then why would I want to invest in Workflow if my Workflows I build today won’t likely run in the next version of BizTalk?”.

My answer – and the point of this post – is that the atom of reuse in WF isn’t at the Workflow/Root level.  The atom of reuse in WF is Activities.   Even thought  a Workflow built for SharePoint won’t run in another host – if you build custom activities to encapsulate your programming logic – those Activities will be able to be reused in other Workflows (and likely other Workflow Hosts as well – although there are some exceptions – the most glaring of course is Activities that relate to communication – since that is often the most host specific type of activities).

So any investment you make in WF will pay off in different hosts – both in terms of general knowledge about how WF works – as well as your investment in custom Activities.