Saturday, April 12, 2008

Fixing BizTalk's WCF Message Contract Mix-Up, Part 1

WCF developers often write OperationContracts that receive and return DataContracts, like so:

[ServiceContract(Namespace = "urn://MyCompany.Purchasing.1_0_0.com")]
public interface IPurchasing
{
[OperationContract]
OrderStatus PlaceOrder(PurchaseOrder po);
}

Suppose you implement this service in BizTalk using an orchestration. First you use a tool such as XSD.exe or SVCUtil.exe to generate XSD schemas for the PurchaseOrder and OrderStatus data contracts. You add these schemas to a BizTalk project, write an orchestration that receives a PurchaseOrder and returns an OrderStatus, and deploy the schemas and orchestration to BizTalk. Then you bind the orchestration’s receive-send port to a two-way receive location using a WCF adapter and the XmlReceive pipeline.

Your may be shocked to find that when a WCF client sends a message to BizTalk, an error occurs in the receive pipeline: “Finding the document specification by message type "urn://MyCompany.Purchasing.1_0_0.com #PlaceOrder" failed. Verify the schema deployed properly.”

It turns out that the SOAP body that your WCF client sent to BizTalk doesn’t begin with the PurchaseOrder data contract. Instead it begins with a message contract that the WCF client generated behind the scenes. The name of this message contract is “PlaceOrder”, i.e. the name of the operation. Inside that message contract is an element named “po” which contains the data exposed by the data contract. Thus although BizTalk expects to receive a message type named PurchaseOrder, there is no element named PurchaseOrder anywhere in the SOAP body!

There's a symmetrical problem at the other end, when the two-way receive port tries to return an OrderStatus to the caller. If the service were hosted in a .NET application, WCF would automatically generate a message contract element named PlaceOrderResponse and wrap it around the OrderStatus. But BizTalk by default will do no such thing.

I call this impedence mismatch the "BizTalk WCF Message Contract Mix-Up". But so much for lingo, how do you fix it? I can suggest three solutions, each with its pros and cons. I’ll discuss them in the next post.

No comments: