# Workflow Applications

## Application types

The following application types are covered in this section:

* Web procedures
* Asynchronous web procedures

The following application types are not covered in this section:

* Incoming webhooks
* Non-interactive clients
* SOAP web services
* WCF services
* Web applications

## 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.&#x20;

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.

{% hint style="info" %}
The JSON context is supported as of WorkflowGen version 7.0.0.
{% endhint %}

## Requirements for .NET development <a href="#requirements-net-development" id="requirements-net-development"></a>

### .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`).<br>
2. Copy the `WorkflowGen.My.dl`l file to this folder.<br>
3. Right-click on your project name and choose **Add reference...**<br>
4. Click **Browse**.<br>
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 install the assembly in your GAC, do the following:

1. Copy `WorkflowGen.My.dll` to `DRIVE:\Windows\system32`.<br>
2. Open a command prompt and browse to `DRIVE:\Program Files (x86)\Microsoft Visual Studio 14.0\SDK\v3.5\Bin`.<br>
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.

{% hint style="warning" %}
`WorkflowGen.My.dll` 3.4.0 and later require [`Newtonsoft.Json.dll`](http://www.newtonsoft.com/json) in the same BIN or GAC.
{% endhint %}

### Configuration settings (`app.config` or `web.config`)

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

## Deploying a custom assembly

There are some considerations when deploying a custom assembly SDK workflow application in WorkflowGen, namely the assembly location, the reference to WorkflowGen.My, and references to other software libraries.

### Assembly location

There are two ways of deploying an assembly file in WorkflowGe&#x6E;**.**

#### **Method 1: Reference by assembly’s full name**

The assembly file must be copied to the three bin folders containing the WorkflowGen executable files: `\wfgen\bin`, `\wfgen\ws\bin`, and `DRIVE:\Program Files\Advantys\WorkflowGen\Services\bin`.

**Method 2: Reference by assembly’s path (full physical path with file name)**

The assembly file can be copied to a custom folder such as `DRIVE:\MyWorkflowApps\Assembly.dll`, and then use that specific path in the workflow application’s definition.

{% hint style="warning" %}
If your custom assembly has dependencies, they must be located in the same folder as the assembly.
{% endhint %}

### Reference to WorkflowGen.My

**WorkflowGen.My v3.1.0 and earlier**

WorkflowGen.My versions 3.1.0 and earlier are strong-named, which means your assembly must be built with and use the same version as your target WorkflowGen. This requires recompiling your assembly whenever you upgrade WorkflowGen to a newer version.

You can use one of the following workarounds to overcome this requirement:

1. Install the required WorkflowGen.My version in the system's global assembly cache (GAC). For instructions on how to do this, see the [How to: Install an assembly into the global assembly cache](https://docs.microsoft.com/en-us/dotnet/framework/app-domains/how-to-install-an-assembly-into-the-gac) Microsoft article.\
   \
   **OR**<br>
2. Add a delegate to handle the assembly resolve event in order to load the current WorkflowGen.My version. For instructions on how to do this, see the [How to add an assembly resolve event delegate to overcome WorkflowGen.My dependency issue when deploying custom assembly SDK workflow application](https://discuss.workflowgen.com/t/how-to-add-an-assembly-resolve-event-delegate-to-overcome-workflowgen-my-dependency-issue-when-deploying-custom-assembly-sdk-workflow-application/330) article on the WorkflowGen Forum & Knowledge Base.\
   \
   **OR**<br>
3. Add a web configuration setting to redirect the required version to the current version of WorkflowGen.My. For more information, see the [\<assemblyBinding> Element for \<runtime>](https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/assemblybinding-element-for-runtime) Microsoft article.&#x20;

{% hint style="info" %}
If your assembly is built with WorkflowGen.My v3.1.0 or earlier, it can be used in WorkflowGen version 6.2.0 and later if one of the above workarounds has been implemented.
{% endhint %}

#### **WorkflowGen.My v3.2.0 and later**

As of version 3.2.0, WorkflowGen.My is no longer strong-named in order to allow non-specific version dependency when referenced by your assembly. You can simply deploy your assembly file using one of the two methods in the [Assembly location](#assembly-location) section above in WorkflowGen 6.2.0 and later.

{% hint style="info" %}
If your assembly is built with WorkflowGen.My v3.2.0 or later, it can be used in WorkflowGen versions prior to 6.2.0 if you have implemented **either workaround 2 or 3** above.
{% endhint %}

### References to other software libraries

If your assembly uses third-party libraries, then these must also be deployed into the three WorkflowGen executable `\bin` folders. Alternatively, they can be installed into the system’s global assembly cache (GAC) if they are strong-named assemblies.

## 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.

{% hint style="info" %}
The WorkflowGen JSON and DataSet contexts exchange DateTime parameters with external applications in the UTC time zone according to the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format (see <https://en.wikipedia.org/wiki/ISO_8601> for more information).
{% endhint %}

For an example of an XML ADO.NET DataSet context, see [WorkflowContext](https://docs.workflowgen.com/integration/9.5/web-services-api#workflowcontext) in the [Web services API](https://docs.workflowgen.com/integration/9.5/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 structures:

#### 📌 JSON example (web procedure)

```json
{
  "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)

```json
{
  "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 ~!@#$%^&;*()_+-=[]{}\\|:\"';?/,<:>.,`"
    }
  ]
}
```

{% hint style="info" %}
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.
{% endhint %}

## 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 from a `workflowGenContext` string:

```csharp
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:

```csharp
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:

```csharp
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 using the collection enumerator. Don't forget to remove the filter afterward, or else you won't be able to access the other parameters.

```csharp
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:

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

{% hint style="info" %}
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.
{% endhint %}

### 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:

```csharp
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).

```csharp
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 <a href="#web-proc-dev-asp-net-xml-web-service" id="web-proc-dev-asp-net-xml-web-service"></a>

### 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.

{% hint style="info" %}
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.
{% endhint %}

### Creating the web procedure

Visual Studio Standard or Professional 2013 or later is suggested for development.

#### Web procedure installation directory

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

{% hint style="warning" %}
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`.
{% endhint %}

### 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.<br>
2. Navigate to your web form location, which should be under the **Default Web Site** node, under `\wfgen\wfapps\webservices\MyWebProc`.<br>
3. Right-click on **MyWebProc** and choose **Convert to Application**.<br>
4. Select the application pool used by your site and another specific application pool.<br>
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.<br>
2. Select **File > New Web Site**.<br>
3. Choose **ASP.NET Web Service** (available for .NET Framework versions 2.0 to 3.5).<br>
4. Choose **File system** from the **Location** drop-down list.<br>
5. Click **Browse** and choose the location of your ASP.NET website.<br>
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`:

```html
<compilation debug="true" />
```

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

```html
<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 service's `web.config` file. The following are the necessary nodes to insert in the `system.web` node of your `web.config` file:

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

### Configuring 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:

```html
<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:

```csharp
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:

```csharp
[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:

```csharp
[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`.

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

```csharp
[WebMethod]
public void WebProcAppJsonXml()
```

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

```csharp
[WebMethod]
public string WebProcAppJsonXml(string WFGEN_CONTEXT)
```

{% hint style="info" %}
The parameter name should always be `WFGEN_CONTEXT`, which is case sensitive.
{% endhint %}

### 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:

```csharp
// 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:

```csharp
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):

```csharp
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:

```csharp
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

```csharp
// 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

```csharp
// Returning the context 
return myWorkflowContextParameters.GetJson();
```

#### XML ADO.NET DataSet using `application/xml` content type

```csharp
// 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

```csharp
// Returning the context 
return myWorkflowContextParameters.GetXml();
```

## Asynchronous web procedure development in .NET Framework <a href="#async-web-prov-dev-net-framework" id="async-web-prov-dev-net-framework"></a>

### Overview

Asynchronous 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](#web-proc-dev-asp-net-xml-web-service):

1. Create the web procedure.<br>
2. Create the application in IIS<br>
3. Create a web procedure workflow application using an ASP.NET XML web service.<br>
4. Configure the IIS rendering framework version in the `web.config` file.<br>
5. Specify 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 updates 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:

```csharp
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 method must receive a string parameter called `WFGEN_CONTEXT`.

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

```csharp
[WebMethod]
public void WebProcAppJsonXmlAsync()
```

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

```csharp
[WebMethod]
public string WebProcAppJsonXmlAsync(string WFGEN_CONTEXT)
```

{% hint style="info" %}
The parameter name should always be `WFGEN_CONTEXT`, which is case sensitive.
{% endhint %}

### 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:

```json
{
  "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](https://docs.workflowgen.com/integration/9.5/web-services-api#workflowcontext) in the [Web services API](https://docs.workflowgen.com/integration/9.5/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:

```csharp
// 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.

```csharp
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:

```csharp
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:

```csharp
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:

```csharp
// 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"]);
```

#### JSON context format

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

#### XML ADO.NET DataSet context format

```csharp
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

```json
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

```json
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-urlencoded`content type

```html
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

```markup
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>Lorem 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"
```
