Workflow applications

Application types

The following application types are covered in this section:

  • Web procedures

  • Asynchronous web procedures

  • RemoteLaunch

The following application types are not covered in this section:

  • Web applications

  • SOAP web services

How it works

When an action using a workflow application is launched, WorkflowGen sends the parameters in a JSON or XML file (depending on the context format previously chosen during the creation of the application) to the application using the HTTP protocol. The application uses the JSON or XML file to get the parameters and executes its operations. Once the application is done, a JSON or XML file with the OUT parameters is sent back to WorkflowGen. JSON is supported by Webproc and Webproc Async applications. For web services, the SOAP protocol is used to communicate with the application. Web services that don’t use the SOAP protocol to communicate with WorkflowGen application, will be referred as WebProc applications.

Note: The JSON context is supported as of WorkflowGen version 7.0.0.

Requirements for .NET development

.NET Framework version

The WorkflowGen.My assembly requires .NET Framework 4.

WorkflowGen.My assembly

In order to implement a custom workflow application using the .NET Framework, you must have the latest version of WorkflowGen.My 4.x referenced in your project. To directly reference an assembly in your web project, do the following:

  1. Create a \bin directory under your project root folder (e.g. \wfgen\wfapps\sdk\MyProject\bin).

  2. Copy the "WorkflowGen.My.dll" file to this folder.

  3. Right-click on your project name and choose Add reference...

  4. Click Browse.

  5. Navigate to the \bin directory you created and choose the "WorkflowGen.My.dll" file, then click OK. WorkflowGen.My is now referenced in your project.

You can also put this assembly in your GAC (Global Assembly Cache) in order to have only one centralized reference, instead of referring to a copy of the assembly in each project. To to install the assembly in your GAC, do the following:

  1. Copy "WorkflowGen.My.dll" to DRIVE:\Windows\system32.

  2. Open a command prompt and browse to DRIVE:\Program Files (x86)\Microsoft Visual Studio 14.0\SDK\v3.5\Bin.

  3. Enter the command gacutil /i c:\windows\system32\WorkflowGen.My.dll, then press ENTER. WorkflowGen.My is now in your GAC.

If you want to use an assembly from the GAC, you should drop your assemblies into a local folder, and then add a reference to the assembly from this folder. You may want to set the Copy Local property to False for that assembly if you don't want the assembly to be copied locally to your project folders. At runtime, the application will automatically use the assembly from the GAC.

Important: WorkflowGen.My.dll 3.4.0 and later requires Newtonsoft.Json.dll in the same BIN or GAC.

Configuration settings ("app.config" or "web.config")

The WorkflowGen.My assembly does not require any particular configuration settings.

WorkflowContext

WorkflowContext is a JSON or XML data structure used to exchange parameters with WorkflowGen. The context format is used by both web procedures and asynchronous web procedures.

