NAV 2009 Web Services: Extending a page web service

Are you familiar with Freddy's blog? As I said in my previous post (and in my presentation about Web Services), Freddy's blog is the "Mekka" of Web Services. And I should have known ... after finishing this blog, I was browsing through his one, and found quite exact the same blog as I wrote here Sad. Stupid me. Here you can find Freddy's entry. But I did the effort, so I publish it anyway. The solution is quite the same, but still a little bit different Smile, so may be it's useful for you.

This application is something I always use in my demo's. It's nice to see how easy it is to publish and use a page-based web service. It's even nicer to see that you can use that same web service to do more. I use the "Sales Invoice"-page (page 43). Publishing it, is nothing more then inserting a record in form 810 "Web Services", and placing the checkmark.

As you can see, I call my service "WS_Salesinvoice". The name is important to extend it later on.

As you know, you can see your services here: http://localhost:7047/DynamicsNAV/WS/Services, supposing you've published it on your local machine. To be able to use your web service, you have to enter a company as well, so the URL would be looking something like:


Anyway, let's try to use it. For the first time in the history of Waldo's Blog, I will be trying to explain a VS.Net application ... which I don't really feel very familiar with anymore .. so don't be to critical about the code... (pppplease, Roger Rabbit would say Smile).

Open Visual Studio and start a new Windows Forms Application. I will show my code in C#, so it might be cool you would do that as well. I called my project "PostSalesInvoice":

First, i want to make a connection to my web service. You can do that by right click on "References" in the Solution Explorer, and select "Add Service Reference". Then "Advanced" and "Web Reference", and then you find a box where you can paste your the URL like above. You will get the list of methods of your page-based web service:

Notice I called my Web Reference name: "SalesInvoice". After that, click "Add Reference". Then, I create the following form by dragging a datagrid and two buttons on the form:

You can clearly see what I'm trying to do: list the invoices (get data from my page-based-web service) and post a selected invoice (extend my page-based web service with the possibility to post the selected invoice).

Now, how do I fill that datagrid? First of all, I create a function "LoadDataGrid".

private void LoadDataGrid()


// Initialize the Service

//localhost.Customer_Service service = new Customer_Service();

//service.UseDefaultCredentials = true;


SalesInvoice.WS_SalesInvoice_Service MySalesInvoicesService = new SalesInvoice.WS_SalesInvoice_Service();

//MySalesInvoicesService.UseDefaultCredentials = true;


//Read Records

SalesInvoice.WS_SalesInvoice[] Invoices = MySalesInvoicesService.ReadMultiple(null, null, 0);


//Fill Grid

dataGridView1.DataSource = Invoices;


You can copy/post the code above and put it in your project (just put it in the Form-class. After that, double click on the button "List My Sales Invoice" and call that function:

private void button4_Click(object sender, EventArgs e)




If you run the application, you get an overview of invoices in your grid:

You see, all columns, including the Key-column. To hide this column, you could add this line of code in the LoadDataGrid-function:

//Hide columns
dataGridView1.Columns[0].Visible = false; //Key Column

Next phase: post the selected invoice. I don't have a method in my web service to post my invoice, so this is where we are going to extend the web service with this possibility. Very simple! I just created a codeunit with a function. In this function, the signature is important: the first parameter should be the same record variable of the page you published (in our case, "Sales Header"). This is my (only) function of my codeunit:

PostInvoice(precSalesinvoice : Record "Sales Header")
CODEUNIT.RUN(CODEUNIT::"Sales-Post", precSalesinvoice);

Indeed, only one line of code.

What's following now, is the magic Wink. We are not going to publish the codeunit as a web service, but we are going to extend the existing web service (WS_SalesInvoice) with the function in the codeunit (I couldn't find a more complicated way to say this...). You can do this by inserting a second record in the Web Services form:

Important: use exactly the same Service Name!

Notice: it's not necessary to publish this codeunit as a web service. I don't want a separate web service with this codeunit, I only want to extend the existing page-based web service.

That's all!!! There is nothing more to it.

But let's check AND use this new method. First, in my Visual Studio project, I have to update my web reference to make my new method available in my VS project: right click on the Web Reference and click "update Web Reference". But to show you clearly, let's just delete the "SalesInvoice"-web reference, and add a new one with the same URL. You'll see the PostInvoice method was added:

Cool. So let's use it now (make sure you call your web reference name "SalesInvoice" again). Double click on the "Post" button, and copy/paste this code:


SalesInvoice.WS_SalesInvoice_Service MySalesInvoicesService = new SalesInvoice.WS_SalesInvoice_Service();

MySalesInvoicesService.UseDefaultCredentials = true;


String MyString = "";





DataGridViewRow MyRow = dataGridView1.SelectedRows[0];

MyString = MyRow.Cells["No"].Value.ToString();




System.Windows.Forms.MessageBox.Show("Not succeeded. Are you sure you REALLY selected a record ;°) ");




if (MyString != "")


Boolean success = true;


SalesInvoice.WS_SalesInvoice MySalesInvoice = new SalesInvoice.WS_SalesInvoice();

MySalesInvoice = MySalesInvoicesService.Read(MyString);






catch (Exception MyE)


success = false;

System.Windows.Forms.MessageBox.Show(MyE.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);



if (success)



System.Windows.Forms.MessageBox.Show("Invoice " + MySalesInvoice.No + " Posted successfully");



The code is quite self-explanatory, isn't it:

  1. Get the selected record (I need that Key)
  2. Call the function
  3. Trap any error and show it (any error in NAV will be shown in .NET).

On side remark: it's important that you SELECT the record by making it completely blue. It's the only way that I found to post a certain record. Selecting one cell is not enough...


The conclusion is that I can a page for data and codeunit for additional business logic ... with one web service (and not two) as a result.

Again, probably the C# code is probably not the most nicely written peace of C# you've ever seen, but try to look through that. I'm no Freddy ;°)

For your convenience, you can download the codeunit and VS project here.

Comment List
No Data
Comment Children
No Data