SOAP Adapter and BizTalk Web Publishing Wizard - things you need to know.

Posted at: 8/17/2007 at 4:42 AM by saravana

Exposing an Orchestration as Web Service:

This is the safest option you can choose, when you want to expose your business process as an industry standard web service, which can later be consumed by a client (consumer) either using a web service proxy or HTTP post of correctly formatted SOAP message.

There is a very good article in MSDN http://msdn2.microsoft.com/en-US/library/ms935219.aspx explaining how you can expose your orchestration as web service.

Let's assume you have exposed your orchestration as web service, bound the inbound logical port to the auto-generated SOAP receive port (created by the wizard) and enlisted-started the Orchestration. Now, when you look at the activation subscription details for the Orchestration it will look something similar to the one shown below:

 

SNIPPET #1

http://schemas.microsoft.com/BizTalk/2003/system-properties.ReceivePortID == {73684F88-8D5C-4659-9E8F-F1B5E6E9A780} And

http://schemas.microsoft.com/BizTalk/2003/system-properties.MessageType == http://www.digitaldeposit.net/samples/schema/1.0#personRequest And

http://schemas.microsoft.com/BizTalk/2003/system-properties.InboundTransportType != SOAP

Or

http://schemas.microsoft.com/BizTalk/2003/system-properties.ReceivePortID == {73684F88-8D5C-4659-9E8F-F1B5E6E9A780} And

http://schemas.microsoft.com/BizTalk/2003/soap-properties.MethodName == GetPersonDetail

 

When you are receiving the messages via the auto-generated SOAP receive port the properties MethodName and ReceivePortID will get promoted by the SOAP adapter and the orchestration will get the message due to second subscription condition. (MethodName will equate to the Operation name you defined inside the logical port within your Orchestration)

If you inspect the first condition carefully, you'll see "if MessageType property is present then the receive adapter should NOT be SOAP". Also, the auto-generated SOAP ReceiveLocation uses PassThru pipeline, which results in MessageType property not being promoted.

