Skip to content

Microsoft.AspNetCore.OpenApi incomplete/inconsistent enum handling #58195

Closed
@ptffr

Description

@ptffr

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

By default using an enum in class will result in a generic schema type of just number (not even an OpenApi enum of integers)

Example enum

public enum Gender
{
  Male,
  Female
}

Resulting schema type

"gender": {
  "type": "integer"
}

but using the enum in a GET request as an argument specifies it as string instead...

Example request

[HttpGet]
public IEnumerable<Person> Search(Gender gender)
{
    return [];
}

Resulting schema parameters

"parameters": [
  {
    "name": "gender",
    "in": "query",
    "schema": {
      "type": "string"
    }
  }
]

Going even further, if we assign a default value for the gender argument

[HttpGet]
public IEnumerable<Person> Search(Gender gender = Gender.Female)
{
    return [];
}

then the entire document generation will fail with an "InvalidCastException: Unable to cast object of type 'Gender' to type 'System.String'"

Expected Behavior

Schema type for enums should be consistent, just an integer enum by default? Ideally I would really like if we had a built-in way to enable enum strings similar to how System.Text.Json has JsonStringEnumConverter

Ignore the previous JsonStringEnumConverter comment, seems to work correctly if configuring JsonOptions explicitly

builder.Services.Configure<JsonOptions>(options =>
{
    options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
});

Document generation should not fail if a request has an enum query argument with a default value.

Is enum handling not expected to be shipped with .NET 9?

Steps To Reproduce

https://github.com/keenjus/OpenApiStuff/tree/088cf16de42bd25078a471b546854be530edcb58

Launch the project and see how /openapi/v1.json fails to generate.

Exceptions (if any)

InvalidCastException: Unable to cast object of type 'OpenApiStuff.Controllers.Gender' to type 'System.String'.

    System.Text.Json.JsonSerializer.UnboxOnWrite<T>(object value)
    System.Text.Json.Serialization.Metadata.JsonTypeInfo<T>.SerializeAsObject(Utf8JsonWriter writer, object rootValue)
    System.Text.Json.JsonSerializer.WriteNodeAsObject(object value, JsonTypeInfo jsonTypeInfo)
    Microsoft.AspNetCore.OpenApi.JsonNodeSchemaExtensions.ApplyDefaultValue(JsonNode schema, object defaultValue, JsonTypeInfo jsonTypeInfo)
    Microsoft.AspNetCore.OpenApi.JsonNodeSchemaExtensions.ApplyParameterInfo(JsonNode schema, ApiParameterDescription parameterDescription, JsonTypeInfo jsonTypeInfo)
    Microsoft.AspNetCore.OpenApi.OpenApiSchemaService.GetOrCreateSchemaAsync(Type type, IServiceProvider scopedServiceProvider, IOpenApiSchemaTransformer[] schemaTransformers, ApiParameterDescription parameterDescription, bool captureSchemaByRef, CancellationToken cancellationToken)
    Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetParametersAsync(ApiDescription description, IServiceProvider scopedServiceProvider, IOpenApiSchemaTransformer[] schemaTransformers, CancellationToken cancellationToken)
    Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetOperationAsync(ApiDescription description, HashSet<OpenApiTag> capturedTags, IServiceProvider scopedServiceProvider, IOpenApiSchemaTransformer[] schemaTransformers, CancellationToken cancellationToken)
    Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetOperationsAsync(IGrouping<string, ApiDescription> descriptions, HashSet<OpenApiTag> capturedTags, IServiceProvider scopedServiceProvider, IOpenApiOperationTransformer[] operationTransformers, IOpenApiSchemaTransformer[] schemaTransformers, CancellationToken cancellationToken)
    Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetOpenApiPathsAsync(HashSet<OpenApiTag> capturedTags, IServiceProvider scopedServiceProvider, IOpenApiOperationTransformer[] operationTransformers, IOpenApiSchemaTransformer[] schemaTransformers, CancellationToken cancellationToken)
    Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetOpenApiDocumentAsync(IServiceProvider scopedServiceProvider, CancellationToken cancellationToken)

.NET Version

9.0.100-rc.1.24452.12

Anything else?

Microsoft.AspNetCore.OpenApi 9.0.0-rc.1.24452.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs: Author FeedbackThe author of this issue needs to respond in order for us to continue investigating this issue.area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesfeature-openapi

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions