Mvc: ApiControllerAttribute incorrectly infers CancellationToken parameter as FromBody

Created on 15 May 2018  路  7Comments  路  Source: aspnet/Mvc

Is this a Bug or Feature request?:

Bug

Steps to reproduce or link to a repro project:

Create a controller with an [ApiController] attribute that has an action with a [FromBody] parameter and a CancellationToken parameter.

```c#
[Route("api/[controller]")]
[ApiController]
public class MyController
{
[HttpPost]
public async Task MyActionAsync([FromBody]RequestMessage requestMessage, CancellationToken cancellationToken) { }
}

#### Description of the problem:
InvalidOperationException is thrown when adding an [ApiController] attribute to a controller that has actions that have a CancellationToken parameter. Might be related to #7770.

**Exception:**

System.InvalidOperationException: 'Action 'Project.MyController.MyActionAsync (Project)' has more than one parameter that was specified or inferred as bound from request body. Only one parameter per action may be bound from body. Inspect the following parameters, and use 'FromQueryAttribute' to specify bound from query, 'FromRouteAttribute' to specify bound from route, and 'FromBodyAttribute' for parameters to be bound from body:
RequestMessage requestMessage
CancellationToken cancellationToken'

**Stack trace:**

at Microsoft.AspNetCore.Mvc.Internal.ApiBehaviorApplicationModelProvider.InferParameterBindingSources(ActionModel actionModel)
at Microsoft.AspNetCore.Mvc.Internal.ApiBehaviorApplicationModelProvider.OnProvidersExecuting(ApplicationModelProviderContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionDescriptorProvider.BuildModel()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionDescriptorProvider.GetDescriptors()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionDescriptorProvider.OnProvidersExecuting(ActionDescriptorProviderContext context)
at Microsoft.AspNetCore.Mvc.Internal.ActionDescriptorCollectionProvider.UpdateCollection()
at Microsoft.AspNetCore.Mvc.Internal.ActionDescriptorCollectionProvider.get_ActionDescriptors()
at Microsoft.AspNetCore.Mvc.ApiExplorer.DefaultApiVersionDescriptionProvider.EnumerateApiVersions(IActionDescriptorCollectionProvider actionDescriptorCollectionProvider)
at Microsoft.AspNetCore.Mvc.ApiExplorer.DefaultApiVersionDescriptionProvider.LazyApiVersionDescriptions.EnumerateApiVersions()
at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location where exception was thrown --- at System.Lazy1.CreateValue()
at Microsoft.AspNetCore.Mvc.ApiExplorer.DefaultApiVersionDescriptionProvider.get_ApiVersionDescriptions()
```

Version of Microsoft.AspNetCore.Mvc or Microsoft.AspNetCore.App or Microsoft.AspNetCore.All:

2.1.0-rc1-final

investigate

Most helpful comment

Setting SetCompatibilityVersion to 2.1 fixed the problem. However, I think this is a breaking change for 2.0.

All 7 comments

@pranavkm, as you already have looked into the related issue, can you look into this one too? Thanks!

@LeroyK, are you calling the SetCompatibilityVersion in your startup? Look at the issue referred by @khellang.

Hi. We're closing this issue as no response or updates have been provided in a timely manner and we have been unable to reproduce it. If you have more details and are encountering this issue please add a new reply and re-open the issue.

You should not have released 2.1 with that ugly bug. I can reproduce that on any of 120 actions on 18 controllers. Whats the correct attribution for CancellationToken? [From???]?

Setting SetCompatibilityVersion to 2.1 fixed the problem. However, I think this is a breaking change for 2.0.

Ah yes. Without [ApiController] there seems to be no problem, too. Will [ApiController] -- introduced with 2.1 -- ever behave well without SetCompatibilityVersion=2.1?

Was this page helpful?
0 / 5 - 0 ratings