Developing client-side extensions

Client-side .NET components are executed on the client computer. Usually, these are components for user interaction, user interface, or parts of the application interacting with the software installed on the client computer.

How to do it...

In the following example, we will develop a document storage where the user can upload Word documents and open files to edit from the storage. MS Word is installed on the client computer and is controlled by a client-side .NET components.

  1. A new table serving document storage is required for this example. Create a table in the C/SIDE table designer. Insert three fields in the new table:

    Field No.

    Field Name

    Data Type

    Length

    1

    ID

    Integer

    2

    File Name

    Text

    250

    3

    Document

    BLOB

  2. Save the object as table 50202 File Storage. The first field in the list automatically becomes the primary key, this is exactly what we want for the walk-through, so leave the default primary key.
  3. Massive inserts into the file storage table are not expected; hence the primary key value can be auto-incremented on insert. To enable auto-increment, open the properties of the ID field and set AutoIncrement to Yes.
  4. Create a new page in the page designer. Select the 50202 table created in the previous step as the source for the page and choose the List page type in the wizard.
  5. Only one field, File Name, should be visible in the page. Select this field and complete the wizard.
  6. We will load and edit Word documents outside NAV, and the filenames in the table should be read-only. To protect filenames from being modified in the page, open the page properties and change the value of the Editable property to No.
  7. Close the page properties and open the action designer. Change the type of the default action container from NewDocumentItems to ActionItems and insert two actions in the container: Import and Edit.
  8. In C/AL Globals, declare a global variable:

    Name

    DataType

    SubType

    FileManagement

    Codeunit

    File Management

  9. Select the Import action item, open the C/AL code, and declare local variables in the Import - OnAction trigger:

    Name

    DataType

    SubType

    FileStorage

    Record

    File Storage

    ClientFileName

    Text

    ServerFileName

    Text

  10. The C/AL code in the Import - OnAction trigger opens a file dialog that prompts the user to choose a file to import. If the file is selected, it is uploaded to the server and saved in the File Storage table:
            ClientFileName :=  
              FileManagement.OpenFileDialog('File to import','', 
              'MS Word documents (*.doc, *.docx)|*.doc;*.docx,'), 
            IF ClientFileName = '' THEN 
              EXIT; 
     
            ServerFileName :=  
              FileManagement.UploadFileSilent(ClientFileName); 
     
            FileStorage."File Name" := ClientFileName; 
            FileStorage.Document.IMPORT(ServerFileName); 
            FileStorage.INSERT; 
     
            FileManagement.DeleteServerFile(ServerFileName); 
    
  11. The Edit - OnAction trigger performs the backward operation. The file stored on the server must be downloaded to the client and opened by the MS Word application. There should be a single local variable in the trigger, ClientFileName of the Text type:
            IF NOT Document.HASVALUE THEN 
              EXIT; 
     
            ClientFileName := BLOBExport(Rec); 
            ClientFileName := OpenEditWordDocument(ClientFileName); 
     
            IF CONFIRM('Do you want to import the modified document?') THEN 
              BLOBImport(Rec,ClientFileName); 
     
            FileManagement.DeleteClientFile(ClientFileName); 
    
  12. A function where MS Word is started is OpenEditWordDocument. It has one Text type parameter, ClientFileName. The return type is also Text.
  13. Declare local function variables:

    Name

    DataType

    Subtype

    WordApp

    DotNet

    Microsoft.Office.Interop.Word.ApplicationClass

    WordHelper

    DotNet

    Microsoft.Dynamics.Nav.Integration.Office.Word.WordHelper

    WordHandler

    DotNet

    Microsoft.Dynamics.Nav.Integration.Office.Word.WordHandler

    WordDocument

    DotNet

    Microsoft.Office.Interop.Word.Document

    ErrorMessage

    Text

  14. Open the properties for each of the DotNet variables and change the value of the RunOnClient property. It must be Yes for all variables.
  15. Write the code for the OpenEditWordDocument:
            WordApp := WordHelper.GetApplication(ErrorMessage); 
            IF ISNULL(WordApp) THEN 
              ERROR(ErrorMessage); 
     
            WordHandler := WordHandler.WordHandler; 
            WordDocument :=  
              WordHelper.CallOpen(WordApp,ClientFileName,FALSE,FALSE); 
            WordDocument.ActiveWindow.Caption := "File Name"; 
            WordDocument.Application.Visible := TRUE; 
            WordDocument.Activate; 
     
            EXIT(WordHandler.WaitForDocument(WordDocument)); 
    

How it works...

Documents are stored in the table designed in the first three steps of the recipe. But the files are edited on client computers and uploaded to the server from the client side. Here we need to take care of client-server interaction and involve client-side .NET components.

Functions for file exchange between client and server are implemented in codeunit 419 File Management. A global variable referencing this codeunit is declared in Step 8. We later employ this codeunit in Step 10 to display the file selection dialog to the user:

ClientFileName := FileManagement.OpenFileDialog 

The selected file is located on the client box, now it has to be uploaded to the server where it will be imported to the storage table. This is done by the UploadFileSilent function in the FileManagement codeunit:

ServerFileName := FileManagement.UploadFileSilent 

Client-side .NET activities are concentrated in the OpenEditWordDocument function. A document stored on the server is downloaded to the client computer and sent to the application that will open and process it. Note that all .NET variables in the function must be running on the client. If any of the interacting .NET classes are instantiated in the server process, while others are on the client side, this will result in a runtime serialization error.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.214.155