This design introduces two potential problems

 (LISTING #1)

  1.  
    1. Configuring MAP(S) on the auto-generated SOAP receive port will be ignored.
    2. Properties (distinguished and promoted) defined in the schema wont get into the context.

Maps will be ignored on the auto-generated SOAP Receive Port:

Usage of PassThru pipeline inside the auto-generated SOAP ReceiveLocation is bit contrary when you are using Orchestrations and dealing with XML messages. Majority of the time Orchestration subscriptions will be based on MessageType you specified on the Activation receive shape and you'll be using XmlReceive pipeline on your ReceiveLocation, so that MessageType and other property promotions (both distinguished and promoted properties defined in the schema) gets into the context. Since the MessageType property is NOT promoted anywhere in the ReceivePort (mainly due to the usage of PassThru pipeline), any MAP you configure on the ReceivePort will be ignored.

Due to the configuration of PassThru pipeline by default, any properties (both distinguished and promoted) defined in your schema won't get into to the context, which creates potential problem if you want to use content based routing.

We can fix these problems easily, by modifying the auto-generated SOAP ReceiveLocation to use XmlReceive pipeline instead of PassThru. As I mentioned in the beginning "Exposing orchestration as web-service" is the safest option, it doesn't introduce too much head aches. The problem really starts when you just want to expose your schemas as web services as explained in next topic.

Exposing schemas as web services:

The MSDN article http://msdn2.microsoft.com/en-US/library/ms935219.aspx got clear explanation of exposing schemas as web services.

After exposing your schemas as web-services using "BizTalk Web Publishing" wizard, you can create an Orchestration to consume the messages published by the auto-generated SOAP ReceivePort. The important thing to note here is the name of the "Operation" you define inside the logical port, make sure it matches the WebMethod name you have specified while generating the web-service. As shown in the below figure:

image

When you bind the logical orchestration port to physical auto-generated SOAP ReceivePort and start (enlist) the orchestration, the subscription for the orchestration will look identical to the one shown in SNIPPET #1 (earlier).

We'll hit the same problems (explained in detail earlier) outlined under "Exposing an Orchestration as web service"

  1. Map won't get applied
  2. Properties (distinguished and promoted) won't get into context

Due to the fact, the auto-generated SOAP ReceiveLocation uses PassThru pipeline by default.

If you modify the auto-generated SOAP ReceiveLocation to use XmlReceive pipeline instead of PassThru (hoping its going to fix all the problems, as we did with "Exposing an Orchestration as web service") the run-time will generate the following exception when it receives the message:

There was a failure executing the receive pipeline: "Microsoft.BizTalk.DefaultPipelines.XMLReceive, Microsoft.BizTalk.DefaultPipelines, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Source: "XML disassembler" Receive Port: "WebPort_SK.ws.viaSchemas.1_0/WebService1" URI: "/SK.ws.viaSchemas.1_0/WebService1.asmx" Reason: The type SK.Schemas.Person_1_0 is not a valid part type for a message. This invalid type may be from a property schema.

The exception is mainly raised because SOAP adapter puts the wrong DocumentSpecName property in the message context and hands over the message to the pipeline. PassThru pipeline (DEFAULT Configuration on auto-generated SOAP ReceiveLocation) doesn't do any processing, so whatever value present in the property DocumentSpecName is ignored. On the other hand if you configure XmlReceive pipeline which uses XmlDisassembler, it will utilizes the "DocumentSpecName" property to resolve the schema.

Behavior of XmlDissambler inside the XmlReceive pipeline:

Having the DocumentSpecName property in the context, will force XmlDissambler pipeline component to use it, to locate your schema. If DocumentSpecName is NOT present then XmlDissambler pipeline component will go through dynamic schema resolution mechanisms to get the correct schema. Since DocumentSpecName is present with wrong value, XmlDissambler throws the exception and it clearly states "This invalid type may be from a property schema".

There are few ways you can get away from this problem

Solution #1: Use PassThru pipeline and Orchestration (DEFAULT config):

If you don't have any inbound maps to be applied on the port level and you are not dependant on promoted properties (distinguished and promoted) defined in the schema outside the orchestration, then you can use PassThru pipeline (configured by default by auto-generated SOAP receive location). The Orchestration gets the message by other subscription conditions (ex: MethodName) without the need for MessageType.

  1. You can get away from the MAP problem by applying it inside your orchestration, and
  2. You automatically get away from property promotion problem. Because when the orchestration receives a message the IBaseMessage (from adapter/pipeline) is converted into a XLANG message, which results in the process of new message construction (since messages are immutable in BizTalk server). During this step all the distinguished and promoted properties gets into the context. [This is my own prediction of how distinguished fields and promoted properties gets into the context automatically within Orchestration even though we used PassThru pipeline, I couldn't find clear documentation explaining it] and available within the Orchestration.

Solution #2: Modify the generated .asmx.cs code. Passing null instead of bodyTypeAssemblyQualifiedName:

By passing the value “null” instead of bodyTypeAssemblyQualifiedName both the problems defined in Listing #1 can be solved

//Original Code

string bodyTypeAssemblyQualifiedName = "SK.Schemas.Person_2_0, SK.Schemas, Version=1.0.0.0, Culture=neutral, PublicKeyTok" +

"en=c2b0cafd9314ef3e";

// BizTalk invocation

object[] invokeResults = this.Invoke("GetPersonDetail", invokeParams, inParamInfos, outParamInfos, 0, bodyTypeAssemblyQualifiedName, inHeaders, inoutHeaders, out inoutHeaderResponses, out outHeaderResponses, null, null, null, out unknownHeaderResponses, false, false);

//Modified Code

// BizTalk invocation

object[] invokeResults = this.Invoke("GetPersonDetail", invokeParams, inParamInfos, outParamInfos, 0, null, inHeaders, inoutHeaders, out inoutHeaderResponses, out outHeaderResponses, null, null, null, out unknownHeaderResponses, false, false);

If the value null is passed instead of bodyTypeAssemblyQualifiedName, SOAP adapter won't add the DocumentSpecName property to the context. Now, when we configure our auto-generated SOAP ReceiveLocation to use XmlReceive pipeline, the XmlDisassembler component inside XmlReceive will go through the process of automatic dynamic schema resolution mechanism, pick up the correct schema and promotes all the required properties (distinguished and promoted) defined in the schema and it also promotes the MessageType property.

Solution #3: Modify the generated .asmx.cs code. Change bodyTypeAssemblyQualifiedName property to include the schema root node.

We are going to follow a similar approach here, but instead of passing null”for bodyTypeAssemblyQualifiedName, we are actually going to pass the correct value.

//Original Code

string bodyTypeAssemblyQualifiedName = "SK.Schemas.Person_2_0, SK.Schemas, Version=1.0.0.0, Culture=neutral, PublicKeyTok" +

"en=c2b0cafd9314ef3e";

//Modified Code

string bodyTypeAssemblyQualifiedName = "SK.Schemas.Person_2_0+personRequest, SK.Schemas, Version=1.0.0.0, Culture=neutral, PublicKeyTok" +

"en=c2b0cafd9314ef3e";

The only difference is we are appending the schema root element name to the schema Type Name. You can see the correct DocumentSpecName name by

  1. Add a Receive Pipeline to your project (or to a dummy project),
  2. Drag-Drop a XmlDisassembler component
  3. Select XmlDisassembler and in the properties window, click on button next to the "Document Schemas" property. You’ll see "Schema collection property editor" window as shown in the below figure, which clearly shows the expected "DocumentSpecName" name.

image

When you expose your Orchestration as web service the auto generated code will look similar to our modified code.

NOTE: You need to be careful with Solution #2 and #3, because regenerating the web-service code will result in losing the manual changes you performed.

You can download the ZIP file containing all the sample projects I used for this research.

Nandri!

Saravana

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: | | |  Categories: BizTalk General
Actions: Email this article Email | Kick it! | DZone it! | Save to del.icio.us | Technorati Links
Post Information: Permanent LinkPermalink | CommentsComments(13) | Comments RSS

Comments

Friday, August 24, 2007 4:27 PM
zoeh
This posting was a lifesaver. I am exposing some schemas as web services. I was not able to use PassThruPipeline because my orchestration subscription relied on a promoted field - so knowing that the fields were promoted later in the orchestration didn't help me. But I successfully implemented your Solution #2, modifying the generated web service code to send null for DocuemntSpecName and configuring the receive port for XMLReceive. It works great - a huge relief after days of fruitless debug. Thanks!
Friday, September 07, 2007 7:32 PM
Anonymous
Anonymous
Sarvana, this is great post..thanks !!!!

I tried the solution#2 (for exposing schema as webservice) and used xmlRcvPipeline and xmlTransitpipeline.

I got an error when sending the response back from orchestration.

"This Assembler cannot retrieve a document specification using this type: "http://TestDime.TestResFile#ResponseWS"."

Sending request to orchestration works fine but the prob is when orchestration sends response back.
Wednesday, January 23, 2008 9:49 AM
Richard Hallgren
Excellent post. Thanks!
Tuesday, February 12, 2008 11:07 AM
U3
U3
Sarvana great post , but I need to know when to expose the Schemas as a web service and when to expose the orchesteration as a web service !!! could you please give us an example the need of each one !!!

Another Ques : Do you think that the "Professional BizTalk Server 2006 " will help to pass the MCTS ?
Wednesday, April 30, 2008 4:35 PM
Anonymous
Anonymous
Hi,

Thanks for the post. I've one query, it would be great if you can help me in it. I have an orch which is exposed as webservice and accepts a msg say Msg1. How when the client consumes it, the operation exposed will have input param of Msg1. What i want to achieve is exposed Msg1 as parameter but it receive port transform it to Msg2 and use that Msg2 in my orch which is exposed as webservice. Can i use map in receive port of webservice and transform it to Msg2. But still my receive shape will have Msg1 as msgtype. How can i get Msg2 in my orch.
Wednesday, April 30, 2008 4:38 PM
Saravana Kumar
Why can't you just receive MSG1 into orchestration and then do a transformation inside the Orchestration to MSG2?
Wednesday, April 30, 2008 4:55 PM
Anonymous
Anonymous
Thanks Saravana for the quick response. I can do the transform of MSG1 to MSG2 in orchestration. But my only concern is i want to avoid doing the transformation in orchestration and see if i can use the same thing in web receive port. I have done transformation in pipeline but the endpoints are MSMQ/FILE... but how can i do for webservice. If there is no alternative i have to do it in orch, but just want to avoid it.

Any ideas...

-Thanks
Tuesday, May 27, 2008 2:13 PM
Vijay Modi
Really very nice blog.

Vijay Modi
http://vijaymodi.wordpress.com/
Friday, September 05, 2008 2:52 AM
Jody Petroni au
Jody Petroni
Great Post, I have implemented solution 3 after exposing my schema as a web service. However when I sent a single message to the web service the subscribing orchestration receives 2 messages (a copy is also received). whats going on - can you help

Thanks
Friday, September 05, 2008 10:54 AM
saravana
When you say, "you receive 2 messages to the orchestration", are you getting 2 messages published to the message box by the SOAP adapter (Receive pipeline)?
Thursday, September 11, 2008 7:42 AM
Shell my
Shell
Great info on publishing schema, we appreciate it alot.

Thanks again.
Monday, November 10, 2008 3:52 PM
Mike Mates us
Mike Mates
I spent a lot of time researching the issue with the bodyTypeAssemblyQualifiedName when generating a web service based on a schema. Thank you for posting this information.
Wednesday, November 12, 2008 12:53 PM
pingback
Pingback from richardhallgren.com

  Handle the "bodyTypeAssemblyQualifiedName" SOAP Adapter bug in MSBuild as a RegEx ninja by .RICHARD

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading