Skip to content

OpenApi Enums generating no schema #58230

Closed
@JohnGalt1717

Description

@JohnGalt1717

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

(References)

#58195
#57979

Using the following Model which correctly gets created in the OpenApi.json file:

public sealed record class NotificationDto : RefDto
{
    public DateTimeOffset CreatedOn { get; init; }
    public bool Viewed { get; init; }
    public required NotificationTypes NotificationType { get; init; }
    public required string Subject { get; init; }
    public string? Body { get; init; }
    public string? ImageUrl { get; init; }
    public Guid? ItemId { get; init; }
}

This is the definition it creates:


     "NotificationDto": {
        "required": [
          "notificationType",
          "subject",
          "id"
        ],
        "type": "object",
        "properties": {
          "createdOn": {
            "type": "string",
            "format": "date-time"
          },
          "viewed": {
            "type": "boolean"
          },
          "notificationType": {
            "$ref": "#/components/schemas/NotificationTypes"
          },
          "subject": {
            "type": "string"
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "imageUrl": {
            "type": "string",
            "nullable": true
          },
          "itemId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          }
        }
      },

This creates a definition for the enum but the definition for the enum itself is empty:

      "NotificationTypes": {
        "type": "integer"
      },

Here's the NotificationTypes enum:

public enum NotificationTypes
{
    General = 0
}

Expected Behavior

This should be the base OpenApi 2 version that just has the text representation AND it should have OneOf syntax like OpenApi 3 has with Type, Enum value and Title (name)

Ideally it should also inject x-ms-enum if you want on enums and give key/values since it's so widely supported by OpenAPI client generators.

Steps To Reproduce

Create an endpoint that returns the above object.
Generate the openapi.json file.

You'll see the bogus output.

Exceptions (if any)

No response

.NET Version

9.0.100-rc.1.24452.12

Anything else?

This also happens with the latest nighly 9.0.0-rtm.24477.5

It did work at one point in the beta process but is broken now. I don't know where it broke.

Also, I have the following that I was using to put in the 3.1 and x-ms-enum functionality:

internal class FixEnumsSchemaTransformer : IOpenApiSchemaTransformer
{
    public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext context,
        CancellationToken cancellationToken)
    {
        Console.WriteLine(context.JsonTypeInfo.Type.Name);

        if (!schema.Enum.Any())
            return Task.CompletedTask;

        if (schema.Type != "integer")
            return Task.CompletedTask;

        var enumType = schema.Enum.First().GetType();

        // Add x-ms-enum extension
        var enumValues = new OpenApiArray();
        enumValues.AddRange(Enum.GetNames(enumType)
            .Select(name => new OpenApiObject
            {
                ["name"] = new OpenApiString(name),
                ["value"] = new OpenApiInteger((int)Enum.Parse(enumType, name)),
                ["description"] = new OpenApiString(GetEnumDescription(enumType, name))
            }));

        schema.Extensions["x-ms-enum"] = new OpenApiObject
        {
            ["name"] = new OpenApiString(enumType.Name),
            ["modelAsString"] = new OpenApiBoolean(false),
            ["values"] = enumValues
        };

        // Add enum schemas to OneOf
        foreach (var name in Enum.GetNames(enumType))
        {
            var enumValue = (int)Enum.Parse(enumType, name);
            var enumSchema = new OpenApiSchema
            {
                Type = "integer", Enum = new List<IOpenApiAny> { new OpenApiInteger(enumValue) }, Title = name
            };

            schema.OneOf.Add(enumSchema);
        }

        return Task.CompletedTask;
    }

    private string GetEnumDescription(Type type, string name)
    {
        var memberInfo = type.GetMember(name).FirstOrDefault();
        var attribute = memberInfo?.GetCustomAttribute<DescriptionAttribute>();
        return attribute?.Description ?? string.Empty;
    }
}

Which also used to work. But it no longer works and if you put a break point in, NotificationTypes is never one of the passed in types (nor is any other enum) yet the output openapi.json does have it listed as if it did process it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ✔️ Resolution: AnsweredResolved because the question asked by the original author has been answered.Status: Resolvedarea-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcfeature-openapi

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions