Skip to content

Fixing minimal api header array binding #55803

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

MattyLeslie
Copy link
Contributor

@MattyLeslie MattyLeslie commented May 20, 2024

Ensuring Minimal APIs and controllers treat header arrays the same.

Summary:
Passing comma-separated list of values to the header was treated differently by controller action and Minimal API endpoint during binding to array. For controller action they were parsed as separate values while for Minimal APIs - as single one. This PR aimed to ensure they both were parsed as separate values by adapting the binding logic within RequestDelegateFactory

Changes:

  1. BindParameterFromExpression now handles comma-separated values appropriately and returns them as separate values.
  2. Test added to RequestDelegateFactoryTests to ensure RequestDelegate_ShouldHandleSingleHeaderValue()
  3. Test added to RequestDelegateFactoryTests to ensure RequestDelegate_ShouldHandleCommaSeparatedHeaderValues

Fixes #54978 by ensuring minimal API's and Controllers treat header arrays the same.

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions label May 20, 2024
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label May 20, 2024
@MattyLeslie MattyLeslie marked this pull request as ready for review May 20, 2024 20:34
@dotnet-policy-service dotnet-policy-service bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Jun 1, 2024
@adityamandaleeka
Copy link
Member

/azp run

@dotnet-policy-service dotnet-policy-service bot removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Jun 13, 2024
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@dotnet-policy-service dotnet-policy-service bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Jun 21, 2024
@MattyLeslie
Copy link
Contributor Author

@BrennanConroy, may I please request a review on this.

Copy link
Member

@BrennanConroy BrennanConroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does RequestDelegateGenerator support this already? Or does it need to be fixed as well?

}
private static void EmitHeaderValueParsing(CodeWriter codeWriter)
{
codeWriter.WriteLine("var headerParameters = handler.Method.GetParameters().Where(p => p.GetCustomAttribute<FromHeaderAttribute>() != null).ToList();");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When emitting code at compile-time, we want to do the discovery of parameters like this via static analysis.

You'll observe that in other parts of the Request Delegate Generator (RDG) code, we generate an EndpointParameter object that we construct after statically analyzing the arguments then we use the information in that data model to emit the generated code. We don't need to re-compute things like the headerName dynamically like this.

You can find the pre-existing code where we emit the binding logic for header parameters here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the review, I will be working on this.

@captainsafia
Copy link
Member

@MattyLeslie Thanks for taking a stab at this! I posted some comments about the approach to take for this change in RDG based on the existing implementation. Let me know if you have questions about it.

}

var result = new List<string>();
Span<Range> parts = stackalloc Range[16];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem correct. If there are more than 16 values in a single header it will miss them. Maybe just revert to the previous code for now. We can look at improving the perf later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @BrennanConroy, I will revert that, I am going to mark this as draft as I'm still working on this.

@smnsht
Copy link
Contributor

smnsht commented Oct 7, 2024

@MattyLeslie
Hello, MattyLeslie

Would you please let me know if you are going to work on this fix?
​If not, I would like to try to handle this by myself.

@MattyLeslie
Copy link
Contributor Author

@MattyLeslie Hello, MattyLeslie

Would you please let me know if you are going to work on this fix? ​If not, I would like to try to handle this by myself.

Yeah if your PR works they're welcome to take it. I just haven't had the time I had when I started it.

@dotnet-policy-service dotnet-policy-service bot added this to the 10.0-preview3 milestone Mar 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions community-contribution Indicates that the PR has been added by a community member pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Minimal APIs and controllers treat header arrays differently
6 participants