Note: The WorkflowGen JSON and DataSet contexts exchange DateTime parameters with external applications in the UTC time zone according to the ISO 8601 format (see https://en.wikipedia.org/wiki/ISO_8601 for more information).

For an example of an XML ADO.NET DataSet context, see WorkflowContext in the Web services API section.

As of WorkflowGen 7.0.0, the application can build ContextParameters instances from JSON strings. The JSON should respect the following structure:

JSON example (web procedure):
{
  "parameters": [
    {
      "name": "DATE_IN",
      "dataType": "DATETIME",
      "direction": "IN",
      "dateTimeValue": "2017-02-23T20:46:00Z"
    },
    {
      "name": "FILE_IN",
      "dataType": "FILE",
      "direction": "IN",
      "fileValue": {
        "name": "Test File.txt",
        "contentType": "text/plain",
        "size": 616,
        "url": "file:///C:/inetpub/wwwroot/wfgen/App_Data/Files/DataSet/runtime/2017/02/27/49726-1.txt"
        "updatedAt": "2017-02-21T15:06:38Z"
      }
    },
    {
      "name": "NUMERIC_IN",
      "dataType": "NUMERIC",
      "direction": "IN",
      "numericValue": 100.0
    },
    {
      "name": "TEXT_IN",
      "dataType": "TEXT",
      "direction": "IN",
      "textValue": " Lorem ipsum dolor sit amet  ~!@#$%^;*()_+-=[]{}\\\\|:\\\"';?/,:;.,`&<>"
    }
  ]
}
JSON example (asynchronous web procedure):
{
  "replyToUrl": "http://localhost/wfgen/show.aspx?QUERY=APPLICATION_COMPLETE&ID_PROCESS_INST=2304&ID_ACTIVITY_INST=1&ENCTYPE=application%2fjson&ID_APP_TYPE=WEBPROCASYNC",
  "parameters": [
    {
      "name": "DATE_IN",
      "dataType": "DATETIME",
      "direction": "IN",
      "dateTimeValue": "2017-02-21T15:07:00Z"
    },
    {
      "name": "FILE_IN",
      "dataType": "FILE",
      "direction": "IN",
      "fileValue": {
        "name": "TestFile.txt",
        "contentType": "text/plain",
        "size": 616,
        "url": "file:///C:/inetpub/wwwroot/wfgen/App_Data/Files/DataSet/runtime/2017/02/27/49749-1.txt"
       "updatedAt": "2017-02-21T15:06:38Z"
      }
    },
    {
      "name": "NUMERIC_IN",
      "dataType": "NUMERIC",
      "direction": "IN",
      "numericValue": 100.0
    },
    {
      "name": "TEXT_IN",
      "dataType": "TEXT",
      "direction": "IN",
      "textValue": "Lorem ipsum dolor sit amet ~!@#$%^&;*()_+-=[]{}\\|:\"';?/,<:>.,`"
    }
  ]
}

Note: JSON context properties are case sensitive; as of WorkflowGen 7.1.0, they use lowercase camelcase notation, and their null values have been removed from the JSON context.

WorkflowContext creation with WorkflowGen.My

Loading the WorkflowGen context

In order to manipulate a WorkflowGen context, it is necessary to load it into a ContextParametersobject instance. Usually, you will receive the context in a string variable. The following sample code loads the context form a workflowGenContext string:

C#
ContextParameters contextHandler = new ContextParameters(workflowGenContext);

Get a particular parameter from the context

You can access any data parameter in the WorkflowGen context by using the contextHandler (ContextParameters instance) that you created in the previous section. When you access a single parameter, you store it in a ContextParameter object to manipulate it. The following example accesses a DATE_EXAMPLE parameter in the previously loaded context:

C#
ContextParameter dateParameter = contextHandler["DATE_EXAMPLE"];

Get the ContextParameter value

To access the value of the context parameter, use the Value property of the ContextParameter instance that you retrieved in the previous section.

C#
ContextParameter dateParameter = contextHandler["DATE_PARAMETER"];
DateTime dateValue = (DateTime)dateParameter.Value;

The dateValue variable now contains the DATE_EXAMPLE parameter value.

Filtering the ContextParameters collection

Suppose that you would like to iterate over all the "IN" parameters of the ContextParameters instance. You could do this by using a filter, and then by using the collection enumerator. Don't forget to remove the filter afterward, or else you won't be able to access the other parameters.

C#
contextHandler.ApplyFilter(ContextParameter.Directions.In, ContextParameters.ComparisonOperators.Equals);
foreach (ContextParameter inParameter in contextHandler)
{
   // Do something here with each "inParameter" variable
}
contextHandler.RemoveFilter();

Modifying a parameter value in the context

After you have stored your data parameter in a ContextParameter, you can modify its value.

C#
ContextParameter dateParameter = contextHandler["DATE_PARAMETER"];
dateParameter.Value = System.DateTime.Now;
contextHandler.Update("DATE_PARAMETER");

Note: If you try to modify a parameter with the wrong data type, you will only receive an exception when you try to serialize the context back to a JSON or XML string.

Adding a parameter to the context

In order to add a parameter to the context, you need to build a new ContextParameter instance, define its name and direction, and then add it to the ContextParameters instance you already have.

C#
ContextParameter newOutParameter = new ContextParameter(typeof(DateTime), DateTime.Now);
newOutParameter.Name = "SAMPLE_OUT_PARAM";
newOutParameter.Direction = ContextParameter.Directions.Out;
contextHandler.Add(newOutParameter);
contextHandler.Update();

Working with file parameters

File parameters need to be put into a ContextFileReference instance. The following is an example that extracts a file parameter value into a ContextFileReference, then modifies the file parameter so that it points to another sample file.

As of WorkflowGen 7.1.0, JSON context file parameters use the file URI scheme in the fileValue URL field (see https://en.wikipedia.org/wiki/File_URI_scheme for more information).

C#
ContextParameters cps = new ContextParameters(context);
ContextFileReference cfr = new ContextFileReference();
FileInfo fi = new FileInfo(@"c:\TestFile.txt");
cfr.Name = fi.Name;
cfr.Description = fi.Name;
cfr.Path = fi.FullName;
cfr.OriginalPath = fi.FullName;
cfr.ContentType = "text/plain";
cfr.DateLastModified = fi.LastWriteTimeUtc;
cfr.Size = fi.Length;
cps["FILE_OUT"].Value = cfr;
cps.Update();

Web procedure development using an ASP.NET XML web service

Overview

The most widely-used type of WorkflowGen integration is the web procedure. Web procedures are used to receive a WorkflowGen context as a parameter, manipulate it, and then return the modified context to WorkflowGen.

Note: As of WorkflowGen 7.0.0, the term "web services" is only used to refer to web services using the SOAP protocol; all others are referred to as web procedures.

Creating the web procedure

Suggested development tools
  • Visual Studio Standard or Professional 2013 or later
Web procedure installation directory

We strongly suggest that you put all of your web services in the \wfgen\wfapps\WebServices\MyWebProc folder.

Be aware that if you modify your WorkflowGen process and you need to modify the associated MyWebProc because of those changes, you should duplicate MyWebProc beforehand and create another IIS application, otherwise the two versions of the process will use the same modified MyWebProc.

Creating the application in IIS

The web service directory must be declared as an application in IIS in order to be recognized as a .NET web service application. To declare your web service directory as an IIS application, do the following:

For IIS 7 and later
  1. Open Internet Information Services (IIS) Manager.

  2. Navigate to your web form location, which should be under the Default Web Site node, under \wfgen\wfapps\webservices\MyWebProc.

  3. Right-click on MyWebProc and choose Convert to Application.

  4. Select the application pool used by your site and another specific application pool.

  5. Click OK.

Creating a web procedure workflow application using an ASP.NET XML web service

You can create a web procedure using an ASP.NET web service, but this Visual Studio template is only available for .NET versions 2.0 to 3.5.

  1. Open Visual Studio.

  2. Select File > New Web Site.

  3. Choose ASP.NET Web Service (available for .NET Framework versions 2.0 to 3.5).

  4. Choose File system from the Location drop-down list.

  5. Click Browse and choose the location of your ASP.NET website.

  6. Click OK.

Obtaining detailed error messages

In order to be able to see complete error messages, change the following properties in the "web.config" file:

Make sure this line is set to true:

<compilation debug="true" />

Make sure this is not commented and that the mode="Off":

<customErrors mode="Off" defaultRedirect="GenericErrorPage.htm">
    <error statusCode="403" redirect="NoAccess.htm" />
    <error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
Authorize GET and POST protocols

In order to use a web service with WorkflowGen, the GET and POST protocols must be enabled in the "web.config" file of the web service. The following are the necessary nodes to insert in your "web.config", in the system.web node:

<webServices>
    <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
    </protocols>
</webServices>

Configure the IIS rendering framework version in the "web.config" file

You will need to revert to the behavior of having only .aspx pages trigger request validation by adding the following code to your "web.config" file:

<httpRuntime requestValidationMode="2.0" />

Basic implementation

Overview

In order to demonstrate how to implement a web procedure that processes a context from WorkflowGen, we'll build a simple web service that receives and returns TEXT, NUMERIC, FILE, and DATETIME parameters using the JSON and XML ADO.NET DataSet context formats and their respective content types.

Reference

You must add a reference to WorkflowGen.My.dll in your web project, and then add a "using" statement (for the WorkflowGen.My.Data namespace of the WorkflowGen.My assembly. For example:

C#
using WorkflowGen.My.Data;
Specifying your class signature

If you want to receive a JSON formatted context, you should add the following signature, located in the "App_Code\Service.cs" file, to your web procedure's Service class (note that ScriptService signatures aren't required for other context formats). Your service class should look like this:

[WebService(Namespace = "http://tempuri.org/")]
[System.Web.Script.Services.ScriptService]
public class Service : System.Web.Services.WebService

Specifying your web method signature

Only the methods that have the WebMethod attribute can be remotely executed. The default web method signature created with your web service should look like this:

C#
[WebMethod]
public string HelloWorld()

Here, we'll modify the web method signature. If JSON is the chosen context format with application/json content type, or if the context format is XML ADO.NET DataSet with application/xml content type, the web method will not receive any parameter. Otherwise, if you exchange a JSON or ADO.NET DataSet context using the application/x-www-form-urlencoded content type, your method must receive a string parameter called WFGEN_CONTEXT.

C#

JSON (application/json) and XML ADO.NET DataSet (application/xml) context formats:

[WebMethod]
public void WebProcAppJsonXml()

JSON and XML ADO.NET DataSet context formats using application/x-www-form-urlencoded content type:

[WebMethod]
public string WebProcAppJsonXml(string WFGEN_CONTEXT)

Note: The parameter name should always be WFGEN_CONTEXT, which is case sensitive.

Loading the WorkflowGen context

The next step is to retrieve the WorkflowGen context. In the case of JSON or XML ADO.NET DataSet contexts (when using application/json or application/xml, respectively), the context is retrieved from the HttpContext request as shown in the following example.

C#
// Reading context from request
string WFGEN_CONTEXT;

HttpContext.Current.Request.InputStream.Position = 0;
using (var reader = new StreamReader(HttpContext.Current.Request.InputStream, System.Text.UTF8Encoding.UTF8))
{
    WFGEN_CONTEXT = reader.ReadToEnd();
}

Otherwise, if the web method has received the WFGEN_CONTEXT in parameters (this is the case for JSON and XML ADO.NET DataSet contexts when using the application/x-www-form-urlencoded content type), it is available to be used within the method.

Now, we're ready to create a ContextParameters instance that will be used to manipulate the WorkflowGen context.

C#
ContextParameters myWorkflowContextParameters = new ContextParameters(WFGEN_CONTEXT);

Retrieving the parameters from the context

We'll now retrieve the NUMERIC_IN value into our numericIn double variable, and at the same time, we'll verify that the value is not null (if it is, we'll send an exception).

double numericIn = 0;
if (myWorkflowContextParameters["NUMERIC_IN"].Value != DBNull.Value)
{
    // Get the value of 'NUMERIC_IN' into the numericIn variable
    numericIn = (double)myWorkflowContextParameters["NUMERIC_IN"].Value;
}
else
{
    // If NUMERIC_IN is null generate an error
    throw new SoapException("Web procedure error: 'NUMERIC_IN' parameter must not be null", SoapException.ServerFaultCode);
}

Modifying the parameters with new values

We'll now modify some parameters by giving them new values.

myWorkflowContextParameters["DATE_OUT"].Value = DateTime.UtcNow;
myWorkflowContextParameters["NUMERIC_OUT"].Value = 1234567.89;
myWorkflowContextParameters["TEXT_OUT"].Value = "Lorem ipsum dolor sit amet ~!@#$%^&;*()_+-=[]{}\\|:\"';?/,<:>.,`";

        ContextFileReference cfr = new ContextFileReference();
        FileInfo fi = new FileInfo(@"c:\temp\TestFile.txt");
        cfr.Name = fi.Name;
        cfr.Description = fi.Name;
        cfr.Path = fi.FullName;
        cfr.OriginalPath = fi.FullName;
        cfr.ContentType = "text/plain";
        cfr.DateLastModified = fi.LastWriteTimeUtc;
        cfr.Size = fi.Length;
        myWorkflowContextParameters["param_file_out"].Value = cfr;

        myWorkflowContextParameters.Update();

Sending the modified context back to WorkflowGen

Now that we've processed the context, we need to send the context back to WorkflowGen. Below is the necessary code, depending on the context format you chose when creating or editing your WorkflowGen application.

JSON context using application/json content type
C#
// Sending context response
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = HttpContext.Current.Request.ContentType;
HttpContext.Current.Response.AddHeader("content-length", myWorkflowContextParameters.GetJson().Length.ToString());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.Write(myWorkflowContextParameters.GetJson());
JSON context using application/x-www-form-urlencoded content type
C#
// Returning the context 
return myWorkflowContextParameters.GetJson();
XML ADO.NET DataSet using application/xml content type
C#
// Sending context response
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = HttpContext.Current.Request.ContentType;
HttpContext.Current.Response.AddHeader("content-length", myWorkflowContextParameters.GetXml().Length.ToString());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.Write(myWorkflowContextParameters.GetXml());
XML ADO.NET DataSet using application/x-www-form-urlencoded content type
C#
// Returning the context 
return myWorkflowContextParameters.GetXml();

Asynchronous web procedure development in .NET Framework

Overview

Aynchronous web procedures allow a WorkflowGen system action to be run asynchronously, meaning that the action is initiated at some point in time during the workflow and can be completed at a later instance by an external application.

This type of asynchronous processing can be used in cases where a system action (such a web service) can time out or cause the UI to hang when processing a large volume of information.

This section will explain how to develop an asynchronous web procedure application using WorkflowGen.My v4.0. The example will consist of two different parts: an ASP.NET XML web service that receives and processes the context, and cURL examples of HTTP POST requests (you can choose the appropriate technology to post these) needed to complete the action.

Creating the asynchronous web procedure

To create the ASP.NET XML web service, follow the steps in the previous section, Web procedure development using an ASP.NET XML web service (Creating the web procedure, Creating the application in IIS, Creating a web procedure workflow application using an ASP.NET XML web service, Configure the IIS rendering framework version in the "web.config" file, Specifying your class signature steps).

Basic implementation

In order to demonstrate how to implement an asynchronous web procedure application, we have developed an ASP.NET XML web service that receives a context in JSON or XML ADO.NET DataSet formats, processes the context and update it.

You must add a reference to "WorkflowGen.My.dll" in your web project, then add a using statement for the WorkflowGen.My.Data namespace of the WorkflowGen.My assembly.

C#
using WorkflowGen.My.Data;

Only methods that have the WebMethod attribute can be remotely executed. If the chosen context format is JSON with the application/json content type, or if the context format is XML ADO.NET DataSet with application/xml content type, the web method will not receive any parameters. Otherwise, if you exchange a JSON or ADO.NET DataSet using the application/x-www-form-urlencoded content type, your metho must receive a string parameter called WFGEN_CONTEXT.

C#

JSON (application/json) and XML ADO.NET DataSet (application/xml) context formats:

[WebMethod]
public void WebProcAppJsonXmlAsync()

JSON and XML ADO.NET DataSet context formats using application/x-www-form-urlencoded content type:

[WebMethod]
public string WebProcAppJsonXmlAsync(string WFGEN_CONTEXT)

Note: The parameter name should always be WFGEN_CONTEXT, which is case sensitive.

Loading the WorkflowGen context

Be aware that WorkflowGen will send the context to your external application formatted based on your chosen context format and context type when creating or editing your application in WorkflowGen application form.

For example, if you choose JSON context with the application/json content type, your incoming payload will have the following structure:

{
  "replyToUrl": "http://localhost/wfgen/show.aspx?QUERY=APPLICATION_COMPLETE&ID_PROCESS_INST=2304&ID_ACTIVITY_INST=1&ENCTYPE=application%2fjson&ID_APP_TYPE=WEBPROCASYNC",
  "parameters": [
    {
      "name": "DATE_IN",
      "dataType": "DATETIME",
      "direction": "IN",
      "dateTimeValue": "2017-02-21T15:07:00Z"
    },
    {
      "name": "FILE_IN",
      "dataType": "FILE",
      "direction": "IN",
      "fileValue": {
        "name": "TestFile.txt",
        "contentType": "text/plain",
        "size": 616,
        "url": "file:///C:/inetpub/wwwroot/wfgen/App_Data/Files/DataSet/runtime/2017/02/27/49749-1.txt"
      }
    },
    {
      "name": "NUMERIC_IN",
      "dataType": "NUMERIC",
      "direction": "IN",
      "numericValue": 100.0
    },
    {
      "name": "TEXT_IN",
      "dataType": "TEXT",
      "direction": "IN",
      "textValue": "Lorem ipsum dolor sit amet ~!@#$%^&;*()_+-=[]{}\\|:\"';?/,<:>.,`"
    }
  ]
}

For an example of an XML ADO.NET DataSet context, see WorkflowContext in the Web services API section.

The next thing to do is receive the WorkflowGen context. In the case of the JSON or XML ADO.NET DataSet contexts, when using application/json and application/xml respectively, the context is retrieved from the HttpContext request:

C#
// Reading context from request
string WFGEN_CONTEXT;

HttpContext.Current.Request.InputStream.Position = 0;
using (var reader = new StreamReader(HttpContext.Current.Request.InputStream, System.Text.UTF8Encoding.UTF8))
{
      WFGEN_CONTEXT = reader.ReadToEnd();
}

Otherwise, if the web method has received the WFGEN_CONTEXT in parameters (this is the case with the JSON and XML ADO.NET DataSet contexts when using the application/x-www-form-urlencoded content type), it is available to be used within the method.

Now, we're ready to create a ContextParameters instance that will be used to manipulate the WorkflowGen context.

C#
ContextParameters myWorkflowContextParameters = new ContextParameters(WFGEN_CONTEXT);

Retrieving the parameters from the context

We'll now receive the NUMERIC_IN value into our numericIn double variable, and at the same time, we'll verify that the value is not null; if it is, we'll send an exception.

C#
double numericIn = 0;
if (myWorkflowContextParameters["NUMERIC_IN"].Value != DBNull.Value)
{
    // Get the value of 'NUMERIC_IN' into the numericIn variable
    numericIn = (double)myWorkflowContextParameters["NUMERIC_IN"].Value;
}
else
{
    // If NUMERIC_IN is null generate an error
    throw new SoapException("Web procedure error: 'NUMERIC_IN' parameter must not be null", SoapException.ServerFaultCode);
}

Modifying the parameters with new values

Now, we'll modify some parameters by giving them new values.

C#
myWorkflowContextParameters["DATE_OUT"].Value = DateTime.UtcNow;
myWorkflowContextParameters["NUMERIC_OUT"].Value = 1234567.89;
myWorkflowContextParameters["TEXT_OUT"].Value = "Lorem ipsum dolor sit amet ~!@#$%^&;*()_+-=[]{}\\|:\"';?/,<:>.,`";

        ContextFileReference cfr = new ContextFileReference();
        FileInfo fi = new FileInfo(@"c:\temp\TestFile.txt");
        cfr.Name = fi.Name;
        cfr.Description = fi.Name;
        cfr.Path = fi.FullName;
        cfr.OriginalPath = fi.FullName;
        cfr.ContentType = "text/plain";
        cfr.DateLastModified = fi.LastWriteTimeUtc;
        cfr.Size = fi.Length;
        myWorkflowContextParameters["FILE_OUT"].Value = cfr;

        myWorkflowContextParameters.Update();

Saving the context in a file

Since the asynchronous web procedure will complete the action afterwards, the context and the replyToUrl values should be stored. In this example, we'll use files for this purpose:

// Save the WFGEN_REPLY_TO and context in a file for later processing and reply to WorkflowGen
System.IO.File.WriteAllText(@"c:\WorkflowGen_ReplyToUrl.txt", HttpContext.Current.Request["WFGEN_REPLY_TO"]);

If the context format is JSON:

C#
System.IO.File.WriteAllText(@"c:\Json_Context.json", myWorkflowContextParameters.GetJson());

If the context format is XML ADO.NET DataSet:

C#
System.IO.File.WriteAllText(@"c:\Xml_Context.xml", myWorkflowContextParameters.GetXml());

After the ASP.NET XML web service used to launch the asynchronous web procedure has saved the context, we need to complete the action by sending it back to WorkflowGen. The following cURL examples provide all of the information required to post the context back to WorkflowGen using the information previously saved in the text files. There are many technologies and applications available to do this; for example, you can develop a .NET console application, or post your request using the Postman application. Be aware that the special character must be correctly escaped depending on your application of technology requirements.

JSON context using application/json content type
curl -X POST  
  -H 'Authorization: Basic [your basic authentication credentials]'
  -H 'Content-Type: application/json
  -d '{
   "replyToUrl": "http://localhost/wfgen/show.aspx?QUERY=APPLICATION_COMPLETE&ID_PROCESS_INST=2482&ID_ACTIVITY_INST=1&ENCTYPE=application%2fjson&ID_APP_TYPE=WEBPROCASYNC",
  "parameters": [
    {

      "name": "DATE_OUT",
      "dataType": "DATETIME",
      "direction": "OUT",
      "dateTimeValue": "2017-03-03T15:54:50Z"
    },
    {
      "name": "FILE_OUT",
      "dataType": "FILE",
      "direction": "OUT",
      "fileValue": {
        "name": "Test File.txt",
        "contentType": "text/plain",
        "size": 616,
        "url": "file:///c:/TestFile.txt",
        "updatedAt": "2017-02-21T15:06:38Z"
      }
    },
    {
      "name": "NUMERIC_OUT",
      "dataType": "NUMERIC",
      "direction": "OUT",
      "numericValue": 1234567.89
    },
    {
      "name": "TEXT_OUT",
      "dataType": "TEXT",
      "direction": "OUT",
      "textValue": "This is my text out Lorem ipsum dolor sit amet"
    }
  ]
}' "http://localhost/wfgen/show.aspx?QUERY=APPLICATION_COMPLETE&ID_PROCESS_INST=2482&ID_ACTIVITY_INST=1&ENCTYPE=application%2fjson&ID_APP_TYPE=WEBPROCASYNC"
JSON context using application/x-www-form-urlencoded content type
curl -X POST  
  -H 'Authorization: Basic [your basic authentication credentials]'
  -H 'Content-Type: application/x-www-form-urlencoded'
  -d 'WFGEN_RESULT={
   "replyToUrl": "http://localhost/wfgen/show.aspx?QUERY=APPLICATION_COMPLETE&ID_PROCESS_INST=2481&ID_ACTIVITY_INST=1&ENCTYPE=application%2fx-www-form-urlencoded&ID_APP_TYPE=WEBPROCASYNC",
  "parameters": [
    {

      "name": "DATE_OUT",
      "dataType": "DATETIME",
      "direction": "OUT",
      "dateTimeValue": "2017-03-03T15:54:50Z"
    },
    {
      "name": "FILE_OUT",
      "dataType": "FILE",
      "direction": "OUT",
      "fileValue": {
        "name": "Test File.txt",
        "contentType": "text/plain",
        "size": 616,
        "url": "file:///c:/TestFile.txt",
        "updatedAt": "2017-02-21T15:06:38Z"
      }
    },
    {
      "name": "NUMERIC_OUT",
      "dataType": "NUMERIC",
      "direction": "OUT",
      "numericValue": 1234567.89
    },
    {
      "name": "TEXT_OUT",
      "dataType": "TEXT",
      "direction": "OUT",
      "textValue": "This is my text out Lorem ipsum dolor sit amet"
    }
  ]
}' "http://localhost/wfgen/show.aspx?QUERY=APPLICATION_COMPLETE&ID_PROCESS_INST=2481&ID_ACTIVITY_INST=1&ENCTYPE=application%2fx-www-form-urlencoded&ID_APP_TYPE=WEBPROCASYNC"
XML ADO.NET DataSet context using application/x-www-form-urlencodedcontent type
curl -X POST  
  -H 'Authorization: Basic [your Basic authentication credentials]'
  -H 'Content-Type: application/x-www-form-urlencoded'
  -d 'WFGEN_RESULT=
   <NewDataSet>
  <parameter>
    <name>DATE_OUT</name>
    <dataType>DATETIME</dataType>
    <direction>OUT</direction>
    <dateTimeValue>2017-02-27T15:39:02.0846762Z</dateTimeValue>
  </parameter>
  <parameter>
    <name>FILE_OUT</name>
    <dataType>FILE</dataType>
    <direction>OUT</direction>
    <fileName>Test File.txt</fileName>
    <fileSize>616</fileSize>
    <fileContentType>text/plain</fileContentType>
    <fileDescription>Test File.txt</fileDescription>
    <fileOriginalPath>c:\Test File.txt</fileOriginalPath>
    <fileDateLastModified>2017-01-12T14:28:32.8829125-05:00</fileDateLastModified>
    <filePath>c:\TestFile.txt</filePath>
  </parameter>
  <parameter>
    <name>NUMERIC_OUT</name>
    <dataType>NUMERIC</dataType>
    <direction>OUT</direction>
    <numericValue>1234567.89</numericValue>
  </parameter>
  <parameter>
    <name>TEXT_OUT</name>
    <dataType>TEXT</dataType>
    <direction>OUT</direction>
    <textValue>Lorem ipsum dolor sit amet </textValue>
  </parameter>
  <session>
    <processInstanceId>2483</processInstanceId>
    <activityInstanceId>1</activityInstanceId>
  </session>
</NewDataSet>' "http://localhost/wfgen/show.aspx?QUERY=APPLICATION_COMPLETE&ID_PROCESS_INST=2483&ID_ACTIVITY_INST=1&ENCTYPE=application%2fx-www-form-urlencoded&ID_APP_TYPE=WEBPROCASYNC"
XML ADO.NET DataSet context using application/xml; charset=UTF=8 content type
curl -X POST  
  -H 'Authorization: Basic [your Basic authentication credentials]'
  -H 'Content-Type: application/xml; charset=UTF-8'
  -d '
   <NewDataSet>
  <parameter>
    <name>DATE_OUT</name>
    <dataType>DATETIME</dataType>
    <direction>OUT</direction>
    <dateTimeValue>2017-02-27T15:39:02.0846762Z</dateTimeValue>
  </parameter>
  <parameter>
    <name>FILE_OUT</name>
    <dataType>FILE</dataType>
    <direction>OUT</direction>
    <fileName>TestFile.txt</fileName>
    <fileSize>616</fileSize>
    <fileContentType>text/plain</fileContentType>
    <fileDescription>TestFile.txt</fileDescription>
    <fileOriginalPath>c:\TestFile.txt</fileOriginalPath>
    <fileDateLastModified>2017-01-12T14:28:32.8829125-05:00</fileDateLastModified>
    <filePath>c:\TestFile.txt</filePath>
  </parameter>
  <parameter>
    <name>NUMERIC_OUT</name>
    <dataType>NUMERIC</dataType>
    <direction>OUT</direction>
    <numericValue>1234567.89</numericValue>
  </parameter>
  <parameter>
    <name>TEXT_OUT</name>
    <dataType>TEXT</dataType>
    <direction>OUT</direction>
    <textValue>TLorem ipsum dolor sit amet </textValue>
  </parameter>
  <session>
    <processInstanceId>2485</processInstanceId>
    <activityInstanceId>1</activityInstanceId>
  </session>
</NewDataSet>' "http://localhost/wfgen/show.aspx?QUERY=APPLICATION_COMPLETE&ID_PROCESS_INST=2485&ID_ACTIVITY_INST=1&ENCTYPE=application%2fxml%3b+charset%3dUTF-8&ID_APP_TYPE=WEBPROCASYNC"

RemoteLaunch development in .NET Framework

Overview

The RemoteLaunch SDK is used to launch a WorkflowGen process from the outside of the WorkflowGen environment. This section will explain how to develop a RemoteLaunch SDK application using WorkflowGen.My v3.3. You'll need to create a new website for each RemoteLaunch SDK application you need.

Creating the RemoteLaunch Web Site

Suggested development tools
  • Visual Studio Standard or Professional 2013 or later
Website installation directory

We strongly suggest that you put all of your RemoteLaunch SDKs in the \wfgen\wfapps\sdk\MyRemoteLaunch folder.

Creating the application in IIS

The RemoteLaunch site directory must be declared as an IIS application in order to be recognized as a .NET website application. Follow these instructions to declare your website directory as an IIS application:

For IIS 7 and later
  1. Open Internet Information Services (IIS) Manager.

  2. Navigate to your web form location, which should be placed under the Default Web Site node, under \wfgen\wfapps\sdk\MyRemoteLaunch.

  3. Right-click on MyRemoteLaunch and choose Convert to Application.

  4. Select the application pool used by your site and another specific application pool.

  5. Click OK.

Creating the project with Visual Studio

Creating the project
  1. Open Visual Studio.

  2. Select File > New Web Site.

  3. Choose ASP.NET Empty Web Site.

  4. Chose File system from the Location drop-down list.

  5. Click Browse and choose the location of your ASP.NET web site.

  6. Click OK.

Obtaining detailed error messages

By default, you will have no "web.config" file in your web project if you are using C# as your development language in the Visual Studio IDE. In order to be able to see complete error messages when you want to debug, you have to have a "web.config" file.

In order to be able to see complete error messages, change the following properties in the "web.config" file:

  1. Make sure this line is set to "true":

    <compilation debug="true" />
    
  2. Make sure this is not commented and that the mode="Off".

    <customErrors mode="Off" defaultRedirect="GenericErrorPage.htm">
         <error statusCode="403" redirect="NoAccess.htm" />
         <error statusCode="404" redirect="FileNotFound.htm" />
    </customErrors>
    

Basic implementation

Overview

In order to demonstrate how to implement a RemoteLaunch application, we'll make a simple RemoteLaunch example that sends a context containing two parameters to a WorkflowGen process: AMOUNT and NAME. This process will be launched with these two parameters.

Reference

You must add a reference to WorkflowGen.My.dll in your web project, then add a "using" statement for the WorkflowGen.My.Data namespace of the WorkflowGen.My assembly.

C#
using WorkflowGen.My.Data;

Defining the Page_Load event

We'll use the Page_Load event to immediately start the remote process. Here is the basic code structure we are going to use for the RemoteLaunch SDK application:

C#
protected void Page_Load(object sender, EventArgs e)
{
    // Call the main function
    RemoteProcessLaunch();
}

/// <summary>
/// RemoteProcessLaunch
/// </summary>
private void RemoteProcessLaunch()
{
    ...
}
Using the "web.config" to store your configurations

It is suggested to use the "web.config" file to store all the configurations, instead of hard coding them directly in your website's code-behind. The advantage to this is that if you modify the name of the process to launch, or the username of the launching user, or any other configurations, you will not have to change your code-behind files, only your "web.config" file, without recompiling the web application. Here are the "web.config" values that we'll use:

<appSettings>
    <add key="WorkflowGenLaunchUrl" value="http://localhost/wfgen/show.aspx?QUERY=PROCESS_START_REMOTE"/>
    <add key="WorkflowGenUsername" value="wfgen_admin"/>
    <add key="WorkflowgenUserPassword" value="Advantys123"/>
    <add key="WorkflowGenUserDomain" value=""/>
    <add key="ProcessName" value="SDK_CS_REMOTE_LAUNCH"/>
    <add key="Language" value="en-US"/>
    <add key="RequesterUsername" value="wfgen_admin"/>
    <add key="Test" value="Y"/>
</appSettings>

The following code declares all the variables we need for the RemoteLaunch, then gets the "web.config" values to populate some of these variables.

C#
// Variables Declaration
System.Net.HttpWebRequest httpWebReq = null;            // Http web request object
System.Net.HttpWebResponse httpWebResp = null;            // Http web response object
System.Net.NetworkCredential myCred = null;            // To hold credential information
System.Net.CredentialCache myCache = null;            // credential cache
System.Text.ASCIIEncoding encoding = null;            // for encoding
System.IO.Stream myStream = null;            // To get request data
System.IO.StreamReader myReader = null;            // To read response stream
string respCode;            // string used to get response status code
string workflowContextXml;            // string to get the xml context data
string appUrl = string.Empty;            // string used to Approval URL
string postData = null;            // string used to put the data for request
string response = null;            // string used to display response
byte[] buffer;            // byte used to get the encoded data

// Get values into Configuration constants
// Get the Launch URL
workflowGenLaunchUrl = ConfigurationManager.AppSettings["WorkflowGenLaunchUrl"].ToString();

// Get the WorkflowGen user username
workflowGenUsername = ConfigurationManager.AppSettings["WorkflowGenUsername"].ToString();

// Get the WorkflowGen user password
workflowgenUserPassword = ConfigurationManager.AppSettings["WorkflowgenUserPassword"].ToString();

// Get the WorkflowGen user domain
workflowGenUserDomain = ConfigurationManager.AppSettings["WorkflowGenUserDomain"].ToString();

// Get the process name
processName = ConfigurationManager.AppSettings["ProcessName"].ToString();

// Get the culture information
language = ConfigurationManager.AppSettings["Language"].ToString();

// Get the requester name, default is wfgen_admin
requesterUsername = ConfigurationManager.AppSettings["RequesterUsername"].ToString();

// Get the launch test mode status
test = Convert.ToChar(ConfigurationManager.AppSettings["Test"].ToString());
Building a context from scratch

We now need to build a new context to send to WorkflowGen, to start the new process that needs two parameters: AMOUNT and NAME, which are numeric and text parameters, respectively. Here is the necessary code to create a new context:

C#
// Create a new WorkflowGen object for context parameters
WorkflowGen.My.Data.ContextParameters myWorkflowContextParameters = new
WorkflowGen.My.Data.ContextParameters();

// Create a new AMOUNT context parameter object
WorkflowGen.My.Data.ContextParameter contextParamAmount = new
WorkflowGen.My.Data.ContextParameter();

// Set the parameter name
contextParamAmount.Name = "AMOUNT";

// Set the direction for the parameter
contextParamAmount.Direction = WorkflowGen.My.Data.ContextParameter.Directions.In;

// Set parameter type as double
contextParamAmount.Type = typeof(double);

// Set parameter value
contextParamAmount.Value = Convert.ToDouble(10000);

// Adding the parameter to the context parameters
myWorkflowContextParameters.Add(contextParamAmount);

// Updating the context parameters
myWorkflowContextParameters.Update();
WorkflowGen.My.Data.ContextParameter contextParamName = new
WorkflowGen.My.Data.ContextParameter();

// Set the parameter name
contextParamName.Name = "NAME";

// Set the direction for the parameter
contextParamName.Direction = WorkflowGen.My.Data.ContextParameter.Directions.In;

// Set parameter type as string
contextParamName.Type = typeof(string);

// Set parameter value
contextParamName.Value = "SDK SAMPLE TEXT";

// Adding the parameter to the context parameters
myWorkflowContextParameters.Add(contextParamName);

// Updating the context parameters
myWorkflowContextParameters.Update();

// Get the xml context data into variable
workflowContextXml = myWorkflowContextParameters.GetXml();
Starting the process and sending the context

After having created the context, we need to make a web request to WorkflowGen to start the remote process, and we also need to post the context to the new process instance. Here is the necessary code:

C#
// Call WorkflowGen to instantiate the process
// Prepare the URL
appUrl = workflowGenLaunchUrl + "&L=" + language + "&PROCESS=" + processName + "&REQUESTER_USERNAME=" + requesterUsername + "&TEST=" + test;

// Submit the parameters
myCred = new System.Net.NetworkCredential(workflowGenUsername,workflowgenUserPassword, workflowGenUserDomain);
myCache = new System.Net.CredentialCache();
myCache.Add(new Uri(workflowGenLaunchUrl), "Basic", myCred);

// Prepare a request
httpWebReq = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(appUrl);
httpWebReq.Method = "POST";

// Set authentication information
httpWebReq.Credentials = myCache;

// Set CONTEXT content
postData = "CONTEXT=" + HttpUtility.UrlEncode(workflowContextXml.ToString());
encoding = new System.Text.ASCIIEncoding();
buffer = encoding.GetBytes(postData);

// Set the content type of the data being posted.
httpWebReq.ContentType = "application/x-www-form-urlencoded";

// Set the content length of the string being posted.
httpWebReq.ContentLength = postData.Length;

// Send the CONTEXT
myStream = httpWebReq.GetRequestStream();
myStream.Write(buffer, 0, buffer.Length);

// Close the Stream object.
myStream.Close();
Managing errors

After starting the process, you might receive errors from WorkflowGen if something is not working as expected. Here is the necessary code to display the WorkflowGen error so that you can debug your RemoteLaunch application:

C#
// Try block to handle exception
try
{
    // Check the WorkflowGen response status
    httpWebResp = (System.Net.HttpWebResponse)httpWebReq.GetResponse();
}
// Catch the exception
catch (WebException e)
{
    // Display the error message
    Response.Write(e.ToString());
    return;
}

respCode = "OK"; // response code variable

// Check the response status code is OK
if (respCode != httpWebResp.StatusCode.ToString())
{
    // Display the Error details
    Response.Write("Error:" + httpWebResp.StatusCode);
}
else
{
    // Gets the stream associated with the response
    httpWebResp = (System.Net.HttpWebResponse)httpWebReq.GetResponse();
    myReader = new System.IO.StreamReader(httpWebResp.GetResponseStream());
    response = myReader.ReadToEnd();
    httpWebResp.Close();

    // Display response message
    Response.Write(response);
}

results matching ""

    No results matching ""