Getting started with NAV and .Net Interop – Part 3

Taking it further

After showing in Part 2 how to take the simplest piece of C# code and walk through the process of converting it to C/AL it’s time we crank it up a notch (see what I did there? J).

Importing a single file with streams

First off something we’ve all done since Dataports left us and XMLPorts refused to import from a filename directly:

lf_File.OPEN(lv_FilePath);
lf_File.CREATEINSTREAM(lis_);
lx_MyXMLPort.SETSOURCE(lis_);
lx_MyXMLPort.IMPORT;
lf_File.CLOSE;

Opening the stream

We can Google for “c# create stream from file” and find this page. With that we see we need to use the FileStream class, instantiate it by calling the constructor with some parameters and close it. Not entirely unlike what we do in our C/AL sample…
[C#]
using System.IO;
FileStream fileStream = new FileStream(@"c:\file.txt", FileMode.Open);
try{
  // read from file or write to file
}
finally{
  fileStream.Close();
}

Enumerations are a pain in NAV 2009 R2

Notice also that we use the FileMode “class”. I put class between double quotes because, if you click the link, you’ll see it’s actually an enum (short for enumeration). An enum is practically exactly like a C/AL Option. Text values are mapped to integer values.

Now, in NAV 2013 (R2) this is a piece of cake. You define a DotNet variable of subtype “System.IO.FileMode.'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'” and you can reference the values in the Symbol Menu:




















In NAV 2009 R2 however this does not work. If that happens you’ll need to find the correct integer values. While .Net likes starting everything everywhere at 0 there is no guarantee that the third value of the FileMode enumeration “Open” will be “2”.

I refer to Blogpost 1 and Blogpost 2 Eric Wauters (aka “waldo”) has made. To sum them up: make a function “Enum2int” to get the integer value from the text value at runtime.
Enum2Int(pSystemEnum : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Enum";pEnumValue : Text(30)) : Integer
EXIT(SystemConvert.ToInt32(pSystemEnum.Parse(pSystemEnum.GetType,pEnumValue)));
This might not be very optimal performance wise, so cache them if you need to.

Putting it together

No matter the version you’ll end up with something like this:

ldn_FileStream := ldn_FileStream.FileStream(lv_FilePath, ldn_FileMode.Open);
lx_MyXMLPort.SETSOURCE(ldn_FileStream);
lx_MyXMLPort.IMPORT;
ldn_FileStream.Close();

Considerations

Now you may question whether that was worth it. I mean, all that trouble and your code is one line shorter. First of all, it’s a lesson. Examples in lessons are always contrived and farfetched (I mean, who buys 50 melons? Am I right?). Second, the deeper lesson is that it’s no surprise where Microsoft got the idea from to suddenly start putting streams in our Navision (to be fair, Java did it before .Net, and OS’es have been doing it since forever).

That’s a wrap

So yeah, Part 3 is done. In Part 4 I’ll continue poking the filesystem and ramble (and on) about Collections (no, not stamp collections).

Reacties

Populaire posts van deze blog

Getting started with NAV and .Net Interop – Part 4

Getting started with NAV and .Net Interop – Part 1