Using Web Services to Access Microsoft Dynamics NAV 5.0

Published 15 April 08 09:32 AM | navblog 

Introduction

Dynamics NAV 2009 contains a new subsystem for dealing with Web Services. This feature has been well received by partners and customers alike. Partners have expressed interest in having web services available for earlier versions of Dynamics NAV. This feedback resulted in a technology talk at Directions2007 in Florida, where the topic was what could be done to day. The conclusion of the talk was that everything we where intending to deliver was already possible today, yes some code is needed but strictly from function/feature perspective all of it is possible, and it is not even all that ugly. Dynamics NAV 2009 will provide out-of-the-box programmatic web service access to the application and will therefore remove the need for this additional technology plumbing described here.

I have to say that the response to my talk has been tremendous. After the response to my talk on Web Services in NAV 5.0 and previous versions I decided to write this blog post and make the source files available.

This post is about how to bridge the gap between the need for web services now and the current platform, it will help you understand how you can provide Web Services directly from Dynamics NAV today, in a “simple” and flexible way, already today.

To work with the samples in this post you will need: Visual Studio 2005, Dynamics NAV 5.0 and .Net 3.0 installed on your system. This sample should work on Dynamics NAV 4.0 to but has not been tested on that version.

Architecture

The system we will build contains 4 different components/moving parts: Web Service Listener, Event Dispatcher, Codeunit Eventhandler and XMLPort for stream handling.

image

Web Service Consumer

Any client that understands how to communicate with Web Services; like InfoPath, Visual Studio, SharePoint or any custom application written by you.

Port

Is the physical communication port that the WCF listens to.

WCF Web Service

Defines the data contracts and service contracts for the Web Service, it also implements the concrete service and opens for listening in the WCF subsystem, it then delegates the requests to the COM Event Dispatcher component.

COM Event Dispatcher

This component provides the hookups for Dynamics NAV, both to activate the service and to register event sinks. It defines 2 IDispatch interfaces the IServiceEvents and the IWebServiceListner, as well as the concrete implementation of the IWebServiceListner in the WebServiceListner class that provides the actual code for hooking up the WCF Web Service to Dynamics NAV.

.NET

We are using the CLR runtime for writing our Web Service component and our COM plugin. Some of this blog entry is about interop between Dynamics NAV and .NET through COM.

Codeunit Event Handler

Is responsible for starting up the WCF Web Service through the COM interface, it then registered for events coming from the WCF Web Service Component. The events routed to XMLPort for processing.

XMLPorts for datastreams

It deals with the actual business logic and data coming from or going to the Web Service.

Implementation

The implementation is in 2 programming languages: C# and C/AL.

Please take a look at the provided code sample, for the rest of the information contained in the posting. It can be found here: http://code.msdn.microsoft.com/nav/Release/ProjectReleases.aspx?ReleaseId=896

I have included comments in the code that should explain what is going on, if you feel something is missing, first look at the documentation for the WCF or post a comment to this post and I will try to answer it.

Deployment of Sample

To deploy the sample you will first have to download it, unpack it.

Then open it up with Visual Studio and compile.

Then import the codeunit.txt and xmlport.txt into your NAV installation and compile those objects, starting with the XMLPort

To run the service simply open the Object Designer in NAV, find the Codeunit that you just imported and press run.

There is no dependency on IIS or other external components. No further deployment steps should be needed.

In the Visual studio solution is a ConsoleTestApp project. After you have followed the steps above you can run that project, it will test if your install was successful, as well as provide sample on how to use the web service.

Special considerations

In this sample I’m using XMLPort to handle the XML stream that is provided.

You can take many different approaches to this, and still reuse large please of the code provided in the sample.

To use the XMLPort as handler you will have to set the encoding property to UTF-8. This is due to a null termination bug in stream handler in NAV.

image

image

With this approach you can already today, incorporate web services in your projects in straightforward way.

The appropriate usage is whenever you need to give external application access to Dynamics NAV data or business process.

For any questions or comments please feel free to ask them in the comment section of this blog post.  I will answer questions to best of my ability on this post in the comments section as well.

One last thing:  This is a sample code.  It has not been tested, you should thoroughly test this code before usage.

Best regards,
Kris Rafnsson

Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# jmadsen said on April 16, 2008 11:04 PM:

Great article demonstrating a minimal framework for exposing NAV business logic. Seems a little more elegant than MSMQ & easier to deploy.

I got this to work on NAV50, but when I try it on NAV50SP1 I receive this error: "The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT))". This error is reported by the Console App when any method is called on Customer_Service.

It seems to me to be related to Stream/IStream/NAV InStream/NAV OutStream compatibilty or something. Is the InStream/OutStream different in NAV50SP1?

Thanks for any help,

