Receintly I had to create a communication with a company that would return an image after having received certain info.
Now, in order to store the image (wether in the disk or a BLOB field) we cannot just use the “save as” feature
What the web service did was generate the image file, code it into base64 and send the “translated” info. What does this mean? Well, it means receiving a string of text 4.000 characters long. Not as visual as expected…
But let us not lose hope! This rang a bell in my head. I could have sworn I had seen something similar previously in my collection. So after searching through the personal box of code and the internet (a line from here, a line from there…) what I discovered was this:
1.- Retrieving the base64 code from the webservice (XML).
2.- “Decode” it to data we can understand. In this case a Stream, which NAV, specially in its latest versions, understands very well.
3.- Save this Stream in a BLOB field.
4.- And optionally, extract the info out to an actual file. The only condition is that we must know the format of the end file. In this case I had the option of choosing the format when calling the webservice. In case you do not have the option you must find somehow the format. Or ask to your provider
But really, what code do we need to perform the actions we’ve just seen?
1.- Retrieve the base64 code
In my case, to send the XML info I used the following automation fcomponents. One of them to generate the XML file to send and the other for the actual sending of the just generated XML. I will not go into details as far as the sending process goes.
|XmlHttp||Automation||‘Microsoft XML, v6.0′.XMLHTTP60|
|XmlDoc||Automation||‘Microsoft XML, v6.0′.DOMDocument60|
What I do want to say is that after having sent the info using the function:
//We load the document XmlDoc.load(XmlHttp.responseBody);
We can capture the response using:
XmlDoc.text // Contains the info of the XML response text XmlDoc.xml // Contains all the XML text of the response, including hierarchy, tags, etc
In this case I only wanted the base64 text and not the entire XML so I used XmlDoc.text.
2.- “Decode” it to data we can use
Nice. So we can retrieve the response from the webservice. To “translate” it and treat it we must first convert it.
To do so we will declare the following variables:
|MemoryStream||DotNet||System.IO.MemoryStream.’mscorlib, Version=18.104.22.168, Culture=neutral, PublicKeyToken=b77a5c561934e089′|
|Bytes||DotNet||System.Array.’mscorlib, Version=22.214.171.124, Culture=neutral, PublicKeyToken=b77a5c561934e089′|
|Convert||DotNet||System.Convert.’mscorlib, Version=126.96.36.199, Culture=neutral, PublicKeyToken=b77a5c561934e089′|
And type the following code:
BigText1.ADDTEXT(XmlDoc.text); // Store in BigText1 the XML result Bytes := Convert.FromBase64String(BigText1); // Convert to String MemoryStream := MemoryStream.MemoryStream(Bytes); // Save in a Stream
3.- Store the Stream in a BLOB
In this case what we’ll do is create an OutStream for the field we wish to store the image onto and afterwards we will write in that Stream. Once we’ve done that we will save the modification.
Record.BLOBField.CREATEOUTSTREAM(OStream); MemoryStream.WriteTo(OStream); Record.MODIFY;
4.- Export the info to a file
Once we’re at this stage, we already have the file decoded and stored in our system. Now we can export it to read it from the right application.
To do so, we will again take the same BLOB field and create a Stream with its content (unlike before, this is an InStream).
ToFile := 'FileName.png'; Record.BlobField.CREATEINSTREAM(IStream); DOWNLOADFROMSTREAM(IStream,'','<TEMP>', '',ToFile); // Silent Download MESSAGE('The file is stored here'+ToFile); // Displays the full path
And that is it!