-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Set ApiParameterDescription.Type to string
for Simple Types
#44747
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
Set ApiParameterDescription.Type to string
for Simple Types
#44747
Conversation
@@ -1579,6 +1583,120 @@ public void GetApiDescription_ParameterDescription_FromQueryEmployee() | |||
Assert.Equal(typeof(string), id.Type); | |||
} | |||
|
|||
[Fact] | |||
public void GetApiDescription_ParameterDescription_ParsablePrimitiveType() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have versions of these tests in EndpointApiDescriptionProvider
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those tests give us a similar coverage:
aspnetcore/src/Mvc/Mvc.ApiExplorer/test/EndpointMetadataApiDescriptionProviderTest.cs
Lines 273 to 327 in c8d252d
[Fact] | |
public void AddsFromRouteParameterAsPathWithCustomClassWithTryParse() | |
{ | |
static void AssertPathParameter(ApiDescription apiDescription) | |
{ | |
var param = Assert.Single(apiDescription.ParameterDescriptions); | |
Assert.Equal(typeof(TryParseStringRecord), param.Type); | |
Assert.Equal(typeof(string), param.ModelMetadata.ModelType); | |
Assert.Equal(BindingSource.Path, param.Source); | |
} | |
AssertPathParameter(GetApiDescription((TryParseStringRecord foo) => { }, "/{foo}")); | |
} | |
[Fact] | |
public void AddsFromRouteParameterAsPathWithPrimitiveType() | |
{ | |
static void AssertPathParameter(ApiDescription apiDescription) | |
{ | |
var param = Assert.Single(apiDescription.ParameterDescriptions); | |
Assert.Equal(typeof(int), param.Type); | |
Assert.Equal(typeof(int), param.ModelMetadata.ModelType); | |
Assert.Equal(BindingSource.Path, param.Source); | |
} | |
AssertPathParameter(GetApiDescription((int foo) => { }, "/{foo}")); | |
} | |
[Fact] | |
public void AddsFromRouteParameterAsPathWithNullablePrimitiveType() | |
{ | |
static void AssertPathParameter(ApiDescription apiDescription) | |
{ | |
var param = Assert.Single(apiDescription.ParameterDescriptions); | |
Assert.Equal(typeof(int?), param.Type); | |
Assert.Equal(typeof(int?), param.ModelMetadata.ModelType); | |
Assert.Equal(BindingSource.Path, param.Source); | |
} | |
AssertPathParameter(GetApiDescription((int? foo) => { }, "/{foo}")); | |
} | |
[Fact] | |
public void AddsFromRouteParameterAsPathWithStructTypeWithTryParse() | |
{ | |
static void AssertPathParameter(ApiDescription apiDescription) | |
{ | |
var param = Assert.Single(apiDescription.ParameterDescriptions); | |
Assert.Equal(typeof(TryParseStringRecordStruct), param.Type); | |
Assert.Equal(typeof(string), param.ModelMetadata.ModelType); | |
Assert.Equal(BindingSource.Path, param.Source); | |
} | |
AssertPathParameter(GetApiDescription((TryParseStringRecordStruct foo) => { }, "/{foo}")); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be nice to have regression tests for all the types we're special-casing like Guid
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added AddsFromRouteParameterAsPathWithSpecialPrimitiveType
and AddsFromRouteParameterAsPathWithNullableSpecialPrimitiveType
Should we check for IParsable? |
I talked to @brunolins16 offline about this @davidfowl. He told me that Most of these types, both built-in and custom IParsable types, are effectively a "string" OpenAPI data type, but swashbuckle and nswag need to special-case "integer", "number" and "boolean" based on So treating user-defined IParsable types as "string" makes sense, because tools like swashbuckle or nswag could never come up with a better OpenAPI data type or format for these types anyway (absent help from something like an
The reason I wanted to do all built-in types is that we can trivially scan these like I did when I created For these built-in |
Contributes #44677
This change updates how the
ApiParameterDescription.Type
is defined for MVC Simple Types (withTypeConverter
orTryParse
) that are notprimitives
. Basically, setting the Type asstring
It is a similar approach that is used here
https://github.com/brunolins16/aspnetcore/blob/7518259777aa22268843401cfa0dfdfaba37eff3/src/Mvc/Mvc.ApiExplorer/src/EndpointMetadataApiDescriptionProvider.cs#L291
But in addition to the simple
IsPrimitive
check this PR includes some additional known types that should be handled by OpenAPI spec.DateTime
DateTimeOffset
DateOnly
TimeOnly
decimal
Guid
Uri
Obs.:
NSwag
will not requires any change to reflect it correctly, however,Swashbuckle
will need a simple change since it is usingMetadata.ModelType
instead ofApiParameterDescription.Type