Jakob Madsen

# Soren Nielsen said on April 16, 2008 11:42 PM:

"To use the XMLPort as handler you will have to set the encoding property to UTF-8. This is due to a null termination bug in stream handler in NAV. "

Has this been fixed in NAV5.0 SP1? I have earlier had issues about importing streams into BLOB's from .NET, but i need to try and test this on SP1.

Great post about the Webservice. Keep up the good work.

# Kenneth Fuglsang said on April 17, 2008 4:59 AM:

I can't get it to work on 5.0SP1 either but 5.0 works.

Ikke-afviklet undtagelse: System.Web.Services.Protocols.SoapHeadeHeaderException: Serveren kunne ikke behandle anmodningen på grund af en intern fejl. (the server could not execute the request because of an internal error).

  ved System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapCli

entMessage message, WebResponse response, Stream responseStream, Boolean asyncCa

ll)

  ved System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String method

Name, Object[] parameters)

  ved ConsoleTestApp.localhost.Customer_Service.Read() i C:\Users\kfc\Desktop\S

ample - WebServicesinNAV5\ConsoleTestApp\Web References\localhost\Reference.cs:l

inje 113

  ved ConsoleTestApp.Program.PrintAllCustomers() i C:\Users\kfc\Desktop\Sample

- WebServicesinNAV5\ConsoleTestApp\Program.cs:linje 21

  ved ConsoleTestApp.Program.Main(String[] args) i C:\Users\kfc\Desktop\Sample

- WebServicesinNAV5\ConsoleTestApp\Program.cs:linje 12

# Kris Rafnsson said on April 17, 2008 8:23 AM:

I will look into the issue regarding 5.0 SP1 sometime next week.

This approach should work on Dynamics NAV 4.0 as well.

# Ravinder Pal Singh said on April 17, 2008 4:02 PM:

cool.

When I import the dataport, i get the error

"There is a syntax error in the import on line 33 in position 2 : REQUESTPAGE.

A'}'(ListEnd) is expected here.

# bleisibach said on April 18, 2008 3:01 AM:

Ravinder. I just removed the Code-Part REQUESTPAGE including PROPERTIES and CONTROLS and was able to import then without Problem.

Kris. Tnx for the Posting. Works fine here on 5.0-CH.

# Andrzej said on April 19, 2008 10:31 AM:

To make it work with all Nav versions, you have to change 2 lines in Stream.Write method:

line:

Marshal.WriteInt64(pcbWritten, (long)cb);

change to:

Marshal.WriteInt32(pcbWritten, cb);

and line:

Marshal.WriteInt64(pcbWritten, (long)0);

change to:

Marshal.WriteInt32(pcbWritten, 0);

# Jonas said on April 23, 2008 3:59 AM:

Thanks for a great example!

I have a couple of questions:

1) Are there any problems if multiple clients makes calls at the same time? Are there any queue handling?

2) Error handling in NAV. If there's an error in NAV, can I get that error back to the client?

# Kenneth Fuglsang said on April 30, 2008 9:32 AM:

I just tried this on another computer with Windows Server 2003 and Dynamics NAV 5.0SP1.

The compuiter has .net 2.0, 3.0 and 3.5. I registered the dll like so:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727>RegAsm.exe c:\NAVWebServiceDemo\bin\Debug\NAVWebServiceDemo.dll /tlb:c:\navwebservicedemo\bin\debug\NAVWebServiceDemo.tlb

Yet, when I try to start the codeunit I get this error:

It was not possible to create an instance of the OLE-object... etc.

However, I can compile the codeunit with no problem.

I noticed that the Input and Output functions is of type IUNKNOWN inside NAV.

Any ideas?

# Kris Rafnsson said on May 2, 2008 8:56 AM:

Jonas:

The code should serialize calls to NAV.

However for large number of requests you should do something different.

Errors should be propagated when you run this on the NAS.

Kenneth:

Try to run the RegAsm with /verbose flag set and see if you can get better info over the registration.

# Kenneth Fuglsang said on May 5, 2008 2:12 AM:

Kris:

I'm afraid it doesn't give a lot of helpful information.

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727>regasm c:\_Shared\NAVWebService\NA

VWebServiceDemo\bin\Debug\NAVWebServiceDemo.dll /tlb c:\_Shared\NAVWebService\NAVWebServiceDemo\bin\Debug\NAVWebServiceDemo.tlb /verbose

Microsoft (R) .NET Framework Assembly Registration Utility 2.0.50727.1433

Copyright (C) Microsoft Corporation 1998-2004.  All rights reserved.

Types registered successfully

Type 'N' exported.

Type 'N' exported.

Type 'N' exported.

