All Products
Search
Document Center

Function Compute:Handlers

Last Updated:Apr 01, 2026

A C# handler is the method that Function Compute calls when your function is invoked. This topic explains the handler string format, valid method signatures, supported handler types (stream and POCO), serialization options, and how to handle HTTP trigger invocations.

Note

If you want to use HTTP triggers or custom domain names to access functions, obtain request struct before you define HTTP responses. For more information, see Use an HTTP trigger to invoke a function.

Handler string format

C# handler strings follow this format:

Assembly::Namespace.ClassName::MethodName
ParameterDescription
AssemblyName of the assembly
NamespaceName of the namespace
ClassNameName of the class
MethodNameName of the method

For example, if the name of the assembly is HelloFcApp, the handler is HelloFcApp::Example.HelloFC::StreamHandler.

Configure the handler string when you create or update a function in the Function Compute console. For more information, see Create an event function.

Valid handler signatures

A handler method can be either a static method or an instance method. All supported signatures are listed below. The IFcContext parameter is optional in all forms.

// Synchronous signatures
ReturnType HandlerName(InputType input, IFcContext context);
ReturnType HandlerName(InputType input);

// Asynchronous signatures
async Task<ReturnType> HandlerName(InputType input, IFcContext context);
async Task<ReturnType> HandlerName(InputType input);

Function Compute waits for async methods to complete before returning.

Parameter types:

ParameterAccepted types
ReturnTypevoid, System.IO.Stream, or any JSON-serializable object. A Stream return value is written directly to the response body; other types are JSON-serialized first.
InputTypeSystem.IO.Stream or any JSON-deserializable object
IFcContextThe function context object. For more information, see Context.

Event handlers

C# event handlers require the Aliyun.Serverless.Core NuGet package (version 1.0.1). Add it to your .csproj file:

<ItemGroup>
  <PackageReference Include="Aliyun.Serverless.Core" Version="1.0.1" />
</ItemGroup>

The package provides two handler types:

  • Stream handler — receives raw event data as a stream and writes results to an output stream.

  • POCO handler — uses plain old class objects (POCO) for typed input and output, with automatic JSON serialization.

Stream handler

A stream handler reads input from a Stream and returns a Stream.

using System.IO;
using System.Threading.Tasks;
using Aliyun.Serverless.Core;
using Microsoft.Extensions.Logging;

namespace Example
{
    public class Hello
    {
        public async Task<Stream> StreamHandler(Stream input, IFcContext context)
        {
            IFcLogger logger = context.Logger;
            logger.LogInformation("Handle request: {0}", context.RequestId);
            MemoryStream copy = new MemoryStream();
            await input.CopyToAsync(copy);
            copy.Seek(0, SeekOrigin.Begin);
            return copy;
        }

        static void Main(string[] args){}
    }
}

For the assembly HelloFcApp, the handler string for this example is:

HelloFcApp::Example.Hello::StreamHandler

Key elements:

ElementDescription
Stream inputInput event data. Read from this stream in your handler.
IFcContext context(Optional) Context object providing request metadata and logging.
Task<Stream>Return type. The stream content is written directly to the response body.

POCO handler

A POCO handler uses typed C# classes for input and output. Function Compute automatically serializes and deserializes these objects using JSON.Net (Newtonsoft.Json).

using Aliyun.Serverless.Core;
using Microsoft.Extensions.Logging;

namespace Example
{
    public class Hello
    {
        public class Product
        {
            public string Id { get; set; }
            public string Description { get; set; }
        }

        // Optional: specify a custom serializer class.
        // If omitted, the default JSON.Net serializer is used.
        // [FcSerializer(typeof(MySerialization))]
        public Product PocoHandler(Product product, IFcContext context)
        {
            string Id = product.Id;
            string Description = product.Description;
            context.Logger.LogInformation("Id {0}, Description {1}", Id, Description);
            return product;
        }

        static void Main(string[] args){}
    }
}

For the assembly HelloFcApp, the handler string for this example is:

HelloFcApp::Example.Hello::PocoHandler

Key elements:

ElementDescription
Product productInput parameter of type Product. Deserialized from the event payload using JSON.Net.
IFcContext context(Optional) Context object.
Product (return type)Output serialized to JSON using JSON.Net and written to the response body.

Serialization

POCO handlers use JSON.Net (Newtonsoft.Json) by default, provided by Aliyun.Serverless.Core. This covers most use cases without additional configuration — Function Compute automatically deserializes the incoming event into your input type and serializes the return value into the response body.

