DocuVieware Reference Guide
Client/Server coming and going with Custom Actions
Tutorials > MVC Razor > Client/Server coming and going with Custom Actions
This tutorial assumes that you have fully followed the Your first DocuVieware MVC Razor page tutorial first as its starting point is the end of it.
 Overview

This tutorial shows how to implement a simple button whose action will be to draw a QR Code on the current document with a specified value that will be prompted to the user in a C# MVC project with Razor view engine.

DocuVieware™ requires .NET Framework 4.5 or above.
The screenshots have been taken using GdPicture.NET™ 12, it may differ from the current release.

Summary

 Preparing your action client side

Step 1 : Add a button on the page (above the DocuVieware™ control for example) and attach an onclick event to it that will execute a JavaScript function in the Index.cshtml view file.

<div style="margin-top: 15px;">
   <button onclick="drawQRCode(); return false;">Draw QR Code</button>
</div>

Step 2 : Add and implement the the JavaScript function that will call the PostCustomServerAction function from the DocuVieware™ JavaScript public API that is documented here.

<script>
   function drawQRCode() {
      var codeValue = prompt("Enter the text to encode", "DocuVieware");
      if (codeValue != null) {
         DocuViewareAPI.PostCustomServerAction("DocuVieware1", true, "drawQRCode", codeValue);
      }
   }
</script>

Here is what you now have:

 Preparing your action server side

The client side part is done, now you need to properly route the DocuVieware™ custom action event in the Global.asax.cs file and implement the corresponding handler.

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

DocuViewareEventsHandler.CustomAction += CustomActionsHandler;

Now, each time the PostCustomServerAction JavaScript function is called client side, it will fire the event server side that will go into CustomActionsHandler method, the actionName will be checked and dispatched accordingly.

Step 2 : Implement CustomActionsHandler that does not exist yet so it won't compile. Because you are going to use GdPicture.NET™ to draw our barcode, you need to add some using first.

using GdPicture12.WEB;
using GdPicture12;
using System.Drawing;

And then, the event handler that will actually draw the QR Code on the documents:

private void CustomActionsHandler(object sender, CustomActionEventArgs e)
{
   // if we are in the drawQRCode action and we have parameters
   if ((e.actionName == "drawQRCode") && (e.args != null))
   {
      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.ToString() + ".",
                  "#ff5656", 2500, 300, 300, false, "130%", "normal",
                  "#ffffff", "none", "none", "48px", DocuViewareMessageIcon.Error);
            }
         }
         else
         {
            // ...or a PDF document
            if (e.docuVieware.GetDocumentType() == DocumentType.DocumentTypePDF)
            {
               GdPicturePDF oGdPicturePDF = new GdPicturePDF();
               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.ToString() + ".",
                     "#ff5656", 2500, 300, 300, false, "130%", "normal",
                     "#ffffff", "none", "none", "48px", DocuViewareMessageIcon.Error);
               }
            }
         }
         e.docuVieware.RedrawPage();
      }
      else
      {
         e.message = new DocuViewareMessage("Please load a document first.",
            "#ff5656", 2500, 300, 300, false, "130%", "normal",
            "#ffffff", "none", "none", "48px", DocuViewareMessageIcon.Error);
      }
   }
}
 Sending and receiving data with a custom action
This part is demonstrated in the Barcode Recognition sample that is provided within the SDK installer (in the barcode_recognition_demo.aspx page).
It is strongly recommend that you refer to it in order to fully understand how it should be used.

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 : Define your success callback funtion in the Index.cshtml file:

function onBarcodeDrawingSuccess(result) {
    alert("result: " + JSON.stringify(result));
}

Step 2 : Still in Index.cshtml, slightly change the parameters you are sending because you need it to contain the code value but the result as well, simply call it json.
Then you can use it in the PostCustomServerAction call together with the success callback defined earlier, like this:

function drawQRCode() {
    var codeValue = prompt("Enter the text to encode", "DocuVieware");
    if (codeValue != null) {
        var json = {
            value: codeValue,
            example: false
        };
        DocuViewareAPI.PostCustomServerAction("DocuVieware1", true, "drawQRCode", json, onBarcodeDrawingSuccess);
    }
}

From now on, each time the custom action is called and successful, the onBarcodeDrawingSuccess function will be triggered.

Step 3 : Declare the structure of the new parameter you are passing, it obviously has to exactly match with the JavaScript object you defined earlier in the drawQRCode function.

internal class myCustomActionParameters
{
    public string value { get; set; }
    public bool example { get; set; }
}

Step 4 : Set up the server side handler. To keep things simple, just change the boolean value called example from false to true.

private void CustomActionsHandler(object sender, CustomActionEventArgs e) {
   // we need to properly cast the parameters according to the internal class we have defined...
   myCustomActionParameters myParameters = JsonConvert.DeserializeObject<myCustomActionParameters>(e.args.ToString());
   // ...so we can access to 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.ToString() + ".",
               "#ff5656", 2500, 300, 300, false, "130%", "normal",
               "#ffffff", "none", "none", "48px", DocuViewareMessageIcon.Error);
         }
      }
      else
      {
         // ...or a PDF document
         if (e.docuVieware.GetDocumentType() == DocumentType.DocumentTypePDF)
         {
            GdPicturePDF oGdPicturePDF = new GdPicturePDF();
            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.ToString() + ".",
                  "#ff5656", 2500, 300, 300, false, "130%", "normal",
                  "#ffffff", "none", "none", "48px", DocuViewareMessageIcon.Error);
            }
         }
      }
      // now we change the example value we want to send back to client side
      myParameters.example = true;
      // and we put our parameter object into the proper one
      e.result = myParameters;
      e.docuVieware.RedrawPage();
   }
   else
   {
      e.message = new DocuViewareMessage("Please load a document first.",
         "#ff5656", 2500, 300, 300, false, "130%", "normal",
         "#ffffff", "none", "none", "48px", 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.

See Also