Skip to content

C# script ​

The C# script component runs your C# code for every record that reaches it. The code is compiled into the flow with the rest of the flow's code, so it runs at the speed of compiled .NET and can use any NuGet package.

What you write ​

You write the body of a class. Connect the input and output first, then open the editor: the template is generated from the connections and already has the right types.

csharp
public override void Execute(IMetaData metaDataInstance, IViaType inputDataInstance)
{
    var metaData = (viauser.FlowMetaData)metaDataInstance;
    var input = (Customer)inputDataInstance;
    var output = new CustomerDto();
    Next(metaData, output);
}

viauser is the flow's namespace, Customer the type of the input connection and CustomerDto the type of the output connection. Add fields, properties and helper methods next to Execute as you need them.

using statements can go anywhere in the script; they are moved to the top before compiling. System, System.Linq, System.Text, the collections and tasks namespaces, the Viaducta type system and the flow's namespace are already imported.

Sending records on ​

Next(metaData, output) sends a record to the components connected to Output.

  • Call it once to transform a record.
  • Call it several times to split one record into many.
  • Don't call it to filter the record out.

Pass an object of the output connection's type. Every flow type is a C# class, so new CustomerDto() creates one.

Options ​

OptionDefaultWhat it does
SingletononOne instance of your class serves all records, so fields keep their values between records. Turn it off to get a new instance per record.
Async/AwaitoffYour class implements ExecuteAsync and sends records with await NextAsync(...). Use it when the script calls asynchronous APIs.

A singleton instance serves records in parallel. Keep its fields thread-safe (Interlocked, ConcurrentDictionary) or use local variables.

When you switch Async/Await, change the method yourself or clear the script to regenerate the template:

csharp
public override async Task ExecuteAsync(IMetaData metaDataInstance, IViaType inputDataInstance)
{
    var metaData = (viauser.FlowMetaData)metaDataInstance;
    var input = (Customer)inputDataInstance;
    await Task.Delay(100, Services.CancellationToken);
    await NextAsync(metaData, input);
}

Flow services ​

The Services property gives your code logging, settings, storage, assets, batches and the rest of the flow services:

csharp
var apiUrl = Services.Settings.Get("Crm", "ApiUrl");
Services.Log.Information($"Calling {apiUrl}", metaData);
Services.Messaging.UpdateStatusMessage($"Last: {input.Email}");

Keep secrets out of the script. Store them in an expression settings package and read them with Services.Settings.

NuGet packages ​

Add packages in the flow properties: References → Add → Nuget package (C#). Every C# script, shared script and decision condition of the flow can use them.

Editor and debugger ​

The C# editor gives you completion, hover help and compile errors as you type. Press F6 to compile the whole flow.

To debug, start the flow with Debug (Ctrl+F5), then click the margin of a line to set a breakpoint. When a record reaches it the flow pauses and the watch window shows the variables. Step with F10, F11 and Shift+F11; continue with F5.

Errors ​

An exception goes to the flow's error handling, like an error in any other component. To report an error and carry on with the next record, catch it and call await Services.HandleExceptionAsync(metaData, input, ex).

C# shared script ​

The C# shared script component holds code the whole flow uses: helper classes, extension methods, clients. It has no pins and processes no records. Place it anywhere on the canvas.

You write a complete C# file. The template has the flow's namespace and a class marked with the component's [ViaScript] attribute:

csharp
using System;
using System.Linq;
using Viaducta.Plugin.Design;
using Viaducta.Plugin.Design.Scripting;

namespace viauser
{
    [ViaScript("3f1d...")]
    public class MySharedScript_1
    {
        [ViaServices]
        public static IFlowService Services { get; set; }

        public static string NormalizePhone(string phone)
        {
            var digits = new string((phone ?? "").Where(char.IsDigit).ToArray());
            Services?.Log.Verbose($"Normalized {phone} to {digits}");
            return digits;
        }
    }
}

Call it from any C# script of the flow:

csharp
output.Phone = MySharedScript_1.NormalizePhone(input.Phone);
  • To use the flow services, declare a public static IFlowService property marked [ViaServices] or named Services in the class with the [ViaScript] attribute. The flow fills it at start.
  • Static members are shared by every component that uses them; keep them thread-safe.
  • When you copy a shared script component, rename the class so the flow doesn't get the same class twice.

Viaducta documentation