azure-functions-openapi-extension icon indicating copy to clipboard operation
azure-functions-openapi-extension copied to clipboard

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

Open johnnyreilly opened this issue 3 years ago • 12 comments

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 https://github.com/Azure/azure-functions-openapi-extension/pull/247 might be the cause?

johnnyreilly avatar Nov 10 '21 17:11 johnnyreilly

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

Did you already find a workaround?

haidelber avatar Nov 12 '21 11:11 haidelber

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

johnnyreilly avatar Nov 12 '21 15:11 johnnyreilly

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

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

faarbaek avatar Dec 01 '21 17:12 faarbaek

Having same problem with a class that contains:

public class AttributeCollection : Dictionary<string, Attribute>

v4 AF, .Net 6, VS 2022

markleavesley avatar Dec 08 '21 15:12 markleavesley

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

Epstone avatar Jul 06 '22 09:07 Epstone

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()

johnnyreilly avatar Aug 08 '22 05:08 johnnyreilly

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.

robertwood62 avatar Sep 28 '22 01:09 robertwood62

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

Shuvajyoti avatar Nov 07 '23 09:11 Shuvajyoti