Groundfloor Docs
Language runtimes

.NET

Write a Coderunner Function, Job or Schedule in C# and .NET.

Use this reference for Functions, Jobs and Schedules written in C#. For a container with your own web server, see Services.

Project files

my-function/
├── Handler.cs
└── CodeRunner.Function.csproj

Zip these at the root of the archive, not inside a folder.

CodeRunner.Function.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <OutputType>Exe</OutputType>
  </PropertyGroup>
</Project>

Add NuGet packages with <PackageReference> as usual.

The handler

Coderunner calls Handler.Handler.Execute: a static Execute method on a static Handler class, in the Handler namespace.

Handler.cs
namespace Handler;

public static class Handler
{
    public static async Task<object> Execute(
        Dictionary<string, object?> context,
        Dictionary<string, object?> payload)
    {
        // your code
    }
}
  • payload is the JSON input: the request body for a Function, the run's input for a Job.
  • context is reserved for information from the runtime. Don't rely on its contents yet.

You don't need an ASP.NET app, controllers, Kestrel settings, routes or ASPNETCORE_URLS.

Function example

A Function can return anything. This shape is the convention:

Handler.cs
namespace Handler;

public static class Handler
{
    public static async Task<object> Execute(
        Dictionary<string, object?> context,
        Dictionary<string, object?> payload)
    {
        var name = payload.TryGetValue("name", out var value) ? value?.ToString() : null;
        if (string.IsNullOrEmpty(name))
        {
            return new
            {
                statusCode = 400,
                body = new { error = "name is required" },
                headers = new Dictionary<string, string> { ["content-type"] = "application/json" }
            };
        }

        return new
        {
            statusCode = 200,
            body = new { greeting = $"Hello, {name}" },
            headers = new Dictionary<string, string> { ["content-type"] = "application/json" }
        };
    }
}

Job and Schedule example

A Job or Schedule returns Task:

Handler.cs
namespace Handler;

public static class Handler
{
    public static async Task Execute(
        Dictionary<string, object?> context,
        Dictionary<string, object?> payload)
    {
        Console.WriteLine("Import started");
        var count = await ImportCustomers();
        Console.WriteLine($"Imported {count} customers");
    }
}

If an exception escapes Execute, the run is marked Failed. If you catch it, the run succeeds and handling it is up to you. See Jobs.

Settings, secrets and logs

Deploy

gf deploy --name my-function --runtime dotnet --workload-type function

Or create the Coderunner in the Client Portal and upload the ZIP; see Functions.

On this page