Displaying multiple select input for Enum in Swagger WebApi UI
Multiple select input Swagger WebApi UI
Enums in C# can contain multiple values if they are decorated with [Flags] attribute. However, Flag Enums are not recommended to be used in web api action method signatures. You might face compatibility problems if your client and API are not on the same platform and they both do not understand Flag Enum in the same way, so that's one good reason not to use Flag Enum, but instead you can always pass IEnumerable of an Enum.
Enums are basically integer values masked with human readable names and it will be eventually serialized into int values. From the functionality and architecture perspective using IEnumerable of an Enum works fine, but what happens if you want to do this in a Swagger.
Swagger as well does not work well with Flag Enums, so no need coming back to that idea which we already discarded.
Let's first see how Swagger works with Enums out of the box. For the sample purpose we'll use existing System.ConsoleColor Enum.
public class ColorsController : ApiController { public HttpResponseMessage post(System.ConsoleColor colors) { return Request.CreateResponse(HttpStatusCode.OK); } }
Now let's see how is this going to look like in Swagger UI
Now this is not really readable way of rendering UI, so first wee need to fix displaying Enum names instead of values.
With simple change of App_Start/Swagger.config we can achieve this. All we have to do is to enable if already exists of add the following line
c.DescribeAllEnumsAsStrings();
Now when you run Swagger you will see names of the Enum options instead of int values.
So what we are left to do is to send multiple Enum values as a parameter. Unfortunately declaring our colors parameter as IEnumerable<System.ConsoleColor> will not render list for parameters which makes it not so friendly to use directly from the api
public class ColorsController : ApiController { public HttpResponseMessage post(IEnumerable<System.ConsoleColor> colors) { return Request.CreateResponse(HttpStatusCode.OK); } }
This will apply multi select list to any enumeration parameter. If we by any chance have more Enum parameters and we want to apply multi select list only for one we can filter in Where condition by param.name property.
Next thing we need to add IOperatorFilter implementation to Swagger.config
c.DescribeAllEnumsAsStrings(); c.OperationFilter<SupportMultipleEnumValues>();
Our controller needs to expect System.ConsoleColor parameter in order for Swagger to render multi select list with Enum values. Unfortunately binding does not work out of the box so we have to do it manually.
public class ColorsController : ApiController { public HttpResponseMessage post(System.ConsoleColor colors) { List<ConsoleColor> colorEnumValues = this.Request.GetQueryNameValuePairs() .Where(k => k.Key.Equals("colors", StringComparison.CurrentCultureIgnoreCase)) .First().Value .Split(',').Select(v => (ConsoleColor)Enum.Parse(typeof(ConsoleColor), v.Trim())) .ToList<ConsoleColor>(); return Request.CreateResponse(HttpStatusCode.OK); } }
Basically we use api method Enum type only for the UI. The actual IEnumerable of System.ConsoleColor we need to fetch and transform manually but we achieved what was the goal from the beginning.
Now swagger renders multi select list in the UI for our list of Enum values.
If you still find this article confusing, you can download the complete source code of the project used for this article from the download section of this page
References
Disclaimer
Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.
Comments for this article