dotnet / dotnet/aspnetcore

ApiExplorer handles [FromHeader] binding (on complex type) differently to [FromQuery] binding

Open
#29,931 12 comments 4 reactions 1 assignee Claimed by @snemeckayova View on GitHub
area-mvc feature-model-binding feature-openapi investigate
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Describe the bug

Given the following two actions that bind query/header params to a complex type:

```csharp
public IActionResult Get1([FromQuery]CustomParams queryParams)
```

```csharp
public IActionResult Get2([FromHeader]CustomParams headerParams)
```

```csharp
public class CustomParams
{
public string Foo { get; set; }
public string Bar { get; set; }
}
```

For the first action, `ApiExplorer` surfaces multiple query parameters, one for each property in the complex type. This makes sense because that's exactly how the model binder behaves - i.e. it will look for individual query parameters and assign them to corresponding properties. However, for the second action, `ApiExplorer` only surfaces a single parameter corresponding to the custom type itself. It's my understanding that the model binder behaves the same way in both cases, and so I would expect `ApiExplorer` to follow suit. Here's an example of the relevant `ApiExplorer` data (serialized as JSON):

```
[
{
"relativePath": "Test/Get1",
"httpMethod": "GET",
"parameters": [
{
"name": "Foo",
"source": {
"displayName": "Query",
"id": "Query",
"isGreedy": false,
"isFromRequest": true
},
"modelType": "System.String"
},
{
"name": "Bar",
"source": {
"displayName": "Query",
"id": "Query",
"isGreedy": false,
"isFromRequest": true
},
"modelType": "System.String"
}
]
},
{
"relativePath": "Test/Get2",
"httpMethod": "GET",
"parameters": [
{
"name": "headerParams",
"source": {
"displayName": "Header",
"id": "Header",
"isGreedy": true,
"isFromRequest": true
},
"modelType": "ApiExplorerIssue.Controllers.CustomParams"
}
]
}
]
```

### To Reproduce
```
> git clone git@github.com:domaindrivendev/ApiExplorerIssue.git
> cd ApiExplorerIssue
> git checkout from-header-property-bindings
> dotnet run

Then navigate to "http://localhost:5000/apidescriptions" to see the ApiExplorer data
```

### Further technical details
- ASP.NET Core version: 5.0

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.