Enhancing Applications using Non-Display File ASPX Pages

Monarch-based programs execute within the context of a Monarch Job and conform to certain conventions allowing the job to be the target of a CALLB or CALLD operation. This Job provides a program with a connection to the database, with a set of global variables shared amongst all the programs in the Job (the LDA and LDC), and with a mechanism to support instantiation based on activation groups, which is particularly important in supporting the call commands.

A Job also provides an interactive program with the infrastructure supporting display files. Refer to Framework ASPX Session Overview for a more complete description of the interaction of the Program and Monarch Job during a normal ASPX session. The Job currently has general 'states' as follows.

  • A. Just created
  • B. Executing a Program
  • C. Waiting for input from the user

After a Job has been created, it is in state A and transitions to state B when the Job.Start method is executed. When the program executes a READ or EXFMT on a workstation format, the job goes into state C.

In order to invoke a program from within the code behind a NDF aspx page, it is necessary to have a Job providing the context where the program can run. This Job should be in a state able to accept requests to execute arbitrary programs outside of the normal calling graph created by program calls.

The cooperation of the Job is essential so a program within the Job must make the Job enter a new state:

  • D. Accepting Commands

In this state, the Job can accept commands.

Note

The LDC can contain any type of object, however only those that are of type string can be sent to the Yellow side.

To access the LDC strong values from the Yellow side use ASNA.Monarch.Command class' methods:

  • public string GetLdcObject( string name )
  • public void SetLdcObject( string name, string value )

This command can be executed only when the Job is waiting in either of these states:

  • Waiting for input from the user (in a READ or EXFMT of a display file)
  • Accepting Commands via the AcceptCommand method on MonarchJob

New Facilities Summary

Facility Enter Command Mode Exit Command Mode Execute Command(s)
Description Prepares a job to accept commands Returns a Job to procedural processing Allows code in aspx.vr to invoke a function within a Job, particularly program calls.
Methods ShowPage AcceptCommands Command.Return

Command.Call Command.CallSilent Command.SetLdaField Command.GetLdaField Command.SetLdcObject Command.GetLdcObject Command.PushKeyFocus Command.RemoveLdcObject Command.RequestShutdown

Parent Object ASNA.Monarch.WebJob(ASNA.isualRPG.Runtime.dll) ASNA.Monarch.Command
(ASNA.Monarch.WebDspF.dll) or (ASNA.isualRPG.Runtime.dll)
ASNA.Monarch.Command
(ASNA.Monarch.WebDspF.dll) or (ASNA.isualRPG.Runtime.dll)

Enter Command Mode (Blue thread)

ShowPage and AcceptCommands

These commands prepare a job to accept commands.


        public string ShowPage(string outsidePage, string parameter)

        public string AcceptCommands(string parameter)        

ShowPage receives an ASPX page that is presented to initiate the conversation with the user. In a way, this command enables a procedural program to 'call' an ASPX.

A single string parameter can be passed to these methods; the parameter will be stored in the session object where the ASPX code behind can retrieve it like this:

Parameter = Session["MONARCH_CMDPARM"] *as *String
   Session["MONARCH_CMDPARM"] = *Nothing

Example

In the procedure code (blue thread):

DclFld Result Type(*String)
  Result = (monarchJob *as ASNA.Monarch.WebJob).ShowPage("~/Clifton.aspx", "23,ABC,X")
  If (Result = "Function Completed")
       Return
   EndIf

Or

DclFld Result Type(*String)
   Result = (monarchJob *as ASNA.Monarch.WebJob).AcceptCommands()
    If (Result = "Function Completed")
Return
   EndIf

In 'Clifton.aspx' (yellow thread):

BegSr Page_Load Access(*Private) Event(*This.Load)
   DclSrParm sender Type(*Object)
   DclSrParm e Type(System.EventArgs)
   DclArray  Parms Rank(1) Type(*String)
   DclFld    Parameters Type(*String)
   If (NOT Page.IsPostBack)
        Parameter = Session["MONARCH_CMDPARM"] *as*String
        Session["MONARCH_CMDPARM"] = *Nothing
          If (Parameter = *Nothing)
            Response.Redirect("./PageRequestOutOfSequence.html")
          EndIf        Parms = Parameter.Split(O',')
        txtCustNumber.Text = Parms[0]
   EndIf
EndSr

Execute Commands (Yellow thread)

Call Command

public void Call(string assemblyName, string programName, string[] parms)

or

public void Call(string assemblyName, string programName, string[] parms string 

callbackPage)

Call can invoke an interactive or process program. Programs receive parameters by reference, i.e. the ASPX code can send and receive data to/from the called programs; the parameters are stored in an array of strings. The called program can define its parameters list using fields of type character and decimal (zoned, packed, binary, and decimal).

Interactive calls also require an ASPX page reference where control will be relinquished once the called program finish execution. Calling interactive programs effectively means a transfer of control, first to the interactive program being called, and then to the callback Page reference. Calls that invoke interactive programs can send data into the program via parameters but the output parameters list will be sent to the callback page by storing the array in the Session under the ["MONARCH_CMDPARM"] key.

Example

Non-Interactive program call:

DclFld Command Type(ASNA.Monarch.Command) New(*Base.Context)
   DclArray   Parms Dim(3)  Type(*String)
   Parms[0] = CustNo
   Parms[1] = Sales.ToString()
   Parms[2] = Returns
   Command.Call("MyCompany.MyTechnology.Utils", "MyCompany.MyTechnology.CUSTINQ", Parms)
   Sales   = Parms[1]
   Returns = Parms[2]
   txtSales.Text = Sales.ToString()
   txtRetrn.Text = Returns.ToString()

Interactive program call:

DclFld Command Type(ASNA.Monarch.Command) New(*Base.Context)
DclArray   Parms Dim(1) Type(*String)
   Parms[0] = CustName
   Command.Call("MyCompany.MyTechnology.Utils",          +
                "MyCompany.MyTechnology.CUSTINQ",        +
                Parms, "~/Brooklyn.aspx")

The updated parameters stored in Parms can be retrieved in "Brooklyn.aspx" with code similar to this one:

BegSr Page_Load Access(*Private) Event(*This.Load)     
  DclSrParm sender Type(Object)   
  DclSrParm e Type(System.EventArgs)
  DclFld ParmArray Type(System.Array)
  If (NOT Page.IsPostBack)
        ParmArray = Session["MONARCH_CMDPARM"] *as System.Array
        If (ParmArray <> *Nothing)
             Session["MONARCH_CMDPARM"] = *Nothing
             txtState.Text = ParmArray.GetValue(0).ToString()
            // Parms[0] 
        Endif
   EndIf
EndSr

CallSilent Command

CallSilent invokes an interactive program from a non-display file aspx.vr (yellow thread) and prevents the display of the program's display file in the browser.

