Handling a Web-Service Null Response: The ‘CreateBodyPart’ Pipeline Component

Originally posted by Nick Heppleston at: http://www.modhul.com/2009/03/11/handling-a-web-service-null-response-the-createbodypart-pipeline-component/

Today I’m releasing a small component that addresses an interesting problem I’ve never come across before – a null response from a web-service.

The web-service in question is provided by a third-party and unfortunately cannot be changed. Their WSDL defines the root response element with a maxOccurs=1 and a minOccurs=0, which allows for a null response to be returned. So instead of a result element with no child nodes as I would expect (below in green):

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="..." xmlns:xsd="..." xmlns:xsi="...">
    <PendingSalesOrdersResult xmlns="..." />

we’re receiving an empty response (note the lack of an element between the <GetPendingSalesOrdersResponse> element):

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="..." xmlns:xsd="..." xmlns:xsi="...">

When the SOAP adapter receives this null response, it creates a message but neglects to create a body part – I presume this is because there is nothing to create it from. As a result, the message fails in both an XmlReceive and PassThruReceive pipeline; when using the PassThruReceive pipeline, the XLANG/s engine throws the following error when it tries to read the body part:

The XLANG/s message has no part at index ‘0’.  The total number of parts found in the message is ‘0’. If you expect a multipart message, check that the pipeline supports multipart messages such as MIME.

To address this problem, I’ve created a very simple receive pipeline component which lives on the receive side of the web-service solicit-response port and interrogates a message to determine whether it has a message body. If a message body is not present, it creates one based on the component properties (which mimic the expected – valid – response from the web-service) allowing the response message to be passed into the Message Box without issue. It a message body is present, it passes the message through unchanged.

The CreateBodyPart Pipeline Component

The component lives in the Decode stage of the receive pipeline and simply detects for the presence of a message body. If the body part is null, a new message part is created using the component properties BodyPartName and BodyPartContent and assigned as the body part of the message, before being passed onto the next stage of the pipeline. The BodyPartName and BodyPartContent properties specify the name of the body part and the Xml you want the part to contain – given that the content of the message is likely to be small-ish (i.e. <PendingSalesOrdersResult xmlns=”…” /> in the example above).

There are a few enhancements that I can envisage for this component already, including the ability to specify whether the part should be a body part – you might just want to create extra parts on the fly, not just a body part; and also the ability to specify the encoding and character set being used with your part content. However, I’ll leave these enhancements for a later day.

You can find binaries and source for the component at Codeplex: http://btscreatebdyprtcomp.codeplex.com/

As a final note, my client is currently running BizTalk 2006 (not R2) and we are running on the out-of-box SOAP adapter. Does anyone know whether this issue is a problem in the WCF-SOAP adapter or the WSE adapter?

Reblog this post [with Zemanta]

10 thoughts on “Handling a Web-Service Null Response: The ‘CreateBodyPart’ Pipeline Component

  1. What do I have to put in on the 2 preoperties? In your example, would I use “” or “GetPendingSalesOrdersResponse” as the body part name and is “” what would go into the content or should the “” tags be stripped out?

  2. Quinton,
    The BodyPartName property would contain the name of the body part (i.e. as you would see it in the BizTalk Admin -> Message Properties dialog, or when you have a soap response message – GetPendingSalesOrderResponse.PendingSalesOrdersResult – where ‘GetPendingSalesOrderResponse’ is the response message name and ‘PendingSalesOrdersResult’ is the message part name, ‘PendingSalesOrdersResult’ would be the value of the BodyPartName property).

    The BodyPartContent property would contain the Xml the part should contain. In the example above, I wanted the pody-part to contain the xml ”, so I put that into the property as is without any quotations (but keeping the quotes for the xmlns!).

    Hope this helps, but it does raise the fact that I need to do a new post explaining how to use the component.

    Cheers, Nick.

  3. Thanks a lot Nick! I will be using the component today and see if I can get it to work, already added the pipeline etc…

    Perhaps you should create a tutorial in the next post? Will let you know if it works ON 2006 R2 as thats what I am trying it on.

    • Quinton,
      Thanks for the feedback, there is a follow-up post in the pipeline which covers how to use the component – watch this space.

      Let me know how you get on with the component – any suggestions for enhancements please drop me a line (either as a comment to this post or over e-mail – see the Contact page).

      Cheers, Nick.

  4. Very interesting Nick.

    I’ve bumped into this relatively recently as well and was trying to figure out a way to handle this exception in the process, as I’ve described on the post: http://www.sabratech.co.uk/blogs/yossidahan/2008/08/zombies.html

    Unfortunatley, it seems that there is not way to handle this error inside the process, something that I would consider a bug, but the product group are ademant that it is not, and all my attempts to convince them otherwise failed….

    This only makes your component all the more useful!

    • Yossi,
      Thanks for the comment and let me know how you get on with it if you get chance to use it.

      As for talking to the Product Team about this possible bug, I’m obviously not as privelledged as you!! ;-)

  5. Hy Nick,

    did you write the mentioned follow up on how to use the pipeline component? Did you initially encouter the null body part problem on BTS2006 or BTS2006 R2?
    I´m asking this because i am currently migrating a process from BTS2006 to BTS2010 and the exception is only thrown on BTS2010, 2006 seems to be fine.


  6. hey Tammo, we experienced this on a BizTalk 2006 R2 environment (back on a project I was working on in 2008!).


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s