It would appear that recently the Chrome ZPL printer emulator is no longer valid which is triggering some people to install a ZPL printer emulator in order to validate Dynamic ZPL code within D365FO. After much research it appears that all these extensions and printer emulators all use the free Label service https://labelary.com/
Because this API is being used throughout the industry why not create our own way to call this API directly within D365 vs installing a printer emulator which then requires a document routing agent to be installed.
The below code snippet shows you how to connect to their RESTful API service which can generate various types of images based on the ZPL codes. You could easily modularize the following logic in order to create something pretty powerful and dynamic based on any dataset.
Webservice to generate a label based on ZPL code: https://labelary.com/service.html
Online ZPL Viewer: https://labelary.com/viewer.html
System.Exception clrError;
InteropPermission interopPermission;
System.Net.HttpWebRequest request;
System.IO.Stream stream;
System.Byte[] zpl = System.Text.Encoding::UTF8.GetBytes("^xa^cfa,50^fo100,100^fdHello World^fs^xz"); //raw zpl code
request = System.Net.WebRequest::Create("http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/") as System.Net.HttpWebRequest;
request.Method = 'POST';
request.Accept = "image/png";
request.ContentType = 'application/x-www-form-urlencoded';
try
{
interopPermission = new InteropPermission(InteropKind::ComInterop);
interopPermission.assert();
// send out the payload
using (System.IO.Stream dataStream = request.GetRequestStream())
{
dataStream.Write(zpl, 0, zpl.Length);
}
using (System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse)
{
stream = response.GetResponseStream();
System.IO.MemoryStream filestream = new System.IO.MemoryStream();
//we need to convert the main stream to a memory stream in order to access the binary objects
stream.CopyTo(filestream);
//send the memory stream directly to the user which now contains a file object
File::SendFileToUser(filestream, "test.png");
//convert the memory stream into an image object which can then be displayed to the user
BinData binData = new BinData();
container baseContainer;
Image image = new Image();
baseContainer = Binary::constructFromMemoryStream(fileStream).getContainer();
binData.setData(baseContainer);
image.setData(binData.getData());
//display the newly created image to the user
FormImageControl1.image(image);
}
Info("done");
}
catch (Exception::CLRError)
{
//catch any clr error
clrError = CLRInterop::getLastException();
if (clrError != null)
{
clrError = clrError.InnerException;
throw error(clrError.ToString());
}
}
finally
{
CodeAccessPermission::revertAssert();
}
No comments:
Post a Comment