Advanced BizTalk 2006 Web Services, Part I

I've recently had the opportunity to build some advanced web services with BizTalk Server 2006, and wanted to show 4 interesting use cases over this 2 part blog post.

Over these 2 posts, I will demonstrate and investigate the following topics ...

  • Using the "bare" and "wrapped" settings during web service generation
  • Creating multi-parameter web services via BizTalk
  • How the "one way" flag affects the web service
  • Decoupling the BizTalk web service from a particular assembly

This post will focus on the first two. [UPDATE: See Part II here]

I would venture to say that virtually no one has clicked the "Advanced" button in the Web Services Publishing Wizard and changed any of those values. The first option in that "Advanced Properties" window is SOAP Parameter Style of which your options are Default, Bare or Wrapped.

This isn't anything BizTalk specific, but a way to design the WSDL. By default, when you build your web service from code, your SOAP request bears the name of the function call as a wrapper element. For instance, if I have a method called "PostOrder" on my web service, then my SOAP request expects an input such as ...

 <soap:Body>
     <PostNewOrder xmlns="http://tempuri.org/"> 
      <InsertOrder xmlns="http://Microsoft.Demo.Blog.AdvancedServices.InsertOrder_XML">
        <OrderID xmlns="">string</OrderID>
        <CustomerName xmlns="">string</CustomerName>
        <ItemID xmlns="">string</ItemID>
        <Quantity xmlns="">string</Quantity>
        <Status xmlns="">string</Status>
      </InsertOrder>
     </PostNewOrder> 
  </soap:Body>

Plus, if this is request/response, you end up with a response node automatically generated (method name + "response"). This is the default behavior, and thus not terrible, but arguably a bit lame (read more here and here).

A more purist approach is to change this setting in the "Advanced Properties" window to Bare so that the expected SOAP request looks like ...

 <soap:Body>
    <InsertOrder xmlns="http://Microsoft.Demo.Blog.AdvancedServices.InsertOrder_XML">
      <OrderID xmlns="">string</OrderID>
      <CustomerName xmlns="">string</CustomerName>
      <ItemID xmlns="">string</ItemID>
      <Quantity xmlns="">string</Quantity>
      <Status xmlns="">string</Status>
    </InsertOrder>
  </soap:Body>

Since BizTalk always deals in "messages", this is almost always a very solid and clean approach. Why is the default value set to be Wrapped? Because it's the safest way to go. Why? If I have *multiple* parameters, and I do a Bare service, I end up with an invalid WSDL. Let's see that next.

So my next point is how to do multi-parameter web services generated by BizTalk. When using the Web Services Publishing Wizard and doing a "generate service from schema" you can only create a web service method accepting a single "part."


Not so with orchestration. Within a BizTalk orchestration, I can easily build multi-part messages. These are messages containing one or more documents. A multi-part message can only have one "Body" but any number of other additional parts. So, I've built a multi-part message which has a "body" node and "attachment" node.

Now, I go ahead and make the "Receive" shape accept that multi-part message, and connect it to a "public" receive port. Build and deploy. Now, I walk through the Web Services Publishing Wizard and build a web service from the orchestration. I first kept the default SOAP Parameter Style (which is Wrapped) when publishing, and ended up with a WSDL looking like this ...

 <soap:Body>
     <PostNewCustomer xmlns="http://tempuri.org/"> 
       <InsertContact xmlns="http://Microsoft.Demo.Blog.AdvancedServices.InsertContact_XML"> 
        <Name xmlns="">string</Name>
        <Address xmlns="">string</Address>
       </InsertContact> 
       <InsertContactAttachment xmlns="http://Microsoft.Demo.Blog.AdvancedServices.InsertContact_XML"> 
        <Payload xmlns="">string</Payload>
       </InsertContactAttachment> 
     </PostNewCustomer> 
 </soap:Body>

See that? I have *two* parameters for my web service, both of different message types. When I call this from code, it looks like ...

//svc is the web service; "contact" and "attachment" are both messages
svc.PostNewCustomer(contact, attachment);

So everything looks good. I now have a multi-parameter web service generated from BizTalk. Lots of use cases for this. Let's circle back, though. What happens if I do this web service with the SOAP Parameter Style set to Bare? As I mentioned above, this leads to invalid WSDL. Why? Because you've removed the wrapped, and provided two different root nodes in the body. When I build my service this way and view the service, I get this ...


When I click the web method name, I see this SOAP request ...

 <soap:Body>
     <InsertContact xmlns="http://Microsoft.Demo.Blog.AdvancedServices.InsertContact_XML"> 
      <Name xmlns="">string</Name>
      <Address xmlns="">string</Address>
     </InsertContact> 
     <InsertContactAttachment xmlns="http://Microsoft.Demo.Blog.AdvancedServices.InsertContact_XML"> 
      <Payload xmlns="">string</Payload>
     </InsertContactAttachment> 
  </soap:Body>

Not good. This would be the same if you used Bare on a web method that took in two native types (e.g. pair of integer values). If you aren't passing in a single object (native type, message, whatever), then you need to wrap it.

Conclusion
So, what have we figured out so far? The SOAP Parameter Style is a nice way to gain ownership over the WSDL and control exactly what's in the <soap:Body> node. We also saw how you can very easily build multi-parameter web services in BizTalk using orchestrations and multi-part messages. However, be careful when mixing the two, since a multi-parameter web service must be wrapped up.

Part II coming up ...

[UPDATE: See Part II here]

Technorati Tags: BizTalk, Web Services