Skip to content
Open backoffice ↗

Submissions & automation · UMBRACO

C# recipes: Umbraco, SQL & HTTP

Use actual field keys, native services and named configuration.

Start with the wizard

The scripting panel's guided samples use the current form's field keys and ask for configuration names. Choose actual fields and named connections/settings; review the generated source before approving it. The following recipes illustrate that same supported execution context.

Read native Umbraco content

Create a numeric content_id field containing an existing node ID. The sample resolves Umbraco's native service from the execution scope:

using MegaForm.Core.Scripting;
var service = ScriptHost.Service<global::Umbraco.Cms.Core.Services.IContentService>();
var content = service.GetById(ctx.GetInt("content_id"));
if (content == null)
    throw new System.InvalidOperationException("Content not found.");
ctx.SetVariable("contentName", content.Name);

This server service can read unpublished content. Do not copy its output into a public response without checking whether that content should be disclosed. The example records only the selected name in the authorised run output.

Insert a row with parameters

Provision an application-owned table App_FormAudit(Reference) first. AuditDatabase must be an existing connection alias registered by the host. Other table columns must accept defaults or nulls.

using MegaForm.Core.Scripting;
using System.Data;
using (var connection = ScriptHost.Connection("AuditDatabase"))
{
    await connection.OpenAsync(ct);
    using (var command = connection.CreateCommand())
    {
        command.CommandText = "INSERT INTO App_FormAudit (Reference) VALUES (@reference)";
        var value = command.CreateParameter();
        value.ParameterName = "@reference";
        value.DbType = DbType.String;
        value.Value = "MF-" + ctx.FormId + "-" + ctx.SubmissionId;
        command.Parameters.Add(value);
        ctx.SetVariable("rowsInserted", await command.ExecuteNonQueryAsync(ct));
    }
}

The wizard can generate an insert for your selected table and answer column. Adapt identifiers to the actual schema; keep submitted values parameterised. Test run inserts a real row.

Call a configured webhook

Store the endpoint in server configuration as Integrations:BookingWebhook. This example posts a minimal payload and verifies the response status:

using MegaForm.Core.Scripting;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;
var endpoint = ScriptHost.Setting("Integrations:BookingWebhook");
var payload = JsonConvert.SerializeObject(new {
    formId = ctx.FormId, submissionId = ctx.SubmissionId
});
using (var client = new HttpClient())
using (var body = new StringContent(payload, Encoding.UTF8, "application/json"))
using (var response = await client.PostAsync(endpoint, body, ct))
{
    response.EnsureSuccessStatusCode();
    ctx.SetVariable("webhookStatus", (int)response.StatusCode);
}

Other guided samples include configured API reads and HMAC-signed webhooks. Keep tokens and signing keys in server configuration. Do not log them.

Know the context boundary

Use ctx.GetString/GetInt/GetDecimal/GetBool/GetDate, ctx.FormId, ctx.SubmissionId, ctx.SetVariable, ctx.Log and ctx.Response. Native services come from ScriptHost.Service<T>(); settings and connections come from ScriptHost. There are no ctx.Db or ctx.Http convenience APIs.

A timeout is cooperative. Pass ct, avoid blocking calls and make side effects safe to retry. See approval and failure policy.