Azure / azure-functions-dotnet-worker

Azure Functions out-of-process .NET language worker
MIT License
419 stars 184 forks source link

HttpTrigger GET parameters not mapped to custom class in .NET 8 and isolated #2530

Open Laumania opened 3 months ago

Laumania commented 3 months ago

What version of .NET does your existing project use?

.NET 6

What version of .NET are you attempting to target?

.NET 8

Description

We are upgrading our .NET 6 in-process function apps to .NET 8 isolated.

In general, upgrade have been fairly easy and doable. Therefore I was also very surprised when I discovered that our custom PoCo request parameters was always null in our GET HTTPTriggers.

POST works, by adding [Microsoft.Azure.Functions.Worker.Http.FromBody], but GET parameters is not working.

After many hours of research, I was surprised to figure out this was not support!

public class DummyPoCo
{
    public string Id { get; set; }
    public int Skip  { get; set; }
    public int Take  { get; set; }
}

[Function("DummyGet")]
public async Task<IActionResult> DummyGet([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "dummy")] DummyPoCo parameters, HttpRequest req, CancellationToken hostCancellationToken)
{
    //parameters is always null for GET requests
    throw new NotImplementedException();
}

This 1 year old post, describes the exact same problem - what use to work out of the box in .NET 6 in-process is not working in .NET 8 and isolated. https://learn.microsoft.com/en-us/answers/questions/1186948/how-to-get-parameter-binding-in-azure-function-iso

As Microsoft are forcing us to .NET 8 and isolated before end of 2026, this have to be implemented, as I assume a lot of people need this.

I'm sorry, but its simply not good enough to manually have to do this via the HttpRequestData.

So is this something that is on the roadmap - I really hope so :)

Project configuration and dependencies


<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <RootNamespace>XXX</RootNamespace>
    <AssemblyName>XXXX</AssemblyName>
    <OutputType>Exe</OutputType>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.6" />
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.22.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.2" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.3.1" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
    <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
    <ProjectReference Include="..\Persistence\Persistence.csproj" />
  </ItemGroup>
  <ItemGroup>
    <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

Link to a repository that reproduces the issue

No response

Laumania commented 3 months ago

Any news or input on this - anyone?

pelonchasva commented 3 months ago

facing this same issue with a POST function app.

Model binding is not happening for my POCO class when using the [FromBody] attribute in the function parameters

Laumania commented 3 months ago

facing this same issue with a POST function app.

Model binding is not happening for my POCO class when using the [FromBody] attribute in the function parameters

POST works, but you need the right FromBody on - this one: [Microsoft.Azure.Functions.Worker.Http.FromBody]

However, I can't get it to work for GET and it's a showstopper for us right now as it seems like a step backward to have to manually parse parameters into a POCO.

erinnmclaughlin commented 2 months ago

For anyone that's currently looking for this, I put together a NuGet package that adds support for binding query parameters:

// Bind directly to primitive types:
// BindPrimatives?id=abc123&skip=0&take=10
[Function("BindPrimitives")]
public HttpResponseData BindPrimitives(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
    [BindQuery] string id,
    [BindQuery] int skip,
    [BindQuery] int take)
{
    // ..
}

// Or POCOs:
// BindPOCOs?id=abc123&skip=0&take=10
[Function("BindPOCOs")]
public HttpResponseData BindPOCOs(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
    [BindQuery] DummyPoCo parameters)
{
    // ..
}

Or feel free to grab the code directly here:

https://github.com/erinnmclaughlin/AzureFunctionsWorkerHttpExtensions

I'm hoping to open up a PR for this as well, but wanted to get something out there in the meantime!