Base solution for your next web application
Open Closed

Error when a list of enums used inside a dto class #12678


User avatar
0
Astech created

I have the following class which is used as a input/filter to an app service method:

using Abp.Actions.Enums;

namespace Abp.Actions.Dtos
{
    public class GetAllActionsFilter
    {
        public List<ActionStatus> Statuses { get; set; }
    }
}

This causes the an error on startup on line number 68 of SwaggerEnumParameterFilter.cs:

concreteSchema.Extensions.Add("x-enumNames", new JsonNodeExtension(enumNames));

The error is: The key already existed in the dictionary

If i remove the list of statuses from the filter class, the error does not occur.

I have found 2 fixes, which are to replace line number 68 of SwaggerEnumParameterFilter.cs with either:

// Fix 1 - only insert if does not exist already
if (!concreteSchema.Extensions.ContainsKey("x-enumNames"))
{
    concreteSchema.Extensions.Add(
        "x-enumNames",
        new JsonNodeExtension(enumNames));
}

or

// Fix 2 - Replace everytime
concreteSchema.Extensions["x-enumNames"] = new JsonNodeExtension(enumNames);

I'd be interested to hear if anyone has any comments on this? Is this something anyone else has experienced and do you see any consequences of this fix?

Many thanks Scott

Markdown is supported
Copy & paste or drag & drop images (max 30 MB per image)

1 Answer(s)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @Astech

    Thank you for reporting this and for sharing your investigation.

    We have confirmed that this is an issue in SwaggerEnumParameterFilter; using List<ActionStatus> in the input DTO is valid and is not the underlying problem.

    When the enum collection is processed, SwaggerEnumSchemaFilter may already have added the x-enumNames extension as a JsonArray. The parameter filter's existing-value check still expects the previous nested JsonObject shape, so the check fails and the code attempts to add the same dictionary key again.

    Both of your changes avoid the exception. As a temporary workaround, we recommend the second option:

    concreteSchema.Extensions["x-enumNames"] = new JsonNodeExtension(enumNames);
    

    This assignment is idempotent and, with the standard ASP.NET Zero Swagger configuration, has no adverse consequence because the value is generated from the same CLR enum. The only potential difference is that it would overwrite x-enumNames if you have a custom Swagger filter that deliberately supplies a different value for that extension.

    The first option also works in the normal generation flow, but ContainsKey followed by Add is not atomic and it would preserve an existing malformed or stale value. Therefore, the indexer assignment is the safer workaround.

    We will correct the filter so enum collections can be used without this workaround.

    Thank you again for bringing this to our attention.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)