How to use XMLPorts in Web Services (1)

15 Jan

About two weeks ago I posted an explanation why Pages are not always sufficient for use with web services. Using XMLPorts in web services offer powerful possibilities that are not available with Pages.

In this post I will explain the basics of using XMLPorts in a web service. Upcoming posts will also cover more advanced features.

Here is a simple XMLPort that we want to use in a web service:

If we use this XMLPort in a web service without further configuring it, we will get the next error message:

The UseDefaultNamespace and DefaultNamespace need to be edited before we can use the XMLPort in a web service:

To use this XMLPort in a web service we need to create a Codeunit with a function that uses this XMLPort as a parameter.

Next we publish this Codeunit as a web service, using Form 810:

No we can check the WSDL using Internet Explorer.

Let’s switch over to Visual Studio. We are creating a web application that displays the exported item list.

First we need to add a Web Reference. (When using Visual Studio 2010 you may need to first choose ‘Add Service Reference’ à ‘Advanced’ à ‘Add Web Reference’).

Next, we add a simple GridView to the web form and let it automatically generate the columns.

And here is the code to consume the webservice and bind the result to the GridView.

[codesyntax lang=”csharp”]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using XMLPortWSDemo.ExportDataWebService;
namespace XMLPortWSDemo
{
  public partial class _Default : System.Web.UI.Page
  {
    protected void Page_Load(object sender, EventArgs e)
    {
      ExportData service = new ExportData();
      service.UseDefaultCredentials = true;
      service.Url = "http://localhost:7047/DynamicsNAV/WS/CRONUS%20International%20Ltd/Codeunit/ExportData";
      NAVItems navItems = new NAVItems();
      service.ExportItems(ref navItems);
      GridView1.DataSource = navItems.NAVItem;
      GridView1.DataBind();
    }
  }
}

[/codesyntax]

That’s all folks! This little application produces this output:

Did you notice that the Codeunit has no code at all? Isn’t that beautiful?

In next posts I will try to:

  • Explain why NAV automatically exports the data without any line of C/AL code and how to influence this behavior.
  • Show how to filter the data within NAV before exporting it.
  • Implement paging.

