How to print raw Zebra EPL (Eltron) commands from ASP.NET directly to the client printer

The Eltron Programming Language 2 (EPL2) is a robust text (ASCII) based command language used to control most Eltron brand Zebra printer models. EPL2 takes advantage of the intelligent features built into the printer to reduce programming overhead and minimize data transmission time. EPL is one of command printer languages from Zebra Technologies that is supported by their printers as well as by others thermal printer manufactures like SATO, Datamax, Intermec, Godex (by providing EPL firmware emulation software). Zebra printers are widely used in POS (Point Of Sales or Point of Services) scenarios like retail, banking, hospitality, manufacturing, healthcare and more!

The main advantage of using raw Zebra EPL commands for printing instead of using the built-in browser javascript printing (window.print();) is that the printing performance will be way faster and you, as the developer in charge, will have full control on the printer operation; a factor that is key in the aforementioned scenarios. In ASP.NET websites, you'll be able to use raw printing feature thanks to our WebClientPrint for ASP.NET solution that was specially designed for this kind of printing needs.

In this walkthrough, you'll learn how to print raw EPL commands from an ASP.NET website directly to the client printer without displaying a print dialog at all. You'll be able to print Zebra EPL commands to the Default client printer as well as to any other installed printer at the client machine. This solution works with any popular browser like Chrome, Firefox, Opera & Safari on Windows, Linux, Raspberry Pi or Mac systems!

The Zebra EPL commands that we'll use in this article will print out a simple barcode label that will look like this:

<a href=A Sample Barcode Label printed from ASP.NET and created by using Zebra EPL commands" />


A Sample Barcode Label printed from ASP.NET and created by using Zebra EPL commands

How to specify EPL commands in ASP.NET

EPL commands sometimes call for ASCII chars that are non-readable. For instance, be aware that each line of EPL commands must be terminated by a "Line Feed/New Line" char i.e. ASCII Dec 10 which you can escape in your .NET code by using 0x10 or &H10 notation
It's also strongly recommended that you always start a new label by using a "Line Feed/New Line" char as well.

Later on this article, you'll find the Zebra EPL commands that you can use in C# or VB to print the sample receipt shown above.

Requirements

Development/Server-side

WebClientPrint 6.0 for ASP.NET (or greater)
ASP.NET 4.6.1+ or ASP.NET Core 2.0+
Visual Studio 2015+
jQuery 1.4.1+

Client-side

WebClientPrint Processor 6.0 for Windows, Linux, Raspberry Pi & Mac

Follow up these steps

Creating/Editing Controllers

Create a new Controller and name it WebClientPrintAPIController and then copy/paste the following code:

 using Neodynamic.SDK.Web; using Microsoft.Extensions.Caching.Memory; using Microsoft.AspNetCore.Authorization; [Authorize] public class WebClientPrintAPIController : Controller < //IMPORTANT NOTE >>>>>>>>>> // We're going to use MemoryCache to store users related staff like // the list of printers and they have the WCPP client utility installed // BUT you can change it based on your dev needs. // For instance, you could use a Distributed Cache instead! //>>>>>>>>>>>>>>>>>>>>>>>>> private readonly IMemoryCache _MemoryCache; public WebClientPrintAPIController(IMemoryCache memCache) < _MemoryCache = memCache; >[AllowAnonymous] public IActionResult ProcessRequest() < //get session ID string sessionID = HttpContext.Request.Query["sid"].ToString(); //get Query String string queryString = HttpContext.Request.QueryString.Value; try < //Determine and get the Type of Request RequestType prType = WebClientPrint.GetProcessRequestType(queryString); if (prType == RequestType.GenPrintScript || prType == RequestType.GenWcppDetectScript) < //Let WebClientPrint to generate the requested script byte[] script = WebClientPrint.GenerateScript(Url.Action("ProcessRequest", "WebClientPrintAPI", null, HttpContext.Request.Scheme), queryString); return File(script, "application/x-javascript", "WebClientPrintScript"); >else if (prType == RequestType.ClientSetWcppVersion) < //This request is a ping from the WCPP utility //so store the session ID indicating it has the WCPP installed //also store the WCPP Version if available string wcppVersion = HttpContext.Request.Query["wcppVer"]; if (string.IsNullOrEmpty(wcppVersion)) wcppVersion = "1.0.0.0"; _MemoryCache.Set(sessionID + "wcppInstalled", wcppVersion); >else if (prType == RequestType.ClientSetInstalledPrinters) < //WCPP Utility is sending the installed printers at client side //so store this info with the specified session ID string printers = HttpContext.Request.Query["printers"].ToString(); if (!string.IsNullOrEmpty(printers) && printers.Length >0) printers = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printers)); _MemoryCache.Set(sessionID + "printers", printers); > else if (prType == RequestType.ClientSetInstalledPrintersInfo) < //WCPP Utility is sending the client installed printers with detailed info //so store this info with the specified session ID //Printers Info is in JSON format string printersInfo = HttpContext.Request.Form["printersInfoContent"]; if (string.IsNullOrEmpty(printersInfo) == false) printersInfo = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printersInfo)); _MemoryCache.Set(sessionID + "printersInfo", printersInfo); >else if (prType == RequestType.ClientGetWcppVersion) < //return the WCPP version for the specified sid if any bool sidWcppVersion = (_MemoryCache.Get(sessionID + "wcppInstalled") != null); return Ok(sidWcppVersion ? _MemoryCache.Get(sessionID + "wcppInstalled") : ""); > else if (prType == RequestType.ClientGetInstalledPrinters) < //return the installed printers for the specified sid if any bool sidHasPrinters = (_MemoryCache.Get(sessionID + "printers") != null); return Ok(sidHasPrinters ? _MemoryCache.Get(sessionID + "printers") : ""); > else if (prType == RequestType.ClientGetInstalledPrintersInfo) < //return the installed printers with detailed info for the specified Session ID (sid) if any bool sidHasPrinters = (_MemoryCache.Get(sessionID + "printersInfo") != null); return Ok(sidHasPrinters ? _MemoryCache.Get(sessionID + "printersInfo") : ""); > > catch < return BadRequest(); >return Ok(); > > 

