Replies: 2 comments
|
I transformed this to a discussion as it's more of a question. |
|
In .NET 10 the schema transformer approach is still valid. The main difference is that ASP.NET Core now uses If the goal is to keep the enum represented as an integer in the OpenAPI schema, while still exposing the C# enum names for code generation, I would keep those as two separate concerns. For example: using System.Globalization;
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi;
using Microsoft.OpenApi.MicrosoftExtensions;
public sealed class EnumSchemaTransformer : IOpenApiSchemaTransformer
{
public Task TransformAsync(
OpenApiSchema schema,
OpenApiSchemaTransformerContext context,
CancellationToken cancellationToken)
{
var enumType =
Nullable.GetUnderlyingType(context.JsonTypeInfo.Type)
?? context.JsonTypeInfo.Type;
if (!enumType.IsEnum)
{
return Task.CompletedTask;
}
schema.Type = JsonSchemaType.Integer;
schema.Format = "int32";
schema.Enum = Enum.GetValues(enumType)
.Cast<object>()
.Select(value =>
(JsonNode)JsonValue.Create(
Convert.ToInt32(value, CultureInfo.InvariantCulture))!)
.ToList();
var extension = new OpenApiEnumValuesDescriptionExtension
{
EnumName = enumType.Name
};
foreach (var value in Enum.GetValues(enumType))
{
var name = Enum.GetName(enumType, value)!;
var numericValue =
Convert.ToInt32(value, CultureInfo.InvariantCulture);
extension.ValuesDescriptions.Add(new EnumDescription
{
Name = name,
Value = numericValue.ToString(CultureInfo.InvariantCulture),
Description = name
});
}
schema.Extensions ??=
new Dictionary<string, IOpenApiExtension>();
schema.Extensions[
OpenApiEnumValuesDescriptionExtension.Name] = extension;
return Task.CompletedTask;
}
}and register it normally: builder.Services.AddOpenApi(options =>
{
options.AddSchemaTransformer<EnumSchemaTransformer>();
});The important .NET 10 change here is One detail worth mentioning is that So if the consumer requires the var values = new JsonArray();
foreach (var value in Enum.GetValues(enumType))
{
var name = Enum.GetName(enumType, value)!;
var numericValue =
Convert.ToInt32(value, CultureInfo.InvariantCulture);
values.Add(new JsonObject
{
["name"] = name,
["value"] = numericValue,
["description"] = name
});
}
schema.Extensions ??=
new Dictionary<string, IOpenApiExtension>();
schema.Extensions["x-ms-enum"] =
new JsonNodeExtension(
new JsonObject
{
["name"] = enumType.Name,
["modelAsString"] = false,
["values"] = values
});I would prefer the second version when preserving the numeric type in both the OpenAPI It also makes the intent explicit: the wire representation remains numeric, while the extension only provides the symbolic C# names for tooling/code generation. |
Uh oh!
There was an error while loading. Please reload this page.
Hello, I have an IOpenApiSchemaTransformer that I use to ensure my enums have a String name but integer values in the definition. How should this be done in .NET 10?
All reactions