Skip to content

OpenApiResponseWithBody and aliased Dictionary type triggers error: Index was outside the bounds of the array #313

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
johnnyreilly opened this issue Nov 10, 2021 · 11 comments · May be fixed by #499

Comments

@johnnyreilly
Copy link

johnnyreilly commented Nov 10, 2021

Describe the issue

See minimal repro at https://github.com/johnnyreilly/azure-functions-openapi-extension-error-repro

Consider the following:

    public class Alias : System.Collections.Generic.Dictionary<string, string> {
    }

    public partial class IsBroken {
        public Alias? Attributes { get; set; } = default!;
    }

    public partial class IsWorking {
        public System.Collections.Generic.Dictionary<string, string>? Attributes { get; set; } = default!;
    }

IsWorking and IsBroken are effectively the same. But they trigger different behaviour when used in concert with OpenApiResponseWithBody. Here is IsBroken:

        [OpenApiOperation(operationId: "greeting", Summary = "Greetings", Description = "This shows a welcome message.", Visibility = OpenApiVisibilityType.Important)]
        [OpenApiParameter("name", Type = typeof(string), In = ParameterLocation.Query, Visibility = OpenApiVisibilityType.Important)]
        [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(IsBroken), Summary = "The response", Description = "This returns the response")]

        [FunctionName("NetCoreApp31HttpTrigger")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = "greetings")] HttpRequest req,
            ILogger log)
        {
            await Task.Yield();
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            return new OkObjectResult($"hi {name}");
        }

When you request the swagger.json you receive:

[2021-11-10T17:39:55.760Z] swagger.json was requested.
[2021-11-10T17:39:55.848Z] Index was outside the bounds of the array.

However IsWorking ... works.

        [OpenApiOperation(operationId: "greeting", Summary = "Greetings", Description = "This shows a welcome message.", Visibility = OpenApiVisibilityType.Important)]
        [OpenApiParameter("name", Type = typeof(string), In = ParameterLocation.Query, Visibility = OpenApiVisibilityType.Important)]
        [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(IsWorking), Summary = "The response", Description = "This returns the response")]

        [FunctionName("NetCoreApp31HttpTrigger")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = "greetings")] HttpRequest req,
            ILogger log)
        {
            await Task.Yield();
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            return new OkObjectResult($"hi {name}");
        }

To Reproduce

There's a reproduction repo here: https://github.com/johnnyreilly/azure-functions-openapi-extension-error-repro

Expected behavior

IsBroken should have the same behaviour as IsWorking - it should not trigger the "Index was outside the bounds of the array" error

Screenshots

N/A

Environment (please complete the following information, if applicable):

N/A

Additional context

Having tested historic versions of the package, it looks like it broke between 0.8.1-preview and 0.9.0-preview. Rolling back to 0.8.1-preview makes things work.

I wonder if #247 might be the cause?

@johnnyreilly johnnyreilly changed the title OpenApiResponseWithBody and aliased type triggers error: Index was outside the bounds of the array OpenApiResponseWithBody and aliased Dictionary type triggers error: Index was outside the bounds of the array Nov 10, 2021
@haidelber
Copy link

Same issue here. just tried to use following type as bodyType public class BrokenDto : Dictionary<string, double> { }

Did you already find a workaround?

@johnnyreilly
Copy link
Author

johnnyreilly commented Nov 12, 2021

Yeah - not having aliased types. Not so much a workaround really

NSwag generated the type in question and we could do some work there to help

@faarbaek
Copy link

faarbaek commented Dec 1, 2021

I'm having the same issue using a class with a Dictionary property:

public Dictionary<string, Dictionary<string, object>> Extensions { get; set; }

@markleavesley
Copy link

Having same problem with a class that contains:

public class AttributeCollection : Dictionary<string, Attribute>

v4 AF, .Net 6, VS 2022

@Epstone
Copy link

Epstone commented Jul 6, 2022

@johnnyreilly Can you give a short hint please, how you manipulated the code produced by Nswag to not contain those alias types?

@johnnyreilly
Copy link
Author

I think it's the one below @Epstone :

                    var settings = new CSharpClientGeneratorSettings
                    {
                        ClassName = "MyClient",
                        UseBaseUrl = false,
                        CSharpGeneratorSettings =
                        {
                            Namespace = "My.App",
                            GenerateNullableReferenceTypes = true,
                            GenerateOptionalPropertiesAsNullable = true,
                            GenerateNativeRecords = true,
                            InlineNamedDictionaries = true, // might have been this
                            InlineNamedArrays = true,
                            RequiredPropertiesMustBeDefined = true,
                        }
                    };

                    var generator = new CSharpClientGenerator(document, settings);
                    var code = generator
                        .GenerateFile()

@robertwood62
Copy link

I'm not sure reading through the thread was the resolution/workaround is for this? I have an existing API that uses several alias such as...

public class ParameterValueCollection : Dictionary<string, string>

How can I get these data types to be serialized correctly. I too get the error mentioned above.

[2022-09-28T00:56:47.840Z] swagger.json was requested.
[2022-09-28T00:56:48.309Z] Index was outside the bounds of the array.

@Shuvajyoti
Copy link

Facing similar exception while using System.Text.Json as the serialization/deserialization library. Is there any solution for this yet.

@Trimatix
Copy link

I'd really like to see a solution for this issue.

My use case is that in CI, we update OAS3 specs for our APIs in APIM, but one of our endpoints returns a Dictionary<string, List<Dictionary<string, decimal>>>. The generated OAS3 spec names this type "list_dictionary`2", which fails regex validation for OAS3 component names ^[a-zA-Z0-9\.\-_]+$. The workaround was going to be an aliased type, but that's not possible yet.

@TuckermanRav
Copy link

This issue was reported in 2001. It's now 2024, It's been reported multiple time by a number of different people and there's even active PRs that are years old to potentially fix the issue. How is this possible?

#588
#611
#499

@Trimatix
Copy link

Hi team, this issue still causes production issues for us, has the issue been triaged?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
9 participants