Edit the HomeController to the following code:

 public class HomeController : Controller < public IActionResult Index() < ViewData["WCPPDetectionScript"] = Neodynamic.SDK.Web.WebClientPrint.CreateWcppDetectionScript(Url.Action("ProcessRequest", "WebClientPrintAPI", null, Url.ActionContext.HttpContext.Request.Scheme), Url.ActionContext.HttpContext.Session.Id); return View(); >public IActionResult PrintEPL() < return View(); >> 

Add a new Controller and name it PrintEPLController and paste the following code:

 using Neodynamic.SDK.Web; public class PrintEPLController : Controller < private readonly IHostingEnvironment _hostEnvironment; public PrintEPLController(IHostingEnvironment hostEnvironment) < _hostEnvironment = hostEnvironment; >public IActionResult Index() < ViewData["WCPScript"] = Neodynamic.SDK.Web.WebClientPrint.CreateScript(Url.Action("ProcessRequest", "WebClientPrintAPI", null, Url.ActionContext.HttpContext.Request.Scheme), Url.Action("PrintCommands", "PrintEPL", null, Url.ActionContext.HttpContext.Request.Scheme), Url.ActionContext.HttpContext.Session.Id); return View(); >[Microsoft.AspNetCore.Authorization.AllowAnonymous] public IActionResult PrintCommands(string useDefaultPrinter, string printerName) < //Create Zebra EPL commands for sample receipt string lineFeed = "0x0A"; string cmds = ""; cmds += lineFeed; cmds += "N"; cmds += lineFeed; cmds += "Q609,24"; cmds += lineFeed; cmds += "q784"; cmds += lineFeed; cmds += "A170,5,0,1,5,5,N,\"WORLDWIDE\""; cmds += lineFeed; cmds += "LO5,230,765,10"; cmds += lineFeed; cmds += "A10,265,0,1,3,3,R,\"MODEL:\""; cmds += lineFeed; cmds += "A280,265,0,1,3,3,N,\"Bar Code Printer\""; cmds += lineFeed; cmds += "A10,340,0,1,3,3,R,\" CODE: \""; cmds += lineFeed; cmds += "B280,340,0,3C,2,6,120,B,\"BCP-1234\""; cmds += lineFeed; cmds += "LO5,520,765,10"; cmds += lineFeed; cmds += "A100,550,0,1,2,2,N,\"ISO 9000 Made In USA\""; cmds += lineFeed; cmds += "P1"; cmds += lineFeed; //Create a ClientPrintJob and send it back to the client! ClientPrintJob cpj = new ClientPrintJob(); //set EPL commands to print. cpj.PrinterCommands = cmds; cpj.FormatHexValues = true; //set client printer. if (useDefaultPrinter == "checked" || printerName == "null") cpj.ClientPrinter = new DefaultPrinter(); else cpj.ClientPrinter = new InstalledPrinter(printerName); return File(cpj.GetContent(), "application/octet-stream"); >> 

Creating/Editing Views

The default View is for detecting whether the client machine has the WebClientPrint Processor (WCPP) Utility installed. Edit the Views / Shared / _Layout.cshtml file and add the folowing section to the BODY:

Be sure this View links to jQuery 1.4.1+ file!

  . @RenderSection("scripts", required: false) . 

Edit the Views / Home / Index.cshtml file and copy/paste the folowing code:

 @ < ViewBag.Title = "Home Page"; > 

Detecting WCPP utility at client side.

Please wait a few seconds.


#1 Install WebClientPrint Processor (WCPP)!

WCPP is a native app (without any dependencies!) that handles all print jobs generated by the WebClientPrint for ASP.NET component at the server side. The WCPP is in charge of the whole printing process and can be installed on Windows, Linux, Mac & Raspberry Pi!

Download and Install WCPP from Neodynamic website

#2 After installing WCPP.

You can go and test the printing page.

@section scripts < @* WCPP detection script generated by HomeController *@ @Html.Raw(ViewData["WCPPDetectionScript"]) >

Add a new View with the following name and under such folders: Views / PrintEPL / Index.cshtml Then, copy/paste the folowing code:

 

Print EPL commands

Click to load and select one of the installed printers!



@section scripts

Creating/Editing Controllers

