.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.csprojZip these at the root of the archive, not inside a folder.
<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.
namespace Handler;
public static class Handler
{
public static async Task<object> Execute(
Dictionary<string, object?> context,
Dictionary<string, object?> payload)
{
// your code
}
}payloadis the JSON input: the request body for a Function, the run's input for a Job.contextis 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:
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:
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
- Read settings with
Environment.GetEnvironmentVariable("NAME"). See Configuration and secrets. - Read secrets from the Secrets API at runtime, never from your ZIP; see Configuration and secrets.
Console.WriteLineoutput goes to the Process Log.
Deploy
gf deploy --name my-function --runtime dotnet --workload-type functionOr create the Coderunner in the Client Portal and upload the ZIP; see Functions.