上QQ阅读APP看书,第一时间看更新
Creating the consumer application
Let's learn how to create the consumer application by performing the following steps:
- In order to create the application that will use our published NAV web service, open Visual Studio, create a new project, and in the New Project window select the Console Application project type:
- Give a desired name to your solution (for example,
ConsoleApplicationNAV
) and click OK. - Visual Studio creates the template for the solution project. You can see it in the Solution Explorer window in the right pane:
- Here, the
Program.cs
file contains the core of the console application (Main
) whileApp.config
is the application configuration file, an XML file that contains specific settings for the application. - Now we have to add a reference to our NAV web service in order to use it. To do this, right-click on your solution file and choose Add | Service Reference… as shown in the following screenshot:
- Here you can add a reference to one or more Windows Communication Foundation (WCF) services in the current solution, locally, on a local area network or on the Internet.
- For NAV, we don't have a WCF service but instead a SOAP XML web service. For adding a reference to an XML web service, in the Add Service Reference window click on Advanced…:
- And then click on Add Web Reference…:
- In the Add Web Reference window, type the URL of your NAV web service (the SOAP URL you can find in the Microsoft Dynamics NAV Web Service page) and Visual Studio will create a proxy for your web service:
- To complete the operation, give a desired web reference name (for example,
NAVWS
) and click Add Reference.Now your solution contains a web reference to your NAV web service:
- We're ready to start writing C# code now. The first thing to do is to write a
using
clause for adding a reference to theNAVWS
namespace:using ConsoleApplicationNAV.NAVWS;
- Console applications have startup parameters that you can specify as arguments in order to take actions (the
string[] args
parameter in theMain
function). In this sample application, we want to read sales orders and create new ones, so we want to have a startup parameter,READ
, to read the NAV registered sales orders andCREATE
to create a new sales order. - In the
Main
function, the first thing to do is to check if the number of startup parameters for the console application is correct. If it's not correct, the best thing to do is to print the syntax instructions to the screen:string OperationType; //If startup parameters are different from one, write the application syntax on screen and exit if (args.Length != 1) { Console.WriteLine(" Usage:"); Console.WriteLine(" ConsoleApplicationNAV <OperationType>"); Console.WriteLine(" ------ "); Console.WriteLine(" OperationType:"); Console.WriteLine(" READ: reads NAV Sales Orders"); Console.WriteLine(" CREATE: create a new Sales Order on NAV"); Console.WriteLine(" ------ "); return; }
- Next, we can read the input parameter and process it accordingly:
//Reading the Operation Type parameter OperationType = args[0].ToUpper(); switch(OperationType) { case "READ": ReadNAVSalesOrders(); break; case "CREATE": CreateNAVSalesOrder(); break; default: Console.WriteLine("Wrong parameter!"); break; }
- Here, we read the input parameter for our application. If the input parameter is
READ
, we call the functionReadNAVSalesOrders
. If the input parameter isCREATE
, we call the functionCreateNAVSalesOrder
, otherwise an error message is printed:private static void ReadNAVSalesOrders() { //Here we have to call our NAV web service for reading Sales Orders } private static void CreateNAVSalesOrder() { //Here we have to call our NAV web service for creating a Sales Order }
- Now we have to write the logic for the preceding two core functions.
Reading NAV sales orders
Let's learn how to read NAV sales orders by performing the following steps:
- In the
ReadNAVSalesOrders
function, we have to create an instantiation of the NAV web service and explicitly set the URL for this service:SalesOrder_Service ws = new SalesOrder_Service(); ws.Url = "...";
- I recommend to place the web service URL in the
<applicationSettings>
section in theapp.config
file and then to read it from there. - To do so, right-click on your project, select Properties, and then select Settings.
- Here you can add all the application settings variables you want and these can be loaded at runtime in your application via code.
- For our example, we can insert a row like the following screenshot:
- Here we have created a setting called
NAVWSURL
where the type is astring
and the value is the URL of our NAV web service. - In
app.config
, Visual Studio creates this entry:<applicationSettings> <ConsoleApplicationNAV.Properties.Settings> <setting name="NAVWSURL" serializeAs="String"> <value> http://192.6.1.37:7047/DynamicsNAV90/WS/ CRONUS%20Italia%20S.p.A./Page/SalesOrder </value> </setting> </ConsoleApplicationNAV.Properties.Settings> </applicationSettings>
- For dynamically reading this setting, just use this line of code:
ws.Url = Properties.Settings.Default.NAVWSURL;
- To access the NAV web service, we also need authentication. We can use explicit credentials (impersonate a particular user) or we can use the default credentials of the user that runs the application. In this case, we want the credentials for the running user, so we use this line:
ws.UseDefaultCredentials = true;
- The method for retrieving a set of records from a NAV page web service is called
ReadMultiple
:Entity [] ReadMultiple(Entity_Filter[] filterArray, string bookmarkKey, int setSize)
- This method reads a filtered set of records (if filters are applied) and returns an array of entities (objects that represents the page web service). The parameters are as follows:
- For our sample application, we want to retrieve all orders for the customer code
10000
(Cannon Group SpA
). Accordingly to theReadMultiple
method's definition, we have to define an array of filters to apply for the sales order entity (exposed by the web service) and then call the method itself by passing this filter array.The piece of code that does the work is this:
//Setting filters on the table List<SalesOrder_Filter> filterArray = new List<SalesOrder_Filter>(); SalesOrder_Filter filter = new SalesOrder_Filter(); filter.Field = SalesOrder_Fields.Sell_to_Customer_No; filter.Criteria = "10000"; filterArray.Add(filter); //Reading sales orders List<SalesOrder> orderList = ws.ReadMultiple(filterArray.ToArray(), null, 0).ToList();
- We have created a
SalesOrder_Filter
array with a filter on theNAV
field,Sell To Customer No. = 10000
, and then we have called theReadMultiple
method of the web service by passing the filter array,NULL
asbookmarKey
(we want the first page of the recordset) and0
assetSize
(we want the complete result set). - The
ReadMultiple
method returns aSalesOrder
array, so here we have used the.ToList()
extension ofList<T>
in order to directly have aList
ofSalesOrder
objects and loop through it for printing the details.The complete function code is as follow:
private static void ReadNAVSalesOrders() { //Here we have to call our NAV web service for reading Sales Orders //Web Service instantiation SalesOrder_Service ws = new SalesOrder_Service(); ws.Url = Properties.Settings.Default.NAVWSURL; ws.UseDefaultCredentials = true; //Setting filters on the table List<SalesOrder_Filter> filterArray = new List<SalesOrder_Filter>(); SalesOrder_Filter filter = new SalesOrder_Filter(); filter.Field = SalesOrder_Fields.Sell_to_Customer_No; filter.Criteria = "10000"; filterArray.Add(filter); //Reading sales orders List<SalesOrder> orderList = ws.ReadMultiple(filterArray.ToArray(), null, 0).ToList(); //Printing the results if (orderList!=null) { foreach(SalesOrder order in orderList) { Console.WriteLine("Order No.: " + order.No); Console.WriteLine("Order Date: " + order.Order_Date); Console.WriteLine("----------------"); } //Waiting user input to terminate Console.ReadKey(); } }
Creating a NAV sales order
In the CreateNAVSalesOrder
function, we use the NAV page web service for creating a sales order with two lines on NAV. This task requires some steps in order to be completed on NAV:
- As a first step, we need to instantiate the NAV web service as previously described:
SalesOrder_Service ws = new SalesOrder_Service(); ws.Url = Properties.Settings.Default.NAVWSURL; ws.UseDefaultCredentials = true;
- Now we have to call the NAV web service in order to create the sales header and having the order header initialized with its order number (here it is exactly like pressing the NEW button in the Sales Order Card page in NAV):
SalesOrder order = new SalesOrder(); ws.Create(ref order);
- For this task, we call the
Create
method by passing a reference to theSalesOrder
object to initialize:void Create(ref Entity entity)
- After this first call, the
SalesOrder
object is created and we have the order number from NAV. - Now we can update the sales header with all the details and we can initialize the sales lines:
//Update the Sales Header with details order.Sell_to_Customer_No = "10000"; order.Order_Date = DateTime.Now; //Create the Sales Lines array and initialize the lines order.SalesLines = new Sales_Order_Line[2]; for (int i=0; i<2; i++) { order.SalesLines[i] = new Sales_Order_Line(); } ws.Update(ref order);
- After that we can create the lines:
//First line Sales_Order_Line line = order.SalesLines[0]; line.Type = NAVWS.Type.Item; line.No = "1000"; line.Quantity = 5; //Second line line = order.SalesLines[1]; line.Type = NAVWS.Type.Item; line.No = "1001"; line.Quantity = 10;
- At the end we can update the order lines:
ws.Update(ref order);
- The complete function code is as follows:
private static void CreateNAVSalesOrder() { //Here we have to call our NAV web service for creating a Sales Order //Web Service instantiation SalesOrder_Service ws = new SalesOrder_Service(); ws.Url = Properties.Settings.Default.NAVWSURL; ws.UseDefaultCredentials = true; //Create the Sales Header SalesOrder order = new SalesOrder(); ws.Create(ref order); //Here the Sales Order is created and we have the order No. //Update the Sales Header with details order.Sell_to_Customer_No = "10000"; order.Order_Date = DateTime.Now; //Create the Sales Lines array and initialize the lines order.SalesLines = new Sales_Order_Line[2]; for (int i=0; i<2; i++) { order.SalesLines[i] = new Sales_Order_Line(); } ws.Update(ref order); //First line //Sales_Order_Line line = new Sales_Order_Line(); Sales_Order_Line line = order.SalesLines[0]; line.Type = NAVWS.Type.Item; line.No = "1000"; line.Quantity = 5; //Second line line = order.SalesLines[1]; line.Type = NAVWS.Type.Item; line.No = "1001"; line.Quantity = 10; //Update the order lines with all the informations ws.Update(ref order); Console.WriteLine("Order {0} created successfully.", order.No); }
Tip
All this code does not contain error handling functions, but you need
ALWAYS
to enclose every call in aTRY…CATCH
block and handling exceptions accordingly.