Create a new Controller and name it WebClientPrintAPIController and then copy/paste the following code:

 public class WebClientPrintAPIController : Controller < //********************************* // IMPORTANT NOTE // In this sample we store users related stuff (like // the list of printers and whether they have the WCPP // client utility installed) in the Application cache // object part of ASP.NET BUT you can change it to // another different storage (like a DB or file server)! // which will be required in Load Balacing scenarios //********************************* [AllowAnonymous] public void ProcessRequest() < //get session ID string sessionID = (HttpContext.Request["sid"] != null ? HttpContext.Request["sid"] : null); //get Query String string queryString = HttpContext.Request.Url.Query; try < //Determine and get the Type of Request RequestType prType = WebClientPrint.GetProcessRequestType(queryString); if (prType == RequestType.GenPrintScript || prType == RequestType.GenWcppDetectScript) < //Let WebClientPrint to generate the requested script byte[] script = WebClientPrint.GenerateScript(Url.Action("ProcessRequest", "WebClientPrintAPI", null, HttpContext.Request.Url.Scheme), queryString); HttpContext.Response.ContentType = "text/javascript"; HttpContext.Response.BinaryWrite(script); HttpContext.Response.End(); >else if (prType == RequestType.ClientSetWcppVersion) < //This request is a ping from the WCPP utility //so store the session ID indicating it has the WCPP installed //also store the WCPP Version if available string wcppVersion = HttpContext.Request["wcppVer"]; if (string.IsNullOrEmpty(wcppVersion)) wcppVersion = "1.0.0.0"; HttpContext.Application.Set(sessionID + "wcppInstalled", wcppVersion); >else if (prType == RequestType.ClientSetInstalledPrinters) < //WCPP Utility is sending the installed printers at client side //so store this info with the specified session ID string printers = HttpContext.Request["printers"]; if (string.IsNullOrEmpty(printers) == false) printers = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printers)); HttpContext.Application.Set(sessionID + "printers", printers); >else if (prType == RequestType.ClientSetInstalledPrintersInfo) < //WCPP Utility is sending the client installed printers with detailed info //so store this info with the specified session ID //Printers Info is in JSON format string printersInfo = HttpContext.Request.Form["printersInfoContent"]; if (string.IsNullOrEmpty(printersInfo) == false) printersInfo = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printersInfo)); HttpContext.Application.Set(sessionID + "printersInfo", printersInfo); >else if (prType == RequestType.ClientGetWcppVersion) < //return the WCPP version for the specified sid if any bool sidWcppVersion = (HttpContext.Application.Get(sessionID + "wcppInstalled") != null); HttpContext.Response.ContentType = "text/plain"; HttpContext.Response.Write((sidWcppVersion ? HttpContext.Application.Get(sessionID + "wcppInstalled") : "")); HttpContext.Response.End(); >else if (prType == RequestType.ClientGetInstalledPrinters) < //return the installed printers for the specified sid if any bool sidHasPrinters = (HttpContext.Application.Get(sessionID + "printers") != null); HttpContext.Response.ContentType = "text/plain"; HttpContext.Response.Write((sidHasPrinters ? HttpContext.Application.Get(sessionID + "printers") : "")); HttpContext.Response.End(); >else if (prType == RequestType.ClientGetInstalledPrintersInfo) < //return the installed printers with detailed info for the specified Session ID (sid) if any bool sidHasPrinters = (HttpContext.Application[sessionID + "printersInfo"] != null); HttpContext.Response.ContentType = "text/plain"; HttpContext.Response.Write(sidHasPrinters ? HttpContext.Application[sessionID + "printersInfo"] : ""); >> catch (Exception ex) < HttpContext.Response.StatusCode = 500; HttpContext.Response.ContentType = "text/plain"; HttpContext.Response.Write(ex.Message + " - StackTrace: " + ex.StackTrace); HttpContext.Response.End(); >> > 

Edit the HomeController to the following code:

 public class HomeController : Controller < public ActionResult Index() < ViewBag.WCPPDetectionScript = Neodynamic.SDK.Web.WebClientPrint.CreateWcppDetectionScript(Url.Action("ProcessRequest", "WebClientPrintAPI", null, HttpContext.Request.Url.Scheme), HttpContext.Session.SessionID); return View(); >public ActionResult PrintEPL() < return View(); >> 

Add a new Controller and name it PrintEPLController and paste the following code:

 using Neodynamic.SDK.Web; public class PrintEPLController : Controller < public ActionResult Index() < ViewBag.WCPScript = WebClientPrint.CreateScript(Url.Action("ProcessRequest", "WebClientPrintAPI", null, HttpContext.Request.Url.Scheme), Url.Action("PrintCommands", "PrintEPL", null, HttpContext.Request.Url.Scheme), HttpContext.Session.SessionID); return View(); >[AllowAnonymous] public void PrintCommands(string useDefaultPrinter, string printerName) < //Create Zebra EPL commands for sample receipt string lineFeed = "0x0A"; string cmds = ""; cmds += lineFeed; cmds += "N"; cmds += lineFeed; cmds += "Q609,24"; cmds += lineFeed; cmds += "q784"; cmds += lineFeed; cmds += "A170,5,0,1,5,5,N,\"WORLDWIDE\""; cmds += lineFeed; cmds += "LO5,230,765,10"; cmds += lineFeed; cmds += "A10,265,0,1,3,3,R,\"MODEL:\""; cmds += lineFeed; cmds += "A280,265,0,1,3,3,N,\"Bar Code Printer\""; cmds += lineFeed; cmds += "A10,340,0,1,3,3,R,\" CODE: \""; cmds += lineFeed; cmds += "B280,340,0,3C,2,6,120,B,\"BCP-1234\""; cmds += lineFeed; cmds += "LO5,520,765,10"; cmds += lineFeed; cmds += "A100,550,0,1,2,2,N,\"ISO 9000 Made In USA\""; cmds += lineFeed; cmds += "P1"; cmds += lineFeed; //Create a ClientPrintJob and send it back to the client! ClientPrintJob cpj = new ClientPrintJob(); //set Zebra EPL commands to print. cpj.PrinterCommands = cmds; cpj.FormatHexValues = true; //set client printer. if (useDefaultPrinter == "checked" || printerName == "null") cpj.ClientPrinter = new DefaultPrinter(); else cpj.ClientPrinter = new InstalledPrinter(printerName); //send it. System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream"; System.Web.HttpContext.Current.Response.BinaryWrite(cpj.GetContent()); System.Web.HttpContext.Current.Response.End(); >> 

Creating/Editing Views

The default View is for detecting whether the client machine has the WebClientPrint Processor (WCPP) Utility installed. Edit the Views / Shared / _Layout.cshtml file and add the folowing section to the BODY:

Be sure this View links to jQuery 1.4.1+ file!

  . @RenderSection("scripts", required: false) . 

Edit the Views / Home / Index.cshtml file and copy/paste the folowing code:

 @ < ViewBag.Title = "Home Page"; > 

Detecting WCPP utility at client side.

Please wait a few seconds.


#1 Install WebClientPrint Processor (WCPP)!

WCPP is a native app (without any dependencies!) that handles all print jobs generated by the WebClientPrint for ASP.NET component at the server side. The WCPP is in charge of the whole printing process and can be installed on Windows, Linux, Mac & Raspberry Pi!

Download and Install WCPP from Neodynamic website

#2 After installing WCPP.

You can go and test the printing page.

@section scripts < @* WCPP detection script generated by HomeController *@ @Html.Raw(ViewBag.WCPPDetectionScript) >

Add a new View with the following name and under such folders: Views / PrintEPL / Index.cshtml Then, copy/paste the folowing code:

 

Print EPL commands

Click to load and select one of the installed printers!



@section scripts

Creating/Editing Controllers