Assembly exported to 'c:\_Shared\NAVWebService\NAVWebServiceDemo\bin\Debug\NAVWebServiceDemo.tlb', and the type library was registered successfully

# Kenneth Fuglsang said on May 5, 2008 2:15 AM:

Just found the solution.

When registering with RegAsm you need to use the /codebase parameter.

This should only be used for signed assemblies, so I'll have to reregister it in a bit.

# Marcel said on May 13, 2008 5:38 AM:

Hi, i'm not so familar with Visual Studio, so please tell me step by step how to compile the VS Files and register it for use with NAV. I have installed Visual C# Express 2008 and MS .NET Framework SDK 2.0 on my PC. Thank in advance for your help. Best regards Marcel

# Kris Rafnsson said on May 14, 2008 10:04 PM:

Andrzej:

I have not had the time to look at you fix to my code you did.  However this fix makes sense.  And thank you for it.  As the complains for SP1 compatibility don’t show up any more I assume it is what it takes to get this working with SP1.  

Marcel:

Make sure that you do the changes that Andrzej suggested.  I have not tried myself with express version of Visual Studio, but if it compiles without errors and warnings,  it should run.  

That means that you should be able to load the project file.  

Compile

Import the objects

Compile the NAV objects

And run

Thanks

Kris

# AG said on May 15, 2008 11:12 AM:

Has anybody tested it on 4.0.3 ?

# salman said on May 21, 2008 10:44 AM:

how does the code unit stop running the service.

# Bruno Pereira said on May 29, 2008 5:27 AM:

How can I have the client on a different machine (instead of localhost) and still have this working?

We have to build another layer to comunicate with the outside, right? And then we'll need IIS...

Or am I wrong?

# vlieffroy said on June 4, 2008 4:54 PM:

Hello,

nice to see that NAV could be Web services enabled theorically.

But what are exactly the business processes that could accessed from outside. I mean i think it is quite easy to enable access to the data of the ERP from outside. But how  could an external client access some of the business processes via a web services ? How is the data integrity and the business processes accessed ? When one needs to create an order entry or a customer invoice from outside of the ERP, how could the web service replace the business logic of the traditional GUI ?

# Kris Rafnsson said on June 4, 2008 6:21 PM:

AG.

I did test on some version of 4.x at point in time, not sure what version exactly.  You should try, most likely it will work.

salman:

You will have to add new method to the COM object that allows for stopping.  Then call this method from within NAV, if you need to call it from outside NAV, you could expose that as a Web Service through the same infrastructure :-)

Bruno Pereira:

I have not tested but this should work already from different box.  

You need to use the actual computer name of the PC that is running the web service in steed of the localhost, in your consumer.  

Make sure your firewalls are not stopping the traffic.

There is no need for IIS.

vlieffroy

I think that we see differently on this issue.  

First I don’t consider the GUI, business logic, but a way to access it.  And as such it has been coded to fit a special actor, flesh and blood user.  I look at Web Services as just another way for accessing this business logic, and it too needs to be coded to fit the actors that should use it, those actors are usually other computer systems.

I don’t have that as a goal to replace GUI with web services but just to compliment the application in this case NAV with access to the data and processes for other systems.

As for the rest of the questions,  this sample does not address that directly, this is more of a plumbing for building your own answer to those questions.  Microsoft Dynamics NAV 2009 will however provide some application level implementation that answers those questions.   I will write more about that later.

Thanks

Kris Rafnsson

# vlieffroy@lecxp.com said on June 9, 2008 10:36 AM:

Kris,

Yes, we definitely see different. I agree with you on the fact that Web Services do not replace the GUI.

But (this is the point) how could the business logic be 'translated' in Web Services : how could an Order-to-Cash process be used with Web Services, in place of GUI. This is why i menton business logic. This is the critical issue with SOA.

# Kris Rafnsson said on June 26, 2008 8:48 PM:

Sorry for the late reply.

Nobody wants to wait for Dynamics NAV 2009 longer than absolutely needed.  I´m pulling my share of the load :-)

Thanks for constructive debate vlieffroy@lecxp.com,  it is much appreciated.

There are many schools of SOA.  I’m not sure if I have been to any of them yet, so I’m not going to list out answer to your question in SOA terms.

My understanding of your question is that it is more philosophical, than I feel that my little code sample merits.

Therefore I’m going to abstract, away from the sample, that is mostly focused on the nitty-gritty details of getting messages in and out of Dynamics NAV, into something completely different.

Applications like Dynamics NAV have a legacy, which does not fit the idealistic world of modeling software as processes.  Don’t get me wrong, Dynamics NAV is fully capable to manage the order to cash process that you where referring to, and some of us it think it is the greatest thing since sliced bread, but it has legacy.  With legacy come a lot of good things.  Such as proven approach, stable codebase and lot of features.

