Table of Contents

Module Settings

Module settings define configurable properties that users can adjust in the Flow Studio UI. Settings are created by inheriting from FlowModuleSettings.

Tip

Required namespaces:

  • Crosser.EdgeNode.Common.Abstractions.Utilities.Validation
  • Crosser.EdgeNode.Flows.Abstractions
  • System.ComponentModel
  • System.ComponentModel.DataAnnotations

Creating Settings Class

Name your settings class with a Settings suffix. For example: RandomNumberModuleRandomNumberModuleSettings

public class RandomNumberModuleSettings : FlowModuleSettings
{
    [Display(Name = "Minimum value", Description = "The smallest value allowed")]
    [JsonSchemaExtensionData("x-sortOrder", 1)]
    [DefaultValue(0)]

    public int MinValue { get; set; }

    [Display(Name = "Maximum value", Description = "The highest value allowed")]
    [JsonSchemaExtensionData("x-sortOrder", 2)]
    [DefaultValue(100)]
    public int MaxValue { get; set; }
}

In this example, we define two integer settings: MinValue and MaxValue, each with display names, descriptions, sort order, and default values. The attributes control how the settings appear in the Flow Studio UI. The sort order ensures that MinValue appears before MaxValue in the Flow Studio UI. The display names and descriptions help users understand the purpose of each setting. The default values provide initial values when the module is added to a flow.

Property Guidelines

Supported Types

  • Primitive types: int, string, bool, double, DateTime, Guid
  • Enums: For predefined choices
  • Collections: List<T> for multiple values
  • Nested objects: Group related settings into classes

Configuration Attributes

Attributes control how settings appear and behave in Flow Studio:

  • Display - Sets labels and tooltips
  • Validation - Adds input restrictions
  • Default Values - Sets initial values
  • Data Types - Specifies special UI behaviors
  • Credentials - Marks a setting as a credential.
  • Resources - Marks a setting as a resource.
Category Attribute Purpose Example
Display [Display] Sets label for field [Display(Name = "Connection String")]
public string ConnectionString { get; set; }
Display [Description] Provides help text and tooltips for fields [Description("Enter the database connection string")]
public string ConnectionString { get; set; }
Validation [Required] Makes a field mandatory [Required]
[Display(Name = "API Key")]
public string ApiKey { get; set; }
Validation [Range] Sets numeric min/max constraints [Range(1, 1000)]
[Display(Name = "Batch Size")]
public int BatchSize { get; set; } = 100;
Validation [MinLength] Sets minimum string length [MinLength(1)]
[Display(Name = "Queue Name")]
public string QueueName { get; set; }
Validation [MaxLength] Sets maximum string length [MaxLength(256)]
[Display(Name = "Description")]
public string Description { get; set; }
Validation [RegularExpression] Validates against regex pattern [RegularExpression(@"^[a-zA-Z0-9_-]+$")]
[Display(Name = "Identifier")]
public string Identifier { get; set; }
Default Values [DefaultValue] Sets default value for a property [DefaultValue(true)]
[Display(Name = "Enable Caching")]
public bool EnableCaching { get; set; } = true;
Data Types [DataType] Specifies special data types (e.g., multiline text) [DataType(DataType.MultilineText)]
[Display(Name = "SQL Query")]
public string SqlQuery { get; set; }
Credentials [JsonSchemaExtensionData]
("x-credential", type)
Links to credential storage
Types: "UsernamePassword", "ApiKey",
"Certificate", "ConnectionString"
[JsonSchemaExtensionData("x-credential", "UsernamePassword")]
[Display(Name = "Database Credentials")]
public Guid? DatabaseCredential { get; set; }
Resources [JsonSchemaExtensionData]
("x-resource", "File")
Links to resource files
Note: Always use "File" for custom modules
[JsonSchemaExtensionData("x-resource", "File")]
[Display(Name = "Configuration File")]
public Guid? ConfigurationFile { get; set; }
Sort Order [JsonSchemaExtensionData]
("x-sortOrder", order)
Sets the display order in the UI [JsonSchemaExtensionData("x-sortOrder", 1)]
[Display(Name = "Min Value")]
public int MinValue { get; set; }
Tip

Key Points:

  • Combine multiple attributes on a single property for comprehensive configuration
  • Never store passwords directly; always use JsonSchemaExtensionData for credentials
  • Always set both [DefaultValue] attribute and property initializer for consistency

Example

[Display(Name = "Connection timeout", Description = "Timeout in seconds")]
[DefaultValue(30)]
[Range(1, 300)]
public int TimeoutSeconds { get; set; } = 30;

[Display(Name = "SQL Query", Description = "Query to execute")]
[DataType(DataType.MultilineText)]
[NotNull]
[DefaultValue("Select * from table")]
public string Query { get; set; } = "Select * from table";