Create a new Controller and name it WebClientPrintAPIController and then copy/paste the following code:

 Imports Neodynamic.SDK.Web Namespace Controllers Public Class WebClientPrintAPIController Inherits Controller ' GET: WebClientPrintAPI Function Index() As ActionResult Return View() End Function '********************************* ' IMPORTANT NOTE ' In this sample we store users related stuff (like ' the list of printers and whether they have the WCPP ' client utility installed) in the Application cache ' object part of ASP.NET BUT you can change it to ' another different storage (like a DB or file server)! ' which will be required in Load Balacing scenarios '********************************* Public Sub ProcessRequest() 'get session ID Dim sessionID As String = (If(HttpContext.Request("sid") IsNot Nothing, HttpContext.Request("sid"), Nothing)) 'get Query String Dim queryString As String = HttpContext.Request.Url.Query Try 'Determine and get the Type of Request Dim prType As RequestType = WebClientPrint.GetProcessRequestType(queryString) If prType = RequestType.GenPrintScript OrElse prType = RequestType.GenWcppDetectScript Then 'Let WebClientPrint to generate the requested script Dim script As Byte() = WebClientPrint.GenerateScript(Url.Action("ProcessRequest", "WebClientPrintAPI", Nothing, HttpContext.Request.Url.Scheme), queryString) HttpContext.Response.ContentType = "text/javascript" HttpContext.Response.BinaryWrite(script) HttpContext.Response.End() ElseIf prType = RequestType.ClientSetWcppVersion Then 'This request is a ping from the WCPP utility 'so store the session ID indicating it has the WCPP installed 'also store the WCPP Version if available Dim wcppVersion As String = HttpContext.Request("wcppVer") If String.IsNullOrEmpty(wcppVersion) Then wcppVersion = "1.0.0.0" End If HttpContext.Application.Set(sessionID & "wcppInstalled", wcppVersion) ElseIf prType = RequestType.ClientSetInstalledPrinters Then 'WCPP Utility is sending the installed printers at client side 'so store this info with the specified session ID Dim printers As String = HttpContext.Request("printers") If String.IsNullOrEmpty(printers) = False Then printers = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printers)) End If HttpContext.Application.Set(sessionID & "printers", printers) ElseIf prType = RequestType.ClientSetInstalledPrintersInfo Then 'WCPP Utility is sending the installed printers at client side 'so store this info with the specified session ID 'Printers Info is in JSON format Dim printersInfo As String = HttpContext.Request.Form("printersInfoContent") If Not String.IsNullOrEmpty(printersInfo) Then printersInfo = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printersInfo)) End If HttpContext.Application.Set(sessionID & "printersInfo", printersInfo) ElseIf prType = RequestType.ClientGetWcppVersion Then 'return the WCPP version for the specified sid if any Dim sidWcppVersion As Boolean = (HttpContext.Application(sessionID & "wcppInstalled") IsNot Nothing) HttpContext.Response.ContentType = "text/plain" If (sidWcppVersion) Then HttpContext.Response.Write(HttpContext.Application(sessionID & "wcppInstalled").ToString()) End If HttpContext.Response.End() ElseIf prType = RequestType.ClientGetInstalledPrinters Then 'return the installed printers for the specified sid if any Dim sidHasPrinters As Boolean = (HttpContext.Application(sessionID & "printers") IsNot Nothing) HttpContext.Response.ContentType = "text/plain" If (sidHasPrinters) Then HttpContext.Response.Write(HttpContext.Application(sessionID & "printers").ToString()) End If HttpContext.Response.End() ElseIf prType = RequestType.ClientGetInstalledPrintersInfo Then 'return the installed printers with detailed info for the specified Session ID (sid) if any Dim sidHasPrinters As Boolean = (HttpContext.Application(sessionID & "printersInfo") IsNot Nothing) HttpContext.Response.ContentType = "text/plain" If (sidHasPrinters) Then HttpContext.Response.Write(HttpContext.Application(sessionID & "printersInfo").ToString()) End If HttpContext.Response.End() End If Catch ex As Exception HttpContext.Response.StatusCode = 500 HttpContext.Response.ContentType = "text/plain" HttpContext.Response.Write(ex.Message + " - StackTrace: " + ex.StackTrace) HttpContext.Response.End() End Try End Sub End Class End Namespace 

Edit the HomeController to the following code:

 Public Class HomeController Inherits System.Web.Mvc.Controller Function Index() As ActionResult ViewData("WCPPDetectionScript") = Neodynamic.SDK.Web.WebClientPrint.CreateWcppDetectionScript(Url.Action("ProcessRequest", "WebClientPrintAPI", Nothing, HttpContext.Request.Url.Scheme), HttpContext.Session.SessionID) Return View() End Function Function PrintEPL() As ActionResult Return View() End Function End Class 

Add a new Controller and name it PrintEPLController and paste the following code:

 Imports Neodynamic.SDK.Web Namespace Controllers Public Class PrintEPLController Inherits Controller Function Index() As ActionResult ViewData("WCPScript") = Neodynamic.SDK.Web.WebClientPrint.CreateScript(Url.Action("ProcessRequest", "WebClientPrintAPI", Nothing, HttpContext.Request.Url.Scheme), Url.Action("PrintCommands", "PrintEPL", Nothing, HttpContext.Request.Url.Scheme), HttpContext.Session.SessionID) Return View() End Function Public Sub PrintCommands(useDefaultPrinter As String, printerName As String) 'Create Zebra EPL commands for sample label Dim lineFeed As String = "0x0A" Dim cmds As String cmds += lineFeed cmds += "N" cmds += lineFeed cmds += "Q609,24" cmds += lineFeed cmds += "q784" cmds += lineFeed cmds += "A170,5,0,1,5,5,N,""WORLDWIDE""" cmds += lineFeed cmds += "LO5,230,765,10" cmds += lineFeed cmds += "A10,265,0,1,3,3,R,""MODEL:""" cmds += lineFeed cmds += "A280,265,0,1,3,3,N,""Bar Code Printer""" cmds += lineFeed cmds += "A10,340,0,1,3,3,R,"" CODE: """ cmds += lineFeed cmds += "B280,340,0,3C,2,6,120,B,""BCP-1234""" cmds += lineFeed cmds += "LO5,520,765,10" cmds += lineFeed cmds += "A100,550,0,1,2,2,N,""ISO 9000 Made In USA""" cmds += lineFeed cmds += "P1" cmds += lineFeed 'Create a ClientPrintJob and send it back to the client! Dim cpj As New ClientPrintJob() 'set Zebra EPL commands to print. cpj.PrinterCommands = cmds cpj.FormatHexValues = True If (useDefaultPrinter = "checked" OrElse printerName = "null") Then cpj.ClientPrinter = New DefaultPrinter() Else cpj.ClientPrinter = New InstalledPrinter(System.Web.HttpUtility.UrlDecode(printerName)) End If System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream" System.Web.HttpContext.Current.Response.BinaryWrite(cpj.GetContent()) System.Web.HttpContext.Current.Response.End() End Sub End Class End Namespace 