Dynamics NAV is architecturally centered around:  Forms (for data entry), Tables (for data storage) and Report (for aggregation and printing of the data), at least from abstraction point of view.  This makes the application task oriented, from the perspective of user that is now going to type in the orders that have just arrived, or print out the invoices needed to be sent out.  

This architecture is based on even more legacy system that probably dates back hundreds of years.  And therefore more proven, is more stable and has more features.  That is the document/form in triplets (or more).   One could think that the IRS or US immigration had invented the concept just by the share volume of forms they use, but it is not so, they us it simply to the reason of: more proven, stable codebase and lot of features.  

The funny thing with form in triplet is that at its heart it is message oriented structure.  Depends on the business the copies go to different departments.  Those where processed differently for different departments.

Web services are also message oriented.  This leaves us with message oriented forms, which is the architectural construct of Dynamics NAV and web services that both are message oriented.

So far we have established that Dynamics NAV is capable of running the order to cash process (I stated that), it works in task oriented way where forms have center stage and forms are message oriented.  

How can we make this help us running the order to cash process through web services?

If we examine this process, it at first appearance looks concrete, there are however as many processes as there are deals made in the world.  Only by very abstract approximation you can claim that there is one process.  There are however general touch points in the process where interaction between customer and vendor frequently happen.  

If we limit us to very general incarnation of the order to cash process those touch points include but are not limited to: The order, the order confirmation, the shipment notice, the invoice, the delivery and the payment.

I will try to list the general steps on how you could fulfill those steps from Dynamics NAV perspective in this very limited process:

The order

The order is sent through a web service request.  It is filled into the system; a sales person looks at the order and approves it by processing it.

The system sends order confirmation to the customer with expected delivery dates, as well as notifying the warehouse of the order.  

Warehouse pushes the ship button when the goods leave the building sending a shipping notice to the buyer and message to the invoicing department.  

Invoice department sends invoice to buyer.

Product is delivered.

Buyer pays at bank.

Invoice department consolidates with the bank.

Standard Dynamics NAV has many of those features already build in.  The rest is easy to get partners to add, with the help of the code I have added in this blog.  

I hope this helps you understand how Web Services can help businesses in the future.  If not please be more specific, and I might be able to answer :-)

Thanks

Kris

# Christian said on July 2, 2008 3:25 PM:

Hi

