How to begin using .Net in C/AL?

So you have a problem and you have found a package on Nuget that might just fix it for you in no time. Where to start?

Lets presume I want a QR generator, I want to create custom QR codes for documents or items. It could be a link to the data sheet, and you want it on your company web page or Item card for easy access for technicians.

They might find the item on a PC but need the drawings later at the machine. So they find it and scan the code, which triggers a download of the PDF data sheet, so they have it offline. There are multiple uses for this. I am not here for the why, just the how.

Here I just make QR codes for contacts so that people can scan them and add the info to their phones.

Prerequests

So I opened Nuget website and entered: QR generator

First hit was this: https://www.nuget.org/packages/QRCoder/

To use this I needed the compiled DLL’s so I clicked the Manual Download button to the right.

2018-06-05_14-39-21

This will give you a Nuget package (which is a zipped file with some naming patterns and metadata), just unzip it.

Inside will be the DLL’s compiled towards different frameworks – I chose the portable-net45 version. This I copied onto the servers addins folder (and to the addins folder on my dev machine, but that is not necessary).

Then I found the documentation for QRCoder which showed a simple example for how to make it in C#. Now we just need to translate that into C/AL.

I took the code example from here:


QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode("The text which should be encoded.", QRCodeGenerator.ECCLevel.Q);
PngByteQRCode qrCode = new PngByteQRCode(qrCodeData);
byte[] qrCodeAsPngByteArr = qrCode.GetGraphic(20);

First we check for the types the code requires. We can see that it refers to some called QRCodeGenerator, QRData, PngByteQRCode, ECCLevel and a byte-array.

Name DataType Subtype
DotNet QRCoder.QRCodeGenerator.’QRCoder, Version=1.3.3.0, Culture=neutral, PublicKeyToken=null’
g_QRCodeData DotNet QRCoder.QRCodeData.’QRCoder, Version=1.3.3.0, Culture=neutral, PublicKeyToken=null’
g_PngQRCode DotNet QRCoder.PngByteQRCode.’QRCoder, Version=1.3.3.0, Culture=neutral, PublicKeyToken=null’
g_ECCLEvel DotNet QRCoder.QRCodeGenerator+ECCLevel.’QRCoder, Version=1.3.3.0, Culture=neutral, PublicKeyToken=null’
g_PayloadURL DotNet QRCoder.PayloadGenerator+Url.’QRCoder, Version=1.3.3.0, Culture=neutral, PublicKeyToken=null’
g_ArrayByte DotNet System.Array.’mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′
g_MemoryStream DotNet System.IO.MemoryStream.’mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′

In my first try I used an URL payload, more interactive (hence fun).

Then I broke down each line and made a C/AL version of the example line.


// QRCodeGenerator qrGenerator = new QRCodeGenerator();
g_QRCodeGenerator := g_QRCodeGenerator.QRCodeGenerator;

// QRCodeData qrCodeData = qrGenerator.CreateQrCode("The text which should be encoded.", QRCodeGenerator.ECCLevel.Q);
g_PayloadURL := g_PayloadURL.Url('https://blog.sshadows.dk');
g_QRCodeData := g_QRCodeGenerator.CreateQrCode(g_PayloadURL, g_ECCLEvel.Q);

// PngByteQRCode qrCode = new PngByteQRCode(qrCodeData);
g_PngQRCode := g_PngQRCode.PngByteQRCode(g_QRCodeData);

// byte[] qrCodeAsPngByteArr = qrCode.GetGraphic(20);
g_ArrayByte := g_PngQRCode.GetGraphic(20); 

No fun if you can not see the result, so let us just quickly add it to a random contact.


// Add to stream
g_MemoryStream := g_MemoryStream.MemoryStream(g_ArrayByte);

//Find a contact and import stream into contact picture.
g_Contact.GET('KT200081');
g_Contact.Image.IMPORTSTREAM(g_MemoryStream,'QR');
g_Contact.MODIFY(TRUE);

The result is this fine QR code – you can check on your own phone if it works.
Microsoft.Dynamics.Nav.Client_2018-06-06_21-40-59

So far, so good.

But I said I wanted to use the contact payload, so let us add what that requires to.

Name DataType Subtype
g_Contact Record Contact
g_PayloadContactData DotNet QRCoder.PayloadGenerator+ContactData.’QRCoder, Version=1.3.3.0, Culture=neutral, PublicKeyToken=null’
g_PayloadContactDataType DotNet QRCoder.PayloadGenerator+ContactData+ContactOutputType.’QRCoder, Version=1.3.3.0, Culture=neutral, PublicKeyToken=null’
g_DateTime DotNet System.DateTime.’mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′

Here I met one of the first bumps on the road, one of the parameters were identified as something called an System.Nullable`1. A bit of searching led me to Mibuso and a post on the forum, saying this is not possible in NAV.
I thought: “what the heck, let us just give it a DOTNET DateTime type that should refer to a birthday and hope that will work!” (Spoiler, it did!)

What I ended up with was this:


g_DateTime := g_DateTime.DateTime(1980,1,1);
g_PayloadContactData := g_PayloadContactData.ContactData(
  g_PayloadContactDataType.VCard4, 
  'Torben', //First
  'Leth', //Last
  'SShadowS', //Nickname
  '', //Phone
  '', //Mobilephone
  '', //Workphone
  '[email protected]', //email
  g_DateTime, //Birthday
  '', //Website
  '', //Street
  '', //Housenumber
  '', //City
  '', //Zip
  '', //Country
  ''); //Note
g_QRCodeData := g_QRCodeGenerator.CreateQrCode(g_PayloadContactData, g_ECCLEvel.Q);

Then I just swapped out the URL payload var with the Contact Payload var and it worked like a charm.

Microsoft.Dynamics.Nav.Client_2018-06-06_21-55-42

Remember; Google is your friend, add some common sense and a dash of trial-and-error and you will get there.

If still at a dead end, add more Google…

Source code:
https://www.dropbox.com/s/ufuxjfr7cgmklul/QR%20Example.txt?dl=1

Leave a Reply

Your email address will not be published. Required fields are marked *