SOAP Adapter and BizTalk Web Publishing Wizard

|  Posted: August 17, 2007  |  Categories: BizTalk Server General Technical

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. 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:

biztalk web service

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.

schema collection property editor

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.

Author: Saravana Kumar

Saravana Kumar is the Founder and CTO of BizTalk360, an enterprise software that acts as an all-in-one solution for better administration, operation, support and monitoring of Microsoft BizTalk Server environments.

  • Raj Jayarai

    Great article Saravana, I have inherited a BizTalk app with a SOAP adapter and tried using solution #3, but have run into issues with XML Disassemble stage in the pipeline. Appreciate if you could let me know the location of the sample project.

  • Jon

    Good morning,

    where I can dowload the examples. A greeting and thank you very much.

  • Jon

    Good afternoon,

    I wanted to ask you about Biztalk. I have to create a SOAP receive port. The web service has several web methods. Depending on which method is invoked, I will have to call another web service or not. I have not much knowledge about BizTalk. Can you help me please.

One Platform Operations, Monitoring and Analytics Software
BizTalk360

microsoft biztalk

Learn more

Over 500 customers across 30+ countries depend on BizTalk360

ServiceBus360

Azure service bus

Learn more

Start managing your Azure Service Bus namespaces in minutes

One Platform - Operations, Monitoring and Analytics Software
BizTalk360

microsoft biztalk

Learn more

Over 500 customers across 30+ countries depend on BizTalk360

One Platform - Operations, Monitoring and Analytics Software
ServiceBus360

Azure service bus

Learn more

Start managing your Azure Service Bus namespaces in minutes

Back to Top