I've raised the following issue with the Autorest team as I feel that their tool is at fault and not Swashbuckle, but maybe you guys will have some insight into what is causing the problem:
https://github.com/Azure/autorest/issues/3380
For clarification I am using Swashbuckle.AspNetCore v5.0.0 with the following schema filter, and I'm using the SerializeAsV2 option as Autorest beta doesn't work with the v3 swagger version either:
public class AutoRestSchemaFilter : ISchemaFilter {
public void Apply(OpenApiSchema schema, SchemaFilterContext context) {
var type = context.Type;
if (type.IsEnum) {
schema.Extensions.Add(
"x-ms-enum",
new OpenApiObject {
["name"] = new OpenApiString(type.Name),
["modelAsString"] = new OpenApiBoolean(true)
}
);
};
}
}
Which is producing what I believe is the correct format for the DocumentType enum that Autorest requires.
I'm having a similar problem. x-ms-enum lists the value, name and description if any of the enum too, but the above code you're sharing doesn't have a values property. I can't figure out how to set the values property properly either.
Looking at the autorest documentation in regards to ms-enum the values field is optional and is only required if you wish to override the values specified within the enum field.
@thedwillis Here's why it's vital that you have the values and the text. Consider without it:
"WorkflowTypes": {
"enum": [
1,
2,
3,
4,
9,
20,
100
],
"type": "integer",
"description": "The types of workflows available",
"format": "int32",
"x-ms-enum": {
"name": "WorkflowTypes",
"modelAsString": true
}
Versus with it:
{
"WorkflowTypes":
{
"enum": ["Course","Lesson","Topic","Assessment","Question","Blog","Translation"],
"type":"string",
"x-ms-enum":
{
"name":"WorkflowTypes",
"modelAsString":true,
"values":
[
{"value":1,"name":"Course","description":"Course"},
{"value":2,"name":"Lesson","description":"Lesson"},
{"value":3,"name":"Topic","description":"Topic"},
{"value":4,"name":"Assessment","description":"Assessment"},
{"value":9,"name":"Question","description":"Question"},
{"value":20,"name":"Blog","description":"Blog"},
{"value":100,"name":"Translation","description":"Translation"}
]
}
}
}
In the former, you cannot actually create an enumeration in a client. You don't have the Text representation. (or you can have the text representation but not the value)
When x-ms-enum is done right, you have everything that is necessary to create an enum on a client. You can take the later and litterally create C#, Typescript, Go whatever code for an enum with the right values attached to the right strongly typed strings which is the point.
The default standard for OpenAPI is completely and utterally broken and x-ms-enum when implemented fixes it. values isn't optional if you want to build clients from it and not pass a string of the enum over the wire.
So for a valid and proper x-ms-enum we need to be able to create the values property, which I cannot seem to get set correctly without it erroring at runtime with a cast error. This may be related to your issue.
I just figured out an ugly way of doing it with V5:
var enumApiObjectValues = values.Select(e => new OpenApiObject
{
["value"] = new OpenApiInteger(Convert.ToInt32(e.value)),
["name"] = new OpenApiString(e.name),
["description"] = new OpenApiString(e.description)
});
var enumObject = new OpenApiObject
{
["name"] = new OpenApiString(typeInfo.Name),
["modelAsString"] = new OpenApiBoolean(true),
["values"] = new OpenApiArray()
};
((OpenApiArray)enumObject["values"]).AddRange(enumApiObjectValues);
schema.Extensions.Add(
"x-ms-enum",
enumObject
);
Hope that helps someone. I'd love to figure out the syntax needed for it to be inline.
Very similar to my solution, sadly autorest is still throwing the same error:
public class AutoRestSchemaFilter : ISchemaFilter {
public void Apply(OpenApiSchema schema, SchemaFilterContext context) {
var type = context.Type;
if (type.IsEnum) {
var values = Enum.GetValues(type);
var valuesArr = new OpenApiArray();
foreach (var value in values) {
var item = new OpenApiObject {
["name"] = new OpenApiString(Enum.GetName(type, value)),
["value"] = new OpenApiString(value.ToString())
};
valuesArr.Add(item);
}
schema.Extensions.Add(
"x-ms-enum",
new OpenApiObject {
["name"] = new OpenApiString(type.Name),
["modelAsString"] = new OpenApiBoolean(true),
["values"] = valuesArr
}
);
};
}
}
The other error report doesn't seem to have anything to do with x-ms-enum. But you also won't be able to generate a C# client without the values in the x-ms-enum unless you're ok with passing magic integers in the client instead of a strongly typed enum, because that's what it will generate with that definition you provided in the error.
Well just please forgive me if i dont understand very well the issue but this works for me ...
Adding the same filter you are adding.
This line of code at the startup.

So instead of numbers and integers, I have real enums

And this is the autorest generated code:

BTW: Im using .Net Core 3, but just try to adapt the same approach to your project :), and I have to use the x-ms-enum extension because autorest was creating the same enum multiple times like GoalMeasurementUnit, GoalMeasurementUnit2, GoalMeasurementUnit3 and so on.
Oh, and I'm using Swashbuckle.AspNetCore 5.3.1
Oh dear, I am trying that and getting nowhere. I am using netcore3.1 with Sqashbuckle.AspNetCore 5.5.1
I put a question on Stackoverflow
Most helpful comment
Well just please forgive me if i dont understand very well the issue but this works for me ...
Adding the same filter you are adding.
This line of code at the startup.
So instead of numbers and integers, I have real enums
And this is the autorest generated code:
BTW: Im using .Net Core 3, but just try to adapt the same approach to your project :), and I have to use the x-ms-enum extension because autorest was creating the same enum multiple times like GoalMeasurementUnit, GoalMeasurementUnit2, GoalMeasurementUnit3 and so on.
Oh, and I'm using Swashbuckle.AspNetCore 5.3.1