2

I recently upgraded a .NET Function App from the in-process worker model to the isolated worker model.
After the upgrade, I noticed that none of the HTTP-triggered APIs were returning any data.

On further investigation I found that the return types were declared as ActionResult<T>.
When I changed the return types to IActionResult, the APIs started working again.

Example

I created a simple example app using the isolated model to illustrate the issue.

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;

namespace FunctionApp1;

public class Function1
{
    [Function("Function1")]
    public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
    {
        return new OkObjectResult("Hello World"); //Works fine
    }

    [Function("Function2")]
    public ActionResult<string> Run2([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
    {
        return "Hello World"; //Returning Nothing
    }

    [Function("Function4")]
    public ActionResult<string> Run4([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
    {
        return new OkObjectResult("Hello World"); //This is how the api's were returning data before, Returning nothing after update
    }

    [Function("Function3")]
    public async Task<ActionResult<MyReturnType>> Run3([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
    {
        return await Task.FromResult<MyReturnType>(new MyReturnType("Jack", "BlacK")); // Returning Nothing
    }

    public record MyReturnType(string Name, string Surname);
}

Questions

  • Is ActionResult<T> not supported in the isolated worker model?
  • Why can the runtime unwrap ActionResult<T> in the in-process model but not in the isolated worker model?
  • Am I missing some configuration, or is the only supported pattern to return HttpResponseData/IActionResult?
1
  • 1
    Your function works within the Function host, when operating in the in-process model, and it can depend on the MVC pipeline for features like content negotiation and automatic wrapping. ActionResult<T> functions there because the MVC layer is capable of converting the T to JSON, selecting a content type, and other tasks. Your code executes in a distinct process without the ASP.NET Core MVC pipeline when using the isolated worker model. The host has no idea what to do with ActionResult<T> Commented Sep 18 at 8:56

1 Answer 1

1

For an Azure Function App to work with HTTP triggers there are two different approaches that can be used: ASP.NET Core integration model and built-in model.

  • Built-in HTTP model - the HTTP request message is translated into HttpRequestData object and the requested return type is HttpResponseData. Read more here.

  • ASP.NET Core integration - HTTP request and response objects using types from ASP.NET Core including HttpRequest, HttpResponse, and IActionResult.

Looking at your code (understanding that you did a migration to isolated model), you are using ASP.NET Core integration. This requires to :

  1. Replace in your host builder ConfigureFunctionsWorkerDefaults with ConfigureFunctionsWebApplication

  2. Add a reference in your project to the Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore package, version 1.0.0 or later.

Update your project to use these specific package versions:2

  1. Microsoft.Azure.Functions.Worker.Sdk, version 1.11.0. or later Microsoft.Azure.Functions.Worker, version 1.16.0 or later.

Azure Functions aren't designed to work with MVC-style ActionResult<T> return types out of the box. Azure Functions use function bindings and return types that are specific to the Functions runtime. ActionResult<T> is part of ASP.NET Core MVC, the Functions runtime doesn't interpret ActionResult<T> the same way. As a result, the runtime doesn't know how to serialize or return the value properly, leading to an empty response. Your only solution is to use IActionResult as a return type or try to use a custom serializer like they describe it here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.