Creating/Editing Views

The default View is for detecting whether the client machine has the WebClientPrint Processor (WCPP) Utility installed. Edit the Views / Shared / _Layout.vbhtml file and add the folowing section to the BODY:

Be sure this View links to jQuery 1.4.1+ file!

  . @RenderSection("scripts", required: False) . 

Edit the Views / Home / Index.vbhtml file and copy/paste the folowing code:

 @Code ViewData("Title") = "Home Page" End Code 

Detecting WCPP utility at client side.

Please wait a few seconds.


#1 Install WebClientPrint Processor (WCPP)!

WCPP is a native app (without any dependencies!) that handles all print jobs generated by the WebClientPrint for ASP.NET component at the server side. The WCPP is in charge of the whole printing process and can be installed on Windows, Linux, Mac & Raspberry Pi!

Download and Install WCPP from Neodynamic website

#2 After installing WCPP.

You can go and test the printing page.

@section scripts @* WCPP detection script generated by HomeController *@ @Html.Raw(ViewData("WCPPDetectionScript")) > End Section

Add a new View with the following name and under such folders: Views / PrintEPL / Index.vbhtml Then, copy/paste the folowing code:

 

Print EPL commands

Click to load and select one of the installed printers!



@section scripts @* Register the WebClientPrint script code generated by PrintEPLController. *@ @Html.Raw(ViewData("WCPScript")) @end section

Creating/Editing Controllers

Create a new Controller and name it WebClientPrintAPIController and then copy/paste the following code:

 public class WebClientPrintAPIController : Controller < //********************************* // IMPORTANT NOTE // In this sample we store users related stuff (like // the list of printers and whether they have the WCPP // client utility installed) in the Application cache // object part of ASP.NET BUT you can change it to // another different storage (like a DB or file server)! // which will be required in Load Balacing scenarios //********************************* [AllowAnonymous] public void ProcessRequest() < //get session ID string sessionID = (HttpContext.Request["sid"] != null ? HttpContext.Request["sid"] : null); //get Query String string queryString = HttpContext.Request.Url.Query; try < //Determine and get the Type of Request RequestType prType = WebClientPrint.GetProcessRequestType(queryString); if (prType == RequestType.GenPrintScript || prType == RequestType.GenWcppDetectScript) < //Let WebClientPrint to generate the requested script byte[] script = WebClientPrint.GenerateScript(Url.Action("ProcessRequest", "WebClientPrintAPI", null, HttpContext.Request.Url.Scheme), queryString); HttpContext.Response.ContentType = "text/javascript"; HttpContext.Response.BinaryWrite(script); HttpContext.Response.End(); >else if (prType == RequestType.ClientSetWcppVersion) < //This request is a ping from the WCPP utility //so store the session ID indicating it has the WCPP installed //also store the WCPP Version if available string wcppVersion = HttpContext.Request["wcppVer"]; if (string.IsNullOrEmpty(wcppVersion)) wcppVersion = "1.0.0.0"; HttpContext.Application.Set(sessionID + "wcppInstalled", wcppVersion); >else if (prType == RequestType.ClientSetInstalledPrinters) < //WCPP Utility is sending the installed printers at client side //so store this info with the specified session ID string printers = HttpContext.Request["printers"]; if (string.IsNullOrEmpty(printers) == false) printers = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printers)); HttpContext.Application.Set(sessionID + "printers", printers); >else if (prType == RequestType.ClientSetInstalledPrintersInfo) < //WCPP Utility is sending the client installed printers with detailed info //so store this info with the specified session ID //Printers Info is in JSON format string printersInfo = HttpContext.Request.Form["printersInfoContent"]; if (string.IsNullOrEmpty(printersInfo) == false) printersInfo = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printersInfo)); HttpContext.Application.Set(sessionID + "printersInfo", printersInfo); >else if (prType == RequestType.ClientGetWcppVersion) < //return the WCPP version for the specified sid if any bool sidWcppVersion = (HttpContext.Application.Get(sessionID + "wcppInstalled") != null); HttpContext.Response.ContentType = "text/plain"; HttpContext.Response.Write((sidWcppVersion ? HttpContext.Application.Get(sessionID + "wcppInstalled") : "")); HttpContext.Response.End(); >else if (prType == RequestType.ClientGetInstalledPrinters) < //return the installed printers for the specified sid if any bool sidHasPrinters = (HttpContext.Application.Get(sessionID + "printers") != null); HttpContext.Response.ContentType = "text/plain"; HttpContext.Response.Write((sidHasPrinters ? HttpContext.Application.Get(sessionID + "printers") : "")); HttpContext.Response.End(); >else if (prType == RequestType.ClientGetInstalledPrintersInfo) < //return the installed printers with detailed info for the specified Session ID (sid) if any bool sidHasPrinters = (HttpContext.Application[sessionID + "printersInfo"] != null); HttpContext.Response.ContentType = "text/plain"; HttpContext.Response.Write(sidHasPrinters ? HttpContext.Application[sessionID + "printersInfo"] : ""); >> catch (Exception ex) < HttpContext.Response.StatusCode = 500; HttpContext.Response.ContentType = "text/plain"; HttpContext.Response.Write(ex.Message + " - StackTrace: " + ex.StackTrace); HttpContext.Response.End(); >> > 

Add a new Controller and name it PrintEPLController and paste the following code:

 using Neodynamic.SDK.Web; public class PrintEPLController : Controller < public ActionResult Index() < return View(); >[AllowAnonymous] public void PrintCommands(string useDefaultPrinter, string printerName) < //Create Zebra EPL commands for sample receipt string lineFeed = "0x0A"; string cmds = ""; cmds += lineFeed; cmds += "N"; cmds += lineFeed; cmds += "Q609,24"; cmds += lineFeed; cmds += "q784"; cmds += lineFeed; cmds += "A170,5,0,1,5,5,N,\"WORLDWIDE\""; cmds += lineFeed; cmds += "LO5,230,765,10"; cmds += lineFeed; cmds += "A10,265,0,1,3,3,R,\"MODEL:\""; cmds += lineFeed; cmds += "A280,265,0,1,3,3,N,\"Bar Code Printer\""; cmds += lineFeed; cmds += "A10,340,0,1,3,3,R,\" CODE: \""; cmds += lineFeed; cmds += "B280,340,0,3C,2,6,120,B,\"BCP-1234\""; cmds += lineFeed; cmds += "LO5,520,765,10"; cmds += lineFeed; cmds += "A100,550,0,1,2,2,N,\"ISO 9000 Made In USA\""; cmds += lineFeed; cmds += "P1"; cmds += lineFeed; //Create a ClientPrintJob and send it back to the client! ClientPrintJob cpj = new ClientPrintJob(); //set EPL commands to print. cpj.PrinterCommands = cmds; cpj.FormatHexValues = true; //set client printer. if (useDefaultPrinter == "checked" || printerName == "null") cpj.ClientPrinter = new DefaultPrinter(); else cpj.ClientPrinter = new InstalledPrinter(printerName); //send it. System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream"; System.Web.HttpContext.Current.Response.BinaryWrite(cpj.GetContent()); System.Web.HttpContext.Current.Response.End(); >> 

Creating SPA by using AngularJS

Create a new index.html file that will act as our view for detecting whether the client machine has the WebClientPrint Processor (WCPP) Utility installed as well as for listing client printers and to finally perform client side printing. This SPA features two parts or sections, one for "Detecting WCPP" and the other one for "Client side printing". The ClientPrintJob is generated by the controller created above from the Web API server side code. Copy/Paste the following markup:

Be sure this html file links to jQuery 1.4.1+ and to AngularJS 1.6.4+ files!

         

Detecting WCPP utility at client side.

Please wait a few seconds.


#1 Install WebClientPrint Processor (WCPP)!

WCPP is a native app (without any dependencies!) that handles all print jobs generated by the WebClientPrint for ASP.NET component at the server side. The WCPP is in charge of the whole printing process and can be installed on Windows, Linux, Mac & Raspberry Pi!

Download and Install WCPP from Neodynamic website

#2 After installing WCPP.

You can go and test the printing page.

Print EPL commands

Click to load and select one of the installed printers!



Creating HTTP Handlers

Create a new Generic Handler and name it WebClientPrintAPI and then copy/paste the following code:

 public class WebClientPrintAPI : IHttpHandler < //********************************* // IMPORTANT NOTE // In this sample we store users related stuff (like // the list of printers and whether they have the WCPP // client utility installed) in the Application cache // object part of ASP.NET BUT you can change it to // another different storage (like a DB or file server)! // which will be required in Load Balacing scenarios //********************************* public void ProcessRequest (HttpContext context) < //get session ID string sessionID = (context.Request["sid"] != null) ? context.Request["sid"].ToString() : null; //get Query String string queryString = context.Request.Url.Query; try < //Determine and get the Type of Request RequestType prType = WebClientPrint.GetProcessRequestType(queryString); if (prType == RequestType.GenPrintScript || prType == RequestType.GenWcppDetectScript) < //Let WebClientPrint to generate the requested script byte[] script = WebClientPrint.GenerateScript(context.Request.Url.AbsoluteUri.Replace(queryString, ""), queryString); context.Response.ContentType = "text/javascript"; context.Response.BinaryWrite(script); >else if (prType == RequestType.ClientSetWcppVersion) < //This request is a ping from the WCPP utility //so store the session ID indicating this user has the WCPP installed //also store the WCPP Version if available string wcppVersion = context.Request["wcppVer"]; if (string.IsNullOrEmpty(wcppVersion)) wcppVersion = "1.0.0.0"; context.Application.Set(sessionID + "wcppInstalled", wcppVersion); >else if (prType == RequestType.ClientSetInstalledPrinters) < //WCPP Utility is sending the installed printers at client side //so store this info with the specified session ID string printers = context.Request["printers"]; if (string.IsNullOrEmpty(printers) == false) printers = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printers)); context.Application.Set(sessionID + "printers", printers); >else if (prType == RequestType.ClientSetInstalledPrintersInfo) < //WCPP Utility is sending the client installed printers with detailed info //so store this info with the specified session ID //Printers Info is in JSON format string printersInfo = context.Request.Form["printersInfoContent"]; if (string.IsNullOrEmpty(printersInfo) == false) printersInfo = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printersInfo)); context.Application.Set(sessionID + "printersInfo", printersInfo); >else if (prType == RequestType.ClientGetWcppVersion) < //return the WCPP version for the specified Session ID (sid) if any bool sidWcppVersion = (context.Application[sessionID + "wcppInstalled"] != null); context.Response.ContentType = "text/plain"; context.Response.Write(sidWcppVersion ? context.Application[sessionID + "wcppInstalled"] : ""); >else if (prType == RequestType.ClientGetInstalledPrinters) < //return the installed printers for the specified Session ID (sid) if any bool sidHasPrinters = (context.Application[sessionID + "printers"] != null); context.Response.ContentType = "text/plain"; context.Response.Write(sidHasPrinters ? context.Application[sessionID + "printers"] : ""); >else if (prType == RequestType.ClientGetInstalledPrintersInfo) < //return the installed printers with detailed info for the specified Session ID (sid) if any bool sidHasPrinters = (context.Application[sessionID + "printersInfo"] != null); context.Response.ContentType = "text/plain"; context.Response.Write(sidHasPrinters ? context.Application[sessionID + "printersInfo"] : ""); >> catch (Exception ex) < context.Response.StatusCode = 500; context.Response.ContentType = "text/plain"; context.Response.Write(ex.Message + " - " + ex.StackTrace); >> public bool IsReusable < get < return false; >> > 