public ASNA.Monarch.WebDisplayFile
CallSilent(string assemblyName, string programName, string [] parms

When the interactive program performs an EXFMT (or READ), it will stop waiting for input from the user and CallSilent will return the WebDisplayFile object allowing the caller to inspect the dataset containing the data tables of the record formats written by the interactive program on the blue thread.

The caller of CallSilent is responsible for feeding input to the waiting interactive program. This is done by updating the appropriate rows of the data table of the WebDisplayFile and then executing the method PushKeyFocus.

PushKeyFocus Command

PushKeyFocus is invoked from the yellow thread to provide input to the blue thread program waiting for input. It sets the parameter values and returns a WebDisplayFile with the focus set as dictated by the parameters.

public ASNA.Monarch.WebDisplayFile PushKeyFocus( + +
ASNA.Monarch.Command.AidKey key, short virtualRowCol, string fieldname )

This method does not affect the indicators that would normally be set/reset if the display file would have gone to the browser. In particular, no numeric indicator will be set based on the key "pressed". The waiting program must base its actions on the feedback AID or the INxx indicators.

Example

DclFld Command Type(ASNA.Monarch.Command) New(*Base.Context)
DclFld DspF Type(ASNA.Monarch.WebDisplayFile) 
DclSrParm sender *Object
DclSrParm e System.EventArgs
DclFld Command Type(ASNA.Monarch.Command) New(*Base.Context)
      Command.RequestShutdown()

InvokeQCmdExc Method

This method (added in 8.0) executes a command on the IBM i's Job associated with the database connection by calling IBM's QCMDEXC.

The WingsJob or MobileRPG Job should have suspended its execution by calling either AcceptCommands or ShowPage (see http://devnet.asna.com/documentation/Help140/MonarchFX/_HTML/amfconEnhancingWithNonDisplayFileASPX.htm). While the executing thread is in this suspended state, a method in the code-behind of the web site can call InvokeQCmdExc, which will forward the command to the IBM i Job for its execution.

public string QCmdExc(string command, string callbackPage)

QCmdExc executes a command on the IBM i's Job associated with the database connection.
If during the execution of the command a screen is displayed, control does not return to the caller, instead, control is transferred to the page on the callbakPageCaller parameter.

public string QCmdExc(string command)

QCmdExc executes a command on the IBM i's Job associated with the database connection.
The execution of the command should not involve any screen I/O.

Wings Example

public partial class Menu : System.Web.UI.Page
{
    protected void btnGo_Click(object sender, EventArgs e)
    {
        ASNA.Monarch.Command command = new ASNA.Monarch.Command(Context);
        int option = int.Parse(txtOption.Text);
        switch (option)
        {
            case 1:
                {
                    command.InvokeQCmdExc("CHGCURLIB ERNUEXPRES");
                    command.InvokeQCmdExc("CALL CUSTINQ", "~/Menu.aspx");
                    break;
                }
            case 2:
                {
                    command.InvokeQCmdExc("DSPLIBL", "~/Menu.aspx");
                    break;
                }
            case 3:
                {
                    Response.Redirect("~/CommandLine.aspx");
                    break;
                }
            case 4:
                {
                    command.Return("SIGNOFF");
                    break;
                }
        }
    }

}

The resulting WingsJob will resemble the following.

	public partial class WingsJob : ASNA.Monarch.WebJob
{
    private AVRRuntime.Database myDatabase;

    override protected AVRRuntime.Database getDatabase()
    {
        return myDatabase;
    }

    override public void Dispose( bool disposing )
    {
        if( disposing )
            myDatabase.Close();
        base.Dispose( disposing );
    }

    protected override void ExecuteStartupProgram()
    {
        myDatabase = new AVRRuntime.Database("", AVRRuntime.VirtualTerminal.MonarchWeb, AVRRuntime.OpenAccessDspF.Wings);
        myDatabase.Server   = "MyServer";
        myDatabase.Label    = "DB2";
       myDatabase.Port     = 5042;
        myDatabase.User     = LDC["UserName"] as string;
        myDatabase.Password = LDC["Password"] as string;
        LDC["Password"]     = "";
        try
        {
            myDatabase.Open();
        }
        catch (Exception e)
        {
            string error = e.Message;
        }
        string rv = AcceptCommands();
    }
}

Exit Command Mode (Yellow Thread)

Return Command

Returns a Job to procedural processing thus exiting command mode.

public void Return(string result)

When an ASPX page wants to return the Job state to continue its procedural processing, it executes this command, passing a string back to the original code in the blue thread that prepared the job to accept commands.

Example

DclFld Command Type(ASNA.Monarch.Command) New(*Base.Context)
   Command.Return("Function Completed")

Next: Moving Data between Workstation and Display Files

Previous: Monarch Framework ASPX Session Overview