30 thoughts on “How to use XMLPorts in Web Services (1)

  1. Thanks for this insight -very useful.

    Is it possible to extend this feature by passing parameters into the XMLPort from the c# calling code to control how the XMLport runs. E.g. passing in a USERID so the XMLPort can return a list of that users customers rather than the whole unfiltered list?

  2. Yes Chris, that is definitely possible. I will cover that in part 2 or 3.
    Sorry for my late reply, I didn’t notice your comment.

  3. Hi AJ,

    You write “UseDefaultNamespace and DefaultNamespace need to be edited before we can use the XMLPort in a web service”.
    Do you have some more background on why this is needed?

    b rg
    Luc

    • Hi Luc,

      Well, at least the UseDefaultNamespace must be set to Yes. If you don’t set this property, the wsdl will get show an error: “XmlPort , is not configured to use namespace. Please set UseDefaultNamespace property to Yes”. Obviously it is mandatory to specify a namespace in a wsdl.

      That still doesn’t answer the question why it is mandatory…

      The WSDL as an XML document. It’s root element is from the http://schemas.xmlsoap.org/wsdl/ namespace. All elements in an XML document that don’t have their own target namespace, have the default namespace from the parent element. When you use an XMLPort in a NAV web service, you introduce a new type in the XML document. To uniquely identify and to group these types, they must be marked with an attribute targetNamespace.

      For more information about this topic, see the next sites:
      http://msdn.microsoft.com/en-us/library/ms996486.aspx
      http://www.liquid-technologies.com/Tutorials/XmlSchemas/XsdTutorial_04.aspx

      Regards,
      Arend-Jan

  4. A small error in your text. You write when adding a Web Reference: “When using Visual Studio 2008 you may need to first choose ‘Add Service Reference’ > ‘Advanced’ > ‘Add Web Reference’”. I guess this should be VS 2010.

  5. Great Post! Instead of loading a DataGrid I would like to load the results into an XMLDocument so I can then read through it and do what I need.

    So intead of:
    GridView1.DataSource = navItems.NAVItem;

    I would like to load navItems.NAVItem into an XMLDocument varaible.

  6. Thanks for the article. You mentioned that
    “The UseDefaultNamespace and DefaultNamespace need to be edited before we can use the XMLPort in a web service:”

    Where may I find the XMLPort properties in NAV 2009 ?

    Regards

    • Hi John,

      As this is quite an old threat, I just read your question from a couple of weeks ago.
      You have not been creating many objects in NAV, have you?
      Go to the last empty line of the XML port (or any other object) and use the property button or Shift+F4 to go the properties of that object.

  7. Thanks for this very informative post. 2 questions:
    1) We want to use this method in Drupal (PHP) to receive NAV data, one direction only: from NAV to Drupal. Do you know how to call NAV from Drupal, or do you know the equivalent call for the Visual Studio Web Reference, in Drupal ? We have no Drupal experience, and our external web designer uses Drupal but does not know how to call NAV web service.
    2) If I understand well, there is no way to receive NAV data with a direct https call? A direct call only retrieves wdsl schema, no data.

    Regards,
    William

    • Unfortunately I don’t have any experience with Drupal.

      But regarding receiving NAV data with a direct https call I can tell you that is possible. You can use OData web services for that, assuming that you are using Dynamics NAV 2013 or higher.

  8. I am getting error when I try to expose the codeunit with the XML parameter. But when i remove the XML parameter from codeunit , the codeunit runs well.
    What could be the problem?




    a:System.ArgumentNullException
    Value cannot be null. Parameter name: initialTarget

    Value cannot be null. Parameter name: initialTarget

  9. Little information, but I’m guessing…

    The ArgumentNullException doesn’t occur when you publish the Codeunit, it occurs when you call it. Is that correct?

    Assuming that is correct, then I would think:
    * You didn’t pass in a parameter value
    * The parameter value doesn’t match the structure as expected

  10. Hi everyone, I am trying to apply this concept and I face the following problems
    1) I cannot not show a BigText CAL datatype on the web service, its not coming up on the GridView columns
    2) some of my text is multiline, on the GridView its coming as 1 single line.
    may somebody help me on how I can sort this out

    • BigText isn’t a datatype on fields. So you have used a global variable to include it in the dataset, right? Are you sure the records in the resulting dataset do have data in the field? Maybe it’s an idea to inspect the data first with Postman for example, instead of using the GridView for that.

      I’m afraid the linefeed character used in NAV isn’t the same as you need in an ASP .Net grid.

      • thank you for your response, I figured the gridview may not be the best tool tool for my tests so I now inspect the data manually (I am exposing Nav data only and another guy is consuming it).

        However I have run into another problem with regards to multiline text. when I run my xml port directly from NAV, the xml document is not showing multiline text so I figured the same happens when I try to consume it. may you help on what the problem may be and how to resolve it

  11. Hi,
    I’m trying to import file through visual studio. I’m using xmlport and codeunit through webservice. Is it posible to import file from visual studio to nav using webservices.

    • I have really no idea, to be honest. And I can’t try out because I’m fully into AL and don’t work with C/SIDE anymore.

  12. Hi,

    Excellent post. I have been using web services and xmlport since 2016. One thing happens : each time I change (add / remove element) xmlport defitinion the type in Visual Studio is changed and it is annoying. From your example it would be

    NAVItems1 navItems = new NAVItems1();
    and next time
    NAVItems2 navItems = new NAVItems2();

    Any idea, why, did I set something wrong?

    • It might be that Visual Studio detects a change and then automatically updates the references. But I’ve not experienced this myself, so I can’t tell you for sure.

      • Thank you for reply. Exactly, Visual Studio shuffles xmlport definitions on reference update (if there were changes on xmlports design / definition). Was hoping that there is some magic setting in xmlport to prevent that. Anyway, thanks again

  13. Should this be testable in PostMan? I get “Parameter exportItems in method ExportItems in service ExportTest is null!”

  14. Thank you for this, it helped a lot and the CU and XML port is not created, but calling the webservice (SOAP) it returns “Decimal is missing or invalid in the expression.” but my XML port not based on a table so it’s text only, I return it as a second parameter parsing all data with format, any idea why it would expect a decimal?

Leave a Reply to ajkCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.