Azure / azure-functions-openapi-extension

This extension provides an Azure Functions app with Open API capability for better discoverability to consuming parties
https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi/
MIT License
373 stars 195 forks source link

How to display Enum values in generated OpenAPI Document as 'string' instead of 'numbers'? #555

Open spmanjunath opened 1 year ago

spmanjunath commented 1 year ago

I have defined a Transport enum as below, i want the Open API Specification to show the enum values as string instead of numeric.

    [JsonConverter(typeof(JsonStringEnumConverter))]
    public enum BusinessFunction
    {
        [EnumMember(Value = "Liner")]
        Liner = 100000000,
        [EnumMember(Value = "Trucking")]
        Trucking = 100000001
    }

Current behaviour image

**Environment

phatcher commented 1 year ago

I can do this with APIs, but would require ISchemaFilter support - see #400

Sefriol commented 1 year ago

Looking at the documentation, it seems to assume this to "just work". There are comments in StackOverflow that say this to work with previous versions on Newtonsoft.Json (12.0), but not anymore.

I wonder if this has worked before or not.

Sefriol commented 1 year ago

Alright. I was able to find a reason after creating a completely new function app. By default my already existing code had using System.Text.Json which has JsonConverter defined. However, this extension requires Newtonsoft.Json.JsonConverter.

Try using [Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))]. Worked for me.

Sefriol commented 1 year ago

Made a quick example

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Example
{
    // Define the enum type with the JsonConverter attribute.
    // NOTE: Check that this uses Newtonsoft.Json instead of System.Text.Json.Serialization 
    [JsonConverter(typeof(StringEnumConverter))]
    public enum BusinessFunction
    {
        Liner = 100000000,
        Trucking = 100000001
    }

    public static class Function
    {
        // Use the OpenApiParameter attribute to specify the enum type and name
        [FunctionName("Function")]
        [OpenApiOperation(operationId: "run", tags: new[] { "example" })]
        [OpenApiParameter(name: "businessFunction", In = ParameterLocation.Query, Required = true, Type = typeof(BusinessFunction))]
        public static IActionResult Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req) // Use the enum type as the function parameter
        {
            var dict = req.GetQueryParameterDictionary();
            dict.TryGetValue("businessFunction", out var val );
            // Do something with the ruleType parameter
            return new OkObjectResult($"You selected {val}");
        }
    }
}
Feoni4 commented 4 months ago

Any updates on the issue? This workaround doesn't work if you annotate a property with an enum. For example: if you have a property with the standard System.DayOfWeek.

{
    [JsonConverter(typeof(StringEnumConverter))]
    public DayOfWeek DayOfWeekEnd { get; init; }
}