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.