I now tested your code with Visual Studio Express 2008 (c#).

Unluckily I can't resolve the IUNKNOWN issue.

Could anyone give me some hints to solve this.

I tried the /codebase option, but still no progress.

Thanks in advance!

//Christian

# vlieffroy [at] lecxp [dot] com said on July 9, 2008 8:31 AM:

@ Kris Rafnsson.

Thanks for the answer. We are quite agree on the purpose and the benefits Web Services could help businesses.

And this is a short-term journey (hopefully).

The SOA way on the other hand is long term journey i think (definition and re-definition of business processes by business analysts, without coding anymore etc..).

Regards,

Vincent Lieffroy

# Kjell H said on July 10, 2008 8:44 AM:

Hi!

I've just tried to use this sample but I can't import the xmlport.txt or the codeunit.txt. The message I get is that I don't have permission to create the xmlport or the codeunit. I do have a developer license for NAV 5.0 and I'm familiar with VS 2008 and .NET since 7 year. I'm rather new to this with NAV and I could use som help to get this running. My version of NAV 5.0 is in Swedish, but I can't see that this should matter.

If someone of you guys could provide me with some more information how to get this running I will be most grateful.

/Kjell H

# Kjell H said on July 10, 2008 10:41 AM:

Hi!

Back again on the same day as previous post. I finally got the xmlport and codeunit to run. But how do I do to register the webservice 'localhost' to the console application? The article says I don't need to use the IIS but how does this work??

/Kjell H

# Ram said on August 8, 2008 8:11 AM:

Hi,

I am trying to use this sample but I can't import the xmlport.txt or the codeunit.txt.

I am getting error message  as

---------------------------

Microsoft Dynamics NAV

---------------------------

'E:\Microsoft Navision\Sample - WebServicesinNAV5\NAVWebServiceDemo\xmlport.txt' is not a valid Language Module file.

Any clue on this?

# Kjell H said on August 18, 2008 4:37 AM:

I've tried to use this code from both VS 2005 and VS 2008 but I really can't find any WCF service in the code. Am I missing something or should this be something I have to create to get this to work?

/Kjell H

# Manav said on November 28, 2008 3:51 AM:

Is it possible to change font size in NAV 5.0 for sales documents like Sales quote,Proforma etc..

# Robin said on December 27, 2008 12:59 PM:

Hi, thanks for your sample code.

I tried it in Nav 5.0 SP1. That strange thing is that when I try to read Input instream with ReadText(buffer, n). Only the first character can be read. For example, if the input stream is "Hello", only "H" can be read. If I set ReadText(Input, 2). The Nav shows read error. Also I can not read by Read.

Does anybody have any idea? Thanks

# Nishikant said on January 19, 2009 5:25 AM:

I have gone through all the guid line  given in this blog to start Web Services to Access Microsoft Dynamics NAV 5.0

with wss3.0 and also downloaded the code sample given in this blog, but I am not able to start Windows SharePoint services 3 Search in Computer Management, Can any one help me for this problem?

# mahir said on January 30, 2009 5:12 AM:

hi, I can not find that Automation that you are using? what is it called? and is it something that is in the windows server (+ .NET 3) ??

thx in advance..

# Kris Rafnsson said on February 2, 2009 3:46 AM:

Robin:  did you try following?

Andrzej said on April 19, 2008 10:31 AM:

To make it work with all Nav versions, you have to change 2 lines in Stream.Write method:

line:

Marshal.WriteInt64(pcbWritten, (long)cb);

change to:

Marshal.WriteInt32(pcbWritten, cb);

and line:

Marshal.WriteInt64(pcbWritten, (long)0);

change to:

Marshal.WriteInt32(pcbWritten, 0);

If that does not help make sure that you are using UTF-8 in all places also in the xmlport.  There is a bug in the NAV internal stream function, it can only work with UTF8

# Kris Rafnsson said on February 2, 2009 3:49 AM:

mahir:

The automation is called: NAVWebServiceDemo'.WebServiceListner

You will need to build the project with Visual Studio before it will show up in your list.  

After the build it should be avalable on Windows server as well as XP and Vista

# Kris Rafnsson said on February 2, 2009 3:52 AM:

Nishikant:  

There should not be any conflict with wss3.0.

the project is not using it at all.  

you can try to change the port number of the WCF service in the project

# Nishikant said on February 3, 2009 11:35 PM:

Kris Rafnsson:

Can you please brief me how can I use Windows Sharepoint Services 3.0  to call NAV5.0 CodeUnits object? Can you suggest me code example or any blog or even any helping URL for the same? Thanks a lot in advance

# Kris Rafnsson said on February 4, 2009 10:15 AM:

I’m not aware of any blog or code examples that use the WSS together with NAV.  

Although I have not tried, you should be able to modify this sample to work with the WSS.

Consider following:  the sample code is not running with in the IIS.  It is using a WCF service hosted within NAV process.  You will have to use a web service to communicate from the WSS to the NAV process.  

Consider following approach.

1.) Get the sample up and running.  

2.) Build a simple web service in Visual Studio that serves some data, as a standalone process (not hosted in IIS)

3.) Bind that newly build web service to WSS and make sure that it can retrieve the data from that service.

4.) Take the learning’s from this and refractor the sample in this post to fit your purpose, then link it to WSS.

5.) Write a blog about the experience and become famous.

# Nishikant said on February 6, 2009 2:33 AM:

Hi Kris,

Thanks for your reply and the approach you have suggested.

Let me walk though what you have suggested, You want to say first I need to create web user interface using WSS3.0 and  bind  the web service that I have created using Visual Studio  to WSS3.0, which will call NAV5.0, Is that you mean to say?  Simply you mean to say is  I will have to create web service to call WSS which will call  NAV functionality from WSS user interface. But Kris this WSS site will be hosted on IIS then what? Although the simple web service built by using visual studio could be standalone no doubt about it! Still it is not going to solve this issue?

What I have done right now I have created one CodeUnit object with XMLport and deployed it into NAV application and trying to call this codeunit object for the web service that I have built in Visual Studio. But the problem is my NAV server is not responding to the MSMQ. I guess it might because authentication functionality provided to server or please let  me know if you may have experience the same?  

Code Unit code:

OBJECT Codeunit 50002 RunNavisionProcess

