DocuVieware Reference Guide
Client/Server coming and going with Custom Actions
Tutorials > Other Web Technologies using REST > Angular2 > Client/Server coming and going with Custom Actions
This tutorial assumes that you have fully followed the Serving DocuVieware through a REST API tutorial first as its starting point is the end of it.
 Overview

This tutorial shows how to implement a simple action that will draw a QR Code on the current document with a specified value in a C# REST service project with ASP.NET Web API 2 from the .NET Framework.

DocuVieware™ requires .NET Framework 4.6 or above.
The screenshots have been taken using Visual Studio 2015 and GdPicture.NET™ 14, it may differ from the current release.

Summary

 Preparing your action client side
Add and implement the the JavaScript function that will call the PostCustomServerAction function from the DocuVieware™ JavaScript public API that is documented here.
It is usually called by a "onclick" event on some other page element like a button.       
<script>
   function drawQRCode() {
      var codeValue = prompt("Enter the text to encode", "DocuVieware");
      if (codeValue != null) {
         DocuViewareAPI.PostCustomServerAction("DocuVieware1", true, "drawQRCode", codeValue);
      }
   }
</script>
 Preparing your action server side

First, you need to implement the method that will actually draw the QR code on the open document. Add a CustomActions.cs class to your project with the following content:

using System.Drawing;
using GdPicture14;
using GdPicture14.WEB;
namespace DocuViewareREST
{
    public class CustomActions
    {
        public static void DrawQrCode(CustomActionEventArgs e)
        {
            string barcodeValue = e.args.ToString();
            if (e.docuVieware.PageCount > 0)
            {
                // we need to check if the document is an image...
                if (e.docuVieware.GetDocumentType() == DocumentType.DocumentTypeBitmap)
                {
                    int imageId;
                    GdPictureStatus status = e.docuVieware.GetNativeImage(out imageId);
                    if (status == GdPictureStatus.OK)
                    {
                        GdPictureImaging oGdPictureImaging = new GdPictureImaging();
                        oGdPictureImaging.BarcodeQRWrite(imageId, barcodeValue,
                           BarcodeQREncodingMode.BarcodeQREncodingModeUndefined,
                           BarcodeQRErrorCorrectionLevel.BarcodeQRErrorCorrectionLevelH,
                           0, 5, 4, 10, 10, 0, Color.Black, Color.Transparent);
                    }
                    else
                    {
                        e.message = new DocuViewareMessage("Error during get native image : " + status + ".",
                           icon: DocuViewareMessageIcon.Error);
                    }
                }
                else
                {
                    // ...or a PDF document
                    if (e.docuVieware.GetDocumentType() == DocumentType.DocumentTypePDF)
                    {
                        GdPicturePDF oGdPicturePdf;
                        GdPictureStatus status = e.docuVieware.GetNativePDF(out oGdPicturePdf);
                        if (status == GdPictureStatus.OK)
                        {
                            oGdPicturePdf.SetOrigin(PdfOrigin.PdfOriginTopLeft);
                            oGdPicturePdf.SetMeasurementUnit(PdfMeasurementUnit.PdfMeasurementUnitCentimeter);
                            oGdPicturePdf.DrawBarcodeQrCode(barcodeValue,
                               BarcodeQREncodingMode.BarcodeQREncodingModeUndefined,
                               BarcodeQRErrorCorrectionLevel.BarcodeQRErrorCorrectionLevelH,
                               0, 4, 1, 1, Color.Black);
                        }
                        else
                        {
                            e.message = new DocuViewareMessage("Error during get native PDF : " + status + ".",
                                icon: DocuViewareMessageIcon.Error);
                        }
                    }
                }
                e.docuVieware.RedrawPage();
            }
            else
            {
                e.message = new DocuViewareMessage("Please load a document first.",
                    icon: DocuViewareMessageIcon.Error);
            }
        }
    }
}

Now you need to properly catch the DocuVieware™ custom action event in the Global.asax.cs file and implement the corresponding handler.

Step 2 : In the Application_Start part, subscribe to the CustomAction event and redirect it to a private handler named CustomActionsDispatcher (for the sake of clarity but it could be named differently).

DocuViewareEventsHandler.CustomAction += CustomActionsDispatcher;

From now on, each time the PostCustomServerAction JavaScript function is called client side, the CustomAction event is fired and caught to go into the CustomActionsDispatcher method.

Step 3 : Implement CustomActionsDispatcher that will dispatch the action to the proper method according to the e.actionName value.

private static void CustomActionsDispatcher(object sender, CustomActionEventArgs e)
{
    if ((e.actionName == "drawQRCode") && (e.args != null))
    {
        CustomActions.DrawQrCode(e);
    }
}
 Sending and receiving data with a custom action

Let's have a closer look at the PostCustomServerAction JavaScript function:

function PostCustomServerAction: function (docuViewareID, async, actionName, params, success, error)

There are two extra parameters that you did not used in the previous example that are success and error.
These two callbacks are used to run your own code on success or on error, they are optional functions you need to write on your own depending on what you want to achieve.

The important part here is the success callback, this is through this one that you will be able to retrieve a result from the server action.                

Step 1 : In your JavaScript drawQRCode function, slightly change the parameters you are sending: you need it to contain the code value but also the result, simply call it params.
Then you can use it in the PostCustomServerAction call together with the success callback that you need to define, like this:

function drawQRCode() {
    var codeValue = prompt("Enter the text to encode", "DocuVieware");
    if (codeValue != null) {
        var params = {
            Value: codeValue,
            Example: false
        };
        DocuViewareAPI.PostCustomServerAction("DocuVieware1", true, "drawQRCode", params, function(result){ console.log("result: " + JSON.stringify(result)); });
    }
}

From now on, each time the custom action is called and successful, we want the result JSON object to be written to the console.

Step 2 : Define the structure of the new parameter in CustomActions.cs, it has to exactly match the JavaScript object structure you previously defined in the drawQRCode function.

internal class MyCustomActionParameters
{
    public string Value { get; set; }
    public bool Example { get; set; }
}

Step 3 : Set up the server side handler. To keep things simple, just change the boolean value called example from false to true. In the end, your CustomActions.cs looks like this:

using System.Drawing;
using GdPicture14;
using GdPicture14.WEB;
using Newtonsoft.Json;
namespace DocuViewareREST
{
    public class CustomActions
    {
        internal class MyCustomActionParameters
        {
            public string Value { get; set; }
            public bool Example { get; set; }
        }
        public static void DrawQrCode(CustomActionEventArgs e)
        {
            // we need to properly cast the parameters according to the internal class previously defined...
            MyCustomActionParameters myParameters = JsonConvert.DeserializeObject<MyCustomActionParameters>(e.args.ToString());
            // ...so we can use its content
            string barcodeValue = myParameters.Value;
            if (e.docuVieware.PageCount > 0)
            {
                // we need to check if the document is an image...
                if (e.docuVieware.GetDocumentType() == DocumentType.DocumentTypeBitmap)
                {
                    int imageId;
                    GdPictureStatus status = e.docuVieware.GetNativeImage(out imageId);
                    if (status == GdPictureStatus.OK)
                    {
                        GdPictureImaging oGdPictureImaging = new GdPictureImaging();
                        oGdPictureImaging.BarcodeQRWrite(imageId, barcodeValue,
                           BarcodeQREncodingMode.BarcodeQREncodingModeUndefined,
                           BarcodeQRErrorCorrectionLevel.BarcodeQRErrorCorrectionLevelH,
                           0, 5, 4, 10, 10, 0, Color.Black, Color.Transparent);
                    }
                    else
                    {
                        e.message = new DocuViewareMessage("Error during get native image : " + status + ".",
                           icon: DocuViewareMessageIcon.Error);
                    }
                }
                else
                {
                    // ...or a PDF document
                    if (e.docuVieware.GetDocumentType() == DocumentType.DocumentTypePDF)
                    {
                        GdPicturePDF oGdPicturePdf;
                        GdPictureStatus status = e.docuVieware.GetNativePDF(out oGdPicturePdf);
                        if (status == GdPictureStatus.OK)
                        {
                            oGdPicturePdf.SetOrigin(PdfOrigin.PdfOriginTopLeft);
                            oGdPicturePdf.SetMeasurementUnit(PdfMeasurementUnit.PdfMeasurementUnitCentimeter);
                            oGdPicturePdf.DrawBarcodeQrCode(barcodeValue,
                               BarcodeQREncodingMode.BarcodeQREncodingModeUndefined,
                               BarcodeQRErrorCorrectionLevel.BarcodeQRErrorCorrectionLevelH,
                               0, 4, 1, 1, Color.Black);
                        }
                        else
                        {
                            e.message = new DocuViewareMessage("Error during get native PDF : " + status + ".",
                                icon: DocuViewareMessageIcon.Error);
                        }
                    }
                }
                e.docuVieware.RedrawPage();
            }
            else
            {
                e.message = new DocuViewareMessage("Please load a document first.",
                    icon: DocuViewareMessageIcon.Error);
            }
        }
    }
}

Each time the client side button is clicked, the result parameter is sent server side with false value, it is changed to true and sent back to client side to be displayed in the console.

See Also