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 … 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. A more purist approach is to change this setting in the “Advanced Properties” window to Bare so that the expected SOAP request looks like … 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.” 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 …
This post will focus on the first two. [UPDATE: See Part II here]
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>
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).
<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>
<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.
<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>
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.
<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 …
<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>
//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