Skip to main content
Version: 2023.1

Custom data source

Custom data sources are used to load data from external sources that are not handled by built-in connection features of WEBCON BPS. For example, when we need to download data from several places in one source definition. The Custom data source also allows you to define your own ways of searching for data and filtering it.

Everything you need to create an SDK and how to create a project is described at the beginning of this article - Create your first plugin

If you use SDK templates (which is the recommended option) right click on the project in the solution explorer and select Add -> New Item. Now select Custom Data Source and choose the name for the newly created class.

CreateNewCustomDataSource

Now you can set the display name and description of the created plugin. The data entered here can always be changed later in the JSON file

PluginMetadata

Two files have been created, in this example CustomDatasourceExample and CustomDatasourceExampleConfig. The file with the Config suffix is a configuration file that is exactly the same as in Custom Action. The second file is more interesting, it contains two methods that only appear in Custom Data Sources.

using WebCon.WorkFlow.SDK.DataSourcePlugins;
using WebCon.WorkFlow.SDK.DataSourcePlugins.Model;

namespace CustomDatasourceExample.CustomDataSourceExample
{
public class CustomDataSourceExample : CustomDataSource<CustomDataSourceExampleConfig>
{
public override Task<List<DataSourceColumn>> GetColumnsAsync()
{
throw new System.NotImplementedException();
}

public override Task<DataTable> GetDataAsync(SearchConditions searchConditions)
{
throw new System.NotImplementedException();
}

}
}

The GetColumns method is called when BPS needs to check what columns the source returns, e.g. when setting a picker field. In most cases, the columns returned by the source will be static, so we can fill this method with such code.

public override Task<List<DataSourceColumn>> GetColumnsAsync()
{
return Task.FromResult(new List<DataSourceColumn>() {
new DataSourceColumn("ID"),
new DataSourceColumn("Name"),
new DataSourceColumn("Surname"),
new DataSourceColumn("Address")
});
}

In this way BPS knows that the source will return four columns named: ID, Name, Surname and Address

The second GetData method is already used to download and return data. The most interesting in this method is the SearchConditions parameter.

On the registered custom data source we can apply two filtering modes: „Using BPS“ or „Using Addin“.

FilteringModes

If the Custom Data Source Filtering is set to 'Using BPS', this parameter will always be null. The only thing left to do is return all data and BPS will do the filtering.

But if we change this option on 'Using addin', the search parameters entered by the user into the picker field will be passed to the method and BPS will stop filtering the result. This filtering mode could be useful when, for example: we have a webserver that allows to provide search conditions to return a limited amount of data. By sending search parameters to it, we can reduce the amount of downloaded data. If we download all the data and only filter it later, the BPS filtering will work just as well.

Search Conditions

SearchConditions has several properties, but OrConditions is the most important for us. This is the list of SearchConditions that corresponds to what the user has entered in the picker.

SearchBox

If we set it to search only in the Name column and enter John, in the code searchCondision will look like this.

SearchConditionsOnlyName

In the ColumnName parameter is the column name selected by the user in the picker, Value parameter contains the value entered by user in the picker, and there is also Match parameter which depends on the picker settings, by default it is “Starts With”.

PickerSearchMode

Values obtained from the picker can be used e.g. to invoke the webservice or in an SQL query. Code using searchConditions could look something like shown below. In this example, from the first element of OrConditions, we take the Value property and pass it to the GetDataFromWebservice method. If you want the returned data to be additionally filtered, you must implement such a functionality yourself.

        public override Task<DataTable> GetDataAsync(SearchConditions searchConditions)
{
var condisionValue = searchConditions.OrConditions[0].Value;
var dt = GetDataFromWebservice(condisionValue);
return Task.FromResult(dt);
}

In addition to OrConditions, there are also AndConditions. AndConditions are set in Expression editor in the choice field configuration.

Expression editor

ConditionsBuilder

The implementation of searchConditions depends entirely on the plugin’s creator, but a good practice to keep in mind is this: It is enough that only one OrCodition is met, but AndConditions should all be met.

Example Conditions checker could look like this:

private bool CheckConditions(DataRow dr, SearchConditions searchConditions)
{
if (searchConditions == null)
return true;

foreach (var condition in searchConditions.AndConditions)
if (!CheckCondition(dr, condition))
return false;

if (!searchConditions.OrConditions.Any())
return true;

foreach (var condition in searchConditions.OrConditions)
if (CheckCondition(dr, condition))
return true;

return false;
}