Webservice to Business Central – Challenge

Offering business central webservices to the world is made easy in this ERP system. Offering fast, reliable webservices is somewhat more challenging.

When you first start with webservices, and a customer ask the question: ‘I have and android app with which I pick articles for a weborder. When the weborder is picked completely on de device, I want to send the info to Business Central, and post and print immediately, so I can put the printed invoice in the box, and a label on the box. We did just that.
(It’s a little more complicated in Nav terms… register a pick, post a warehouse shipment, post a sales shipment and generated the label, post an invoice and print it… at the correct workplace of the device user but for terms of simplicity this is ignored.)
But then some strange things start happening… multiple devices do this simultaneous on picks on the same warehouse shipment, etc… And online users also to things. So locking and deadlock issues occur.

And fixing those took lot more time than initially expected.

So be careful and think deeply on how the webservices will be used in the multi-user world. A device user has no Business Central page on which he can take action in a simple manner.


30+ year programming experience, and still…

Creating a programming error still is simple, and AI isn’t helping me yet.

I develop software for Microsoft Business Central, in a programming language called C/AL (and in de current version this is changed to AL).

Today in a hurry, bugfixing job, I introduced a new error. The code was more than one page long, and I used a for loop with a local variable _i.
And then I nested two for loops…

for _i := 0 to n do begin

// … a bunch of code for the rest of the page
for _i := 0 to m do begin
//create a record and insert into the database
// and m begin typically begin 1 or 2 and n going to 40 or so.

And so I created an infinite loop, for the first time in years.
In C/AL this was inside a transaction, so the table got locked, users complained, and I was able to kill the process. But it had to rollback the transaction. And it already contained +3.5 million records before the message reached us.

And although this is legit coding (or how should the compiler know?), reusing _i in a second inner loop.
With all AI stuff currently available, I hope for a compiler warning at least.


Business Central Error

We are trying to deploy a mega app to Business Central 16 (spring 2020) and get an ‘Object reference not set to an instance of an object’ in Microsoft.Dynamics.Nav.Management.dll.

With some help of the mibuso forum and the poster of the original problem there, we have found the error and could solve it.

Finding the root problem involves installing visual studio (enterprise in our case) on the business central server, attaching to the Nav server.exe process for debugging and deploying when de debugger is attached.

You will get into the debugger at the moment of the error in the deployment. We’ve got a neat error on the callstack, pointing out the object which is being processed at the time of the error, and the statement which is causing the problem. Not why it’s a problem, but you get some idea.
In our case it seams to be the use of a global Boolean called Update which is initialized to True in the OnPageOpen of the requestpage of the report.
Removing this initialization on that particular place in code resolves the issue.


C# en Web Reference vs. Service Reference

Er zijn nog steeds verschillende mensen die verward raken door het verschil van deze 2 manieren om een webservice te gebruiken in een visual studio C# applicatie.

Add Web Reference: de ‘oude’ manier van werken, gebruik makende van de XmlSerializer. De gegenereerde code is in vele projecten bruikbaar (Web App, Web Site, Console toepassing, winforms toepassing…)

Add Service Reference: de nieuwere manier van werken die een WCF service reference toevoegd. Dit is ‘moderner’ en geeft je meer mogelijkheden om in te grijpen in de communciatielaag.

Het gebruik van de code is op de ‘oude’ manier iets eenvoudiger. Echter is dat een afweging tegen de nieuwe mogelijkheden.

Voorbeeld nieuwe code (servicereference):

binding.Name = "mve1";
binding.Security.Mode = BasicHttpsSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

Uri baseAddress = new Uri("");
EndpointAddress addr = new EndpointAddress(baseAddress);

var client = new ICSGeneral.CSGeneral_PortClient(binding, addr);
           System.ServiceModel.Security.UserNamePasswordClientCredential cre = client.ClientCredentials.UserName;
cre.UserName = @"uuuuuuuuuuu";
cre.Password = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";

string result = client.GetItemVariantInfoByCrossRef("2013111427275", "90-CM", true, true);

Voorbeeld oude code (webreference)

TestDmaCall.ICSGeneral ws = new TestDmaCall.ICSGeneral();
ws.Credentials = new System.Net.NetworkCredential("userid", "passwordtoken");
ws.Url =";        
string result = ws.GetItemVariantInfoByCrossRef("2013111427275", "90-CM", true, true);