[Display(Name = "Allowed IPs", Description = "List of allowed IP addresses")]
public List<string> AllowedIps { get; set; } = new();

Validation

Override Validate to add custom validation logic:

public class RandomNumberModuleSettings : FlowModuleSettings
{
    [Display(Name = "Minimum value")]
    [DefaultValue(0)]
    public int MinValue { get; set; }

    [Display(Name = "Maximum value")]
    [DefaultValue(100)]
    public int MaxValue { get; set; }

    public override void Validate(SettingsValidator validator)
    {
        // Built-in validators
        validator.Validate(nameof(this.MinValue), this.MinValue)
            .MinValue(1)
            .MaxValue(1000);

        validator.Validate(nameof(this.MaxValue), this.MaxValue)
            .MinValue(1)
            .MaxValue(1000);

        // Custom validation logic
        if (this.MinValue >= this.MaxValue)
        {
            validator.AddError(nameof(this.MinValue), 
                "Minimum value must be less than maximum value");
        }
    }
}

Available Validators

  • MinValue(int) / MaxValue(int) - Range validation for numbers
  • MinLength(int) / MaxLength(int) - Length validation for strings
  • Required() - Ensures value is not null/empty
  • AddError(propertyName, message) - Custom validation errors

Common Patterns

Enums

[JsonConverter(typeof(StringEnumConverter))]
public enum ConnectionMode
{
    [Description("Automatic")]
    Auto,
    [Description("Always use SSL")]
    Ssl
}

[Display(Name = "Connection mode")]
[DefaultValue(ConnectionMode.Auto)]
public ConnectionMode Mode { get; set; }

Collections

[Display(Name = "Allowed IPs", Description = "IP addresses allowed to connect")]
public List<string> AllowedIps { get; set; } = new();

[Display(Name = "Field Mappings")]
public List<FieldMapping> Mappings { get; set; } = new();

public class FieldMapping
{
    [Display(Name = "Source")]
    public string Source { get; set; }
    
    [Display(Name = "Target")]
    public string Target { get; set; }
}

Nested Settings

public class MyModuleSettings : FlowModuleSettings
{
    [Display(Name = "Connection Settings")]
    public ConnectionSettings Connection { get; set; } = new();
}

public class ConnectionSettings
{
    [Display(Name = "Host")]
    [Required]
    public string Host { get; set; }
    
    [Display(Name = "Port")]
    [DefaultValue(443)]
    [Range(1, 65535)]
    public int Port { get; set; } = 443;
}

Conditional Validation

[Display(Name = "Enable authentication")]
[DefaultValue(false)]
public bool UseAuth { get; set; }

[Display(Name = "Username")]
public string Username { get; set; }

public override void Validate(SettingsValidator validator)
{
    if (this.UseAuth && string.IsNullOrEmpty(this.Username))
    {
        validator.AddError(nameof(this.Username), 
            "Username required when authentication enabled");
    }
}

Accessing Settings

Access settings in your module via the Settings property:

public class MyModule : FlowModule<MyModuleSettings>
{
    protected override async Task MessageReceived(IFlowMessage message)
    {
        // Direct access
        var timeout = this.Settings.TimeoutSeconds;
        
        // Nested settings
        var host = this.Settings.Connection.Host;
        var port = this.Settings.Connection.Port;
        
        // Enum settings
        if (this.Settings.Mode == ProcessingMode.Batch)
        {
            await ProcessBatch(message);
        }
        
        // Collections
        foreach (var mapping in this.Settings.Mappings)
        {
            var value = message.Get<object>(mapping.Source);
            message.Set(mapping.Target, value);
        }
        
        await this.Next(message);
    }
}

Common Settings (Platform-Managed)

The CommonSettings property provides platform-managed configuration that you can read but should NOT modify:

  • MaxItemsInQueue - Queue size limit
  • ChannelFullMode - Behavior when queue is full
  • MessagesRetries - Number of retry attempts
  • MessagesRetryDelay - Delay between retries
  • PersistentMessages - Whether messages are persisted
  • DisableQueues - Queue disable flag

Advanced Features

Credentials

[JsonSchemaExtensionData("x-credential", "UsernamePassword")]
[Display(Name = "Database Credentials")]
public Guid? DatabaseCredential { get; set; }

// Other types: "ApiKey", "Certificate", "ConnectionString"

Resources

[JsonSchemaExtensionData("x-resource", "File")]
[Display(Name = "Configuration File")]
public Guid? ConfigFile { get; set; }
Note

See Crosser documentation for how to create credentials and resources in flow studio.

Summary

  • Provide defaults: Always set [DefaultValue] when possible
  • Clear naming: Use descriptive names that users will understand
  • Add descriptions: Help users understand what each setting does
  • Validate early: Catch configuration errors before the flow starts
  • Logical order: Arrange properties in the order users should configure them

Next Steps

>> Module Status