When to use a custom serializer: if you need to handle special types, custom naming conventions, or non-JSON formats, implement the IFcSerializer interface:

public interface IFcSerializer
{
    T Deserialize<T>(Stream requestStream);
    void Serialize<T>(T response, Stream responseStream);
}

To use a custom serializer, apply the [FcSerializer] attribute to your handler method:

[FcSerializer(typeof(MySerialization))]
public Product PocoHandler(Product product, IFcContext context) { ... }

Use an HTTP trigger to invoke a function

Sample code

The following example defines typed classes for an HTTP trigger request and response, reads the request body, and echoes it back.

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;
using Aliyun.Serverless.Core;
using Microsoft.Extensions.Logging;

namespace Example
{
    public class Hello
    {
        public class HTTPTriggerEvent
        {
            public string Version { get; set; }
            public string RawPath { get; set; }
            public string Body { get; set; }
            public bool IsBase64Encoded { get; set; }
            public RequestContext RequestContext { get; set; }
            public Dictionary<string, string> Headers { get; set; }
            public Dictionary<string, string> QueryParameters { get; set; }

            public override string ToString()
            {
                return JsonSerializer.Serialize(this);
            }
        }

        public class RequestContext
        {
            public string AccountId { get; set; }
            public string DomainName { get; set; }
            public string DomainPrefix { get; set; }
            public string RequestId { get; set; }
            public string Time { get; set; }
            public string TimeEpoch { get; set; }
            public Dictionary<string, string> Http { get; set; }
        }

        public class HTTPTriggerResponse
        {
            public int StatusCode { get; set; }
            public Dictionary<string, string> Headers { get; set; }
            public bool IsBase64Encoded { get; set; }
            public string Body { get; set; }
        }

        public HTTPTriggerResponse PocoHandler(HTTPTriggerEvent input, IFcContext context)
        {
            context.Logger.LogInformation("receive event: {0}", input.ToString());
            string requestBody = input.Body;
            if (input.IsBase64Encoded)
            {
                byte[] decodedBytes = Convert.FromBase64String(input.Body);
                requestBody = Encoding.UTF8.GetString(decodedBytes);
            }
            return new HTTPTriggerResponse
            {
                StatusCode = 200,
                IsBase64Encoded = false,
                Body = requestBody
            };
        }
        static void Main(string[] args){}
    }
}

Prerequisites

Before you begin, ensure that you have:

Invoke the function

  1. Log on to the Function Compute console. In the left-side navigation pane, click Functions.

  2. In the top navigation bar, select a region. On the Functions page, click the target function.

  3. On the function details page, click the Triggers tab to get the public endpoint of the HTTP trigger.

  4. Run the following command to invoke the function. Replace https://test-python-ipgrwr****.cn-shanghai.fcapp.run with your endpoint.

    curl -i "https://test-python-ipgrwr****.cn-shanghai.fcapp.run" -d 'Hello fc3.0'

    The expected response:

    HTTP/1.1 200 OK
    Content-Disposition: attachment
    Content-Length: 12
    Content-Type: application/json
    X-Fc-Request-Id: 1-64f7449a-127fbe39cd7681596e33ebad
    Date: Tue, 05 Sep 2023 15:09:14 GMT
    
    Hello fc3.0
    Important
    • If Authentication Method is set to No Authentication, invoke with Postman or curl.

    • If Authentication Method is set to Signature Authentication or JWT Authentication, use the corresponding method. For more information, see Authentication.

Possible errors

This sample is designed for HTTP trigger or custom domain name invocation. If you click Test Function in the console and pass a plain string such as "Hello, FC!", the function returns a deserialization error because the input does not match the HTTPTriggerEvent format:

{
    "errorMessage": "Unexpected character encountered while parsing value: H. Path '', line 0, position 0.",
    "errorType": "Newtonsoft.Json.JsonReaderException",
    "stackTrace": [
        "   at Newtonsoft.Json.JsonTextReader.ParseValue()",
        "   at Newtonsoft.Json.JsonReader.ReadAndMoveToContent()",
        "   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)",
        "   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)",
        "   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)",
        "   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)",
        "   at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)",
        "   at Aliyun.Serverless.Core.JsonSerializer.Deserialize[T](Stream requestStream) in /dotnetcore/Libraries/src/Aliyun.Serverless.Core.Impl/JsonSerializer.cs:line 95"
    ]
}

Sample programs

The following GitHub repositories contain complete examples with build and deployment scripts: