Skip to content

wrong parameter type in api document with [FromODataUri] attribute #693

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
anranruye opened this issue Nov 9, 2020 · 4 comments
Closed

Comments

@anranruye
Copy link

anranruye commented Nov 9, 2020

Run the newest aspnetcore odata swagger sample project directly. all parameters decorated with [FromODataUri] are marked with 'query' (in query string) but not 'path' (in url) in the api document. path parameters decorated with [FromRoute] attribute or no attribute are marked as 'path' correctly.

add [ApiController] (i use this to make auto 400 response and some analyzers use this to realize a controller is not a view controller) and [Route("")] (which can't work without api versioning because multiple actions match same route; it seems that api versioning make it be ignored) to odatacontroller, path parameters in odata route template decorated with no attribute can't be recognized by the middleware , instead they are considered same as decorated with [FromQuery]. This is a default behavior of [ApiController] if the middleware can not find the parameter in route template. The problem is that the middleware should find these parameters but not. In odata api versioning 4.1.1, there is no such problem. This might be caused by same underlying mistake with problem i mentioned in #692 (comment)

@commonsensesoftware
Copy link
Collaborator

I only partially understand your scenario or setup. I don't know that [ApiController] applies to OData controllers nor should. API Versioning uses IApiControllerSpecification to define whether a controller should be considered for versioning (e.g. filter out non-API controllers). The two default implementations match the [ApiController] attribute and ODataController. These roll up into the IApiControllerFilter. As long as a controller matches one of the specifications, it's included in the filter.

[Route] should not be used on an OData controller. The routing attributes are incompatible. Anything you may have gotten to work is some undocumented, unexpected use case. OData has it's own routing conventions and attributes.

Endpoint Routing is the default routing mechanism in ASP.NET Core (since 2.2). OData finally supports it (as of 7.4). All examples and defaults now use Endpoint Routing as well. This may be hanging you up because the runtime behavior will be different. If you want to go back to the legacy routing conventions, you can. You need only configuration the MVC options with: options.EnableEndpointRouting = false. At some point, you'll likely have to make the change. As it currently stands, OData 8.0 is in the works and support for the legacy routing method via IRouter has been removed. This means the only supported routing method will be Endpoint Routing. The implementation in 8.0 is also quite different that 7.x.

OData by itself does not have formal support for the API Explorer and it will not work with the default ASP.NET Core API Explorer. API Versioning does not consider or use non-OData attributes such [FromRoute]. There's no special consideration for [FromODataUri] because there shouldn't need to be. All OData routes must match what comes from the corresponding EDM. If a route parameter doesn't match the EDM path, then it's lifted to a query string parameter; this is the expected OData behavior. If there's a particular route that is not being generated correctly, then I can take a look at that case. It's possible there is a mistake or regression in URL generation that slipped past the test suite.

I need more information before I can investigate.

@anranruye
Copy link
Author

@commonsensesoftware

The behavior with [ApiController] is right in odata api versioning 5.0.0 . I can't make [ApiController] recognize parameters in odata route template in a none-versioning environment. In other words, behavior of odata api versioning 4.1.1 is wrong. (In version 4.1.1, parameters in odata route template can't be bound with the usage of [ApiController] when the application start. However, requesting the api document causes some side effects which change the way controllers work. After the request to api document, parameters in odata route template can be bound. I set the debug option to open swagger document page when the app start, which hides the real problem.)

As you said, [FromODataUri] should do nothing to the api explorer, so there is no need to consider it specially. But in fact, [FromODataUri] causes wrong api document. Like this:

image

This screenshot is taken from AspNetCore SwaggerODataSample project.

@anranruye anranruye changed the title wrong parameter type in api document with [FromODataUri] attribute and incompatible behavior with [ApiController] attribute wrong parameter type in api document with [FromODataUri] attribute Dec 21, 2020
@avisra
Copy link

avisra commented Jan 19, 2021

I am also running into this issue - when attempting to use FromODataUri attribute, it is assuming a query parameter when displayed in Swagger.

@commonsensesoftware
Copy link
Collaborator

I'm going to mark this as a bug because it doesn't do what you expect. Honestly, the OData implementation is not meant to support OpenAPI/Swagger. There continues to be very shallow support for what OData would really need. This particular issue derives from [FromODataUri] which maps to the ODataModelBinder. The value can be bound from a few different places in the URI. No effort seems to have been made to more appropriately map it, so it always results in mapping to BindingSource.Custom. It seems that Swashbuckle treats that as a query string parameter because it doesn't know what to do with it.

I think have a solution for it. In the meantime, your options are:

  1. Fix up the parameter via a Swashbuckle hook
  2. Fix up the parameter via a custom IActionDescriptorProvider
  3. Don't use [FromODataUri]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants