Using IActionResult with Azure Functions in .NET 5?

Viewed 2972

After migrating my Azure Functions project to .NET 5, it has started wrapping my responses in a weird wrapper class.

For instance, consider the following endpoint:

public record Response(string SomeValue);

[Function("Get")]
public async Task<IActionResult> Get(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "get-something")]
    HttpRequestData request)
{
    return new OkObjectResult(new Response("hello world"));
}

Before, it would return:

{
    "someValue": "hello world"
}

But now, it returns:

{
  "Value": {
    "SomeValue": "hello world"
  },
  "Formatters": [],
  "ContentTypes": [],
  "DeclaredType": null,
  "StatusCode": 200
}

I get that it must be because it just tries to serialize the object result, but I can't find any documentation on how this is supposed to work in .NET 5.

My main function currently looks like this:

public static async Task Main()
{
    var host = new HostBuilder()
        .ConfigureFunctionsWorkerDefaults(x => 
            x.UseDefaultWorkerMiddleware())
        .ConfigureAppConfiguration((_, builder) => builder
            .AddJsonFile("local.settings.json", true)
            .Build())
        .ConfigureServices(ConfigureServices)
        .Build();

    await host.RunAsync();
}

My project is located here, in case someone are interested: https://github.com/sponsorkit/sponsorkit.io

Currently, my .NET 5 work is on a branch called feature/signup-flow.

4 Answers

Using IActionResult with Azure Functions in .NET 5?

You can't return IActionResult with Azure Functions in .NET 5. Or more generally, you can't return IActionResult with Azure Functions using the isolated process model. Quote from the docs:

For HTTP triggers, you must use HttpRequestData and HttpResponseData to access the request and response data. This is because you don't have access to the original HTTP request and response objects when running out-of-process.

Instead of IActionResult, you need to return HttpResponseData. Example code is here.

To return an object from .NET 5 Azure Functions, use the following code:

var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteAsJsonAsync(obj);
return response;

Was pleasantly surprised to find that returning Task from a "dotnet-isolated" function workins in Core 6. Saved me a few hours as I do not need to change to Task in a number of functions

After searching around and wanting to stay in the context of the IActionResult object, I ended up leveraging the ObjectResult object so that I can standardize all the service responses with the standardize JSON messages.

Related