Skip to content

Incorrectly generated metadata for arrays in Swagger for .NET Core with OData #496

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
Lonli-Lokli opened this issue May 8, 2019 · 7 comments

Comments

@Lonli-Lokli
Copy link

Lonli-Lokli commented May 8, 2019

Im on 3.0 version,

  1. Add this code to Functions controller
        [HttpGet]
        [ODataRoute( nameof( CountThem ) + "(Vars={vars})" )]
        [ProducesResponseType( typeof( int ), Status200OK )]
        public IActionResult CountThem( [FromODataUri] string[] vars ) => Ok( vars.Length );

And this code to AllConfigurations
builder.Function( "CountThem" ).Returns<int>().CollectionParameter<string>( "Vars" );

  1. Run Swagger
  2. Add multiple parameters line by line
  3. Press Execute

Generated url errors with 404. It looks like this
http://localhost:59918/api/CountThem(Vars={vars})?vars=111&vars=222

While for OData with Parameter Alisases this url should look like this
http://localhost:59918/api/CountThem(Vars=@vars)?@vars=[%27111%27,%27222%27]
or
http://localhost:59918/api/CountThem(Vars=[%27111%27,%27222%27])

@Lonli-Lokli Lonli-Lokli changed the title Incorreccly generated metadata for arrays in Swagger for .NET Core Incorrectly generated metadata for arrays in Swagger for .NET Core with OData May 8, 2019
@commonsensesoftware commonsensesoftware self-assigned this May 8, 2019
@commonsensesoftware
Copy link
Collaborator

Interesting. I didn't know you can use collections in functions like this. This issue seems to be two-part.

First, the API Explorer is not generating the expected route template. I have complete control over that and should be able to fix it. To the extent that it should be supported, but isn't, I'll consider that bug/enhancement.

The second part, however, is with Swagger itself. I have no control or direct dependencies on anything Swagger-related. I've historically used Swashbuckle in examples, but NSwag or any other Swagger generator can use the API Explorer. I'm not 100% sure that Swagger supports parameters defined in this format. I'll have to reach out to some experts I know. Even if it does, I'm not convinced you'll be able to get Swagger UI tools to generate the completed route template in the format you expect since it is OData-specific. It may be possible, but not without some additional customization on the Swagger side of things.

@Lonli-Lokli
Copy link
Author

@commonsensesoftware actually swagger supports lists, so only route template correction required.

@commonsensesoftware
Copy link
Collaborator

@Lonli-Lokli can you point me to the documentation for lists? I'm curious how this works. It doesn't seem to be mentioned in the Swagger specification. Furthermore, it's important the API Explorer reports these type of parameters correctly so that tools like a Swagger generator do the right thing.

@commonsensesoftware
Copy link
Collaborator

Any links you have may be useful, but I think I answered my own question. It seems like they are just supported. However, there is still a caveat because OData has special URL conventions that are not known to tools such as Swagger. I would expect an array of integers to work, but an array of strings, geography, or other special types may not.

Which Swagger generator are you using? Swashbuckle? It sounds like there may be an issue or limitation in the way that it handles/generates lists. The API Explorer only provides the template. It doesn't generate anything. The template should have been api/CountThem(Vars={vars}). The result you observed would be the Swagger generator filling out the template using the user-supplied values - which is incorrect.

The only way to make this fully work with OData may require modeling the parameter as a string with the proper OData route template and filling in the value as a set of appropriate comma-separated values. This issue might be resolved by using a custom Swagger data type format (ex: odata-string), but that will likely take coordination from this project to document the actions correctly and one or more Swagger generators to understand that documentation and/or format.

@Lonli-Lokli
Copy link
Author

@commonsensesoftware Yep, we use Swashbuckle v3 for that. The template for OData (without specific OData knowledge) should be http://localhost:59918/api/CountThem(Vars=[%27111%27,%27222%27])

instead of usual WebApi combination of array parameters. Is it an issue with Swashbuckle or with the template provided by ApiVersioning?
I Understand that array of some non value types (integers, string) might require additional work, but basic types should be available for use same as in WebApi.

@commonsensesoftware
Copy link
Collaborator

OK. Thanks for confirming. I'll see if I can't get it work.

@commonsensesoftware
Copy link
Collaborator

I have something working that will come in the next patch, but you'll have to enter the values with the OData-specific escaping, if required. In your example, you used a string array so the values must be entered as '1', '2', and so on. Values that do not require escaping such as numeric primitives will work as is.

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

2 participants