{

 OBJECT-PROPERTIES

 {

    Date=22.03.08;

   Time=17:03:44;

   Modified=Yes;

   Version List=;

 }

 PROPERTIES

 {

   SingleInstance=Yes;

   OnRun=BEGIN

           IF ISCLEAR(ComCom) THEN

             IF NOT CREATE(ComCom) THEN

               ERROR(Text001);

           IF ISCLEAR(MSMQ_BA) THEN

             IF NOT CREATE(MSMQ_BA) THEN

               ERROR(Text001);

           ComCom.AddBusAdapter(MSMQ_BA,1);

           MSMQ_BA.OpenReceiveQueue('.\private$\' + COMPANYNAME + ' 1',0,0);

           MSMQ_BA.OpenReplyQueue('.\private$\' + COMPANYNAME + ' 2',0,0);

         END;

 }

 CODE

 {

   VAR

     ComCom@1450001 : Automation "{F9A57667-8AC5-45C5-9416-99D3955BCAC0} 1.0:{01018FA5-E4B4-413C-A47C-AD34B0CC2647}:'Navision Communication Component version 2'.CommunicationComponent" WITHEVENTS;

     MSMQ_BA@1450000 : Automation "{B8BD635A-E191-47EF-84A0-02921E2A44A6} 1.0:{CD49794B-0E84-4A2E-9522-C518C825D390}:'Navision MS-Message Queue Bus Adapter'.MSMQBusAdapter";

     Text001@1450003 : TextConst 'ENU=Cannot create communication components.';

     Text002@1450002 : TextConst 'ENU=Document No. cannot be found';

     Text003@1450004 : TextConst 'ENU=Document Type is missing in ParameterList';

     Text004@1450005 : TextConst 'ENU=Company does not exist';

     Text005@1450006 : TextConst 'ENU=Item No. cannot be found';

     Text006@1450007 : TextConst 'ENU=Completed';

     Text007@1450008 : TextConst 'ENU=Customer No. cannot be found';

     Text008@1450009 : TextConst 'ENU=Customer has been blocked in Navision';

   LOCAL PROCEDURE ReturnOriginalMessage@1240002(OutMsg@1450002 : Automation "{F9A57667-8AC5-45C5-9416-99D3955BCAC0} 1.0:{6CB9762C-E61C-4F96-BA34-8B20D3A5B46E}:'Navision Communication Component version 2'.OutMessage";XMLDoc@1450000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument");

   VAR

     OutStreamQueue@1450001 : OutStream;

   BEGIN

     OutStreamQueue := OutMsg.GetStream();

     XMLDoc.save(OutStreamQueue);

     OutMsg.Send(0);

     CLEAR(OutMsg);

   END;

   LOCAL PROCEDURE SendItem@1450000(ItemNo@1450000 : Code[20];OutMsg@1450006 : Automation "{F9A57667-8AC5-45C5-9416-99D3955BCAC0} 1.0:{6CB9762C-E61C-4F96-BA34-8B20D3A5B46E}:'Navision Communication Component version 2'.OutMessage");

   VAR

     Item@1450003 : Record 27;

     ItemXMLPort@1450002 : XMLport 8002;

     OutStreamQueue@1450004 : OutStream;

     XMLDoc@1450001 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument";

   BEGIN

     OutStreamQueue := OutMsg.GetStream();

     Item.SETRANGE("No.",ItemNo);

     ItemXMLPort.SETTABLEVIEW(Item);

     ItemXMLPort.SETDESTINATION(OutStreamQueue);

     ItemXMLPort.EXPORT;

     CREATE(XMLDoc);

     XMLDoc.save(OutStreamQueue);

     OutMsg.Send(0);

     CLEAR(OutMsg);

   END;

   PROCEDURE PopulateResult@1450001(XMLDoc@1450000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument";Result@1450001 : Text[250]);

   VAR

     XMLNode@1450003 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v3.0'.IXMLDOMNode";

     XMLDOMMgmt@1450002 : Codeunit 99008516;

   BEGIN

     IF XMLDOMMgmt.FindNode(XMLDoc,'/NavisionObject/Result',XMLNode) THEN

       XMLNode.text := Result;

   END;

   LOCAL PROCEDURE SendCustomer@1450002(CustomerNo@1450000 : Code[20];OutMsg@1450006 : Automation "{F9A57667-8AC5-45C5-9416-99D3955BCAC0} 1.0:{6CB9762C-E61C-4F96-BA34-8B20D3A5B46E}:'Navision Communication Component version 2'.OutMessage");

   VAR

     Customer@1450003 : Record 18;

     CustomerXMLPort@1450002 : XMLport 50002;

     OutStreamQueue@1450004 : OutStream;

     XMLDoc@1450001 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument";

   BEGIN

     OutStreamQueue := OutMsg.GetStream();

     Customer.SETRANGE("No.",CustomerNo);

     CustomerXMLPort.SETTABLEVIEW(Customer);

     CustomerXMLPort.SETDESTINATION(OutStreamQueue);

     CustomerXMLPort.EXPORT;

     CREATE(XMLDoc);

     XMLDoc.save(OutStreamQueue);

     OutMsg.Send(0);

     CLEAR(OutMsg);

   END;

   LOCAL PROCEDURE FindNode@3(RootNode@1020 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v3.0'.IXMLDOMNode";NodePath@1000 : Text[250];VAR ReturnedNode@2030 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v3.0'.IXMLDOMNode") : Boolean;

   BEGIN

     ReturnedNode := RootNode.selectSingleNode(NodePath);

     IF ISCLEAR(ReturnedNode) THEN

       EXIT(FALSE)

     ELSE

       EXIT(TRUE);

   END;

   EVENT ComCom@1450001::MessageReceived@1(VAR InMessage@1450000 : Automation ":{00020400-0000-0000-C000-000000000046}:''.IDISPATCH");

   VAR

     Item@1450012 : Record 27;

     SalesHeader@1450010 : Record 36;

     InMsg@1450003 : Automation "{F9A57667-8AC5-45C5-9416-99D3955BCAC0} 1.0:{D184D0AC-61C9-4AC1-B537-0D28C277FEDE}:'Navision Communication Component version 2'.InMessage";

     XMLDoc@1450006 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument";

     XMLNode@1450005 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v3.0'.IXMLDOMNode";

     InStreamQueue@1450002 : InStream;

     XMLChar@1450007 : Text[1];

     XMLText@1450004 : Text[1024];

     UserName@1450014 : Text[1024];

     CompanyName@1450013 : Text[1024];

     FunctionName@1450008 : Text[1024];

     ParameterList@1450009 : Text[1024];

     DocumentType@1450011 : Option;

     Company@1450016 : Record 2000000006;

     Customer@1450017 : Record 18;

   BEGIN

     InMsg := InMessage;

     InStreamQueue := InMsg.GetStream();

     REPEAT

       InStreamQueue.READTEXT(XMLChar);

       XMLText := XMLText + XMLChar;

     UNTIL InStreamQueue.EOS;

     CREATE(XMLDoc);

     XMLDoc.loadXML(XMLText);

     IF FindNode(XMLDoc,'/NavisionObject/UserName',XMLNode) THEN

       UserName := XMLNode.text;

     IF FindNode(XMLDoc,'/NavisionObject/CompanyName',XMLNode) THEN

       CompanyName := XMLNode.text;

     IF FindNode(XMLDoc,'/NavisionObject/FunctionName',XMLNode) THEN

       FunctionName := XMLNode.text;

     IF FindNode(XMLDoc,'/NavisionObject/ParameterList',XMLNode) THEN

       ParameterList := XMLNode.text;

     CASE FunctionName OF

       'GetCustomer':

         BEGIN

           IF Customer.GET(SELECTSTR(1,ParameterList)) THEN

             SendCustomer(Customer."No.",InMsg.CreateReply)

           ELSE BEGIN

             PopulateResult(XMLDoc,Text007);

             ReturnOriginalMessage(InMsg.CreateReply,XMLDoc);

           END;

         END;

       'BlockCustomer':

         BEGIN

           IF Customer.GET(SELECTSTR(1,ParameterList)) THEN BEGIN

             Customer.VALIDATE(Blocked,Customer.Blocked::All);

             IF Customer.MODIFY(TRUE) THEN BEGIN

               PopulateResult(XMLDoc,Text008);

               ReturnOriginalMessage(InMsg.CreateReply,XMLDoc);

             END;

           END ELSE BEGIN

             PopulateResult(XMLDoc,Text007);

             ReturnOriginalMessage(InMsg.CreateReply,XMLDoc);

           END;

         END;

     END;

     InMsg.CommitMessage;

     CLEAR(InMsg);

   END;

   BEGIN

   END.

 }

}

# Nishikant said on February 6, 2009 2:35 AM:

XMLPort Code file:

OBJECT XMLport 50002 Customer

{

 OBJECT-PROPERTIES

 {

   Date=22.03.08;

   Time=17:05:05;

   Modified=Yes;

   Version List=;

 }

 PROPERTIES

 {

 }

 ELEMENTS

 {

   { [{BF00F684-48BE-4FA3-9A60-D83313729921}];  ;Customer            ;Element ;Table   ;

                                                 VariableName=Customer;

                                                 SourceTable=Table18;

                                                 MaxOccurs=Once }

   { [{36E410F8-09CA-432C-A2D7-9EEB24513092}];1 ;No                  ;Element ;Field   ;

                                                 DataType=Code;

                                                 SourceField=Customer::No. }

   { [{449E6B20-B2AE-4585-BF5D-547100835006}];1 ;Name                ;Element ;Field   ;

                                                 DataType=Text;

                                                 SourceField=Customer::Name }

   { [{0C886C80-C7A9-4E81-AE78-81DE61832033}];1 ;Address             ;Element ;Field   ;

                                                 DataType=Text;

                                                 SourceField=Customer::Address }

   { [{1B4BBDE2-33BA-45B4-93E4-C8E008C45874}];1 ;Address2            ;Element ;Field   ;

                                                 DataType=Text;

                                                 SourceField=Customer::Address 2 }

   { [{6393F10D-A0FF-4E7B-AE81-E6A984B1ED85}];1 ;City                ;Element ;Field   ;

                                                 DataType=Text;

                                                 SourceField=Customer::City }

   { [{D2B42495-00F6-4906-A4B1-2A5E73F7254C}];1 ;Contact             ;Element ;Field   ;

                                                 DataType=Text;

                                                 SourceField=Customer::Contact }

   { [{BAFCD676-8601-4144-94EA-56BA5B202A5D}];1 ;PhoneNo             ;Element ;Field   ;

                                                 DataType=Text;

                                                 SourceField=Customer::Phone No. }

   { [{01C9BE54-E4E6-4949-B964-9A0430D4A2C6}];1 ;CreditLimitLCY      ;Element ;Field   ;

                                                 DataType=Decimal;

                                                 SourceField=Customer::Credit Limit (LCY) }

   { [{2041A5A2-584E-47D4-9DB6-495004D419F9}];1 ;BalanceLCY          ;Element ;Field   ;

                                                 DataType=Decimal;

                                                 AutoCalcField=Yes;

                                                 SourceField=Customer::Balance (LCY);

                                                 Export::OnBeforePassField=BEGIN

                                                                             Customer.CALCFIELDS("Balance (LCY)");

                                                                           END;

                                                                            }

   { [{F2D72680-C141-4FF5-9874-ADA61EFED87A}];1 ;FaxNo               ;Element ;Field   ;

                                                 DataType=Text;

                                                 SourceField=Customer::Fax No. }

   { [{93F35292-DC24-4ABF-BFB4-1DBD85A61FF4}];1 ;PostCode            ;Element ;Field   ;

                                                 DataType=Code;

                                                 SourceField=Customer::Post Code }

   { [{D38CD468-1A4E-40B9-ABBB-92DCDBED7F34}];1 ;County              ;Element ;Field   ;

                                                 DataType=Text;

                                                 SourceField=Customer::County }

 }

 EVENTS

 {

 }

 CODE

 {

   BEGIN

   END.

 }

}

# Nishikant said on February 6, 2009 4:53 AM:

URL to download code example

http://code.msdn.microsoft.com/nishikantmadghe

# Raju said on February 10, 2009 2:04 AM:

i am not able to run your sample application its return me error at Program.cs class at below line in method PrintAllCustomers()

            foreach (Customer cust in service.Read())

exception is:-

" The server was unable to process the request due to an internal error.  For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs."

kindly help me to solve it

# Raju said on February 11, 2009 4:40 AM:

I am not able to connect with below url just tell me what i have to do to solve this problem.

Url = "http://localhost:8000/nav/customer"

i am getting error:-

"The server was unable to process the request due to an internal error.  For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs."

# s.todd said on February 11, 2009 9:39 AM:

I have a little problem with the sample.

"Then import the codeunit.txt and xmlport.txt into your NAV installation..." -> I can't seem to find any option to import code objects or xmlports.

I'm running with a demo license, could that be the reason?

Also, I only started out with nav today, please be lenient.

# Nishikant said on February 12, 2009 4:19 AM:

hi Kris:

How do I do to register the web service 'localhost' to the console application? The article says I don't need to use the IIS but how does this work??

When I am debugging the sample code i am getting an exception at service.Read() the exception is

"The request failed with HTTP status 400: Bad Request."

can you let me know what’s wrong with it? How we are going to use this sample code?

at the same time i am unable to find this

URL"http://localhost:8000/nav/customer"

Thanks in advance

# Rooky said on February 13, 2009 5:07 AM:

Hi, i am trying to integrate third party .Net Application with NAV. .Net Application will write the data into MSMQ in XML format and NAV code Unit which Calls XML Ports receive this data and push into NAV. Can any one please help how i can handle Validation failures (like County Code does not exists in NAV) in Dynamics NAV and in my Design.

# Raju Bodkhe said on March 9, 2009 7:19 AM:

Dear Kris Rafnsson,

Your code example and Article is very helpful to me for insert and update data using  navision business layer  but i am not able to Read data,  i am getting error:-

The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT))

i am not able to understand it, i read about this error on net but not found solution. i think it may because

of below reason:-

In WebServiceListner Class's Output method your write

 /// Note:  We need to create and manage the buffer.

what is the meaning of it and how should we mange buffer

give me your mail id to communicate with u

kindly do the needful      

# John said on April 14, 2009 7:52 AM:

hi Kris,

Your article and code example is very useful to me for Read, Edit and Insert New record, but search functionality for a Particular record is not work for me ...........if u have any idea............kindly help for it

Leave a Comment

(required) 
(optional)
(required) 

Search

Go

This Blog

Syndication

Page view tracker