Create a new Generic Handler and name it PrintEPLHandler and then copy/paste the following code:

  using System; using System.Web; using Neodynamic.SDK.Web; public class PrintEPLHandler : IHttpHandler < /*############### IMPORTANT. ############ If your website requires AUTHENTICATION, then you MUST configure THIS Handler file to be ANONYMOUS access allowed. ######################################### */ public void ProcessRequest (HttpContext context) < if (WebClientPrint.ProcessPrintJob(context.Request.Url.Query)) < bool useDefaultPrinter = (context.Request["useDefaultPrinter"] == "checked"); string printerName = context.Server.UrlDecode(context.Request["printerName"]); //Create Zebra EPL commands for sample receipt string lineFeed = "0x0A"; string cmds = ""; cmds += lineFeed; cmds += "N"; cmds += lineFeed; cmds += "Q609,24"; cmds += lineFeed; cmds += "q784"; cmds += lineFeed; cmds += "A170,5,0,1,5,5,N,\"WORLDWIDE\""; cmds += lineFeed; cmds += "LO5,230,765,10"; cmds += lineFeed; cmds += "A10,265,0,1,3,3,R,\"MODEL:\""; cmds += lineFeed; cmds += "A280,265,0,1,3,3,N,\"Bar Code Printer\""; cmds += lineFeed; cmds += "A10,340,0,1,3,3,R,\" CODE: \""; cmds += lineFeed; cmds += "B280,340,0,3C,2,6,120,B,\"BCP-1234\""; cmds += lineFeed; cmds += "LO5,520,765,10"; cmds += lineFeed; cmds += "A100,550,0,1,2,2,N,\"ISO 9000 Made In USA\""; cmds += lineFeed; cmds += "P1"; cmds += lineFeed; //Create a ClientPrintJob and send it back to the client! ClientPrintJob cpj = new ClientPrintJob(); //set Zebra EPL commands to print. cpj.PrinterCommands = cmds; cpj.FormatHexValues = true; //set client printer. if (useDefaultPrinter || printerName == "null") cpj.ClientPrinter = new DefaultPrinter(); else cpj.ClientPrinter = new InstalledPrinter(printerName); //send it. context.Response.ContentType = "application/octet-stream"; context.Response.BinaryWrite(cpj.GetContent()); context.Response.End(); >> public bool IsReusable < get < return false; >> > 

Creating/Editing WebForm Pages

Be sure ALL *.aspx link to jQuery 1.4.1+ file!

The default page is for detecting whether the client machine has the WebClientPrint Processor (WCPP) Utility installed. Edit the Default.aspx file and copy/paste the following code inside the BODY:

  

Detecting WCPP utility at client side.

Please wait a few seconds.


#1 Install WebClientPrint Processor (WCPP)!

WCPP is a native app (without any dependencies!) that handles all print jobs generated by the WebClientPrint for ASP.NET component at the server side. The WCPP is in charge of the whole printing process and can be installed on Windows, Linux, Mac & Raspberry Pi!

Download and Install WCPP from Neodynamic website

#2 After installing WCPP.

You can go and test the printing page.

<%=Neodynamic.SDK.Web.WebClientPrint.CreateWcppDetectionScript(HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + ":" + HttpContext.Current.Request.Url.Port + "/WebClientPrintAPI.ashx", HttpContext.Current.Session.SessionID)%>

Add a new page and name it PrintEPL.aspx. Copy/paste the following code inside the BODY:

 

Print EPL commands

Click to load and select one of the installed printers!



<%=Neodynamic.SDK.Web.WebClientPrint.CreateScript(HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + ":" + HttpContext.Current.Request.Url.Port + "/WebClientPrintAPI.ashx", HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + ":" + HttpContext.Current.Request.Url.Port + "/PrintEPLHandler.ashx", HttpContext.Current.Session.SessionID)%>

Creating HTTP Handlers

Create a new Generic Handler and name it WebClientPrintAPI and then copy/paste the following code:

  Imports System Imports System.Web Imports Neodynamic.SDK.Web Public Class WebClientPrintAPI : Implements IHttpHandler '********************************* ' IMPORTANT NOTE ' In this sample we store users related stuff (like ' the list of printers and whether they have the WCPP ' client utility installed) in the Application cache ' object part of ASP.NET BUT you can change it to ' another different storage (like a DB or file server)! ' which will be required in Load Balacing scenarios '********************************* Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest 'get session ID Dim sessionID As String = "" If (context.Request("sid") IsNot Nothing) Then sessionID = context.Request("sid") End If 'get Query String Dim queryString As String = context.Request.Url.Query Try 'Determine and get the Type of Request Dim prType As RequestType = WebClientPrint.GetProcessRequestType(queryString) If prType = RequestType.GenPrintScript OrElse prType = RequestType.GenWcppDetectScript Then 'Let WebClientPrint to generate the requested script Dim script As Byte() = WebClientPrint.GenerateScript(context.Request.Url.AbsoluteUri.Replace(queryString, ""), queryString) context.Response.ContentType = "text/javascript" context.Response.BinaryWrite(script) ElseIf prType = RequestType.ClientSetWcppVersion Then 'This request is a ping from the WCPP utility 'so store the session ID indicating this user has the WCPP installed 'also store the WCPP Version if available Dim wcppVersion As String = context.Request("wcppVer") If String.IsNullOrEmpty(wcppVersion) Then wcppVersion = "1.0.0.0" End If context.Application.Set(sessionID & "wcppInstalled", wcppVersion) ElseIf prType = RequestType.ClientSetInstalledPrinters Then 'WCPP Utility is sending the installed printers at client side 'so store this info with the specified session ID Dim printers As String = context.Request("printers") If Not String.IsNullOrEmpty(printers) Then printers = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printers)) End If context.Application.Set(sessionID & "printers", printers) ElseIf prType = RequestType.ClientSetInstalledPrintersInfo Then 'WCPP Utility is sending the installed printers at client side 'so store this info with the specified session ID 'Printers Info is in JSON format Dim printersInfo As String = context.Request.Form("printersInfoContent") If Not String.IsNullOrEmpty(printersInfo) Then printersInfo = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printersInfo)) End If context.Application.Set(sessionID & "printersInfo", printersInfo) ElseIf prType = RequestType.ClientGetWcppVersion Then 'return the WCPP version for the specified Session ID (sid) if any Dim sidWcppVersion As Boolean = (context.Application(sessionID & "wcppInstalled") IsNot Nothing) context.Response.ContentType = "text/plain" If (sidWcppVersion) Then context.Response.Write(context.Application(sessionID & "wcppInstalled").ToString()) End If ElseIf prType = RequestType.ClientGetInstalledPrinters Then 'return the installed printers for the specified Session ID (sid) if any Dim sidHasPrinters As Boolean = (context.Application(sessionID & "printers") IsNot Nothing) context.Response.ContentType = "text/plain" If (sidHasPrinters) Then context.Response.Write(context.Application(sessionID & "printers").ToString()) End If ElseIf prType = RequestType.ClientGetInstalledPrintersInfo Then 'return the installed printers with detailed info for the specified Session ID (sid) if any Dim sidHasPrinters As Boolean = (context.Application(sessionID & "printersInfo") IsNot Nothing) context.Response.ContentType = "text/plain" If (sidHasPrinters) Then context.Response.Write(context.Application(sessionID & "printersInfo").ToString()) End If End If Catch ex As Exception context.Response.StatusCode = 500 context.Response.ContentType = "text/plain" context.Response.Write(ex.Message + " - " + ex.StackTrace) End Try End Sub Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property End Class 

Create a new Generic Handler and name it PrintEPLHandler and then copy/paste the following code:

  Imports System Imports System.Web Imports Neodynamic.SDK.Web Public Class PrintEPLHandler : Implements IHttpHandler '############### IMPORTANT. ############ ' If your website requires AUTHENTICATION, then you MUST configure THIS Handler file ' to be ANONYMOUS access allowed. '######################################### Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest If WebClientPrint.ProcessPrintJob(context.Request.Url.Query) Then Dim useDefaultPrinter As Boolean = (context.Request("useDefaultPrinter") = "checked") Dim printerName As String = context.Server.UrlDecode(context.Request("printerName")) 'Create Zebra EPL commands for sample label Dim lineFeed As String = "0x0A" Dim cmds As String cmds += lineFeed cmds += "N" cmds += lineFeed cmds += "Q609,24" cmds += lineFeed cmds += "q784" cmds += lineFeed cmds += "A170,5,0,1,5,5,N,""WORLDWIDE""" cmds += lineFeed cmds += "LO5,230,765,10" cmds += lineFeed cmds += "A10,265,0,1,3,3,R,""MODEL:""" cmds += lineFeed cmds += "A280,265,0,1,3,3,N,""Bar Code Printer""" cmds += lineFeed cmds += "A10,340,0,1,3,3,R,"" CODE: """ cmds += lineFeed cmds += "B280,340,0,3C,2,6,120,B,""BCP-1234""" cmds += lineFeed cmds += "LO5,520,765,10" cmds += lineFeed cmds += "A100,550,0,1,2,2,N,""ISO 9000 Made In USA""" cmds += lineFeed cmds += "P1" cmds += lineFeed 'Create a ClientPrintJob and send it back to the client! Dim cpj As New ClientPrintJob() 'set Zebra EPL commands to print. cpj.PrinterCommands = cmds cpj.FormatHexValues = True Dim cpj As New ClientPrintJob() cpj.PrintFile = file If useDefaultPrinter OrElse printerName = "null" Then cpj.ClientPrinter = New DefaultPrinter() Else cpj.ClientPrinter = New InstalledPrinter(printerName) End If context.Response.ContentType = "application/octet-stream" context.Response.BinaryWrite(cpj.GetContent()) context.Response.End() End If End Sub Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property End Class 

Creating/Editing WebForm Pages

Be sure ALL *.aspx link to jQuery 1.4.1+ file!

The default page is for detecting whether the client machine has the WebClientPrint Processor (WCPP) Utility installed. Edit the Default.aspx file and copy/paste the following code inside the BODY:

  

Detecting WCPP utility at client side.

Please wait a few seconds.


#1 Install WebClientPrint Processor (WCPP)!

WCPP is a native app (without any dependencies!) that handles all print jobs generated by the WebClientPrint for ASP.NET component at the server side. The WCPP is in charge of the whole printing process and can be installed on Windows, Linux, Mac & Raspberry Pi!

Download and Install WCPP from Neodynamic website

#2 After installing WCPP.

You can go and test the printing page.

<%=Neodynamic.SDK.Web.WebClientPrint.CreateWcppDetectionScript(HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + ":" + HttpContext.Current.Request.Url.Port + "/WebClientPrintAPI.ashx", HttpContext.Current.Session.SessionID)%>

Add a new page and name it PrintEPL.aspx. Copy/paste the following code inside the BODY:

 

Print EPL commands

Click to load and select one of the installed printers!



<%=Neodynamic.SDK.Web.WebClientPrint.CreateScript(HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + ":" + HttpContext.Current.Request.Url.Port + "/WebClientPrintAPI.ashx", HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + ":" + HttpContext.Current.Request.Url.Port + "/PrintEPLHandler.ashx", HttpContext.Current.Session.SessionID)%>

NOTE You can also print directly to any LPT Parallel Port, RS232 Serial Port or IP/Ethernet Printer although these scenarios have not been considered in this article for simplicity. For further details on those scenarios, please contact our tech support.