Putting SOAP on a rope (part 1)

First, forgive the title of this post.  I couldn't help myself.

Now that we're past that, every now and then I get called on to make SOAP work for customers.  It used to be pretty popular back in the day (2009-ish) but now REST (specifically OData in the NAV/BC world) is all the rage.  I like OData, it's easier to work with for most purposes but even now there are still a few things that SOAP is better at.  One thing that makes SOAP difficult is that it's got a more complex structure and is not easily understood.  With OData, you just set your verb and give it a little JSON and you're up and running.  I recently had to help someone get SOAP working and in the process I debugged the calls with Wireshark and Fiddler and I wanted to document what I got out of that.  It might just help me a few years from now and help someone else sooner.

First the basics.  In the interest of being complete, I'll jot down the first steps just in case anyone else is looking.  To get a list of SOAP endpoints, NAV/BC (henceforth referred to as BC) always publishes a WSDL page at WS/Services.  For example:

From here, you can enter the URL in the ref attribute to get more information about the endpoint.



This will give you all of the information you need to know to access the endpoint.  From here, you can construct a SOAP call.  The first thing you will need is the soapAction.  Depending on your object type (page or codeunit), your actions will be different.  Just search for "soapAction" in the endpoint's metadata and you'll get a list of your options.  This value goes into your http header (I'm using Fiddler here because it's easier when it comes to authentication).


This is a pretty basic call.  Possibly the simplest one you can do.  Almost everything comes from the page metadata we got earlier.

  1. In order to retrieve data, you need to specify a company.  Any special characters should be URL encoded although many utilities will do that for you automatically.
  2. The soapAction goes in the header, as discussed earlier.
  3. An abbreviated version of the soapAction serves as the encapsulating XML element.
  4. The namespace associated with the action can be found at the top of the endpoint metadata.  You can see it in the XML we got earlier.
  5. Finally, the endpoint name serves as the inner XML element.  Within this, we can put additional elements for filters and fields.
The XML around the call-specific names "soap:Envelope" to "soap:Body" is standard SOAP.  You can read about it here if you're so inclined.

This call returns a list of XML formatted records.


Notice that <Key> field... you're going to need that for any update or delete operations. It's the equivalent of the eTag field in OData (although it's a slightly different format).

Now let's try a create.  Even though the XML structure is in the endpoint metadata for this, I find it's easier to cheat and just get it from the ReadMultiple call.  With SOAP, you can do nested inserts (that should be in the most recent version of the BC API as well).  Here is an example that creates a sales order with two lines.



The response looks like this.


Once again, notice the <Key> field.  That's going to be important if you want to update or delete this record.  Also, it's important to note that any API operations behave as though they were done through the front end.  That means that any fields that would normally be populated during data entry are also populated via the API.  Notice how the customer name, address and other related information are filled in?  That was just from sending a couple of fields.  

... and that's all for today. I have to do real work-related work now but more soon.

Comments

Popular posts from this blog

Accessing Dynamics NAV OData with Postman

When you are falsely accused of not having SQL Server Report Builder installed

Error with Zetadocs on Sharepoint Online