Swashbuckle.aspnetcore: Adding x-ms-enum extension to a parameter does not populate in the schema

Created on 27 Apr 2018  路  3Comments  路  Source: domaindrivendev/Swashbuckle.AspNetCore

This is essentially a duplicate of #368, but I can't reopen that issue since I didn't create it. The creator of that issue had an idea why this was happening, which may help.

Here is a minimal example project demonstrating this (with .NET Core 2.0 and Swashbuckle 2.4.0):
SwashbuckleEnumTest.zip

It's a single controller with a single action:

[HttpGet]
public Color Get(Color color) {
    return color;
}

Where Color is an enum. And it uses this schema filter:

public class EnumTypeSchemaFilter : ISchemaFilter {
    public void Apply(Schema schema, SchemaFilterContext context) {
        var typeInfo = context.SystemType.GetTypeInfo();

        if (typeInfo.IsEnum) {
            schema.Extensions.Add(
                "x-ms-enum",
                new {
                    name = typeInfo.Name,
                    modelAsString = false
                });
        }
    }
}

I included the generated swagger.json file in the zip file. You'll see that it includes x-ms-enum with the return type, but not for the parameter.

"parameters":[
   {
      "name":"color",
      "in":"query",
      "required":false,
      "type":"string",
      "enum":[
         "Red",
         "Green",
         "Blue"
      ]
   }
],
"responses":{
   "200":{
      "description":"Success",
      "schema":{
         "enum":[
            "Red",
            "Green",
            "Blue"
         ],
         "type":"string",
         "x-ms-enum":{
            "name":"Color",
            "modelAsString":false
         }
      }
   }
}

Most helpful comment

If you look closely at the AutoRest docs, you'll see that x-ms-enum needs to be applied to Parameter objects in addition to Schema objects. You'll need to dig a little deeper into the Swagger specification to understand why this is the case but in summary non-body parameters (i.e. query, header etc) don't have an associated Schema. They just have the structure metadata baked directly into the Parameter object.

Anyway, you can solve your issue by adding a Parameter filter in addition to your Schema filter:

public class AutoRestParameterFilter : IParameterFilter
{
    public void Apply(IParameter parameter, ParameterFilterContext context)
    {
        var type = context.ApiParameterDescription.Type;

        if (type.IsEnum)
            parameter.Extensions.Add( "x-ms-enum", new { name = type.Name, modelAsString = false });
    }
}

All 3 comments

If you look closely at the AutoRest docs, you'll see that x-ms-enum needs to be applied to Parameter objects in addition to Schema objects. You'll need to dig a little deeper into the Swagger specification to understand why this is the case but in summary non-body parameters (i.e. query, header etc) don't have an associated Schema. They just have the structure metadata baked directly into the Parameter object.

Anyway, you can solve your issue by adding a Parameter filter in addition to your Schema filter:

public class AutoRestParameterFilter : IParameterFilter
{
    public void Apply(IParameter parameter, ParameterFilterContext context)
    {
        var type = context.ApiParameterDescription.Type;

        if (type.IsEnum)
            parameter.Extensions.Add( "x-ms-enum", new { name = type.Name, modelAsString = false });
    }
}

Ahh, ok. That makes sense I guess. I didn't realize that a Parameter filter was a different thing. That works.

Thank you.

This doesn't seem to work for a parameter that is an array of enums. Any ideas? @domaindrivendev

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nezoic picture nezoic  路  3Comments

vanillajonathan picture vanillajonathan  路  3Comments

TimmyGilissen picture TimmyGilissen  路  3Comments

rgelb picture rgelb  路  3Comments

voroninp picture voroninp  路  3Comments