Tallan's Technology Blog

Tallan's Top Technologists Share Their Thoughts on Today's Technology Challenges

BizTalk Orchestration handling webHttp REST GET requests

Dan Field

Consider the following scenario: you have a tested BizTalk Orchestration that effectively takes a parameter (say, a message identifier) and returns the message from a database for consumption.  Now you want to expose a WCF Service for consumers of that orchestration to use.  While you could design a SOAP based interface, a simple RESTful interface that accepts a GET verb would do the trick more elegantly (and in a way that would be much easier for clients to work with). It also may meet a requirement when you already have clients that expect a RESTful interface for data retrieval.

There’s plenty out there on handling REST GET requests using BizTalk Orchestrations as a consumer:

Unfortunately, the same can’t quite be said about handling REST GET requests as a provider; there are resources:

…but this side of the equation tends to focus on POST and PUT verbs where there will be a message body.  The GET verb is not going to provide a message body (only parameters).

Using the above two articles should be enough to get a WCF webHttp service deployed and ready, and I’m not going to rehash every step of that process (MSDN and Richard Seroter provide excellent instructions including pictures and diagrams).

However, when you get to the configuration of the receive location, there is some additional work needed to properly handle GET requests:

In the Transport Type Configuration of the receive location, you’ll want the following HTTP Method and URL Mapping:

<BtsHttpUrlMapping>
  <Operation Name='OpName' Method='GET' Url='/OpName?param1={param1}&amp;id={id}' />
</BtsHttpUrlMapping>

Then, you can modify your variable mapping like so:

variable mapping

You’ll notice there’s a property namespace, which means you’ll need a property schema.  Create your property schema with those properties, set the Property Schema Base to MessageContextPropertyBase.

I then set up my orchestration to receive a System.Xml.XmlDocument, and had the receive shape filter on the BTS.Operation == “OpName” && BTS.ReceivePortName == “ReceivePortName”.  However, when I tried to read these properties from the context of the message it failed.  This is because the context properties are not automatically promoted by the adapter.  Looking at the pipeline, it made sense – by default the pipeline was a PassThruTransmit, which does no promotion.

I started working on a custom pipeline component to solve this problem, but then I realized I could still use the XML Disassembler if I set the “Allow Unrecognized Document” property to true:

xml assembler props

Now, the assembler will let a message with an empty body (like from a GET request) pass through, but still do property promotion.

The last piece of this process is to add logic in your orchestration to test for these properties before trying to read them, like so:

strId = "";
if (SchemaProjectNameSpace.Id exists msg_Request)
{
  strId = msg_Request(SchemaProjectNameSpace.Id);
}

Viola!  I can now have this receive location process RESTful GET requests (that will always have empty bodies) and my orchestration can use the variables passed in like parameters.  I can even use the same pipeline and receive location to deal with other HTTP verbs by modifying the BtsHttpUrlMapping!

No comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>